本文档记录 miaoguo_system_server 的服务端错误日志采集、入库、查询、本机检查和 Codex 定期检查配置。
线上 Node.js 服务出现异常时,把错误写入 MySQL 的 SystemErrorLogs 表,并提供内部 API 查询。
当前链路:
Koa / console.error / unhandledRejection / uncaughtException
-> SystemErrorLogs
PM2 error log
-> scripts/collect-pm2-error-logs.js
-> SystemErrorLogs
本机 VS Code / Codex
-> SSH 到服务器
-> curl http://127.0.0.1:3050/internal/error-logs
src/util/errorLogger.js: 应用内错误采集入口src/model/systemErrorLog.js: SystemErrorLogs 表和查询模型src/api/internal/routes.js: 内部错误日志 API 路由src/api/internal/errorLogController.js: 内部 API controllerscripts/collect-pm2-error-logs.js: 服务器 PM2 error log 兜底采集scripts/poll-error-logs.js: 本机持续轮询脚本local-error-monitor/: 本机一键检查工具.vscode/tasks.json: VS Code 任务配置doc/system_error_logs.sql: 建表 SQL在服务器项目目录执行:
mysql -u cdb_outerroot -p kylx365_db < doc/system_error_logs.sql
服务启动时也会自动尝试创建表,但首次部署建议手动执行一次,便于确认权限正常。
生成 token:
openssl rand -hex 32
生产环境必须设置:
INTERNAL_API_TOKEN=你的token
注意: token 不要提交到 git,不要写入公开文档。
服务器默认 node 可能是旧版本,所以 PM2 要使用 Node 24 的解释器。
先确认 Node 24 路径:
nvm which 24.1.0
示例路径:
/root/.nvm/versions/node/v24.1.0/bin/node
如果已有 app-24,重启时带上 token:
INTERNAL_API_TOKEN=你的token pm2 restart app-24 --update-env
如果需要重新启动:
INTERNAL_API_TOKEN=你的token pm2 start src/app.js \
--name app-24 \
--interpreter /root/.nvm/versions/node/v24.1.0/bin/node \
--update-env
推荐直接启动脚本,不经过 npm,避免落到旧 Node。
INTERNAL_API_TOKEN=你的token pm2 start scripts/collect-pm2-error-logs.js \
--name error-log-pm2 \
--interpreter /root/.nvm/versions/node/v24.1.0/bin/node \
--update-env
检查状态:
pm2 list
pm2 logs error-log-pm2 --lines 50
正常日志类似:
[pm2-error-log-collector] watching /root/.pm2/logs
保存 PM2 配置:
pm2 save
在服务器上执行:
curl -H "x-internal-token: 你的token" \
"http://127.0.0.1:3050/internal/error-logs/latest?status=all"
正常返回:
{"errcode":10000,"result":{"list":[],"next_since_id":0}}
无 token 应返回 401:
curl "http://127.0.0.1:3050/internal/error-logs/latest?status=all"
正常返回:
{"errcode":10401,"errMsg":"Unauthorized"}
手动写一条测试错误:
/root/.nvm/versions/node/v24.1.0/bin/node -e "import('./src/util/errorLogger.js').then(async ({recordError}) => { await recordError(new Error('manual test error log')); console.log('ok'); process.exit(0); }).catch((err) => { console.error(err); process.exit(1); })"
本机工具目录:
local-error-monitor/
.env复制模板:
cp local-error-monitor/.env.example local-error-monitor/.env
编辑:
ERROR_LOG_SSH_HOST=root@81.68.248.121
ERROR_LOG_REMOTE_API_URL=http://127.0.0.1:3050/internal/error-logs
ERROR_LOG_API_TOKEN=你的token
ERROR_LOG_CHECK_LIMIT=20
ERROR_LOG_CHECK_STATUS=open,reopened
说明:
3050。127.0.0.1:3050。.env 已被 local-error-monitor/.gitignore 忽略,不应提交。建议使用 SSH key,不要把服务器密码写入项目。
本机生成 key:
ssh-keygen -t ed25519 -C "miaoguo-error-monitor"
安装到服务器:
cat ~/.ssh/id_ed25519.pub | ssh root@81.68.248.121 "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys"
测试:
ssh root@81.68.248.121 "echo ok"
不再要求输入密码即可。
也可以配置 ~/.ssh/config:
Host miaoguo-server
HostName 81.68.248.121
User root
IdentityFile ~/.ssh/id_ed25519
然后把 .env 改为:
ERROR_LOG_SSH_HOST=miaoguo-server
在 VS Code 打开项目后:
Cmd + Shift + PTasks: Run Task检查近期服务端 Bug它实际执行:
local-error-monitor/run.sh
检查结果保存到:
local-error-monitor/data/recent-error-check.txt
检查状态保存到:
local-error-monitor/data/check-state.json
下次检查只显示上次之后的新错误。
如果要从头重新检查,删除状态文件:
rm local-error-monitor/data/check-state.json
当前已配置 Codex 自动化:
ID: miaoguo
名称: 定期检查 miaoguo 服务端错误日志
频率: 每 1 小时
状态: ACTIVE
它会定期运行:
/Users/chengjie/Documents/git/miaoguo_system_server/local-error-monitor/run.sh
如果没有新错误,会简短报告没有新错误。
如果有新错误,会在当前 Codex 任务里列出错误摘要。之后可以让 Codex 根据日志定位代码并修复。
说明 SSH 和接口路径已经通了,但 token 不正确。
检查:
local-error-monitor/.env 的 ERROR_LOG_API_TOKENINTERNAL_API_TOKEN服务器验证:
curl -H "x-internal-token: 你的token" \
"http://127.0.0.1:3050/internal/error-logs/latest?status=all"
通常是本机直接访问公网 3050 失败,或者 SSH 隧道方式未启动。
现在推荐使用 local-error-monitor/check-once.js 的 SSH 远程 curl 模式,不需要本机直接访问公网端口。
非交互 SSH 可能不会加载完整 PATH。排查 PM2 时可以用登录 shell:
ssh root@81.68.248.121 'bash -lc "pm2 list"'
说明使用了旧 Node。服务器默认 Node 可能是 12,需要显式使用 Node 24:
/root/.nvm/versions/node/v24.1.0/bin/node
PM2 启动脚本时使用:
--interpreter /root/.nvm/versions/node/v24.1.0/bin/node
INTERNAL_API_TOKEN 和 ERROR_LOG_API_TOKEN 不要提交到 git。app-24、error-log-pm2。3050。