监控与日志配置
- docker/docker-compose.yaml
- docker/configs/octo-server.yaml
- docker/nginx/nginx.conf
- docker/configs/wk.yaml
- 经验建议
OCTO 监控与日志配置指南 v1.0
适用范围:`docker/docker-compose.yaml` 中定义的单机 / 单节点部署。Helm/K8s 部署的监控接入逻辑类似但采集点需参照 K8s 原生探针与 ServiceMonitor。
1. 各服务日志
1.1 Docker 容器日志(默认)
# 查看某个服务实时日志(follow)
docker compose logs -f octo-server
docker compose logs -f --tail=200 mysql
# 查看最近 N 行
docker compose logs --tail=100 nginx
# 带时间戳
docker compose logs -f -t wukongim
# 一次性输出某个服务全部日志(慎用,历史长时易过大)
docker compose logs octo-server > octo-server.log
经验建议:生产环境建议在 `/etc/docker/daemon.json` 中配置 `json-file` 的 `max-size` 与 `max-file` 做日志轮转,避免磁盘被容器日志打满,例如:
```json
{
"log-driver": "json-file",
"log-opts": { "max-size": "100m", "max-file": "5" }
}
```
配置后需 `systemctl reload docker` 并重建容器生效。需要集中收集时可切换 `log-driver` 为 `syslog`、`fluentd` 或 `journald` 后对接 ELK/Loki。
1.2 服务日志级别相关环境变量
| 服务 | 变量 / 配置 | 默认值 | 说明 |
|---|---|---|---|
| octo-server | configs/octo-server.yaml 中 logger.level: 2、mode: "release" |
level=2(info)、mode=release | level 数字越大越详细;mode 可设 debug/release,影响 Gin 框架是否输出 debug 信息 |
| wukongim | WK_MODE |
debug |
WuKongIM 运行模式;生产建议改为 release(在 .env 中设置) |
| redis | 启动参数 --loglevel warning |
warning | 硬编码在 command 中 |
| octo-fleet | LOG_LEVEL |
info(可通过 FLEET_LOG_LEVEL 覆盖) |
Fleet 服务日志级别 |
| docs-html | LOG_LEVEL |
info |
硬编码为 info |
说明:compose 中未发现统一的 `LOG_LEVEL`/`GIN_MODE`/`DEBUG` 变量贯穿所有服务;其余服务(summary、speech、docs-backend、es-indexer、drive-indexer 等)的日志级别未在 compose 中显式暴露,使用镜像默认值。如需调整,需进入对应镜像文档确认环境变量名,或通过定制镜像/entrypoint 设置。
1.3 日志卷与 Nginx 日志
server-logs→ octo-server 容器内/home/logs(对应configs/octo-server.yaml中logger.dir: "./logs",但 compose 挂载到/home/logs,实际路径以容器工作目录为准;经验建议:排查问题时优先使用docker compose logs,如需文件日志需进入容器或挂载路径确认)。nginx-logs→ nginx 容器内/var/log/nginx,其中:/var/log/nginx/access.log:访问日志,格式为main(含 remote_addr、time_local、request、status、body_bytes_sent、referer、user_agent、x_forwarded_for)。/var/log/nginx/error.log:错误日志,级别notice。
# 直接查看 nginx 访问日志(通过卷)
docker run --rm -v octo_nginx-logs:/logs alpine tail -100 /logs/access.log
1.4 中间件日志
- MySQL:使用官方镜像默认配置,日志走 stdout/stderr,可通过
docker compose logs mysql查看错误日志;慢查询日志如需开启需自定义 my.cnf 挂载(当前 compose 未挂载自定义配置)。 - MinIO:输出到 stdout/stderr,默认 info 级别。
- OpenSearch / Kafka / PostgreSQL (fleet-postgres):输出到 stdout/stderr。
2. 健康检查端点
| 服务 | 探针方式 | 端点 / 命令 | 间隔 | 超时 | 重试 | start_period |
|---|---|---|---|---|---|---|
| mysql | CMD-SHELL | mysqladmin ping -h 127.0.0.1 --protocol=tcp -u root |
10s | 5s | 12 | 30s |
| redis | CMD | redis-cli ping |
5s | 3s | 20 | — |
| minio | CMD | curl -fsS http://localhost:9000/minio/health/live |
10s | 5s | 12 | 20s |
| wukongim | CMD-SHELL | wget --header="token: $WK_MANAGERTOKEN" http://localhost:5001/health(fallback /varz) |
10s | 5s | 12 | 40s |
| octo-server | CMD-SHELL | wget http://localhost:8090/v1/ping |
15s | 5s | 12 | 60s |
| nginx | CMD-SHELL | wget http://localhost/_nginx_up(内部 up 探测页) |
10s | 5s | 12 | 10s |
| web(octo-web 前端) | CMD | wget http://127.0.0.1/ |
30s | 5s | 3 | 10s |
| admin(管理后台前端) | CMD | wget http://127.0.0.1/admin/ |
30s | 5s | 3 | 10s |
| marketplace | CMD-SHELL | wget http://localhost:8092/healthz |
15s | 5s | 8 | 30s |
| summary-api(profile: summary) | CMD | wget http://localhost:8080/health |
30s | 5s | 3 | 30s |
| summary-worker(profile: summary) | CMD-SHELL | wget http://localhost:8082/internal/healthz |
30s | 5s | 3 | 30s |
| octo-speech(profile: speech) | CMD bash /dev/tcp | GET / HTTP/1.0 to 127.0.0.1:8780,检查返回含 HTTP/ |
30s | 5s | 3 | 30s |
| octo-speech-admin(profile: speech) | CMD bash /dev/tcp | GET /healthz HTTP/1.0 to 127.0.0.1:8781,要求 2xx |
30s | 5s | 3 | 30s |
| octo-docs-backend(profile: docs) | CMD-SHELL | wget http://localhost:3000/healthz |
15s | 5s | 3 | 60s |
| search-kafka(profile: search) | CMD-SHELL | kafka-broker-api-versions.sh --bootstrap-server localhost:9092 |
15s | 10s | 12 | 30s |
| search-opensearch(profile: search) | CMD-SHELL | curl -fs http://localhost:9200/_cluster/health |
15s | 10s | 18 | 30s |
| fleet-postgres(profile: fleet) | CMD-SHELL | pg_isready -U fleet -d fleet |
10s | 5s | 12 | 30s |
| octo-fleet(profile: fleet) | CMD-SHELL | wget http://localhost:8080/healthz |
15s | 5s | 30 | 300s(迁移耗时较长) |
| doc-indexer(profile: doc-index) | CMD-SHELL(node http 探测) | node http.get http://localhost:3100/readyz,要求 statusCode=200 |
15s | 5s | 5 | 30s |
未配置 healthcheck 的常驻服务
| 服务 | 原因 | 可替代探测方式 |
|---|---|---|
| drive(octo-drive) | distroless 镜像(runAsUser 65532,无 shell/curl/wget) | 通过 nginx 代理后的 /health 端点外部探测,或 docker inspect 看进程状态 |
| docs-html(octo-docs-html) | distroless Go 二进制,无 shell/curl | 通过 nginx /docs-html/ 路径外部探测 /healthz |
| drive-indexer(profile: drive-index) | distroless 二进制(readOnlyRootFilesystem) | 通过上游依赖(Kafka lag、OpenSearch 文档数)间接判断;或外部端口 TCP 探测 |
| tika(profile: drive-index) | 官方 tika 镜像内无 curl/wget | readiness 已由 drive-index-ensure 在启动时 wget /version 阻塞,外部可直接探测 :9998/version |
一次性初始化 Job 类服务(`preflight`、`minio-init`、`*-preflight`、`*-migrate`、`*-kafka-init`、`*-ensure`、`search-cursor-seed`、`search-backfill`、`botfather-robot` 等)属于 run-once 任务,不配置 healthcheck,由 `service_completed_successfully` 条件被下游依赖。
快速查看所有服务健康状态
# 列出所有服务健康状态
docker compose ps
# 仅看 unhealthy 的
docker inspect --format '{{.Name}} {{if .State.Health}}{{.State.Health.Status}}{{end}}' $(docker compose ps -q) | grep -v healthy
3. Prometheus Metrics 端点
| 服务 | Metrics 端点 | 说明 |
|---|---|---|
| MinIO | http://minio:9000/minio/v2/metrics/cluster |
MinIO 原生 Prometheus 端点(集群指标);compose 未将 9000 额外做 Prometheus 专用 scrape 注解,需自行通过容器网络或发布端口采集。另 /minio/v2/metrics/node 提供节点级指标 |
| wukongim | 监控端口 5300(容器内)→ 宿主机 ${OCTO_WK_MONITOR_BIND:-127.0.0.1}:${OCTO_WK_MONITOR_PORT:-25300} |
compose 注释称该端口暴露 varz / metrics / route 等管理面接口。具体路径未在配置中确认(待确认:请在部署后访问 http://127.0.0.1:25300/metrics 验证是否为 Prometheus 文本格式) |
| search-opensearch | http://search-opensearch:9200/_prometheus/metrics(需插件) |
官方 OpenSearch Prometheus 插件需单独安装;当前 compose 使用的是带 analysis-ik 的 OSS 镜像,默认未配置 Prometheus exporter 插件,未在配置中找到 |
| mysql | 未在配置中找到 | 建议部署 mysqld_exporter 作为 sidecar 或独立服务采集 |
| redis | 未在配置中找到 | 建议部署 redis_exporter |
| octo-server | 独立抓取服务器,opt-in默认关闭:需设 DM_METRICS_ENABLED=true 后才监听 :9090【✅源码确认 A-7补证复核:main.go:1076-1078 未设true直接返回nil(避免默默开端口);DM_METRICS_ADDR可调地址;pkg/metrics/server.go仅暴露/metrics,promhttp.Handler】 |
Prometheus标准端点,指标全家桶:HTTP指标(dmwork_http_*)/依赖指标/连接池/头像/会话/sticker/Bot限流指标全部注册到DefaultRegisterer,一次抓取拿全 |
| octo-server自研服务 | 以下服务同仓同机制(各自进程独立:9090或自定义):summary/speech/docs/fleet/drive/indexer等需逐一确认是否启用metrics server(主仓代码已具备能力,各服务镜像是否开启待部署实测) |
经验建议:若需完整 Prometheus 监控,可选用以下两种方案之一:
1. 在宿主机或独立监控节点部署 `node_exporter` + `cAdvisor`,采集主机与容器级 CPU/内存/磁盘/网络指标(不依赖业务暴露 metrics)。
2. 针对中间件补部署官方 exporter(`mysqld_exporter`、`redis_exporter`、`kafka_exporter`、`postgres_exporter`),通过加入 `octo-net` 网络访问各容器。
4. 关键监控指标建议(经验建议)
下表为经验建议,可作为 Prometheus/Grafana 告警规则与监控大盘的基础指标集。
| 层面 | 指标 | 告警阈值建议 | 说明 |
|---|---|---|---|
| 主机 CPU | CPU 使用率(5m avg) | >85% 持续 5min warn;>95% 持续 2min crit | OCTO 为 CPU 密集场景(消息索引、AI 总结、语音),需关注峰值 |
| 主机内存 | 内存使用率 / 可用内存 | 可用 < 10% crit;Swap 使用 > 20% warn | JVM 类服务(OpenSearch/Kafka)对内存敏感 |
| 主机磁盘 | 根分区 / 数据分区使用率 | >80% warn;>90% crit | 特别关注 mysql-data、minio-data、wukongim-data、opensearch-data、kafka-data 所在磁盘,以及 Docker 数据盘 /var/lib/docker |
| 容器状态 | 容器是否在运行 / health 状态 | 任一核心服务 health=unhealthy 持续 2min crit;容器 restart 次数 >5 次/10min warn | 核心服务:octo-server、mysql、redis、minio、wukongim、nginx |
| 容器资源 | 单容器 CPU/Mem 使用率 | Mem OOM 事件 立即 crit | 关注 summary-worker、opensearch 是否被 OOMKill |
| MySQL | 连接数、慢查询数、主从延迟(若有)、QPS | 连接数 > max_connections*80% warn;慢查询突增 warn | 性能问题高发点 |
| Redis | 内存使用率、key 数量、命中命中率 | 内存 > maxmemory*80% warn;命中率 < 0.7 warn | |
| MinIO | 集群/节点健康、bucket 读写延迟、磁盘用量 | 节点离线 crit;bucket 错误率突增 warn | |
| WuKongIM | 在线连接数、消息投递延迟、health 探针 | health 连续失败 crit | 长连接服务对网络抖动敏感 |
| OpenSearch | 集群状态(green/yellow/red)、JVM heap、索引延迟 | cluster=red crit;JVM heap >85% 持续 5min crit | |
| Kafka | Broker 在线、消费 lag(es-indexer、search-producer) | Broker 离线 crit;消费 lag > 10000 持续 10min warn | |
| Nginx | 5xx 比率、请求延迟 P99 | 5xx 比率 > 5% 持续 3min warn |
5. ELK / Grafana 接入简述
5.1 日志:Docker → Filebeat → ELK(经验建议)
- Docker 日志驱动:保持默认 `json-file`(带轮转,见 1.1 节)。
- Filebeat(宿主机部署或容器部署):
- 若宿主机部署 Filebeat:配置
type: container,读取/var/lib/docker/containers/*/*.log,通过add_docker_metadataprocessor 自动附加容器名、service 标签。 - 若容器部署:以特权容器挂载
/var/lib/docker/containers:/var/lib/docker/containers:ro和/var/run/docker.sock(只读)。
- Logstash(可选):做日志解析、字段抽取(如 nginx access log 解析出 status、request_time)。简单场景可由 Filebeat 直接送 Elasticsearch + Ingest Pipeline。
- Elasticsearch:存储与索引。
- Kibana:日志查询、可视化、告警。
对于 octo-server 自己落盘的文件日志(`/home/logs` 挂载到 `server-logs` 卷),可通过 Filebeat 的 `type: log` 配置 `paths: ["/var/lib/docker/volumes/octo_server-logs/_data/*.log"]` 补充采集。
5.2 指标:Prometheus + Grafana(经验建议)
- Prometheus:采集与存储。
- 加入
scrape_configs采集 node_exporter、cAdvisor、各中间件 exporter。 - MinIO 直接通过
http://采集(需确认 9000 端口对 Prometheus 可达,注意鉴权;如 MinIO 开启了 anonymous access 可直接抓)。: /minio/v2/metrics/cluster - Grafana:可视化,推荐导入以下现成 Dashboard ID(Grafana Labs):
- Node Exporter:1860 或 11074
- cAdvisor:14282 或 893
- MySQL:7362
- Redis:763
- PostgreSQL:9628
- Kafka:721
- MinIO:官方 Dashboard(MinIO 文档提供 ID 13502)
- Nginx:由 nginx-prometheus-exporter 暴露后使用 12708
- Alertmanager:告警路由,分发到企微/飞书/邮件/PagerDuty 等。
compose 中没有内置 Prometheus/Grafana 服务,需要在部署 OCTO 的主机或独立监控主机上另行部署。
6. 告警规则建议(经验建议)
P0(立即处理)
- 服务宕机:
container_last_seen{container_label_com_docker_compose_service=~"octo-server|mysql|redis|minio|wukongim|nginx"} == 0(或容器健康health_status == unhealthy持续 2min)。- 磁盘 >90%:
node_filesystem_avail_bytes / node_filesystem_size_bytes < 0.1(数据盘、Docker 盘)。- OOM 事件:
- 容器被 OOM Kill(可通过 cadvisor
container_oom_events_total或docker events --filter event=oom检测)。 - MySQL / Redis / MinIO / WuKongIM 不可达:probe_success == 0 持续 1min。
- OpenSearch cluster status = red。
P1(1小时内处理)
- 磁盘 >80%:
avail/size < 0.2。 - CPU >90% 持续 10min。
- 内存可用 <10% 持续 5min。
- Nginx 5xx 比率 >5% 持续 5min。
- Kafka 消费 lag >10000 持续 10min(es-indexer / search-producer 消费组)。
- 容器频繁重启:容器 restart 次数 10min 内增加 >= 3 次。
P2(工作时间处理)
- CPU >80% 持续 30min(需要扩容或排查)。
- Redis 内存 > maxmemory 80%。
- OpenSearch JVM heap > 85%。
- MySQL 连接数 > 80%。
- MinIO 节点磁盘 >80%。
经验建议:告警收敛非常重要,务必配置 Alertmanager 的 `group_by` 与 `repeat_interval`,避免告警风暴。
7. 常用运维命令
# 1) 查看所有服务状态(含健康状态)
docker compose ps
# 2) 实时跟踪核心服务日志
docker compose logs -f octo-server nginx mysql redis wukongim minio
# 3) 查看最近 200 行 octo-server 日志(带时间戳)
docker compose logs --tail=200 -t octo-server
# 4) 重启单个服务(例如 octo-server 配置变更后)
docker compose restart octo-server
# 5) 进入 octo-server 容器排查
docker compose exec octo-server sh
# 6) 一键健康检查脚本(遍历所有服务健康状态)
docker inspect --format 'table {{.Name}}\t{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}' $(docker compose ps -q)
# 7) 手动打 octo-server ping 端点(宿主机)
curl -fsS http://127.0.0.1:28080/v1/ping # 通过 nginx
curl -fsS http://127.0.0.1:28081/v1/ping # 直接到 octo-server(若 OCTO_SERVER_BIND 开放)
# 8) 查看容器资源使用(实时)
docker stats
# 9) 查看 MySQL / Redis / MinIO 进程是否存活
docker compose exec mysql mysqladmin -p ping # 需输入 MYSQL_ROOT_PASSWORD
docker compose exec redis redis-cli ping
docker compose exec minio curl -fsS http://localhost:9000/minio/health/live
# 10) 查看磁盘占用(含 docker 卷)
docker system df -v
df -h
8. 待确认项
- 各可选 profile 服务(summary-api/worker、speech、docs-backend、fleet、doc-indexer、drive-indexer 等)是否暴露 Prometheus
/metrics端点未在 compose 配置中体现,需由对应服务镜像文档确认。 - wukongim 5300 monitor 端口的
/metrics路径与返回格式需在部署后实测验证。 octo-server文件日志(server-logs 卷)的实际文件名与滚动策略未在配置中明确,需进入容器确认。- 是否存在统一的 GIN_MODE/LOG_LEVEL 全局配置(当前 compose 仅对 fleet 和 docs-html 显式设置 LOG_LEVEL)。
- MinIO metrics 端点是否需要认证(默认配置下,未通过 compose 设置
MINIO_PROMETHEUS_AUTH_TYPE,默认可能为public,需实测)。
附:变更记录
- v1.0(2026-09-22):初版,基于
docker/docker-compose.yaml健康检查配置、configs 与 nginx 配置整理,覆盖日志、健康端点、metrics、监控指标、ELK/Grafana 接入、告警建议与常用命令。