Przeglądaj źródła

Add Log-operation.md (moved from shop-recycle2 README)

DevOps Team 2 miesięcy temu
rodzic
commit
1baf0e90ce
1 zmienionych plików z 215 dodań i 0 usunięć
  1. 215 0
      Log-operation.md

+ 215 - 0
Log-operation.md

@@ -0,0 +1,215 @@
+# Promtail JSON 采集方案 (v1.3)
+
+零侵入 · 防爆炸 · 生产级
+
+适用:Kubernetes 1.20+ / 裸机 / 容器混合场景
+
+目标:业务输出单行 JSON,采集层(Promtail / Vector)负责解析、采样、标签与告警,尽量降低业务代码改动与系统资源消耗。
+
+---
+
+## 目录
+- [快速概述](#快速概述)
+- [日志格式](#日志格式)
+- [开发接入(低侵入)](#开发接入低侵入)
+- [Agent 选择与 Promtail 指南](#agent-选择与-promtail-指南)
+- [资源占用参考](#资源占用参考)
+- [存储与爆炸兜底](#存储与爆炸兜底)
+- [告警模板(LogQL)](#告警模板logql)
+- [运维 Checklist](#运维-checklist)
+- [迁移与回滚简要流程](#迁移与回滚简要流程)
+- [附录:脚本与示例文件](#附录脚本与示例文件)
+
+---
+
+## 快速概述
+
+- 目标:统一单行 JSON 输出,由采集层负责所有解析与降噪。
+- 核心设计:尽早低成本过滤 → 保留低基数标签 → 基于哈希的采样 → 针对异常/慢调用/审计分支保留。
+- 可选优化:在高吞吐场景使用 `Vector` 替代 Promtail 做解析以节省 CPU/内存。
+
+---
+
+## 日志格式
+
+建议业务输出单行 JSON(最小必需字段):
+
+```json
+{
+  "ts":"2026-01-23T14:23:45.123Z",
+  "level":"INFO|WARN|ERROR",
+  "logger":"c.x.Foo",
+  "msg":"...",
+  "traceId":"a1b2c3",
+  "uri":"/api/order",
+  "duration":120,
+  "userId":123456,
+  "event":"order_create|login|APP_START|security|slow_sql",
+  "error":"NullPointerException: xxx"
+}
+```
+
+说明:
+- 无异常:`error=""`
+- 慢调用:`duration>500`(ms)
+- 审计/安全/生命周期:通过 `event` 字段区分
+
+注意:不要将高基数字段(如 `userId`、`orderId`)作为标签。
+
+---
+
+## 开发接入(低侵入)
+
+- 将 `logback` 配置与 `common-logging` 模块统一下发,业务只需引入一次依赖并使用简单 wrapper(如 `AppLogger.info(...)`)。
+- 在网关/Filter/拦截器中统一设置 MDC 字段:`traceId`、`uri`、`startTime`、`userId`,请求结束时写入 `duration` 并清理。
+- 推荐接入 OpenTelemetry 自动注入 traceId,减少手动传递。
+
+示例:Async JSON appender(logback)
+
+```xml
+<appender name="JSON" class="ch.qos.logback.core.ConsoleAppender">
+  <encoder class="net.logstash.logback.encoder.LogstashEncoder">
+    <includeContext>true</includeContext>
+    <provider class="net.logstash.logback.composite.loggingevent.LoggingEventPatternJsonProvider">
+      <pattern>{"ts":"%d{yyyy-MM-dd'T'HH:mm:ss.SSS'Z'}","level":"%level","logger":"%logger","msg":"%msg","traceId":"%X{traceId:-}","uri":"%X{uri:-}","duration":"%X{duration:-0}","userId":"%X{userId:-}","event":"%X{event:-}","error":"%X{error:-}"}</pattern>
+    </provider>
+  </encoder>
+</appender>
+
+<appender name="ASYNC_JSON" class="ch.qos.logback.classic.AsyncAppender">
+  <appender-ref ref="JSON" />
+</appender>
+
+<root level="INFO"><appender-ref ref="ASYNC_JSON"/></root>
+```
+
+Servlet Filter(伪码)
+
+```java
+public class LoggingFilter implements Filter {
+  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
+    String traceId = extractOrGenerate(req);
+    MDC.put("traceId", traceId);
+    MDC.put("uri", ((HttpServletRequest)req).getRequestURI());
+    long start = System.currentTimeMillis();
+    try { chain.doFilter(req, res); }
+    finally {
+      MDC.put("duration", String.valueOf(System.currentTimeMillis() - start));
+      MDC.remove("traceId"); MDC.remove("uri"); MDC.remove("duration");
+    }
+  }
+}
+```
+
+---
+
+## Agent 选择与 Promtail 指南
+
+- 何时用 Vector:当每节点日志吞吐大(数十 MB/s)或对 CPU/内存敏感,优先使用 Vector 做高效 JSON 解析与标签抽取。
+- Promtail 场景:路径收集或小规模集群。若用 Promtail,尽量把复杂解析移到 Vector/后端。
+
+Promtail 配置要点(原则):
+- 先用非常廉价的判断(按 `level` 快速 drop DEBUG/TRACE),避免复杂正则。
+- 在深度解析前完成 drop/采样,减少 JSON parse 次数。
+- 只将低基数字段作为 label(例:`level`、`namespace`、`event`、`exception_type`)。
+- 把 `duration` 作为 numeric 字段供 `unwrap`/`unpack` 使用,不作为标签。
+
+(保留原方案“三段减压 + 哈希采样 + 异常/慢调用/审计分支”思路,详见 `Log.md`。)
+
+---
+
+## 资源占用参考(4C8G 节点)
+
+阶段 | CPU | 内存 | 说明
+---|---:|---:|---
+原始全量 JSON 解析 | 150-200% | 400 MB | 无过滤
+加三段减压阀后 | 30-40% | 120 MB | 同集群实测
+换 Vector 解析 | 10-15% | 100 MB | Promtail 仅转发
+
+测试提示:在 staging 用真实流量做 A/B 对比(72 小时)量化效果。
+
+---
+
+## 存储与爆炸兜底
+
+1. 标签基数门禁:上线前运行基数扫描脚本,任一计划作为 label 的字段 24h 唯一值 > 5000 则阻断发布。
+
+2. Loki 整流:
+
+```yaml
+limits_config:
+  per_stream_rate_limit: 3MB
+  per_stream_rate_limit_burst: 5MB
+  ingestion_rate_mb: 10
+  ingestion_burst_size_mb: 20
+```
+
+超限将被丢弃并暴露 `rate_limit_discarded_bytes` 指标。
+
+3. Retention:`audit` 流 365d,其余 7d,持久化到 S3/OSS。
+
+基数扫描示例(部署前/CI)
+
+```bash
+logcli query '{env="prod"}' --since=24h | jq -r '.[].event' | sort | uniq -c | awk '$1>5000{print $2, $1}'
+```
+
+---
+
+## 告警模板(LogQL)
+
+保留原有:异常突增、慢调用 P99、审计事件下降。
+
+补充监控:agent 解析错误与丢弃量
+
+```logql
+# agent parsing errors
+sum(rate(promtail_parsing_errors_total[5m])) > 0
+
+# Loki 丢弃流量
+rate(loki_ingester_discarded_bytes_total[5m]) > 0
+
+# Promtail/Vector 本地丢弃量(采样)
+rate(promtail_dropped_bytes_total[5m]) > 0
+```
+
+---
+
+## 运维 Checklist
+
+每日
+- `kubectl top pod -l app=promtail` 单核 CPU <500m
+- 部署前运行基数扫描脚本(CI/PR 阶段)
+
+每周
+- 检查 `rate(promtail_dropped_bytes_total[5m]) > 0`(确认采样生效)
+
+每月
+- 回顾 `per_stream_rate_limit` 丢弃量并调整采样策略
+
+新增:在 Helm/Chart CI 中加入基数检测脚本,发现高基数阻断发布并在 PR 中给出异常样例。
+
+---
+
+## 迁移与回滚简要流程
+
+阶段:
+1. Staging:双写(旧流 & 新流)72 小时,验证告警与检索一致性。
+2. Canary:10% 节点,逐步增加采样并监控 `parsing_errors`、`dropped_bytes`、Loki ingress。
+3. 全量切换并监控 24-72 小时;若异常立即回滚并恢复双写。
+
+回滚:通过 Git/Helm release 快速回退到上一个成功版本。
+
+---
+
+## 附录:脚本与示例文件
+
+如果需要我可以把以下内容作为独立文件加入仓库:
+- `LoggingFilter.java`(完整示例)
+- `logback-spring.xml` 模板
+- 基数检测脚本(CI 用)
+- 完整迁移 Playbook(含 Helm 示例)
+
+---
+
+如果希望我现在把示例文件写入仓库,请回复我需要的文件清单(例如:`LoggingFilter.java`, `logback-spring.xml`, `ci/check_cardinality.sh`)。