feat(syslog): 增加普通通道字段截断并完善慢写诊断

- 新增普通通道字段上限配置,默认2048个UTF-8字节,截断尾部保留标记
- 规则计算后执行截断,告警不应用新增2KB限制,原有256KB策略不变
- 非标原文、头部及详细原因应用新增限制,大日志通道和InfluxDB策略不变
- Retry/Replay按原始Topic识别通道,启动日志输出生效上限
- 补充达梦实际写入内容大小、最大行及最大字段诊断
- 慢日志默认阈值统一调整为1000毫秒,异常和失败仍记录
- 更新v4配置说明及回归测试

验证:JDK 8构建成功,250项测试通过
升级:替换JAR并重启,无需数据库或Kafka脚本
This commit is contained in:
王绍宏
2026-09-13 08:00:08 +08:00
parent 8173c2ff3f
commit e393350c8b
16 changed files with 684 additions and 19 deletions
@@ -125,12 +125,43 @@ docker exec syslog-consumer-rule-dm sh -c 'curl -fsS http://127.0.0.1:8289/xdrru
`dropped_fact_rows_total` 指受统计缺失影响的事实行数/尝试行数,并不表示事实数据被删除。
这些内存指标会在重启后清零,不能覆盖崩溃时丢失的统计。损失日志最多每10秒一次,计数逐次累加。
`published_total` 仅表示Kafka确认,不代表统计已落达梦;统计最终入库还需检查投影消费组积压。
`SLOW_DM_TRANSACTION` 自动沿用500ms阈值,无须打开所有事务INFO日志:
`SLOW_DM_TRANSACTION` 自动沿用1000ms(1秒)默认阈值,无须打开所有事务INFO日志:
`connectionBeginMs`包括取连接/事务初始化,`lateAlarmBucketMs`仅为分钟桶小键准备/注册提交回调,
`jdbcExecuteMs`是JDBC批执行,`statsProjectionStageMs`在DIRECT下是统计事件构造/注册回调阶段,
不含后台Kafka/统计写库;`commitMs`是事实事务提交阶段。状态中的统计成功指标表示聚合/注册完成,不保证投影落库。
`SLOW_DM_QUEUE` 单独说明批写任务排队超过阈值。
### 达梦写入内容大小诊断
`SLOW_DM_TRANSACTION` 的普通表/告警表成功慢事务、失败事务日志增加以下字段,无需新配置、数据库或Kafka脚本:
| 字段 | 含义 |
| --- | --- |
| sizeEstimateStatus | COMPLETE:支持的参数内容已测量;PARTIAL:有未测量类型;FAILED:估算异常;NOT_MEASURED:尚未执行到测量阶段 |
| estimatedPayloadBytes | 本次小事务实际INSERT列的非空参数内容估算总字节数 |
| maxRowEstimatedBytes | 单行内容估算最大字节数 |
| maxFieldEstimatedBytes / maxFieldName | 单个字段值最大估算字节数及列名,不打印内容;同大小取首个,均为零时名称为none |
| unmeasuredValues | 不支持测量的非空参数个数,如LOB/流/自定义对象;不会为了测量读取它们 |
| sizeEstimateMs | 大小估算自身耗时,包含在事务总耗时中,不计入jdbcExecuteMs或commitMs |
测量在已有字段截断和字段准备之后、按表元数据确定INSERT列之后、绑定和执行之前进行。
String按UTF-8计数(含中文、emoji,不创建完整编码字节数组),byte[]按原始长度计数,
常用数值/布尔/日期按文本表示估算,NULL计零。不包含SQL文本、驱动协议、索引、数据库页及REDO开销,
也不等于数据库字符集编码后的物理长度。COMPLETE表示参数内容估算完整,不代表精确磁盘字节数。
失败事务表示本次尝试量,不是成功落库量;失败/二分/重试的多条日志不能累加为净新增量。
NOT_MEASURED或FAILED中的零/部分值不能理解为本次写入内容为空。
仅增加观测,不修改字段值、截断阈值、保存条数或Kafka确认策略;不覆盖现有非标异步写库路径。
若需要快慢批次对照,已有stats.direct.transaction-log-enabled=true可打印DIRECT成功事务信息(日志量会增加)。
客户仍在宿主机执行:
```bash
docker logs --since 10m syslog-consumer-rule-dm 2>&1 | grep 'SLOW_DM_TRANSACTION' | tail -30
```
将estimatedPayloadBytes、maxRowEstimatedBytes与jdbcExecuteMs、commitMs一起比较,
通过batchId关联SLOW_SYSLOG_BATCH;不能将polledMessageBytes视为达梦写入大小。
在有Kafka脚本的现场节点执行(已确认bootstrap地址):
```bash
@@ -182,7 +213,12 @@ docker exec syslog-consumer-rule-dm sh -c 'curl -fsS http://127.0.0.1:8289/xdrru
`stageMs`各阶段为互斥墙钟时间,跨业务块累加;旧有normalizeMs等字段包含部分子阶段,不能再与stageMs相加。
兼容字段ruleComputeWorkerMs实际是整批规则计算墙钟耗时;新增ruleWorkerBusySumMs才是worker耗时之和,二者不要混淆。
业务异常和提交异常即使小于500ms也输出诊断。`processedRecords/prepared`等旧计数仅覆盖完成的业务块;
慢日志统一使用 `syslog.slow-batch.threshold-ms`,默认1000ms,适用于 `SLOW_SYSLOG_BATCH`、
`SLOW_DM_TRANSACTION`、`SLOW_DM_QUEUE` 和 `SLOW_NON_NORMAL_WRITE`。
如容器已有 `SYSLOG_SLOW_BATCH_THRESHOLD_MS=500`,需删除该覆盖或改为1000;仅替换JAR不会覆盖环境变量。
启动日志 `SYSLOG_BUILD_READY` 中的 `slowBatchThresholdMs` 可确认生效值。无需执行数据库或Kafka脚本。
业务异常和提交异常即使小于1000ms也输出诊断。`processedRecords/prepared`等旧计数仅覆盖完成的业务块;
出现failedChunks时不能把它们理解为整次poll已成功入库。无限等待中的操作尚未结束,不会提前输出最终慢批次。
采样审计接口新增 `audit_async`,直接统计接口的 `dm_transaction.late_alarm_bucket_async` 查看通知队列。
@@ -192,6 +228,30 @@ docker exec syslog-consumer-rule-dm sh -c 'curl -fsS http://127.0.0.1:8289/xdrru
新审计指标 `audit_lost_or_unconfirmed_messages_total` 表示未记录或提交结果未知的消息数,
旧 `audit_fallback_messages_total` 本路径不再增加。
## 普通通道字段截断(默认2KB)
配置文件:`syslog-consumer-rule/src/main/resources/application.properties`(prod也继承)。
```properties
syslog.raw-listener.field-max-utf8-bytes=${SYSLOG_RAW_LISTENER_FIELD_MAX_UTF8_BYTES:2048}
```
- 默认2048个UTF-8字节,不是2048个汉字;改为4KB时填4096。0仅关闭本层限制,启用时至少64。
- 对原始Topic等于 `spring.kafka.consumer.topic` 的消息生效。Retry/Replay优先按信封的originalTopic判断;
缺失originalTopic时只按当前Topic判断,不猜测大日志来源。
- 在规则计算及采样决策后、达梦写入前处理:`syslog_normal_data` 的文本内容字段
(包括自定义映射字段),以及非标表的 `syslog_message`、`header_message`、`reason_detail`。
- 不截断数值、日期、二进制对象;标准化结果的ID、syslog_uuid、Topic、规则版本、设备/租户/采集ID、
分区时间和event_level等技术字段保持不变。`syslog_normal_alarm` 跳过新增2KB限制,
但仍保留原有 `dm.normal.large-field-max-utf8-bytes`(默认256KB,配置字段白名单)限制,本次不改旧策略。
- 超限内容尾部追加 `...[HB_XDR_TRUNCATED original_utf8_bytes=原字节数]`,标记包含在2048字节内,
不切断中文或emoji。不会修改规则输入或InfluxDB原文限制;大日志通道不应用2KB限制,仍沿用旧策略。
- 旧的 `dm.normal.large-field-max-utf8-bytes` 和 `dm.non-normal.large-field-max-utf8-bytes` 继续生效;
同时命中时最终遵循较小上限。此配置不修改历史记录,已截掉的字段内容不能靠回滚JAR恢复。
替换JAR并重启即可,无需数据库或Kafka脚本。若容器已有 `SYSLOG_RAW_LISTENER_FIELD_MAX_UTF8_BYTES`,
环境变量优先于JAR内默认值。启动日志 `SYSLOG_BUILD_READY` 的 `rawFieldMaxUtf8Bytes=2048` 可确认实际值。
## 回滚
回滚旧JAR会恢复主消费同步入口统计、事实计数Outbox、同步审计及分钟桶保护,新独立listener随进程退出停止。