前言
就目前来说开源日志系统功能已经非常完善, 除非大企业如有特殊需求否则没必要自研日志系统;
日志的作用
- 线上问题跟踪
- 场景还原
- 监控调优
- 业务记录
什么时候记录日志
- 编程语言提示异常:即语言中的异常模块反馈出来的错误信息
- 业务流程与预期不符
- 系统核心角色,组件关键动作
- 系统初始化时环境的检查
- 有必要才记录日志,频繁过量日志对性能是有损耗的
日志处理流程
产生->采集->传输->过滤/转换->存储->分析
相关开源组件
采集侧:
- filebeat
- syslog/rsyslog
- fluentd/fluent-bit
- logtail
- plumelog
- Vector
- otel Collectors
- Packetbeat 网络流量数据
- Winlogbeat Windows 事件日志数据
- promtail/Alloy
缓冲中间件
- kafka
过滤/转换
- logstash
- otel Collectors
存储层
- elasticsearch
- minio
- loki
- clickHouse
告警
- elasticAlert
采集方式
目前云原生主流推荐方式有几种
- 应用程序不写日志文件, 直接标准输出, 由容器服务捕获转成日志文件, 再由agent采集;
- 应用程序通过内置sdk, 发送到远程日志服务器;
- 应用程序标准输出, 由 otel 自动注入agent进行采集;
日志不落盘: 不用担心日志占用磁盘空间过多, 少一次日志审计, 可用集中处理敏感信息;
日志落盘: 就需要考虑空间占用, 需要处理轮转和权限, 需要落盘前处理脱敏:
标准化日志
日志级别
- crit 最高级别错误, 反映系统发生了非常严重的故障, 无法自动恢复到正常态工作, 需要人工介入处理
- error 严重的错误, 某项业务出现的异常
- warn 低级别异常日志, 反映系统在业务处理时触发了异常流程; 但系统可恢复到正常态, 下一次业务逻辑还可以正常执行;
- INFO 主要记录系统关键信息, 旨在保留系统正常工作期间关键运行指标
- DEBUG 详细的调试信息
日志格式规范
目前主推结构化日志;
标准元数据字段
- request_id: 唯一请求id
- trace_id: 链路跟踪id
- time: 日志产生时间, 时间戳 /ISO8601/ 毫秒级别, 包含时区
- level: 日志等级
- app_id: 应用 id, 用于标示日志来源, 全局唯一
- instance_id: 实例 id, 用于区分同一应用不同实例, 格式业务方自行设定
- message: string 正文, 或结构化 json
其它可选字段
- 业务模块名称
- 版本号
- 函数名称
集中式日志系统设计
数据流: 采集->传输->过滤/转换->存储->检索/分析
业务功能点:
- 方便搜索, 统计, 异常排查
非业务功能点:
- 可根据数据规模横向扩展
- 跨数据中心支持
- 数据生命周期支持
设计要点
- 实时性和非实时性
- 日志格式能否统一
- 采集阶段不能占用业务太多计算资源
- 离线分析需求
- 有优先级控制和流量控制
过滤/转换
- 补元数据
- 去除无效日志
- 记录重点日志
存储
- 存储的索引、压缩、和查询
- 体量:分布式存储, 横向扩容
- 速度:内存缓存, 索引
- 生命周期: 冷热数据存放,设定日志清理轮转时间