第一部分 日志管理整体技术方案
1. 方案概述
为统一服务器部署应用的日志采集、存储、检索、告警、清理与安全管控能力,解决日志散乱、无法排查问题、磁盘爆满、无追溯、不合规等问题,建立标准化、可运维、高可靠、低成本的全链路日志管理体系。本方案适用于Linux服务器部署的Java、Python、Go、PHP等所有业务应用及Nginx、Redis、MySQL等中间件日志。
2. 总体架构设计
2.1 中小型业务标准架构(推荐生产落地)
业务应用输出结构化日志 → 本地logrotate日志轮转兜底 → Filebeat轻量化采集 → Loki存储 → Grafana可视化检索+告警
2.2 大并发高可用架构
业务应用日志 → logrotate本地切割 → Filebeat采集 → Kafka消息队列削峰缓冲 → Logstash日志清洗过滤 → Elasticsearch热数据检索 → 冷数据自动归档OSS对象存储
2.3 架构设计原则
业务解耦:应用不直接推送远程日志,仅本地写文件,不占用业务IO与网络
双兜底保障:远端存储异常时,本地日志完整留存,不丢失数据
冷热分离:热数据可检索,冷数据归档降本,杜绝存储爆炸
规范统一:全服务统一结构化JSON格式、统一字段、统一日志级别
安全合规:自动脱敏、传输加密、操作审计、日志不可篡改
3. 核心管理策略(制度级规范)
3.1 日志采集策略
采集范围:业务应用日志、接口访问日志、错误异常日志、中间件日志(Nginx/MySQL/Redis)、服务器系统日志。
禁止采集:明文密码、手机号、身份证、银行卡等敏感数据;冗余重复日志、无效调试日志。
采集规则:采用Filebeat轻量化采集,异步批量上报,开启背压与限流;Java异常堆栈多行自动合并,保证日志完整性。
3.2 日志格式规范
全线业务统一使用JSON结构化日志,固定必填字段:
timestamp:标准北京时间时间戳
traceId:全链路追踪ID(核心排查字段)
level:日志级别(INFO/WARN/ERROR/FATAL)
serviceName:应用服务名
serverIp:部署服务器IP
module:代码模块/接口名
message:正常日志内容
errorStack:异常堆栈信息(错误日志必填)
生产环境关闭DEBUG日志,仅保留INFO及以上级别日志。
3.3 日志存储与生命周期策略
热数据(0-7天):Loki/ES,支持实时检索、故障排查、告警分析
温数据(7-30天):降低副本、开启压缩,保留检索能力
冷数据(30天以上):自动归档至OSS对象存储,按需离线查询
通用留存周期:普通业务30-90天;金融、政务合规业务180天以上
3.4 日志轮转与清理策略(磁盘防护核心)
所有日志文件禁止单文件无限累加,必须双机制防护:应用日志滚动 + 系统logrotate兜底。
切割规则:按日切割 + 单文件200MB阈值切割
保留份数:本地仅保留最近7天日志文件
自动清理:过期文件自动删除,杜绝磁盘占满
备份策略:切割后文件自动压缩,节省本地空间
3.5 告警与监控策略
统一配置日志告警规则,触发后推送钉钉/企业微信:
服务ERROR/FATAL日志突增(环比上涨50%)
业务服务长时间无日志输出(服务宕机/卡死)
Filebeat采集中断、客户端离线
日志存储磁盘使用率≥85%
日志堆积、上报延迟过高
3.6 安全合规策略
数据脱敏:日志输出阶段自动脱敏手机号、身份证、账号密码
传输加密:采集端至存储端全程TLS加密,禁止明文传输
不可篡改:原始日志只读,归档日志开启防篡改机制
操作审计:日志平台查询、下载、导出操作全程留痕
权限最小化:运维、开发分级授权,禁止随意删除日志
4. 整体落地流程
需求梳理→规范制定→应用日志改造→采集组件部署→存储集群配置→可视化与告警配置→功能压测验证→灰度上线→日常巡检优化
第二部分 日志管理实操运维手册
1. 前置准备工作
1.1 环境与资源梳理
统计所有业务服务器IP、应用名称、日志存储路径
确认业务日志量级,预估每日存储占用
明确业务合规留存时长、敏感字段清单
1.2 组件版本选型
采集端:Filebeat 7.x/8.x(稳定轻量,生产首选)
缓冲(高并发):Kafka 2.x
清洗(可选):Logstash 7.x
存储检索:Loki/Elasticsearch 7.x
可视化告警:Grafana/Kibana
2. 应用端日志标准化改造(开发落地)
2.1 统一日志框架配置
所有应用使用logback/log4j2,开启JSON结构化输出,关闭DEBUG日志,添加全链路字段,实现敏感数据脱敏。
2.2 应用日志滚动配置
应用内部配置日志滚动:单文件最大200MB,按天切割,保留7天日志,配合系统logrotate双重防护。
2.3 改造验收标准
日志为标准JSON格式,无杂乱非结构化文本
必填字段齐全,包含traceId、服务名、时间戳
无明文敏感信息,异常堆栈完整不截断
生产环境无DEBUG日志输出
3. 服务端实操部署(运维落地)
3.1 Filebeat安装部署(所有业务机必装)
1. 安装Filebeat并设置开机自启
2. 核心配置filebeat.yml(生产可用):配置日志路径、多行合并、日志过滤、输出地址、限流重试、服务标签
3. 校验配置文件:filebeat test config
4. 重启服务并设置开机自启,验证采集状态
3.2 Logrotate日志轮转配置(系统兜底)
针对所有业务日志目录配置系统级轮转规则,实现按大小、按时间切割,自动压缩、自动清理,彻底杜绝磁盘爆满。
3.3 存储与可视化部署
部署Loki/ES,配置索引生命周期、冷热分离、存储压缩策略
配置Grafana数据源,搭建日志检索大盘、服务监控大盘
配置日志告警规则、告警渠道、告警静默策略
4. 上线验证流程
4.1 功能验证
正常日志实时采集、检索正常
Java异常堆栈多行合并完整,无拆分错乱
可通过traceId、服务名、时间范围精准检索
敏感字段脱敏生效
4.2 故障验证
远端存储离线:本地日志正常留存,无丢失
网络恢复后,日志自动补传同步
日志量突增场景,采集无堆积、无丢数
4.3 告警验证
手动触发错误日志,验证告警及时推送、无漏告、无错告。
5. 日常运维巡检手册
5.1 每日巡检项
检查所有服务器Filebeat服务运行状态
检查服务器磁盘使用率、日志文件大小
查看日志大盘,确认无服务断流、无大量异常日志
检查是否存在明文敏感数据泄露
5.2 每周巡检项
核查日志留存周期、冷热归档策略是否生效
清理无效日志索引、过期冗余文件
优化日志过滤规则,剔除无效日志,降低存储压力
巡检告警规则,清理无效告警、优化告警阈值
5.3 每月巡检项
整体日志量级统计,评估存储扩容需求
全量校验日志格式规范性
故障演练:模拟采集中断、存储宕机,验证兜底能力
6. 常见问题排错手册
6.1 日志采集不到
排查方向:Filebeat服务状态、配置文件路径权限、日志文件是否为空、网络连通性、输出地址配置是否正确。
6.2 异常日志堆栈拆分错乱
原因:未开启多行合并规则,解决方案:在Filebeat配置中开启Java堆栈多行匹配合并。
6.3 服务器磁盘爆满
原因:未配置日志轮转、保留日志过多。解决方案:完善logrotate配置,强制切割清理,设置最大保留天数。
6.4 日志量过大导致存储压力高
解决方案:过滤无效INFO日志、开启存储压缩、严格执行冷热分离、缩短无效日志留存周期。
6.5 日志出现敏感明文泄露
解决方案:代码层新增脱敏规则,采集端补充过滤替换规则,回溯清理违规日志。
7. 生产落地禁忌(红线规则)
禁止应用直接远程推送日志,影响业务性能
禁止单日志文件无限累加,必须开启轮转
禁止生产环境开启DEBUG日志
禁止日志明文传输、明文留存敏感数据
禁止随意删除、篡改原始业务日志
附件:生产可直接复制配置模板
附件 1:logrotate 日志轮转配置
文件路径:/etc/logrotate.d/applog
# 业务应用日志轮转配置 /data/applogs/*.log { daily size 200M rotate 7 compress delaycompress missingok notifempty create 0644 www www sharedscripts postrotate # 通知应用重新打开日志句柄,Java应用可发送SIGUSR1信号 pkill -USR1 -f java || true endscript }说明:
- daily:按天切割;size 200M:文件超过 200MB 触发切割
- rotate 7:最多保留 7 个历史归档文件
- compress:gzip 压缩旧日志,delaycompress:上一轮日志在下一次轮转时再压缩,避免正在写入的文件压缩
- missingok:日志文件不存在不报错;notifempty:空文件不轮转
- create:新日志文件权限与属主;postrotate 脚本用于通知应用刷新日志句柄,防止应用继续写入旧已切割文件
校验命令:
logrotate -d /etc/logrotate.d/applog附件 2:Filebeat 生产标准 filebeat.yml
filebeat.inputs: - type: filestream paths: - /data/applogs/*.log # Java异常堆栈多行合并 multiline.type: pattern multiline.pattern: '^[\d]{4}-[\d]{2}-[\d]{2}' multiline.negate: true multiline.match: after # 标签,区分环境、服务 tags: ["prod","business-app"] fields: env: "prod" fields_under_root: false # 采集限流,防止IO打满 prospector.scanner.scan_frequency: 10s backoff.init: 1s backoff.max: 10s # 过滤规则:丢弃DEBUG级别日志 processors: - drop_event: when: contains: message: '"level":"DEBUG"' - add_fields: target: '' fields: serverIp: ${host.ip} # 输出配置【中小方案输出Loki,高并发改为kafka】 output.loki: hosts: ["http://127.0.0.1:3100"] batch.size: 2048 batch.flush: 1s retry.max_attempts: 5 backoff.max: 5s # 输出到Kafka(高并发场景,注释上面loki,启用下面kafka) # output.kafka: # hosts: ["kafka-01:9092","kafka-02:9092"] # topic: app-log-prod # partition.round_robin: # reachable_only: true # batch.size: 2048 # retry.max_attempts: 5 # 监控与日志 logging.level: info logging.to_files: true logging.files: path: /var/log/filebeat name: filebeat keepfiles: 7 permissions: 0644校验 & 启停命令:
# 校验配置 filebeat test config # 启动 systemctl enable filebeat systemctl restart filebeat # 查看状态 systemctl status filebeat附件 3:logback-spring.xml JSON 结构化日志配置(SpringBoot Java 应用)
依赖:引入 logstash-logback-encoder
<?xml version="1.0" encoding="UTF-8"?> <configuration scan="true" scanPeriod="60 seconds" debug="false"> <include resource="org/springframework/boot/logging/logback/defaults.xml"/> <include resource="org/springframework/boot/logging/logback/console-appender.xml"/> <property name="LOG_PATH" value="/data/applogs"/> <property name="LOG_FILE" value="${LOG_PATH}/app.log"/> <appender name="JSON_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_FILE}</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_PATH}/app.%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>200MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <maxHistory>7</maxHistory> <totalSizeCap>2G</totalSizeCap> </rollingPolicy> <encoder class="net.logstash.logback.encoder.LogstashEncoder"> <includeMdcKeyName>traceId</includeMdcKeyName> <includeMdcKeyName>serviceName</includeMdcKeyName> <includeMdcKeyName>serverIp</includeMdcKeyName> <includeMdcKeyName>module</includeMdcKeyName> <customFields>{"env":"prod"}</customFields> <throwableConverter class="net.logstash.logback.stacktrace.ShortenedThrowableConverter"> <maxDepthPerThrowable>30</maxDepthPerThrowable> <shortenedClassNameLength>20</shortenedClassNameLength> <exclude>sun.*|com.sun.*</exclude> </throwableConverter> </encoder> </appender> <root level="INFO"> <appender-ref ref="JSON_FILE"/> </root> </configuration>说明:
- MDC 中需要业务代码埋点注入 traceId、serviceName、module,放入 MDC 上下文,日志自动带入
- 内置按天 + 200MB 双切割,最多保留 7 天,上限 2G,作为应用侧滚动,和系统 logrotate 双层防护
- 输出标准 JSON,包含异常堆栈,适配 Filebeat 采集
补充:日志脱敏简易示例(Java)
// 手机号脱敏 public static String maskPhone(String phone) { if(phone == null || phone.length() < 11) return phone; return phone.substring(0,3)+"****"+phone.substring(7); } // 身份证脱敏 public static String maskIdCard(String id) { if(id == null || id.length() < 18) return id; return id.substring(0,6)+"********"+id.substring(14); }