日志截断与采样是用可控精度换系统稳定性,需分层控制:一、源头截断单条日志长度与敏感内容;二、运行时按场景动态采样;三、落地层轮转压缩确保磁盘空间可预测。

日志截断与采样不是“省日志”,而是用可控的精度换系统的稳定性。监控平台存储空间溢出,往往不是因为日志量大,而是因为日志结构失控——比如单条日志几MB、重复无意义堆栈、全量请求体照单全收。真正有效的策略,是分层控制:在生成端截断,在传输端采样,在存储端轮转。
一、源头截断:限制单条日志长度与敏感内容
超长日志(如完整 JSON 请求体、Base64 图片、未处理的异常堆栈)极易拖垮写入性能,甚至触发 OOM。必须在日志记录前做轻量级预处理:
- 对 message 字段统一设置硬性长度上限(建议 ≤2048 字符),超出部分截断并标记 (truncated)
- 避免在日志中拼接大对象 toString();改用 占位符 + 参数化输出(如
logger.info("Order processed: {}, status: {}", orderId, status)) - 对已知大字段(如 request.body、stackTrace)做白名单过滤或深度裁剪:只保留前 N 行、关键异常类名、不打印原始二进制数据
二、运行时采样:按场景动态降频,而非全局关日志
高频低价值日志(如健康检查、幂等校验成功、缓存命中)没必要全量落盘。应基于 MDC 或业务标识做条件采样:
- 使用 Logback 的 ThresholdFilter + JaninoEventEvaluator 实现表达式采样,例如:仅对 error 级别或 traceId 末尾为 “000” 的请求记录 DEBUG 日志
- Log4j2 可配置 RateLimitingFilter,对同一事件类型每秒最多记录 10 条,其余丢弃(非阻塞)
- 对灰度流量、特定 tenant ID 或 API 路径开启全量日志,其他走 1% 随机采样 —— 既保可观测性,又控体积
三、落地层轮转与压缩:让磁盘空间可预测
即使做了前端控制,日志仍会持续产生。必须依赖可靠的滚动策略,把增长变成周期性释放:
- 启用 TimeBasedRollingPolicy + SizeAndTimeBasedFNATP(Logback),例如:每天滚动 + 单文件不超过 100MB,自动压缩旧文件为 .gz
- 设置 maxHistory=30(保留 30 天)+ totalSizeCap=10GB(总容量硬限),超出则删除最旧归档
- 避免将日志直接写入根分区;挂载独立磁盘卷,并配置 systemd 或 logrotate 监控 可用空间 时触发告警与自动清理
四、监控平台侧协同:拒绝“来者不拒”式接入
ELK 或 Loki 不是垃圾桶。需在采集层就设防:
- Filebeat / Fluentd 配置 drop_event 过滤器,剔除含特定关键词(如 “health”, “/actuator”)或字段为空的日志行
- Loki 的 Promtail 支持 pipeline stages:先 parse,再 drop,最后 labels 降维,确保每条日志只带必要 label(如 level、service、traceID)
- 在 Grafana/Loki 查询中强制要求 加 time range 和 label filter,禁用无约束的全量查询,防止前端 OOM
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











