记录和跟踪事件
记录和跟踪事件
1)目标和框架
徽标和跟踪是可观察性的基础。
Logi回答"发生了什么"和"上下文是什么"。
Traces在分布式查询路径中响应"慢速/错误的地点和原因"。
- Structured by default (JSON);跟踪第一:热路径中的每个日志都绑定到"trace_id"/"span_id"。
- 噪声最小,信号最大:水平,采样,反基数。
- 安全和隐私:掩盖、编辑、划分访问权限。
- 测试的日志和事件方案。
2)事件分类
按目的划分线程和索引:1.技术记录(运行时,错误,网络计时器,retrai)。
2.业务活动(注册,存款,利率,提取,KYC阶段)-适用于食品分析和"现金"路径事件。
3.审计(谁/何时更改:configs,访问,标志,限制)是不可更改的日志。
4.安全(身份验证,特权升级,制裁/RER标志)。
5.基础架构(K8s活动,自动缓解,HPA/VPA,节点/驱动器/网络)。
对于每个线程,分别是还原,索引和访问规则。
3)结构原理(JSON基准)
json
{
"ts": "2025-11-03T14:28:15.123Z",
"level": "ERROR",
"service": "payments-api",
"env": "prod",
"region": "eu-central-1",
"trace_id": "8a4f0c2e9b1f42d7",
"span_id": "c7d1f3a4b8b6e912",
"parent_span_id": "a1b2c3d4e5f60789",
"logger": "withdraw.handler",
"event": "psp_decline",
"msg": "PSP declined transaction",
"http": { "method": "POST", "route": "/withdraw", "status": 502, "latency_ms": 842 },
"user": { "tenant_id": "t_9f2", "user_key": "hash_0a7c", "vip_tier": 3 },
"payment": { "psp": "acme", "amount": 120.50, "currency": "EUR", "idempotency_key": "u123:wd:7845" },
"safe": true, // пройдена проверка на секреты
"version": "1.14.2", // версия сервиса (SemVer)
"build": "sha-1f2a3b4",
"kubernetes": { "pod": "payments-7cbdf", "node": "ip-10-0-2-41" }
}
要求:平面方案+域附件,必填字段('ts,level,service,env,trace_id,msg'),数值是数字,不是字符串。
4)水平,基数和体积
级别:"DEBUG"(不销售),"INFO"(业务事实),"WARN"(异常),"ERROR"(错误),"FATAL"(碰撞)。
基数:避免任意键/动态标签。没有"id in key"。
Sampling logs:限量版重复消息;仅包括"DEBUG" scoped和时间(功能旗)。
相似性:构造"idempotency_key"以抑制重复的消费者事件。
5)隐私和安全
在座席上伪装PII/秘密 (Fluent Bit/Vector):按密钥伪装卡("电子邮件","card"、"token"、"授权")。
散列"user_key",仅保留所需的上下文(国家/地区,KYC级别,VIP级)。
分隔存储:温暖(操作搜索)和寒冷(存档没有PII/c简化上下文)。
审计-仅限应用程序,WORM存储,仅可通过least privilege原则访问。
6)跟踪: 标准和上下文
W3C Trace Context:标题"traceparent"/"tracestate",以及用于安全密钥的baggage(例如"tenant_id","region")。
指标和跟踪关联:Exemplars-将"trace_id"传输到直方图的采样点(加速RCA)。
采样:对于有问题的查询,基本采样1-5%+动态"在错误/缓慢p95上"高达100%。
Links:对于异步队列/sag,请通过"links"(不仅仅通过"母公司")链接睡眠。
7)收集和路由
代理商:用于日志的Fluent Bit/Vector;OTLP导出到OpenTelemetry Collector。
集合:中央网关(batch/transform/filter/routing)。
App → (OTLP logs/traces/metrics) → OTel Collector
→ logs: redact → route(security audit tech biz) → hot index / cold archive
→ traces: tail_sampling(errors p95>threshold) → APM backend
→ metrics: Prometheus exporter (for SLO/alerts)
OTel Collector(片段):
yaml processors:
batch: {}
attributes:
actions:
- key: env value: prod action: insert filter/logs:
logs:
include:
match_type: strict resource_attributes:
- key: service.name value: payments-api exporters:
otlp/traces: { endpoint: "apm:4317", tls: { insecure: true } }
loki: { endpoint: "http://loki:3100/loki/api/v1/push" }
prometheus: {}
service:
pipelines:
logs: { receivers: [otlp], processors: [attributes,batch], exporters: [loki] }
traces: { receivers: [otlp], processors: [batch], exporters: [otlp/traces] }
metrics: { receivers: [otlp], processors: [batch], exporters: [prometheus] }
8)指导: SDK示例
8.1 Node.js (Pino + OTel)
js import pino from "pino";
import { context, trace } from "@opentelemetry/api";
const logger = pino({ level: process.env.LOG_LEVEL "info" });
function log(info) {
const span = trace.getSpan(context.active());
const base = span? { trace_id: span.spanContext().traceId, span_id: span.spanContext().spanId }: {};
logger.info({...base,...info });
}
// пример log({ event: "deposit.created", amount: 50, currency: "EUR", user: { user_key: "hash_0a7c" } });
8.2 Java (SLF4J + OTel)
java
MDC.put("trace_id", Span.current().getSpanContext().getTraceId());
MDC.put("span_id", Span.current().getSpanContext().getSpanId());
log.info("psp_response status={} latency_ms={}", status, latency);
8.3 Python (structlog + OTel)
python import structlog from opentelemetry import trace log = structlog.get_logger()
def log_json(event, kwargs):
span = trace.get_current_span()
ctx = {}
if span and span.get_span_context().is_valid:
ctx = {"trace_id": span.get_span_context().trace_id, "span_id": span.get_span_context().span_id}
log.msg(event=event, ctx, kwargs)
8.4个NGINX →标题跟踪
nginx proxy_set_header traceparent $http_traceparent;
proxy_set_header tracestate $http_tracestate;
9)Logi作为警报和自动动作信号
有缺陷的模式("psp_decline","fraud_flag")汇总并与SLO相关联。
Alerts on pattern-rate:"5xx by/withdraw> 0.5%为10m","fraud_flag spike>+200%为基本"。
自动操作:在log'withdrawals_manual_mode=true'中,通过标志平台启用杀手开关。
rate(count_over_time({service="payments-api", level="ERROR", event="psp_decline"}[5m])) > 5
10)重建,索引,存储
热:7-14天(快速调查)。
温暖:30-90天(趋势,RCA)。
冷: 180-365+(存档,审核)-压缩,廉价类,可能没有全文搜索.
索引:固定键('service, env, level, event, trace_id, user.tenant_id'),指数禁令"一连串"。
事件大小限制(例如≤ 32KB),trim/底部:"在存储中多余的是MTTR敌人"。
11)审核和不变性
使用字幕/哈希、服务器时间、"who/what/when/why"和字幕链接单独编写审核事件。
"谁在DE中打开了100%的奖金旗帜?"-答案必须在1-2请求中。
json
{
"ts": "2025-11-03T14:00:00.000Z",
"actor": "alice@company",
"action": "feature_flag.update",
"target": "bonus.enable_vip",
"old": {"rollout": 10},
"new": {"rollout": 100},
"reason": "campaign_2311",
"ticket": "OPS-3481",
"trace_id": "cf12ab.."
}
12)业务事件和数据模型
业务事件不是"日志中的文本",而是合同:- `event_type`, `event_id`, `occurred_at`, `actor`, `subject`, `amount`, `currency`, `status`, `idempotency_key`.
- 与相等的消费者一起使用Outbox和"at-least-once"。
13) Kubernetes和pipeline logs
用于路由的pod注释('log。type`, `retention.tier`).
Sidecar/DaemonSet代理具有磁盘缓冲区(网络中断时)。
K8s控制器日志单独收集(群集索引)。
ini
[FILTER]
Name modify
Match
Remove authorization, password, card_number
14)反模式
字符串逻辑"必须",不存在"trace_id"。
PII/Logs中的秘密,payload的整个转储。
数以百万计的独特密钥→"爆炸"索引。
DEBUG全天候销售。
将审计,安全性和技术人员混合为一个索引。
从存档中没有还原策略和恢复测试。
15)实施清单(0-45天)
0-10天
在gateway/客户端中启用 W3C Trace Context (W3C Trace Context)。
将应用日志翻译为JSON,添加"trace_id"/"span_id"。
禁止PII/秘密(掩盖代理),批准字段列表。
11-25天
分离线程:tech/biz/audit/securit/infra,设置还原和ACL。
启用OTel Collector,进行错误采样/慢速查询。
"Log Rate/Error by route"+Jump-to-trace(Exemplars)的行车记录板。
26-45天
Alerta按事件模式和与SLO的相关性。
冷日志归档/恢复(DR测试)。
Linter Log Scheme in CI,商业活动合同。
16)成熟度量
"trace_id"查询覆盖率≥ 95%。
JSON Logs的份额≥ 99%。
通过"jump-to-trace"发现的事件由<15 min(p50)解决。
0例PII在日志中(泄漏扫描仪)。
在所有线程上都遵循重构(我们自动证明审计)。
17)附录: 迷你嗅觉
W3C traceparent生成(伪)
txt traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
PromQL-一组日志和SLO(示例)
high_error_logs = rate(log_events_total{service="payments-api",level="ERROR"}[5m])
5xx_rate = sum(rate(http_requests_total{service="payments-api",status=~"5.."}[5m])) / sum(rate(http_requests_total{service="payments-api"}[5m]))
alert if high_error_logs > 10 and 5xx_rate > 0.005
OpenAPI-韩语标题
yaml components:
parameters:
Traceparent:
name: traceparent in: header required: false schema: { type: string }
18)结论
强大的逻辑和跟踪回路是约定+学科:结构JSON逻辑,单个"trace_id",安全的PII处理,流路和重新连接,以及与SLO,Alerting和回扣的紧密结合。从"文字垃圾填埋场"过渡到事件和轨道合同,并且程序事件的诊断将变得快速,可预测和可验证。