perf: 更好的日志输出;

fix: 修复可视化面板刷新404
This commit is contained in:
Soulter
2024-05-08 19:01:36 +08:00
parent a13562dcea
commit 08cd3ca40c
12 changed files with 177 additions and 298 deletions
+9 -7
View File
@@ -13,7 +13,6 @@ from nakuru.entities.components import (
from util import general_utils as gu
from model.provider.provider import Provider
from util.cmd_config import CmdConfig as cc
from util.general_utils import Logger
from cores.astrbot.types import (
GlobalObject,
AstrMessageEvent,
@@ -24,6 +23,10 @@ from cores.astrbot.types import (
)
from typing import List, Tuple
from SparkleLogging.utils.core import LogManager
from logging import Logger
logger: Logger = LogManager.GetLogger(log_name='astrbot-core')
PLATFORM_QQCHAN = 'qqchan'
PLATFORM_GOCQ = 'gocq'
@@ -35,7 +38,6 @@ class Command:
def __init__(self, provider: Provider, global_object: GlobalObject = None):
self.provider = provider
self.global_object = global_object
self.logger: Logger = global_object.logger
async def check_command(self,
message,
@@ -85,11 +87,11 @@ class Command:
if hit:
return True, res
except BaseException as e:
self.logger.log(
f"{plugin.metadata.plugin_name} 插件异常,原因: {str(e)}\n如果你没有相关装插件的想法, 请直接忽略此报错, 不影响其他功能的运行。", level=gu.LEVEL_WARNING)
logger.error(
f"{plugin.metadata.plugin_name} 插件异常,原因: {str(e)}\n如果你没有相关装插件的想法, 请直接忽略此报错, 不影响其他功能的运行。")
except BaseException as e:
self.logger.log(
f"{plugin.metadata.plugin_name} 插件异常,原因: {str(e)}\n如果你没有相关装插件的想法, 请直接忽略此报错, 不影响其他功能的运行。", level=gu.LEVEL_WARNING)
logger.error(
f"{plugin.metadata.plugin_name} 插件异常,原因: {str(e)}\n如果你没有相关装插件的想法, 请直接忽略此报错, 不影响其他功能的运行。")
if self.command_start_with(message, "nick"):
return True, self.set_nick(message, platform, role)
@@ -248,7 +250,7 @@ class Command:
p = gu.create_markdown_image(msg)
return [Image.fromFileSystem(p),]
except BaseException as e:
self.logger.log(str(e))
logger.error(str(e))
return msg
def command_start_with(self, message: str, *args):
+8 -5
View File
@@ -16,6 +16,10 @@ import time
from ._platfrom import Platform
from ._message_parse import nakuru_message_parse_rev
from cores.astrbot.types import MessageType, AstrBotMessage, MessageMember
from SparkleLogging.utils.core import LogManager
from logging import Logger
logger: Logger = LogManager.GetLogger(log_name='astrbot-core')
class FakeSource:
@@ -34,7 +38,6 @@ class QQGOCQ(Platform):
self.waiting = {}
self.cc = CmdConfig()
self.cfg = cfg
self.logger: gu.Logger = global_object.logger
try:
self.nick_qq = cfg['nick_qq']
@@ -106,8 +109,8 @@ class QQGOCQ(Platform):
self.client.run()
async def handle_msg(self, message: AstrBotMessage):
self.logger.log(
f"{message.sender.nickname}/{message.sender.user_id} -> {self.parse_message_outline(message)}", tag="QQ_GOCQ")
logger.info(
f"{message.sender.nickname}/{message.sender.user_id} -> {self.parse_message_outline(message)}")
assert isinstance(message.raw_message,
(GroupMessage, FriendMessage, GuildMessage))
@@ -188,8 +191,8 @@ class QQGOCQ(Platform):
res = result_message
self.logger.log(
f"{source.user_id} <- {self.parse_message_outline(res)}", tag="QQ_GOCQ")
logger.info(
f"{source.user_id} <- {self.parse_message_outline(res)}")
if isinstance(source, int):
source = FakeSource("GroupMessage", source)
+8 -7
View File
@@ -18,10 +18,12 @@ from ._message_parse import (
from cores.astrbot.types import MessageType, AstrBotMessage, MessageMember
from typing import Union, List
from nakuru.entities.components import BaseMessageComponent
from SparkleLogging.utils.core import LogManager
from logging import Logger
logger: Logger = LogManager.GetLogger(log_name='astrbot-core')
# QQ 机器人官方框架
class botClient(Client):
def set_platform(self, platform: 'QQOfficial'):
self.platform = platform
@@ -59,7 +61,6 @@ class QQOfficial(Platform):
self.token = cfg['qqbot']['token']
self.secret = cfg['qqbot_secret']
self.unique_session = cfg['uniqueSessionMode']
self.logger: gu.Logger = global_object.logger
qq_group = cfg['qqofficial_enable_group_message']
if qq_group:
@@ -104,8 +105,8 @@ class QQOfficial(Platform):
is_group = message.type != MessageType.FRIEND_MESSAGE
_t = "/私聊" if not is_group else ""
self.logger.log(
f"{message.sender.nickname}({message.sender.user_id}{_t}) -> {self.parse_message_outline(message)}", tag="QQ_OFFICIAL")
logger.info(
f"{message.sender.nickname}({message.sender.user_id}{_t}) -> {self.parse_message_outline(message)}")
# 解析出 session_id
if self.unique_session or not is_group:
@@ -157,8 +158,8 @@ class QQOfficial(Platform):
source = message
assert isinstance(source, (botpy.message.Message,
botpy.message.GroupMessage, botpy.message.DirectMessage))
self.logger.log(
f"{message.sender.nickname}({message.sender.user_id}) <- {self.parse_message_outline(res)}", tag="QQ_OFFICIAL")
logger.info(
f"{message.sender.nickname}({message.sender.user_id}) <- {self.parse_message_outline(res)}")
plain_text = ''
image_path = ''
+25 -31
View File
@@ -14,7 +14,10 @@ from cores.database.conn import dbConn
from model.provider.provider import Provider
from util import general_utils as gu
from util.cmd_config import CmdConfig
from util.general_utils import Logger
from SparkleLogging.utils.core import LogManager
from logging import Logger
logger: Logger = LogManager.GetLogger(log_name='astrbot-core')
abs_path = os.path.dirname(os.path.realpath(sys.argv[0])) + '/'
@@ -23,7 +26,6 @@ abs_path = os.path.dirname(os.path.realpath(sys.argv[0])) + '/'
class ProviderOpenAIOfficial(Provider):
def __init__(self, cfg):
self.cc = CmdConfig()
self.logger = Logger()
self.key_list = []
# 如果 cfg['key'] 中有长度为 1 的字符串,那么是格式错误,直接报错
@@ -43,7 +45,7 @@ class ProviderOpenAIOfficial(Provider):
self.api_base = None
if 'api_base' in cfg and cfg['api_base'] != 'none' and cfg['api_base'] != '':
self.api_base = cfg['api_base']
self.logger.log(f"设置 api_base 为: {self.api_base}", tag="OpenAI")
logger.info(f"设置 api_base 为: {self.api_base}")
# 创建 OpenAI Client
self.client = AsyncOpenAI(
@@ -52,8 +54,6 @@ class ProviderOpenAIOfficial(Provider):
)
self.openai_model_configs: dict = cfg['chatGPTConfigs']
self.logger.log(
f'加载 OpenAI Chat Configs: {self.openai_model_configs}', tag="OpenAI")
self.openai_configs = cfg
# 会话缓存
self.session_dict = {}
@@ -69,10 +69,9 @@ class ProviderOpenAIOfficial(Provider):
db1 = dbConn()
for session in db1.get_all_session():
self.session_dict[session[0]] = json.loads(session[1])['data']
self.logger.log("读取历史记录成功。", tag="OpenAI")
logger.info("读取历史记录成功。")
except BaseException as e:
self.logger.log("读取历史记录失败,但不影响使用。",
level=gu.LEVEL_ERROR, tag="OpenAI")
logger.info("读取历史记录失败,但不影响使用。")
# 创建转储定时器线程
threading.Thread(target=self.dump_history, daemon=True).start()
@@ -143,15 +142,12 @@ class ProviderOpenAIOfficial(Provider):
if self.openai_model_configs['max_tokens'] < len(_encoded_prompt):
prompt = self.enc.decode(_encoded_prompt[:int(
self.openai_model_configs['max_tokens']*0.80)])
self.logger.log(f"注意,有一部分 prompt 文本由于超出 token 限制而被截断。",
level=gu.LEVEL_WARNING, tag="OpenAI")
logger.info(f"注意,有一部分 prompt 文本由于超出 token 限制而被截断。")
cache_data_list, new_record, req = self.wrap(
prompt, session_id, image_url)
self.logger.log(f"cache: {str(cache_data_list)}",
level=gu.LEVEL_DEBUG, tag="OpenAI")
self.logger.log(f"request: {str(req)}",
level=gu.LEVEL_DEBUG, tag="OpenAI")
logger.debug(f"cache: {str(cache_data_list)}")
logger.debug(f"request: {str(req)}")
retry = 0
response = None
err = ''
@@ -194,15 +190,15 @@ class ProviderOpenAIOfficial(Provider):
if 'Invalid content type. image_url is only supported by certain models.' in str(e):
raise e
if 'You exceeded' in str(e) or 'Billing hard limit has been reached' in str(e) or 'No API key provided' in str(e) or 'Incorrect API key provided' in str(e):
self.logger.log("当前 Key 已超额或异常, 正在切换",
level=gu.LEVEL_WARNING, tag="OpenAI")
logger.info("当前 Key 已超额或异常, 正在切换",
)
self.key_stat[self.client.api_key]['exceed'] = True
is_switched = self.handle_switch_key()
if not is_switched:
raise e
retry -= 1
elif 'maximum context length' in str(e):
self.logger.log("token 超限, 清空对应缓存,并进行消息截断", tag="OpenAI")
logger.info("token 超限, 清空对应缓存,并进行消息截断")
self.session_dict[session_id] = []
prompt = prompt[:int(len(prompt)*truncate_rate)]
truncate_rate -= 0.05
@@ -213,17 +209,17 @@ class ProviderOpenAIOfficial(Provider):
time.sleep(30)
continue
else:
self.logger.log(str(e), level=gu.LEVEL_ERROR, tag="OpenAI")
logger.error(str(e))
time.sleep(2)
err = str(e)
retry += 1
if retry >= 10:
self.logger.log(
r"如果报错, 且您的机器在中国大陆内, 请确保您的电脑已经设置好代理软件(梯子), 并在配置文件设置了系统代理地址。详见 https://github.com/Soulter/QQChannelChatGPT/wiki", tag="OpenAI")
logger.warning(
r"如果报错, 且您的机器在中国大陆内, 请确保您的电脑已经设置好代理软件(梯子), 并在配置文件设置了系统代理地址。详见 https://github.com/Soulter/QQChannelChatGPT/wiki")
raise BaseException("连接出错: "+str(err))
assert isinstance(response, ChatCompletion)
self.logger.log(
f"OPENAI RESPONSE: {response.usage}", level=gu.LEVEL_DEBUG, tag="OpenAI")
logger.debug(
f"OPENAI RESPONSE: {response.usage}")
# 结果分类
choice = response.choices[0]
@@ -288,18 +284,16 @@ class ProviderOpenAIOfficial(Provider):
image_url.append(response.data[i].url)
break
except Exception as e:
self.logger.log(str(e), level=gu.LEVEL_ERROR)
logger.warning(str(e))
if 'You exceeded' in str(e) or 'Billing hard limit has been reached' in str(
e) or 'No API key provided' in str(e) or 'Incorrect API key provided' in str(e):
self.logger.log("当前 Key 已超额或者不正常, 正在切换",
level=gu.LEVEL_WARNING, tag="OpenAI")
logger.warning("当前 Key 已超额或者不正常, 正在切换")
self.key_stat[self.client.api_key]['exceed'] = True
is_switched = self.handle_switch_key()
if not is_switched:
raise e
elif 'Your request was rejected as a result of our safety system.' in str(e):
self.logger.log("您的请求被 OpenAI 安全系统拒绝, 请稍后再试",
level=gu.LEVEL_WARNING, tag="OpenAI")
logger.warning("您的请求被 OpenAI 安全系统拒绝, 请稍后再试")
raise e
else:
retry += 1
@@ -378,12 +372,12 @@ class ProviderOpenAIOfficial(Provider):
continue
is_all_exceed = False
self.client.api_key = key
self.logger.log(
f"切换到 Key: {key}(已使用 token: {self.key_stat[key]['used']})", level=gu.LEVEL_INFO, tag="OpenAI")
logger.warning(
f"切换到 Key: {key}(已使用 token: {self.key_stat[key]['used']})")
break
if is_all_exceed:
self.logger.log(
"所有 Key 已超额", level=gu.LEVEL_CRITICAL, tag="OpenAI")
logger.warning(
"所有 Key 已超额")
return False
return True