集中式日志平台生产实践:Loki与OpenSearch日志治理
日志平台不是把所有文本集中到一个搜索框。生产系统需要同时解决采集可靠性、字段规范、敏感信息、索引与标签基数、存储成本、查询性能、权限隔离、保留与删除,以及平台自身故障后的恢复。缺少治理时,日志量通常增长得比业务更快,真正发生故障时反而查不到关键证据。
本文以Grafana Loki和OpenSearch两类常见路线为例,建立从日志源到查询、告警和归档的完整设计。两者的数据模型不同,不应照搬同一套字段与容量经验。具体配置应结合当前版本官方文档验证。
一、先定义日志使用场景
每类日志先明确主要用途:
| 类型 | 主要用途 | 典型保留 |
|---|---|---|
| 应用运行日志 | 故障定位、发布验证 | 数天至数周 |
| 访问日志 | 性能、错误、流量分析 | 数周至数月 |
| 审计日志 | 责任追踪、合规 | 按制度长期保存 |
| 安全日志 | 威胁检测、溯源 | 按风险和法规确定 |
| 数据库慢日志 | SQL优化、容量分析 | 数周至数月 |
| 基础设施日志 | 节点、网络、存储排障 | 数周 |
| 调试日志 | 临时诊断 | 短期、默认关闭 |
不能只设置一个统一保留期。审计日志需要防篡改,调试日志则应快速过期;两者放在同一策略中会造成成本和合规风险。
二、日志平台的端到端链路
标准链路包括:
- 应用或系统产生日志;
- 节点Agent、Sidecar或Collector读取;
- 解析、补充元数据、过滤和脱敏;
- 缓冲并发送到集中入口;
- 平台进行索引、分块或持久化;
- 查询层完成检索、聚合和权限控制;
- 告警规则生成事件;
- 生命周期策略完成降级、归档或删除。
每个阶段都可能丢数据。需要给日志记录一个可追踪的时间线:产生时间、采集时间、接收时间、可查询时间,从而区分应用延迟、Agent积压和平台写入延迟。
三、统一日志格式
新应用优先输出结构化JSON,而不是依赖复杂正则解析。
{
"timestamp": "2026-10-22T09:30:12.314+08:00",
"level": "ERROR",
"service": "order-api",
"environment": "prod",
"message": "payment provider timeout",
"trace_id": "f9c...",
"request_id": "r8a...",
"error_type": "upstream_timeout",
"duration_ms": 3021
}
字段规范至少约定:
- 时间使用带时区的ISO 8601或统一UTC;
- level集合统一;
- service、environment、cluster、namespace命名稳定;
- trace_id/request_id保留在字段中,不盲目成为索引或标签;
- 错误类型使用可聚合值,message保留人类可读上下文;
- 禁止直接记录密码、Token、Cookie、身份证号和完整密钥。
多行堆栈应在采集端正确合并,否则每一行都会变成独立事件。
四、采集Agent如何选择
常见选择包括Grafana Alloy、OpenTelemetry Collector、Fluent Bit、Vector和厂商Agent。评估维度:
- 支持的输入、输出和解析能力;
- 本地磁盘缓冲;
- 背压与重试;
- 多行日志;
- Kubernetes元数据;
- 脱敏和采样;
- CPU、内存与磁盘占用;
- 配置热加载;
- 自监控指标;
- 升级和兼容策略。
Agent使用DaemonSet时要配置资源上限和优先级,但不能因内存上限过低反复OOM。节点磁盘缓冲必须有容量上限,防止日志平台故障拖满业务节点。
五、采集可靠性与背压
日志平台短暂不可用时,Agent应缓冲并重试;长时间不可用时,需要明确取舍:
- 最多缓存多少小时;
- 磁盘达到水位后删除最旧还是停止读取;
- 哪些日志优先保留;
- 是否允许对低价值日志采样;
- 恢复后以多大速率回放,避免冲垮平台。
必须监控输入速率、输出速率、缓冲字节、最老未发送日志时间、重试、丢弃和解析失败。只监控Agent进程存活无法发现静默丢日志。
六、Loki的数据模型
Loki主要索引标签,日志正文压缩存入chunk。每组唯一标签组合形成一条stream。标签应描述稳定、低基数的来源,例如:
cluster=prod-shanghai
namespace=payments
app=order-api
environment=prod
不要把Pod UID、请求ID、用户ID、客户端IP或trace_id作为普通索引标签,否则会产生大量stream并显著影响写入、查询和存储。高基数字段可使用结构化元数据或在查询时解析。
LogQL查询示例:
{cluster="prod-shanghai", namespace="payments", app="order-api"}
| json
| level="ERROR"
| duration_ms > 2000
查询先用标签缩小stream,再解析正文,避免对全部日志执行正则。
七、Loki部署模式
常见模式包括:
- 单体模式:实验和小规模;
- 简单可扩展模式:读、写、backend分组;
- 微服务模式:组件独立扩展,适合更大规模。
生产架构需关注Distributor、Ingester、Querier、Query Frontend、Compactor、对象存储和ring。不要因为组件能水平扩展就忽略故障域:副本应跨节点或可用区,ring状态和对象存储必须可观测。
Loki通常把索引和chunk持久化到对象存储。TSDB索引是当前主路线,新增部署应以官方最新推荐为准。
八、Loki保留与删除
保留通常由Compactor执行,而不是等待Ingester自动删除。示意配置:
compactor:
working_directory: /data/loki/compactor
retention_enabled: true
delete_request_store: s3
limits_config:
retention_period: 360h
需要验证:
- Compactor实际运行且只有正确的工作模式;
- 对象存储生命周期不会提前删除数据;
- 不同租户和stream是否需要不同保留;
- 删除请求是否有审计和延迟窗口;
- 法务保留是否能阻止自动删除。
保留策略改变后,空间不会立即下降,应观察Compactor指标和对象删除进度。
九、OpenSearch的数据模型
OpenSearch对文档字段建立倒排索引,适合复杂全文搜索、字段聚合和安全分析,但映射、分片和索引数量必须治理。
推荐使用索引模板统一:
- 时间字段类型;
- keyword与text的边界;
- IP、数值、布尔和嵌套字段;
- 动态映射策略;
- 分片、副本与刷新间隔;
- 生命周期策略和别名。
不要让任意JSON字段自动无限扩张。字段爆炸会增加集群状态、内存和查询成本。对不需要检索的原文可关闭索引,仅保留_source。
十、分片不是越多越好
OpenSearch分片过大会降低迁移和恢复速度,过小则增加集群状态、文件句柄和堆内存开销。容量规划应基于每日写入量、保留期、压缩比、节点磁盘、查询并发和恢复时间测试。
建议:
- 使用rollover按大小或时间滚动;
- 让主分片大小落在经压测验证的范围;
- 为热写入、温查询和冷归档设计不同层;
- 副本数按可用性和查询吞吐决定;
- 控制每节点分片数量;
- 预留节点故障后的重新分配空间。
不要把所有日志按“每天一个索引”机械拆分。低流量业务会产生大量小索引,可通过数据流、共享索引与租户字段治理。
十一、生命周期与冷热分层
典型策略:
- 热层:高性能磁盘,接收写入和近期查询;
- 温层:停止写入、降低副本或迁移到普通磁盘;
- 冷层:低频查询、快照或远程存储;
- 删除:超过保留期且无保留令。
生命周期动作必须在测试索引验证。发生分片未分配、磁盘水位或快照失败时,自动策略可能停滞,需要告警而不是静默等待。
十二、租户、权限与审计
日志常包含内部地址、用户标识和业务上下文。至少实现:
- 单点登录与MFA;
- 团队/环境级最小权限;
- 生产日志与测试日志隔离;
- 查询和导出审计;
- 敏感字段脱敏;
- API Token短期化和轮换;
- 批量下载限制;
- 离职和项目结束后的权限回收。
多租户不只是一列tenant字段。必须确保写入入口不能伪造租户、查询层强制过滤、对象存储前缀和缓存不会跨租户泄露。
十三、日志脱敏与隐私
脱敏尽量在数据离开源环境前完成。常见规则:
- 密码、Token、Authorization头直接删除;
- 手机号、邮箱、身份证号按制度掩码;
- URL查询参数使用白名单;
- SQL绑定参数按风险决定是否保留;
- 堆栈中的请求对象避免完整输出;
- 测试脱敏规则对Unicode、换行和编码的处理。
脱敏失败应计数和告警,但不要把原始敏感文本再次写入错误日志。规则变更需要样本回归测试。
十四、日志、指标和追踪关联
统一service、environment、cluster等资源属性。应用日志记录trace_id,在日志界面链接到追踪;从追踪跳转回同一时间范围的日志;告警携带服务、集群和Runbook。
关联字段不等于全部做成索引。Loki中高基数trace_id更适合结构化元数据或查询时解析;OpenSearch可将trace_id设为keyword,但要评估写入和存储成本。
十五、从日志生成告警
适合日志告警的场景:
- 明确错误码或安全事件;
- 没有指标暴露的遗留系统;
- 审计操作;
- 低频但严重的异常。
不适合把所有日志关键字都转成告警。高频错误应先转为指标并按错误率、影响面和持续时间告警。规则要处理“没有日志”和“采集停止”的区别。
十六、查询治理
建立以下保护:
- 默认查询时间范围;
- 最大扫描量和并发;
- 慢查询记录;
- 正则和通配符限制;
- 租户公平调度;
- 查询缓存;
- 大批量导出审批;
- 仪表盘固定字段和索引范围。
故障期间用户会同时扩大时间范围和刷新频率,查询峰值可能高于平时数倍。应为应急查询预留容量,同时保护写入链路。
十七、容量与成本模型
每日容量可从源日志字节、采集开销、压缩比、副本、索引、保留期和安全余量估算。还要计算对象存储请求、跨区流量、查询缓存和快照成本。
治理顺序通常是:
- 禁止无界debug;
- 修正高基数标签和动态字段;
- 按价值设置保留;
- 对低价值重复日志采样;
- 优化格式和压缩;
- 最后才是增加存储。
成本看板应按团队、服务、环境和日志类型归属,让产生者看到自身增量。
十八、平台自身监控
至少监控:
- 每租户写入速率与拒绝;
- Agent积压、丢弃和解析失败;
- Loki stream、chunk、ring和Compactor;
- OpenSearch集群状态、堆、GC、分片和磁盘水位;
- 对象存储错误和延迟;
- 查询QPS、P95/P99、超时和取消;
- 生命周期任务与快照;
- 从生成到可查询的端到端延迟。
建立合成日志:定时写入唯一标识,持续验证它能在目标时间内被查询到。
十九、备份与灾难恢复
需要保护:
- Agent与平台配置;
- 索引模板、生命周期和解析规则;
- 租户、权限与审计配置;
- 仪表盘、保存查询和告警;
- 对象存储或OpenSearch快照;
- 加密密钥与凭据;
- 恢复Runbook。
恢复演练要验证查询结果、时间范围、字段映射、权限和告警,不是只确认对象或快照存在。
二十、迁移路线
- 盘点日志源、日增量、保留和使用者;
- 建立字段与敏感信息规范;
- 选择少量服务双写;
- 比对条数、延迟、字段、查询和告警;
- 建立容量与成本基线;
- 分批迁移仪表盘和告警;
- 保留旧平台只读窗口;
- 验证审计和恢复后再下线。
双写会增加应用和网络负担,应在Collector层完成并监控两个出口,避免由应用重复发送。
二十一、常见故障
日志条数突然减少
检查应用是否仍输出、Agent文件偏移、容器轮转、解析失败、限流、网络和平台拒绝。不能只看平台入口。
Loki查询非常慢
先缩小标签和时间范围,检查高基数stream、无界正则、查询拆分、缓存、Store Gateway与对象存储。
OpenSearch集群变黄或红
检查未分配分片原因、节点磁盘水位、分片副本、节点角色和恢复限速。不要直接删除索引腾空间。
磁盘每天都增长
核对生命周期是否实际执行、Compactor或ISM任务状态、对象存储删除延迟、快照和副本占用。
二十二、生产验收清单
- [ ] 日志源、用途、负责人和保留策略已登记;
- [ ] 结构化字段、时间和level规范统一;
- [ ] Agent具备磁盘缓冲、背压和丢弃告警;
- [ ] Loki标签或OpenSearch映射经过基数审查;
- [ ] 敏感信息在采集前脱敏;
- [ ] 租户、环境和导出权限隔离;
- [ ] 生命周期、对象存储和快照策略一致;
- [ ] 写入、查询和保留任务均可观测;
- [ ] 日志与指标、追踪可以关联;
- [ ] 已完成隔离恢复和权限验证。
二十三、官方参考
- Grafana Loki Documentation
- Loki Architecture
- Loki Labels
- Loki Retention
- OpenSearch Documentation
- OpenSearch Index State Management
- OpenTelemetry Logs
可靠的日志平台必须回答三个问题:日志有没有完整到达、用户能否在需要时快速找到、保存和删除是否符合制度。只有把采集、模型、权限、成本和恢复统一治理,集中日志才会真正成为生产证据。