Files

143 lines
5.1 KiB
Markdown
Raw Permalink Normal View History

# Syslog WAL 与分 IP 诊断历史
## 功能范围
`syslog-serve` 每分钟保存一次全局 WAL 状态,并按来源 IP 保存接收、WAL 持久化、Kafka ACK、过滤、背压、丢弃和 TCP 异常计数。网络异常发生时立即写入事件文件。
某个来源 IP 抛出网络接入异常后,如果后续重新收到该 IP 的数据,服务会打印一次
`Syslog 网络接入异常后已恢复接收` 日志,并包含异常时间、恢复时间和两者间隔。该机制不根据无数据时长推断断网,也不生成离线统计;连续正常数据不会重复打印恢复日志。
诊断文件不经过 Kafka 和数据库,默认写入容器目录 `/app/logs/syslog-monitor`。生产编排已将 `/app/logs` 映射到宿主机 `/home/syslog/logs`,因此容器重启不会删除历史。文件按自然日生成,保留今天及此前 6 天,共 7 天。
诊断记录不包含日志正文、凭据或 Kafka 消息内容。
## 文件目录
```text
/home/syslog/logs/syslog-monitor/
├── snapshots/syslog-status-YYYY-MM-DD.jsonl
├── ip-snapshots/syslog-ip-status-YYYY-MM-DD.jsonl
└── events/syslog-events-YYYY-MM-DD.jsonl
```
- `snapshots`:全局 WAL、磁盘和 Kafka 投递状态,每分钟一行。
- `ip-snapshots`:每个来源 IP 每分钟一行,包含进程累计值与相邻快照增量 `delta`。
- `events`:`TOO_LONG_FRAME`、`CONNECTION_RESET`、超长消息和最终设备过滤等即时事件。
每次进程启动生成新的 `instance_id`,并记录 `process_start_time`。对累计值进行跨重启分析时必须按 `instance_id` 分段。
## 部署配置
生产默认值:
```yaml
environment:
- SYSLOG_DIAGNOSTICS_DIRECTORY=/app/logs/syslog-monitor
- SYSLOG_DIAGNOSTICS_RETENTION_DAYS=7
```
可选参数:
```text
SYSLOG_DIAGNOSTICS_ENABLED=true
SYSLOG_DIAGNOSTICS_SNAPSHOT_INTERVAL_MS=60000
SYSLOG_DIAGNOSTICS_MAX_SOURCE_IPS=10000
SYSLOG_DIAGNOSTICS_EVENT_QUEUE_CAPACITY=10000
```
来源 IP 超过上限后,新 IP 的指标汇总到 `__OTHER__`,避免伪造 UDP 来源导致内存无限增长。事件队列满时不会阻塞 Netty 接入线程,丢弃的诊断事件数量通过 `event_queue_dropped` 暴露。
## 现场查询
### 第一步:检查诊断持久化是否正常
```bash
docker exec syslog-serve-dm sh -c \
"curl -fsS http://127.0.0.1:8189/syslogserve/api/syslog/wal/diagnostics/current"
```
确认以下字段:
```text
persistence.enabled = true
persistence.active = true
persistence.retention_days = 7
persistence.initialization_failures = 0
persistence.snapshot_write_failures = 0
persistence.event_write_failures = 0
persistence.event_queue_dropped = 0
persistence.last_write_error = null
```
### 第二步:查询单个来源 IP
```bash
docker exec syslog-serve-dm sh -c \
"curl -fsS 'http://127.0.0.1:8189/syslogserve/api/syslog/wal/diagnostics/current?source_ip=10.56.170.107'"
```
主要字段:
```text
network_received
wal_appended
wal_admission_backpressure
wal_admission_unavailable
kafka_acked
invalid_device_dropped
oversized_dropped
udp_dropped
tcp_pause_total
tcp_pending_frames_current
tcp_pending_frames_max
network_exception_total
tcp_network_exception_total
udp_network_exception_total
tcp_connection_reset_total
tcp_too_long_frame_total
dispatch_terminal_dropped
dispatch_retry
last_receive_time
last_exception_time
```
`wal_appended` 只在 WAL 完成持久化后增加;`kafka_acked` 只在 Kafka 明确 ACK 后增加。
全局状态还包含 `wal_pending_bytes`、`wal_max_pending_bytes`。前者是当前待落盘字节数,后者是配置上限,配置为 `0` 表示不限制。`wal_admission_unavailable` 表示 WAL 因未运行、致命错误或磁盘进入 `CRITICAL` 而拒绝接入尝试的次数;TCP 会保留并重试待处理帧,因此该值不等于 TCP 丢失消息数。`tcp_pending_frames_current` 是当前在 TCP Handler 内等待进入 WAL 的帧数,`tcp_pending_frames_max` 是当前进程启动以来的峰值;连接关闭时未处理帧会从 current 中回减。
### 第三步:查询当天历史
直接在宿主机按 IP 查询:
```bash
grep -F '"source_ip":"10.56.170.107"' \
/home/syslog/logs/syslog-monitor/ip-snapshots/syslog-ip-status-2026-09-16.jsonl
```
查询该 IP 的异常事件:
```bash
grep -F '"source_ip":"10.56.170.107"' \
/home/syslog/logs/syslog-monitor/events/syslog-events-2026-09-16.jsonl
```
也可以通过 HTTP 下载:
```text
GET /syslogserve/api/syslog/wal/diagnostics/history?date=2026-09-16&type=snapshots
GET /syslogserve/api/syslog/wal/diagnostics/history?date=2026-09-16&type=ip
GET /syslogserve/api/syslog/wal/diagnostics/history?date=2026-09-16&type=events
```
## 计数对账
同一 `instance_id` 下:
```text
有效设备 WAL 持久化量 ≈ wal_appended
成功发往 Kafka 的数量 = kafka_acked
当前实例尚未 ACK 的近似数量 = wal_appended - kafka_acked - dispatch_terminal_dropped
```
重启后可能重放旧 WAL,因此分 IP 的 `kafka_acked` 可能暂时大于本实例的 `wal_appended`。此时以全局 `wal_pending_approx`、WAL 序号以及 `instance_id` 为准,不应把负差值解释为异常。