日志分类与分级存储

做日志管理有些年头了,我最大的体会就是:日志不分类,神仙也崩溃。你想想看,每天成千上万条日志混在一起,就像把螺丝钉、弹簧和电路板全扔进一个桶里——找问题的时候根本无从下手。所以,这章咱们就聊聊怎么给日志分门别类,再按重要性排个座次,最后塞到不同的存储坑里。

为什么非要分类?

我记得刚带团队那会儿,有个线上事故特别诡异:用户登录总是超时。我们一群人翻了几万条日志,才发现是DNS解析偶尔失败。但那个DNS错误日志混在用户行为日志里,被INFO级别的“用户点击了按钮”淹没了。那么问题来了——不分类,你根本不知道哪些日志该优先看。

分类解决的问题很简单:

  • 可读性——同类型的日志放一起,查问题就像逛超市一样,去对应货架拿就行。
  • 存储效率——不同类型的日志价值不一样,没必要全存到最高级存储上。
  • 合规要求——某些行业(比如金融、医疗)要求安全日志保留5年,而debug日志保留7天。你混在一起怎么分?

四种核心分类维度

我一般把日志分成四个大类,每个大类底下还能再细分,但先抓住主干:

日志类别 典型来源 特点 我遇到的坑
应用日志 业务代码、微服务 最杂、量最大、跟业务直接挂钩 有人把密码明文打出来,差点出事
系统日志 OS、内核、系统服务 格式相对固定,一般syslog 曾经漏掉了磁盘IO告警,结果服务器挂了
安全日志 WAF、IDS、SSH、auth 敏感、留存时间长、审计必查 合规审计时发现少存了3个月,补都来不及
数据库日志 MySQL慢查询、binlog、MongoDB oplog 慢查询最值钱,binlog用完删 binlog没及时归档,磁盘满了

当然,你还可以加网络日志、中间件日志等等。但记住:分类别超过6个,否则团队记不住。

分级存储:热、温、冷

分类搞定,接下来咱们按重要性和访问频率,给日志分个温度等级。说白了,就像冰箱里的食物——肉馅常吃放冷藏(热),腊肉偶尔吃放冷冻(温),冻了一年的老腊肉直接扔冷库(冷)。

  1. 热存储(性能型) — 快速读写,用于近期排查。一般保留7~30天。
    常见:SSD、ES集群、Redis(作为缓冲)。
  2. 温存储(容量型) — 成本适中,用于季度或半年度合规查询。
    常见:SATA HDD、对象存储(S3兼容)、压缩后的ES冷节点。
  3. 冷存储(归档型) — 最低成本,用于法律或监管审计,保留1~7年。
    常见:离线磁带、低成本对象存储(Glacier等)、压缩打包后扔S3。

我曾经犯过一个低级错误:把所有的ERROR级别日志都扔到了热存储里。后来发现,有些ERROR是业务逻辑里的“正常报错”(比如支付超时重试),完全不值钱。嗯,分级不能只凭级别,还得结合业务字段。

实战:如何配置分级策略?

我建议从两个角度定义规则:日志类别 + 日志级别。比如应用日志:

  • DEBUG / TRACE → 热存储保留3天,或者干脆不落盘(走标准输出,不采集)
  • INFO → 热存储保留15天,然后转温存储30天,之后删除
  • WARN → 热存储保留30天,温存储90天,之后删除
  • ERROR / FATAL → 热存储保留90天,温存储1年,冷存储2年

小技巧:把分级规则写进你的日志采集工具(如Filebeat、Fluentd)的配置文件里,而不是等到存储端再分类。这样可以提前过滤掉无用的debug日志,节省带宽和存储成本。

下面是一个简单的Filebeat配置片段,演示如何按级别分流到不同的Elasticsearch索引:

filebeat.inputs:
- type: log
  paths: /var/log/app/*.log
  fields:
    log_type: app
  processors:
    - drop_event:
        when:
          equals:
            log.level: "DEBUG"

output.elasticsearch:
  hosts: ["es-cluster:9200"]
  index: "app-%{+yyyy.MM.dd}"
  ilm.enabled: false
  pipelines:
    - if: ctx.log.level in ["ERROR", "FATAL"]
      then:
        index: "app-error-%{+yyyy.MM.dd}"
        settings:
          number_of_replicas: 2
    - if: ctx.log.level in ["WARN"]
      then:
        index: "app-warn-%{+yyyy.MM.dd}"

这段配置里,我把ERROR单独扔一个索引,方便设置更长的保留周期;WARN走单独索引;INFO默认;DEBUG直接丢弃。注意:生产环境一定要测试过滤规则,别把该留的日志丢掉了。

分级存储的SVG架构图

下面这张图总结了我们刚才聊的:从日志产生到分类、分级,再到三个存储层。

日志分类 & 分级存储架构 应用日志 系统日志 安全日志 数据库日志 日志采集器(Filebeat / Fluentd)→ 分类 & 级别过滤 🟥 热存储 SSD / Redis 保留 7~30 天 🟧 温存储 HDD / 对象存储 保留 90~365 天 🟩 冷存储 磁带 / Glacier 保留 1~7 年 分级依据示例 • ERROR / FATAL + 应用日志 → 热存储 90 天,温存储 1 年,冷存储 2 年 • INFO + 系统日志 → 热存储 15 天,温存储 60 天,之后删除 • DEBUG (全部) → 直接丢弃或不落盘,仅用于临时调试 • 安全日志(无论级别)→ 热存储 90 天,冷存储 5 年(合规)

避坑指南:我曾经踩过的雷

雷区一:级别过滤过于激进——我看到有人把WARN和ERROR之外的日志全过滤掉,结果生产问题排查时,缺少INFO上下文,完全看不懂报错原因。我的建议:DEBUG可以丢,INFO至少保留15天。

雷区二:冷存储的压缩格式不兼容——以前我用gzip压缩了所有冷日志,一年后合规审计要查,解压发现有些文件头损坏。后来我统一用zstd + 校验和,再也没出过问题。

雷区三:忘了考虑跨地域合规——如果你们公司有海外业务,某些国家的数据保护法要求日志必须存储在本地境内。分类分级的策略还要加上地理标签,否则吃罚单。

小结

这一章的核心就三句话:按来源分类、按级别分级、按价值存储。分类解决的是找得到,分级解决的是留得起。你可以在自己的项目里先从最小的试点做起——比如先对应用日志做分级,跑一个月看看存储成本下降了多少。相信我,你会爱上这种“花小钱办大事”的感觉。