mirror of
https://github.com/Nezumi-2711/astrbot_plugin_qq_group_daily_analysis.git
synced 2026-09-22 13:38:43 +00:00
feat: Add documentation for log quick reference and viewing research.
This commit is contained in:
@@ -0,0 +1,457 @@
|
|||||||
|
# TraceID 日志增强指南 + AstrBot 日志查看
|
||||||
|
|
||||||
|
> **核心观点**:`contextvars + logging.Filter` 方案是对 AstrBot logger 的增强,不是替换。日志仍通过 AstrBot 输出,只是自动注入 trace_id。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔍 日志查看入口(三种方式)
|
||||||
|
|
||||||
|
### 1️⃣ 控制台输出(最简单,开发环境推荐)
|
||||||
|
|
||||||
|
**启动 AstrBot 后,直接在终端看日志**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python main.py
|
||||||
|
|
||||||
|
# 输出示例:
|
||||||
|
[10:30:45] [Plug] [INFO ] [group_daily:45]: [123456789-1707292800] 开始分析群
|
||||||
|
[10:30:46] [Plug] [INFO ] [group_daily:46]: [123456789-1707292800] 获取 256 条消息
|
||||||
|
[10:30:47] [Plug] [INFO ] [group_daily:47]: [123456789-1707292800] 话题分析完成
|
||||||
|
[10:30:48] [Plug] [ERROR] [group_daily:50]: [123456789-1707292800] LLM 超时
|
||||||
|
↑
|
||||||
|
TraceID(自动注入)
|
||||||
|
```
|
||||||
|
|
||||||
|
**优点**:
|
||||||
|
- ✅ 零配置,启动即可看
|
||||||
|
- ✅ 实时显示,彩色输出
|
||||||
|
- ✅ 容易识别错误
|
||||||
|
|
||||||
|
### 2️⃣ 日志文件(生产环境标配)
|
||||||
|
|
||||||
|
**在 `astrbot_config.yml` 中启用文件日志**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
log_file_enable: true
|
||||||
|
log_file_path: "logs/astrbot.log" # 日志文件路径
|
||||||
|
log_file_max_mb: 20 # 文件大小限制(轮转)
|
||||||
|
```
|
||||||
|
|
||||||
|
**查看方式**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Linux/Mac 实时查看
|
||||||
|
tail -f logs/astrbot.log
|
||||||
|
|
||||||
|
# Windows PowerShell 实时查看
|
||||||
|
Get-Content -Path logs/astrbot.log -Wait
|
||||||
|
|
||||||
|
# 搜索特定群的所有日志
|
||||||
|
grep "123456789" logs/astrbot.log
|
||||||
|
|
||||||
|
# 查看最后 100 行
|
||||||
|
tail -100 logs/astrbot.log
|
||||||
|
```
|
||||||
|
|
||||||
|
**优点**:
|
||||||
|
- ✅ 永久保存
|
||||||
|
- ✅ 支持搜索和分析
|
||||||
|
- ✅ 生产环境必须
|
||||||
|
|
||||||
|
### 3️⃣ AstrBot Dashboard(最舒服,Web 界面)
|
||||||
|
|
||||||
|
**方式 A:AstrBot 内置 Dashboard(如果启用了)**
|
||||||
|
|
||||||
|
```
|
||||||
|
访问:http://localhost:8000
|
||||||
|
→ 日志 / Logs 菜单
|
||||||
|
→ 可看实时日志流
|
||||||
|
```
|
||||||
|
|
||||||
|
**方式 B:Astrbot-dashboard 独立工具**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 安装独立的 dashboard 包
|
||||||
|
pip install astrbot-dashboard
|
||||||
|
|
||||||
|
# 启动(连接本地 AstrBot)
|
||||||
|
astrbot-dashboard
|
||||||
|
|
||||||
|
# 浏览器打开
|
||||||
|
# http://localhost:6185/#/console
|
||||||
|
```
|
||||||
|
|
||||||
|
**优点**:
|
||||||
|
- ✅ Web 界面直观
|
||||||
|
- ✅ 实时流式显示
|
||||||
|
- ✅ 支持过滤和搜索
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ 为什么使用 contextvars + logging.Filter?
|
||||||
|
|
||||||
|
### 核心原因:**自动 TraceID 注入**
|
||||||
|
|
||||||
|
```
|
||||||
|
现状问题: 使用 contextvars 后:
|
||||||
|
────────────────────────────────────────────────────
|
||||||
|
logger.info("开始") logger.info("开始")
|
||||||
|
logger.info("获取消息") → logger.info("获取消息")
|
||||||
|
logger.error("超时") logger.error("超时")
|
||||||
|
|
||||||
|
输出: 输出:
|
||||||
|
[INFO] 开始 [trace_id:123] [INFO] 开始
|
||||||
|
[INFO] 获取消息 [trace_id:123] [INFO] 获取消息
|
||||||
|
[ERROR] 超时 [trace_id:123] [ERROR] 超时
|
||||||
|
|
||||||
|
❌ 100 个群并发时看不出 ✅ 清晰看出所有日志属于
|
||||||
|
谁的日志在哪里 同一个分析任务!
|
||||||
|
```
|
||||||
|
|
||||||
|
### 有没有利用 AstrBot 现有日志?
|
||||||
|
|
||||||
|
**完全利用了!** 这是在 AstrBot logger 上添加一层装饰器:
|
||||||
|
|
||||||
|
```
|
||||||
|
你的代码: logger.info("message")
|
||||||
|
↓
|
||||||
|
[TraceIDFilter](新增)← 自动注入 trace_id
|
||||||
|
↓
|
||||||
|
[AstrBot Logger](已有)
|
||||||
|
├─ ColoredFormatter
|
||||||
|
├─ StreamHandler(控制台)
|
||||||
|
└─ RotatingFileHandler(文件)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 代码实现(简化版)
|
||||||
|
|
||||||
|
```python
|
||||||
|
# src/utils/trace.py
|
||||||
|
import contextvars
|
||||||
|
import logging
|
||||||
|
from astrbot.api import logger
|
||||||
|
|
||||||
|
# 全局 ContextVar
|
||||||
|
_trace_id: contextvars.ContextVar[str] = contextvars.ContextVar('trace_id', default='')
|
||||||
|
|
||||||
|
# 自定义 Filter
|
||||||
|
class TraceIDFilter(logging.Filter):
|
||||||
|
def filter(self, record):
|
||||||
|
record.trace_id = _trace_id.get('') or 'no-trace'
|
||||||
|
return True
|
||||||
|
|
||||||
|
# 注册到 AstrBot logger(在插件初始化时)
|
||||||
|
logger.addFilter(TraceIDFilter())
|
||||||
|
|
||||||
|
# 使用(在分析开始处)
|
||||||
|
async def analyze_group(group_id: str):
|
||||||
|
import time
|
||||||
|
|
||||||
|
# 设置 trace_id
|
||||||
|
_trace_id.set(f"{group_id}-{int(time.time())}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
logger.info("开始分析") # 自动包含 trace_id
|
||||||
|
# ... 分析逻辑
|
||||||
|
finally:
|
||||||
|
_trace_id.set('') # 清理
|
||||||
|
```
|
||||||
|
|
||||||
|
### 输出效果
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ tail -f logs/astrbot.log | grep trace_id
|
||||||
|
|
||||||
|
[123456789-1707292800] [10:30:45] [Plug] [INFO ] [group_daily:45]: 开始分析群
|
||||||
|
[123456789-1707292800] [10:30:46] [Plug] [INFO ] [group_daily:46]: 获取 256 条消息
|
||||||
|
[123456789-1707292800] [10:30:47] [Plug] [INFO ] [group_daily:47]: 话题分析完成
|
||||||
|
[123456789-1707292800] [10:30:48] [Plug] [ERROR] [group_daily:50]: LLM 超时
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🏗️ 架构流程图
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ AstrBot 应用 │
|
||||||
|
├─────────────────────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ 核心组件/插件 │
|
||||||
|
│ │ │
|
||||||
|
│ ├─→ logger.info("message") │
|
||||||
|
│ └─→ logger.error("error") │
|
||||||
|
│ │
|
||||||
|
│ ▼ │
|
||||||
|
│ ┌──────────────────────────────────────┐ │
|
||||||
|
│ │ LogQueueHandler (日志处理器) │ │
|
||||||
|
│ │ 接收 logging.LogRecord │ │
|
||||||
|
│ └──────────────────────────────────────┘ │
|
||||||
|
│ ▼ │
|
||||||
|
│ ┌──────────────────────────────────────────────────────┐ │
|
||||||
|
│ │ LogBroker (日志代理) │ │
|
||||||
|
│ │ - log_cache: deque(maxlen=500) [环形缓冲区] │ │
|
||||||
|
│ │ - subscribers: List[Queue] [订阅者队列] │ │
|
||||||
|
│ │ │ │
|
||||||
|
│ │ publish(log_entry): │ │
|
||||||
|
│ │ 1. 添加到 log_cache │ │
|
||||||
|
│ │ 2. 分发给所有 subscribers │ │
|
||||||
|
│ └──────────────────────────────────────────────────────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ ├──────────────────┬─────────────────────────────┐ │
|
||||||
|
│ ▼ ▼ ▼ │
|
||||||
|
│ ┌─────────────┐ ┌───────────────┐ ┌──────────────┐ │
|
||||||
|
│ │ Dashboard │ │ Trace Logger │ │ 其他订阅者 │ │
|
||||||
|
│ │ SSE 连接 │ │ (可选) │ │ (可选) │ │
|
||||||
|
│ │ (实时推送) │ │ (文件/内存) │ │ │ │
|
||||||
|
│ └─────────────┘ └───────────────┘ └──────────────┘ │
|
||||||
|
│ │
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
▼
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ 数据输出 │
|
||||||
|
├─────────────────────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ 1. Dashboard UI (/:console) │
|
||||||
|
│ - 实时日志显示 │
|
||||||
|
│ - 级别过滤 │
|
||||||
|
│ │
|
||||||
|
│ 2. 日志文件 (可选) │
|
||||||
|
│ - data/logs/astrbot.log │
|
||||||
|
│ - data/logs/astrbot.trace.log │
|
||||||
|
│ │
|
||||||
|
│ 3. 浏览器 Memory │
|
||||||
|
│ - SSE 缓存 (断网重连补发) │
|
||||||
|
│ │
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📁 文件位置速查
|
||||||
|
|
||||||
|
| 类型 | 位置 | 启用方式 |
|
||||||
|
|------|------|--------|
|
||||||
|
| **普通日志** | `data/logs/astrbot.log` | `log_file_enable: true` |
|
||||||
|
| **Trace 日志** | `data/logs/astrbot.trace.log` | `trace_log_enable: true` |
|
||||||
|
| **配置文件** | `data/cmd_config.json` | 直接编辑 |
|
||||||
|
| **数据目录** | `data/` | 环境变量 `ASTRBOT_ROOT` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 配置项清单
|
||||||
|
|
||||||
|
### 日志配置(最常用)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"log_level": "INFO", // DEBUG|INFO|WARNING|ERROR|CRITICAL
|
||||||
|
"log_file_enable": false, // 启用文件日志
|
||||||
|
"log_file_path": "logs/astrbot.log", // 相对于 data/ 目录
|
||||||
|
"log_file_max_mb": 20, // 单个文件最大大小
|
||||||
|
|
||||||
|
"trace_enable": false, // 启用 Trace 记录
|
||||||
|
"trace_log_enable": false, // 启用 Trace 文件日志
|
||||||
|
"trace_log_path": "logs/astrbot.trace.log", // Trace 文件位置
|
||||||
|
"trace_log_max_mb": 20
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💻 代码使用速查
|
||||||
|
|
||||||
|
### 记录日志(最常用)
|
||||||
|
|
||||||
|
```python
|
||||||
|
from astrbot.core import logger
|
||||||
|
|
||||||
|
logger.debug("Debug message")
|
||||||
|
logger.info("Info message")
|
||||||
|
logger.warning("Warning message")
|
||||||
|
logger.error("Error message")
|
||||||
|
logger.critical("Critical error")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Trace 追踪(链路追踪)
|
||||||
|
|
||||||
|
```python
|
||||||
|
from astrbot.core.utils.trace import TraceSpan
|
||||||
|
|
||||||
|
span = TraceSpan(
|
||||||
|
name="operation_name",
|
||||||
|
sender_name="ComponentA",
|
||||||
|
message_outline="Brief description"
|
||||||
|
)
|
||||||
|
|
||||||
|
span.record("stage1", key1="value1")
|
||||||
|
span.record("stage2", key2="value2")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 订阅日志流(高级)
|
||||||
|
|
||||||
|
```python
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
async def listen_logs(log_broker):
|
||||||
|
queue = log_broker.register()
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
log_entry = await queue.get()
|
||||||
|
print(f"{log_entry['level']}: {log_entry['data']}")
|
||||||
|
finally:
|
||||||
|
log_broker.unregister(queue)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 常见操作
|
||||||
|
|
||||||
|
### ❓ 如何启用文件日志?
|
||||||
|
|
||||||
|
1. 打开 `data/cmd_config.json`
|
||||||
|
2. 修改:
|
||||||
|
```json
|
||||||
|
"log_file_enable": true,
|
||||||
|
"log_file_path": "logs/astrbot.log"
|
||||||
|
```
|
||||||
|
3. 重启应用
|
||||||
|
|
||||||
|
### ❓ 如何查看特定群的日志?
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 方式 1: Dashboard 中搜索 group_id
|
||||||
|
http://localhost:6185/#/console
|
||||||
|
|
||||||
|
# 方式 2: 命令行查询
|
||||||
|
grep "QQGroup:123456789" data/logs/astrbot.log
|
||||||
|
```
|
||||||
|
|
||||||
|
### ❓ 如何用 span_id 追踪完整请求?
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Trace 日志包含 span_id,可追踪单个请求的全生命周期
|
||||||
|
grep "span_id.*abc-123-def" data/logs/astrbot.trace.log
|
||||||
|
|
||||||
|
# 或在 Dashboard 的 /trace 页面实时查看
|
||||||
|
```
|
||||||
|
|
||||||
|
### ❓ 日志缓存大小是多少?
|
||||||
|
|
||||||
|
- **内存缓存**: 最近 500 条日志(deque with maxlen=500)
|
||||||
|
- **Dashboard 前端缓存**: 最近 1000 条日志
|
||||||
|
- **文件日志**: 单个文件 20MB,自动轮转(3 个备份)
|
||||||
|
|
||||||
|
### ❓ 日志是否会自动删除?
|
||||||
|
|
||||||
|
- **内存缓存**: 自动淘汰(先进先出,保持最近 500 条)
|
||||||
|
- **文件日志**: 不自动删除,需手动管理或配置轮转
|
||||||
|
- **Dashboard 前端**: 页面关闭后清空
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 日志格式示例
|
||||||
|
|
||||||
|
### Console 日志输出
|
||||||
|
|
||||||
|
```
|
||||||
|
[12:34:56] [Core] [INFO] [astrbot.py:123]: Application started successfully
|
||||||
|
[12:34:57] [Plug] [WARN] [plugin.py:45]: Missing dependency: requests
|
||||||
|
[12:35:00] [Core] [ERRO] [error.py:78]: Connection timeout to server [v4.14.4]
|
||||||
|
```
|
||||||
|
|
||||||
|
格式:`[时间] [来源] [级别] [文件:行号]: 消息`
|
||||||
|
|
||||||
|
### Trace JSON 日志
|
||||||
|
|
||||||
|
```json
|
||||||
|
[2024-01-01 12:34:56] {"type":"trace","span_id":"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx","name":"group_analysis","sender_name":"QQGroup:123456789","action":"start","fields":{"group_id":"123456789","step":"initialization"}}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎨 日志级别和颜色
|
||||||
|
|
||||||
|
| 级别 | 缩写 | 颜色 | 含义 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| DEBUG | DBUG | 🟢 绿色 | 调试信息 |
|
||||||
|
| INFO | INFO | 🔵 青色 | 一般信息 |
|
||||||
|
| WARNING | WARN | 🟡 黄色 | 警告信息 |
|
||||||
|
| ERROR | ERRO | 🔴 红色 | 错误信息 |
|
||||||
|
| CRITICAL | CRIT | 🟣 紫色 | 严重错误 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📈 性能指标
|
||||||
|
|
||||||
|
| 项目 | 值 | 说明 |
|
||||||
|
|------|-----|------|
|
||||||
|
| 日志缓存大小 | 500 条 | 环形缓冲区 |
|
||||||
|
| Dashboard 前端缓存 | 1000 条 | 浏览器内存 |
|
||||||
|
| SSE 队列大小 | 510 条 | maxsize = CACHED_SIZE + 10 |
|
||||||
|
| 日志文件大小 | 20MB | 单个文件,可配置 |
|
||||||
|
| 备份文件数 | 3 个 | 自动轮转 |
|
||||||
|
| SSE 连接超时 | None | 永不超时 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔐 安全相关
|
||||||
|
|
||||||
|
### 日志中的敏感信息
|
||||||
|
|
||||||
|
```python
|
||||||
|
# ❌ 不要直接记录密钥
|
||||||
|
logger.info(f"API key: {api_key}")
|
||||||
|
|
||||||
|
# ✅ 使用脱敏
|
||||||
|
logger.info(f"API key: {api_key[:8]}...")
|
||||||
|
|
||||||
|
# ✅ 或使用占位符
|
||||||
|
logger.info(f"Using API key: ***")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dashboard 访问认证
|
||||||
|
|
||||||
|
- 默认用户名:`astrbot`
|
||||||
|
- 默认密码:(MD5 哈希,需在配置中修改)
|
||||||
|
- JWT Token:用于 API 认证
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔗 相关链接
|
||||||
|
|
||||||
|
| 资源 | 位置 |
|
||||||
|
|------|------|
|
||||||
|
| 完整文档 | `LOG_VIEWING_RESEARCH.md` |
|
||||||
|
| 日志实现 | `astrbot/core/log.py` |
|
||||||
|
| Trace 系统 | `astrbot/core/utils/trace.py` |
|
||||||
|
| Dashboard API | `astrbot/dashboard/routes/log.py` |
|
||||||
|
| 前端组件 | `dashboard/src/components/shared/ConsoleDisplayer.vue` |
|
||||||
|
| 默认配置 | `astrbot/core/config/default.py` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ 检查清单
|
||||||
|
|
||||||
|
### 开发调试
|
||||||
|
|
||||||
|
- [ ] Dashboard 可以实时看到日志
|
||||||
|
- [ ] 日志级别设置为 DEBUG
|
||||||
|
- [ ] Trace 追踪已启用(if needed)
|
||||||
|
|
||||||
|
### 生产部署
|
||||||
|
|
||||||
|
- [ ] 日志级别设置为 INFO
|
||||||
|
- [ ] 文件日志已启用(for persistence)
|
||||||
|
- [ ] 日志轮转已配置
|
||||||
|
- [ ] 监控系统已连接
|
||||||
|
|
||||||
|
### 问题诊断
|
||||||
|
|
||||||
|
- [ ] 日志中包含 span_id(for tracing)
|
||||||
|
- [ ] 时间戳正确(for correlation)
|
||||||
|
- [ ] 日志级别适当(not too verbose)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*最后更新:2024年 | AstrBot v4.14.4*
|
||||||
@@ -0,0 +1,677 @@
|
|||||||
|
# AstrBot 日志查看方式研究报告
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
本文档详细说明了 AstrBot 的日志系统架构、查看方式、以及如何在代码中集成日志查看功能。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 日志文件默认位置
|
||||||
|
|
||||||
|
### 1.1 日志文件存储位置
|
||||||
|
|
||||||
|
根据配置,AstrBot 的日志文件存储在以下位置:
|
||||||
|
|
||||||
|
| 日志类型 | 默认位置 | 配置键 | 说明 |
|
||||||
|
|---------|--------|-------|------|
|
||||||
|
| **普通日志** | `data/logs/astrbot.log` | `log_file_path` | 主应用日志,记录应用运行信息 |
|
||||||
|
| **Trace 日志** | `data/logs/astrbot.trace.log` | `trace_log_path` | 链路追踪日志,记录请求跨度信息 |
|
||||||
|
|
||||||
|
### 1.2 日志文件配置参数
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 配置文件位置: astrbot/core/config/default.py
|
||||||
|
DEFAULT_CONFIG = {
|
||||||
|
"log_level": "INFO", # 日志级别(DEBUG, INFO, WARNING, ERROR, CRITICAL)
|
||||||
|
"log_file_enable": False, # 是否启用文件日志(默认禁用)
|
||||||
|
"log_file_path": "logs/astrbot.log", # 日志文件相对路径(相对于 data/ 目录)
|
||||||
|
"log_file_max_mb": 20, # 单个日志文件最大大小(MB)
|
||||||
|
"trace_enable": False, # 是否启用 Trace 记录
|
||||||
|
"trace_log_enable": False, # 是否启用 Trace 文件日志
|
||||||
|
"trace_log_path": "logs/astrbot.trace.log", # Trace 日志文件路径
|
||||||
|
"trace_log_max_mb": 20, # Trace 日志文件最大大小
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.3 日志目录基路径
|
||||||
|
|
||||||
|
- **根数据目录**: `data/`
|
||||||
|
- **日志目录**: `data/logs/`
|
||||||
|
- **获取方法**(Python 代码):
|
||||||
|
```python
|
||||||
|
from astrbot.core.utils.astrbot_path import get_astrbot_data_path
|
||||||
|
log_dir = os.path.join(get_astrbot_data_path(), "logs")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.4 日志文件轮转配置
|
||||||
|
|
||||||
|
当启用文件日志时,AstrBot 使用 `RotatingFileHandler`:
|
||||||
|
- 最大单个文件大小:`log_file_max_mb`(默认 20MB)
|
||||||
|
- 备份文件数量:3 个
|
||||||
|
- 超过大小后自动轮转:`astrbot.log.1`, `astrbot.log.2`, `astrbot.log.3`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Dashboard 中的日志查看功能
|
||||||
|
|
||||||
|
### 2.1 Dashboard 路由和 API
|
||||||
|
|
||||||
|
AstrBot Dashboard 提供以下日志相关的 REST API(代码位置:`astrbot/dashboard/routes/log.py`):
|
||||||
|
|
||||||
|
| API 端点 | 方法 | 功能 | 说明 |
|
||||||
|
|---------|------|------|------|
|
||||||
|
| `/api/live-log` | GET | 实时日志流 | Server-Sent Events (SSE) 连接,推送实时日志 |
|
||||||
|
| `/api/log-history` | GET | 日志历史 | 获取缓存的日志历史(JSON 格式) |
|
||||||
|
| `/api/trace/settings` | GET | Trace 设置查询 | 获取当前 Trace 启用状态 |
|
||||||
|
| `/api/trace/settings` | POST | Trace 设置更新 | 更新 Trace 启用/禁用状态 |
|
||||||
|
|
||||||
|
### 2.2 实时日志流(SSE)
|
||||||
|
|
||||||
|
#### 连接方式
|
||||||
|
|
||||||
|
**前端代码**(Vue.js,位置:`dashboard/src/stores/common.js`):
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
fetch('/api/live-log', {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'multipart/form-data',
|
||||||
|
'Authorization': 'Bearer ' + localStorage.getItem('token')
|
||||||
|
},
|
||||||
|
cache: 'no-cache',
|
||||||
|
}).then(response => {
|
||||||
|
const reader = response.body.getReader();
|
||||||
|
const decoder = new TextDecoder();
|
||||||
|
// 处理流式数据...
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
#### SSE 消息格式
|
||||||
|
|
||||||
|
后端返回的 SSE 消息格式(`astrbot/dashboard/routes/log.py`):
|
||||||
|
|
||||||
|
```
|
||||||
|
id: {timestamp}
|
||||||
|
data: {json_object}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
JSON 对象结构:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"level": "INFO",
|
||||||
|
"data": "[12:34:56] [Core] [INFO] [file.py:123]: Log message",
|
||||||
|
"time": 1697787296.123456,
|
||||||
|
"uuid": "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 日志缓存和重放
|
||||||
|
|
||||||
|
- **缓存大小**: 最多 500 条日志(常量 `CACHED_SIZE = 500`)
|
||||||
|
- **缓存数据结构**: `deque(maxlen=500)`(环形缓冲区)
|
||||||
|
- **浏览器断网重连**: 发送 `Last-Event-ID` 请求头,服务端根据时间戳重放缺失的日志
|
||||||
|
|
||||||
|
### 2.3 Dashboard 前端界面
|
||||||
|
|
||||||
|
#### 控制台页面(Console)
|
||||||
|
|
||||||
|
**路由**: `/console`
|
||||||
|
**组件**: [ConsolePage.vue](dashboard/src/views/ConsolePage.vue)
|
||||||
|
|
||||||
|
功能:
|
||||||
|
- ✅ 实时日志显示(通过 SSE 连接)
|
||||||
|
- ✅ 日志级别过滤(DEBUG, INFO, WARNING, ERROR, CRITICAL)
|
||||||
|
- ✅ 自动滚动开关
|
||||||
|
- ✅ pip 包安装界面
|
||||||
|
|
||||||
|
日志样式:
|
||||||
|
```
|
||||||
|
[12:34:56] [Core] [INFO] [astrbot.py:123]: AstrBot started successfully
|
||||||
|
[12:34:57] [Plug] [WARN] [plugin.py:45]: Missing dependency
|
||||||
|
[12:35:00] [Core] [ERRO] [error.py:78]: Connection timeout [v4.14.4]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 链路追踪页面(Trace)
|
||||||
|
|
||||||
|
**路由**: `/trace`
|
||||||
|
**组件**: [TracePage.vue](dashboard/src/views/TracePage.vue)
|
||||||
|
|
||||||
|
功能:
|
||||||
|
- ✅ 实时链路追踪显示
|
||||||
|
- ✅ Trace 启用/禁用开关
|
||||||
|
- ✅ Trace 事件详细信息展示
|
||||||
|
|
||||||
|
#### 日志显示器组件
|
||||||
|
|
||||||
|
**组件**: [ConsoleDisplayer.vue](dashboard/src/components/shared/ConsoleDisplayer.vue)
|
||||||
|
|
||||||
|
特性:
|
||||||
|
- 日志级别色彩标记
|
||||||
|
- ANSI 颜色代码转换为 HTML 样式
|
||||||
|
- 日志缓存最多保留 1000 条(configurable)
|
||||||
|
- 自动滚动到最新日志
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. LogBroker 架构(发布-订阅模式)
|
||||||
|
|
||||||
|
### 3.1 LogBroker 类设计
|
||||||
|
|
||||||
|
**位置**: `astrbot/core/log.py`
|
||||||
|
|
||||||
|
```python
|
||||||
|
class LogBroker:
|
||||||
|
"""日志代理类, 用于缓存和分发日志消息"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.log_cache = deque(maxlen=CACHED_SIZE) # 环形缓冲区
|
||||||
|
self.subscribers: list[Queue] = [] # 订阅者列表
|
||||||
|
|
||||||
|
def register(self) -> Queue:
|
||||||
|
"""注册新的订阅者,返回一个队列用于接收日志"""
|
||||||
|
q = Queue(maxsize=CACHED_SIZE + 10)
|
||||||
|
self.subscribers.append(q)
|
||||||
|
return q
|
||||||
|
|
||||||
|
def unregister(self, q: Queue):
|
||||||
|
"""取消订阅"""
|
||||||
|
self.subscribers.remove(q)
|
||||||
|
|
||||||
|
def publish(self, log_entry: dict):
|
||||||
|
"""发布日志到所有订阅者(非阻塞方式)"""
|
||||||
|
self.log_cache.append(log_entry)
|
||||||
|
for q in self.subscribers:
|
||||||
|
try:
|
||||||
|
q.put_nowait(log_entry)
|
||||||
|
except asyncio.QueueFull:
|
||||||
|
pass # 订阅者队列满,丢弃该日志
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 工作流程图
|
||||||
|
|
||||||
|
```
|
||||||
|
日志记录器 (logger)
|
||||||
|
↓
|
||||||
|
LogQueueHandler (日志处理器)
|
||||||
|
↓
|
||||||
|
LogBroker.publish(log_entry)
|
||||||
|
├→ 添加到 log_cache(环形缓冲区)
|
||||||
|
└→ 分发给所有订阅者的队列
|
||||||
|
├→ Dashboard SSE 连接
|
||||||
|
├→ Trace 日志记录器
|
||||||
|
└→ 其他订阅者
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 日志项结构
|
||||||
|
|
||||||
|
```python
|
||||||
|
log_entry = {
|
||||||
|
"level": "INFO", # 日志级别
|
||||||
|
"time": 1697787296.123, # Unix 时间戳
|
||||||
|
"data": "Log message text", # 格式化的日志文本
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.4 在代码中集成 LogBroker
|
||||||
|
|
||||||
|
#### 启动应用时初始化
|
||||||
|
|
||||||
|
```python
|
||||||
|
# main.py 或 cmd_run.py
|
||||||
|
from astrbot.core import LogBroker, LogManager, logger
|
||||||
|
|
||||||
|
# 创建日志代理
|
||||||
|
log_broker = LogBroker()
|
||||||
|
|
||||||
|
# 将日志处理器连接到 LogBroker
|
||||||
|
LogManager.set_queue_handler(logger, log_broker)
|
||||||
|
|
||||||
|
# 传递给应用初始化器
|
||||||
|
core_lifecycle = InitialLoader(db, log_broker)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 在 Dashboard 中使用
|
||||||
|
|
||||||
|
```python
|
||||||
|
# dashboard/routes/log.py
|
||||||
|
class LogRoute(Route):
|
||||||
|
def __init__(self, context: RouteContext, log_broker: LogBroker) -> None:
|
||||||
|
self.log_broker = log_broker
|
||||||
|
# 注册 API 路由...
|
||||||
|
|
||||||
|
async def log(self) -> QuartResponse:
|
||||||
|
"""SSE 日志流"""
|
||||||
|
queue = self.log_broker.register() # 注册订阅者
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
message = await queue.get() # 等待日志
|
||||||
|
yield _format_log_sse(message, current_ts)
|
||||||
|
finally:
|
||||||
|
self.log_broker.unregister(queue) # 取消订阅
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Trace 日志系统
|
||||||
|
|
||||||
|
### 4.1 Trace 概念
|
||||||
|
|
||||||
|
Trace 日志用于记录**请求的整个链路**,包括:
|
||||||
|
- 跨度信息(span_id)
|
||||||
|
- 请求发起者(sender_name)
|
||||||
|
- 操作阶段(action)
|
||||||
|
- 自定义字段(fields)
|
||||||
|
|
||||||
|
### 4.2 Trace 启用配置
|
||||||
|
|
||||||
|
**配置项**:
|
||||||
|
```python
|
||||||
|
"trace_enable": False, # 启用 Trace 记录
|
||||||
|
"trace_log_enable": False, # 启用 Trace 文件日志
|
||||||
|
"trace_log_path": "logs/astrbot.trace.log", # Trace 日志文件路径
|
||||||
|
```
|
||||||
|
|
||||||
|
**Dashboard 设置**: `/api/trace/settings` 端点可动态启用/禁用 Trace
|
||||||
|
|
||||||
|
### 4.3 使用 TraceSpan 记录链路
|
||||||
|
|
||||||
|
**代码位置**: `astrbot/core/utils/trace.py`
|
||||||
|
|
||||||
|
```python
|
||||||
|
from astrbot.core.utils.trace import TraceSpan
|
||||||
|
|
||||||
|
# 创建 Trace 跨度
|
||||||
|
span = TraceSpan(
|
||||||
|
name="group_analysis",
|
||||||
|
umo="qq_group",
|
||||||
|
sender_name="QQGroup:123456789",
|
||||||
|
message_outline="Daily analysis request"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 记录不同阶段的操作
|
||||||
|
span.record("start", step="initialization")
|
||||||
|
span.record("process", data_count=1000)
|
||||||
|
span.record("end", result_code=200)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.4 Trace 日志格式
|
||||||
|
|
||||||
|
**发布到 LogBroker**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "trace",
|
||||||
|
"level": "TRACE",
|
||||||
|
"time": 1697787296.123,
|
||||||
|
"span_id": "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx",
|
||||||
|
"name": "group_analysis",
|
||||||
|
"umo": "qq_group",
|
||||||
|
"sender_name": "QQGroup:123456789",
|
||||||
|
"message_outline": "Daily analysis request",
|
||||||
|
"action": "start",
|
||||||
|
"fields": {"step": "initialization"}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**写入文件**(JSON 格式,每行一条):
|
||||||
|
```json
|
||||||
|
[2024-01-01 12:34:56] {"type":"trace","span_id":"...","name":"group_analysis",...}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.5 Trace 查询方式
|
||||||
|
|
||||||
|
1. **Dashboard UI** (`/trace` 路由)
|
||||||
|
- 实时查看所有 Trace 事件
|
||||||
|
- 可启用/禁用 Trace 记录
|
||||||
|
|
||||||
|
2. **日志文件查询**
|
||||||
|
- 文件位置:`data/logs/astrbot.trace.log`
|
||||||
|
- 使用 `jq` 或 Python 解析 NDJSON 格式
|
||||||
|
|
||||||
|
3. **span_id 查询** - 用于追踪单个请求
|
||||||
|
```bash
|
||||||
|
grep "span_id.*abc123" data/logs/astrbot.trace.log
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 日志访问方式总结
|
||||||
|
|
||||||
|
### 5.1 实时日志查看
|
||||||
|
|
||||||
|
| 方式 | 说明 | 适用场景 |
|
||||||
|
|------|------|---------|
|
||||||
|
| **Dashboard Console** | 浏览器访问 `http://localhost:6185/#/console` | 实时监控、界面友好 |
|
||||||
|
| **REST API SSE** | `GET /api/live-log`(Server-Sent Events) | 集成第三方系统 |
|
||||||
|
| **文件直接查看** | `tail -f data/logs/astrbot.log` | 服务器终端查看 |
|
||||||
|
|
||||||
|
### 5.2 历史日志查看
|
||||||
|
|
||||||
|
| 方式 | 说明 | 命令/代码 |
|
||||||
|
|------|------|---------|
|
||||||
|
| **Dashboard History** | `GET /api/log-history` 返回缓存的日志 | 返回最近 500 条 |
|
||||||
|
| **文件查询** | 日志文件存储在 `data/logs/astrbot.log` | `grep` 或编辑器打开 |
|
||||||
|
| **日志分析** | Python/shell 脚本处理日志文件 | 自定义分析 |
|
||||||
|
|
||||||
|
### 5.3 Trace 日志查看
|
||||||
|
|
||||||
|
| 方式 | 说明 | 对应 API |
|
||||||
|
|------|------|---------|
|
||||||
|
| **Dashboard Trace** | 实时追踪链路,浏览器访问 `/trace` | SSE 推送 |
|
||||||
|
| **Trace 文件** | `data/logs/astrbot.trace.log`(NDJSON 格式) | 离线分析 |
|
||||||
|
| **span_id 查询** | 按 span_id 追踪单个请求 | `grep` 搜索 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 插件/群分析日志集成示例
|
||||||
|
|
||||||
|
### 6.1 为群分析日志添加 Trace ID
|
||||||
|
|
||||||
|
对于"QQ 群日常分析插件"(`astrbot_plugin_qq_group_daily_analysis`),可以这样集成日志追踪:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# main.py 或分析模块
|
||||||
|
from astrbot import logger
|
||||||
|
from astrbot.core.utils.trace import TraceSpan
|
||||||
|
|
||||||
|
class GroupAnalyzer:
|
||||||
|
def analyze_group(self, group_id: str):
|
||||||
|
# 创建追踪跨度
|
||||||
|
span = TraceSpan(
|
||||||
|
name="group_daily_analysis",
|
||||||
|
umo="qq_group",
|
||||||
|
sender_name=f"QQGroup:{group_id}",
|
||||||
|
message_outline=f"Daily analysis for group {group_id}"
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
span.record("start", group_id=group_id)
|
||||||
|
logger.info(f"[GroupAnalysis] Starting analysis for group: {group_id}")
|
||||||
|
|
||||||
|
# 分析逻辑...
|
||||||
|
data = self._fetch_messages(group_id)
|
||||||
|
span.record("fetch_complete", message_count=len(data))
|
||||||
|
|
||||||
|
# 处理数据...
|
||||||
|
result = self._process_data(data)
|
||||||
|
span.record("process_complete", result_code=200)
|
||||||
|
|
||||||
|
logger.info(f"[GroupAnalysis] Analysis complete for {group_id}")
|
||||||
|
return result
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
span.record("error", error_type=type(e).__name__, error_msg=str(e))
|
||||||
|
logger.error(f"[GroupAnalysis] Error analyzing group {group_id}: {e}")
|
||||||
|
raise
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.2 查询特定群的日志
|
||||||
|
|
||||||
|
**在 Dashboard 中**:
|
||||||
|
1. 打开 `/console` 页面
|
||||||
|
2. 输入日志过滤器(或查看所有日志)
|
||||||
|
3. 搜索 `GroupAnalysis` 或特定的 group_id
|
||||||
|
|
||||||
|
**通过命令行**:
|
||||||
|
```bash
|
||||||
|
# 查找特定群的日志
|
||||||
|
grep "QQGroup:123456789" data/logs/astrbot.log
|
||||||
|
|
||||||
|
# 或查找 Trace 日志
|
||||||
|
grep "group_id.*123456789" data/logs/astrbot.trace.log
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.3 日志格式确保
|
||||||
|
|
||||||
|
在日志中需要包含:
|
||||||
|
- **时间戳**: 自动添加(格式 `HH:MM:SS`)
|
||||||
|
- **日志级别**: DEBUG, INFO, WARNING, ERROR, CRITICAL
|
||||||
|
- **来源标记**: [Core] 或 [Plug]
|
||||||
|
- **文件和行号**: 自动添加
|
||||||
|
- **消息内容**: 手动添加
|
||||||
|
|
||||||
|
**示例日志行**:
|
||||||
|
```
|
||||||
|
[12:34:56] [Plug] [INFO] [group_analyzer.py:145]: [GroupAnalysis] Analysis complete for QQGroup:123456789
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. LogManager 高级配置
|
||||||
|
|
||||||
|
### 7.1 配置日志级别
|
||||||
|
|
||||||
|
```python
|
||||||
|
from astrbot.core import LogManager, logger
|
||||||
|
|
||||||
|
# 根据配置设置日志级别
|
||||||
|
config = {
|
||||||
|
"log_level": "DEBUG",
|
||||||
|
"log_file_enable": True,
|
||||||
|
"log_file_path": "logs/astrbot.log",
|
||||||
|
"log_file_max_mb": 50,
|
||||||
|
}
|
||||||
|
|
||||||
|
LogManager.configure_logger(logger, config)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.2 配置 Trace 日志
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 启用 Trace 日志文件
|
||||||
|
config = {
|
||||||
|
"trace_enable": True,
|
||||||
|
"trace_log_enable": True,
|
||||||
|
"trace_log_path": "logs/astrbot.trace.log",
|
||||||
|
"trace_log_max_mb": 30,
|
||||||
|
}
|
||||||
|
|
||||||
|
LogManager.configure_trace_logger(config)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.3 日志过滤器
|
||||||
|
|
||||||
|
LogManager 自动添加以下过滤器:
|
||||||
|
|
||||||
|
| 过滤器 | 功能 | 输出示例 |
|
||||||
|
|-------|------|--------|
|
||||||
|
| **PluginFilter** | 标记日志来源(Core/Plug) | `[Core]` 或 `[Plug]` |
|
||||||
|
| **FileNameFilter** | 修改文件名格式 | `folder.filename` |
|
||||||
|
| **LevelNameFilter** | 4 字母缩写 | `DBUG`, `INFO`, `WARN`, `ERRO`, `CRIT` |
|
||||||
|
| **AstrBotVersionTagFilter** | 在 WARNING 及以上追加版本 | `[v4.14.4]` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. 日志配置管理
|
||||||
|
|
||||||
|
### 8.1 配置文件路径
|
||||||
|
|
||||||
|
- **配置文件**: `data/cmd_config.json`
|
||||||
|
- **默认配置**: `astrbot/core/config/default.py`
|
||||||
|
- **编辑方式**:
|
||||||
|
1. 直接编辑 JSON 文件
|
||||||
|
2. 通过 Dashboard 管理面板修改(未来功能)
|
||||||
|
|
||||||
|
### 8.2 配置更新
|
||||||
|
|
||||||
|
配置更改后,需要重启应用以生效(或通过 API 动态更新)。
|
||||||
|
|
||||||
|
### 8.3 环境变量支持
|
||||||
|
|
||||||
|
**根目录自定义**(可选):
|
||||||
|
```bash
|
||||||
|
export ASTRBOT_ROOT=/path/to/root
|
||||||
|
# 数据目录将为 /path/to/root/data
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. 代码示例汇总
|
||||||
|
|
||||||
|
### 9.1 获取日志记录器
|
||||||
|
|
||||||
|
```python
|
||||||
|
from astrbot.core import logger
|
||||||
|
|
||||||
|
# 已配置的全局日志记录器
|
||||||
|
logger.info("Message")
|
||||||
|
logger.debug("Debug message")
|
||||||
|
logger.warning("Warning")
|
||||||
|
logger.error("Error")
|
||||||
|
logger.critical("Critical error")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 9.2 创建自定义日志记录器
|
||||||
|
|
||||||
|
```python
|
||||||
|
from astrbot.core import LogManager
|
||||||
|
|
||||||
|
# 获取命名日志记录器
|
||||||
|
plugin_logger = LogManager.GetLogger("my_plugin")
|
||||||
|
plugin_logger.info("Plugin message")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 9.3 发起 Trace 追踪
|
||||||
|
|
||||||
|
```python
|
||||||
|
from astrbot.core.utils.trace import TraceSpan
|
||||||
|
|
||||||
|
span = TraceSpan(
|
||||||
|
name="custom_operation",
|
||||||
|
umo="custom_type",
|
||||||
|
sender_name="CustomOperator",
|
||||||
|
message_outline="Operation description"
|
||||||
|
)
|
||||||
|
|
||||||
|
span.record("stage1", param1="value1")
|
||||||
|
span.record("stage2", param2="value2", status="success")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 9.4 订阅日志流(自定义)
|
||||||
|
|
||||||
|
```python
|
||||||
|
import asyncio
|
||||||
|
from astrbot.core import LogBroker
|
||||||
|
|
||||||
|
# 从 LogBroker 获取日志队列
|
||||||
|
log_broker = app.log_broker # 从应用上下文获取
|
||||||
|
|
||||||
|
async def listen_logs():
|
||||||
|
queue = log_broker.register()
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
log_entry = await queue.get()
|
||||||
|
print(f"[{log_entry['level']}] {log_entry['data']}")
|
||||||
|
finally:
|
||||||
|
log_broker.unregister(queue)
|
||||||
|
|
||||||
|
# 运行监听器
|
||||||
|
asyncio.run(listen_logs())
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. 常见问题和最佳实践
|
||||||
|
|
||||||
|
### 10.1 为什么文件日志默认禁用?
|
||||||
|
|
||||||
|
- 性能考虑(避免磁盘 I/O 开销)
|
||||||
|
- 容器环境中不需要持久化
|
||||||
|
- 大多数用户通过 Dashboard 查看日志
|
||||||
|
|
||||||
|
### 10.2 启用文件日志的步骤
|
||||||
|
|
||||||
|
1. 编辑 `data/cmd_config.json`:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"log_file_enable": true,
|
||||||
|
"log_file_path": "logs/astrbot.log",
|
||||||
|
"log_file_max_mb": 50
|
||||||
|
}
|
||||||
|
```
|
||||||
|
2. 重启 AstrBot 应用
|
||||||
|
3. 日志将写入 `data/logs/astrbot.log`
|
||||||
|
|
||||||
|
### 10.3 日志级别选择
|
||||||
|
|
||||||
|
- **DEBUG**: 开发调试,包含所有详细信息
|
||||||
|
- **INFO**: 生产环境推荐,记录重要事件
|
||||||
|
- **WARNING**: 只记录警告和错误
|
||||||
|
- **ERROR**: 仅记录错误
|
||||||
|
- **CRITICAL**: 仅记录严重错误
|
||||||
|
|
||||||
|
### 10.4 Trace ID 用于群分析追踪
|
||||||
|
|
||||||
|
对于"QQ 群日常分析"场景:
|
||||||
|
- 每个群的分析请求都有唯一的 `span_id`
|
||||||
|
- 可通过此 ID 追踪整个分析流程
|
||||||
|
- 涉及多群并发时日志清晰分离
|
||||||
|
|
||||||
|
**查询示例**:
|
||||||
|
```bash
|
||||||
|
# 查找 span_id 相关的所有日志
|
||||||
|
grep "span_id: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx" data/logs/astrbot.trace.log
|
||||||
|
```
|
||||||
|
|
||||||
|
### 10.5 性能考虑
|
||||||
|
|
||||||
|
- **日志缓存**: 最多 500 条,超出自动淘汰(先进先出)
|
||||||
|
- **SSE 连接**: 断网自动重连,支持日志补发
|
||||||
|
- **文件轮转**: 单个文件超过 20MB(可配置)自动轮转
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. 相关文件速查表
|
||||||
|
|
||||||
|
| 功能 | 文件路径 |
|
||||||
|
|------|--------|
|
||||||
|
| 日志核心逻辑 | `astrbot/core/log.py` |
|
||||||
|
| 日志管理器 | `astrbot/core/log.py` (LogManager 类) |
|
||||||
|
| Trace 系统 | `astrbot/core/utils/trace.py` |
|
||||||
|
| Dashboard API | `astrbot/dashboard/routes/log.py` |
|
||||||
|
| 默认配置 | `astrbot/core/config/default.py` |
|
||||||
|
| 路径工具 | `astrbot/core/utils/astrbot_path.py` |
|
||||||
|
| Dashboard Console UI | `dashboard/src/views/ConsolePage.vue` |
|
||||||
|
| 日志显示器组件 | `dashboard/src/components/shared/ConsoleDisplayer.vue` |
|
||||||
|
| Trace UI | `dashboard/src/views/TracePage.vue` |
|
||||||
|
| 公共 Store | `dashboard/src/stores/common.js` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 12. 总结
|
||||||
|
|
||||||
|
### 日志查看的完整流程
|
||||||
|
|
||||||
|
1. **应用启动**
|
||||||
|
- LogBroker 初始化
|
||||||
|
- LogQueueHandler 连接到日志记录器
|
||||||
|
|
||||||
|
2. **日志产生**
|
||||||
|
- 应用或插件调用 `logger.info()` 等方法
|
||||||
|
- LogQueueHandler 拦截日志记录
|
||||||
|
|
||||||
|
3. **日志分发**
|
||||||
|
- LogBroker.publish() 添加到缓存
|
||||||
|
- 分发给所有订阅者(Dashboard SSE、Trace 日志等)
|
||||||
|
|
||||||
|
4. **用户查看**
|
||||||
|
- **Dashboard Console**: 实时看到日志
|
||||||
|
- **REST API**: 获取历史日志或 SSE 流
|
||||||
|
- **文件**: 直接查看 `data/logs/astrbot.log`
|
||||||
|
|
||||||
|
5. **Trace 追踪**
|
||||||
|
- 创建 TraceSpan 记录请求链路
|
||||||
|
- Dashboard `/trace` 实时查看
|
||||||
|
- 或通过 span_id 在文件中查询
|
||||||
|
|
||||||
|
### 推荐使用方式
|
||||||
|
|
||||||
|
- **开发调试**: Dashboard `/console` 页面
|
||||||
|
- **生产监控**: 启用文件日志 + 日志收集系统
|
||||||
|
- **问题诊断**: 通过 span_id 追踪完整请求链路
|
||||||
|
- **群分析**: 在日志中包含 group_id,便于后续查询
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*本文档基于 AstrBot v4.14.4 代码分析生成。*
|
||||||
Reference in New Issue
Block a user