119 lines
4.1 KiB
Python
119 lines
4.1 KiB
Python
import traceback
|
|
import psutil
|
|
import time
|
|
import threading
|
|
from .route import Route, Response, RouteContext
|
|
from astrbot.core import logger
|
|
from quart import request
|
|
from astrbot.core.core_lifecycle import AstrBotCoreLifecycle
|
|
from astrbot.core.db import BaseDatabase
|
|
from astrbot.core.config import VERSION
|
|
from astrbot.core import DEMO_MODE
|
|
|
|
|
|
class StatRoute(Route):
|
|
def __init__(
|
|
self,
|
|
context: RouteContext,
|
|
db_helper: BaseDatabase,
|
|
core_lifecycle: AstrBotCoreLifecycle,
|
|
) -> None:
|
|
super().__init__(context)
|
|
self.routes = {
|
|
"/stat/get": ("GET", self.get_stat),
|
|
"/stat/version": ("GET", self.get_version),
|
|
"/stat/start-time": ("GET", self.get_start_time),
|
|
"/stat/restart-core": ("POST", self.restart_core),
|
|
}
|
|
self.db_helper = db_helper
|
|
self.register_routes()
|
|
self.core_lifecycle = core_lifecycle
|
|
|
|
async def restart_core(self):
|
|
if DEMO_MODE:
|
|
return (
|
|
Response()
|
|
.error("You are not permitted to do this operation in demo mode")
|
|
.__dict__
|
|
)
|
|
|
|
await self.core_lifecycle.restart()
|
|
return Response().ok().__dict__
|
|
|
|
def format_sec(self, sec: int):
|
|
m, s = divmod(sec, 60)
|
|
h, m = divmod(m, 60)
|
|
return f"{h}小时{m}分{s}秒"
|
|
|
|
async def get_version(self):
|
|
return Response().ok({"version": VERSION}).__dict__
|
|
|
|
async def get_start_time(self):
|
|
return Response().ok({"start_time": self.core_lifecycle.start_time}).__dict__
|
|
|
|
async def get_stat(self):
|
|
offset_sec = request.args.get("offset_sec", 86400)
|
|
offset_sec = int(offset_sec)
|
|
try:
|
|
stat = self.db_helper.get_base_stats(offset_sec)
|
|
now = int(time.time())
|
|
start_time = now - offset_sec
|
|
message_time_based_stats = []
|
|
|
|
idx = 0
|
|
for bucket_end in range(start_time, now, 1800):
|
|
cnt = 0
|
|
while (
|
|
idx < len(stat.platform)
|
|
and stat.platform[idx].timestamp < bucket_end
|
|
):
|
|
cnt += stat.platform[idx].count
|
|
idx += 1
|
|
message_time_based_stats.append([bucket_end, cnt])
|
|
|
|
stat_dict = stat.__dict__
|
|
|
|
cpu_percent = psutil.cpu_percent(interval=0.5)
|
|
thread_count = threading.active_count()
|
|
|
|
# 获取插件信息
|
|
plugins = self.core_lifecycle.star_context.get_all_stars()
|
|
plugin_info = []
|
|
for plugin in plugins:
|
|
info = {
|
|
"name": getattr(plugin, "name", plugin.__class__.__name__),
|
|
"version": getattr(plugin, "version", "1.0.0"),
|
|
"is_enabled": True,
|
|
}
|
|
plugin_info.append(info)
|
|
|
|
stat_dict.update(
|
|
{
|
|
"platform": self.db_helper.get_grouped_base_stats(
|
|
offset_sec
|
|
).platform,
|
|
"message_count": self.db_helper.get_total_message_count() or 0,
|
|
"platform_count": len(
|
|
self.core_lifecycle.platform_manager.get_insts()
|
|
),
|
|
"plugin_count": len(plugins),
|
|
"plugins": plugin_info,
|
|
"message_time_series": message_time_based_stats,
|
|
"running": self.format_sec(
|
|
int(time.time()) - self.core_lifecycle.start_time
|
|
),
|
|
"memory": {
|
|
"process": psutil.Process().memory_info().rss >> 20,
|
|
"system": psutil.virtual_memory().total >> 20,
|
|
},
|
|
"cpu_percent": round(cpu_percent, 1),
|
|
"thread_count": thread_count,
|
|
"start_time": self.core_lifecycle.start_time,
|
|
}
|
|
)
|
|
|
|
return Response().ok(stat_dict).__dict__
|
|
except Exception as e:
|
|
logger.error(traceback.format_exc())
|
|
return Response().error(e.__str__()).__dict__
|