19.5.2 指标、日志、链路三大数据模型
指标、日志、链路是可观测性体系的三大数据模型,分别回答“系统是否健康”“发生了什么”“问题发生在哪里”。本节给出统一采集与关联的原理、安装与示例、排错与练习。
指标(Metrics)
指标是数值化状态,适合实时监控与趋势分析。建议以 Prometheus 体系为例落地。
- 安装与采集示例(Node Exporter + Prometheus)
# 1) 安装 node_exporter(以 systemd 为例)
useradd -r -s /sbin/nologin node_exporter
tar -zxvf node_exporter-1.7.0.linux-amd64.tar.gz -C /opt/
ln -s /opt/node_exporter-1.7.0.linux-amd64 /opt/node_exporter
cat >/etc/systemd/system/node_exporter.service <<'EOF'
[Unit]
Description=Node Exporter
After=network.target
[Service]
User=node_exporter
ExecStart=/opt/node_exporter/node_exporter
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now node_exporter
# 预期效果:本机 9100 端口提供 /metrics
curl -s http://127.0.0.1:9100/metrics | head
# 2) 安装 Prometheus 并配置抓取
tar -zxvf prometheus-2.49.0.linux-amd64.tar.gz -C /opt/
ln -s /opt/prometheus-2.49.0.linux-amd64 /opt/prometheus
cat >/opt/prometheus/prometheus.yml <<'EOF'
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['127.0.0.1:9100']
labels:
env: prod
app: os
region: bj
EOF
/opt/prometheus/prometheus --config.file=/opt/prometheus/prometheus.yml \
--storage.tsdb.path=/opt/prometheus/data &
# 预期效果:http://127.0.0.1:9090/targets 显示 UP
- PromQL 示例与解释
# CPU 使用率(1分钟)
100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[1m])) * 100)
# 磁盘使用率(/)
(1 - (node_filesystem_avail_bytes{mountpoint="/"} /
node_filesystem_size_bytes{mountpoint="/"})) * 100
# 解释:
# rate: 计算时间序列变化率;avg by(instance): 按实例聚合;
# 100- idle*100:得到非空闲占用百分比
- 排错要点
targets显示 DOWN:检查 9100 端口、防火墙、node_exporter 进程。- 指标缺失:确认
scrape_interval、实例标签是否写错。
日志(Logs)
日志描述事件细节,适合追溯与审计。以 Promtail + Loki 为例展示。
- 安装与采集示例(Promtail + Loki)
# 1) 运行 Loki(本地单机)
/opt/loki/loki-linux-amd64 -config.file=/opt/loki/loki.yml &
# 2) Promtail 采集 /var/log/messages
cat >/opt/promtail/promtail.yml <<'EOF'
server:
http_listen_port: 9080
positions:
filename: /opt/promtail/positions.yaml
clients:
- url: http://127.0.0.1:3100/loki/api/v1/push
scrape_configs:
- job_name: syslog
static_configs:
- targets: [localhost]
labels:
job: varlogs
app: os
__path__: /var/log/messages
pipeline_stages:
- regex:
expression: '^(?P<ts>\w+\s+\d+\s+\d+:\d+:\d+)\s+(?P<host>\S+)\s+(?P<svc>\S+)'
- labels:
svc:
EOF
/opt/promtail/promtail-linux-amd64 -config.file=/opt/promtail/promtail.yml &
# 预期效果:Loki 中可查询 {job="varlogs"}
- 日志规范示例(JSON 结构化)
{"ts":"2024-06-01T10:00:01+08:00","level":"INFO","trace_id":"abc123","svc":"api",
"user_id":"u001","path":"/v1/order","latency_ms":120,"status":200}
- 排错要点
- Loki 无数据:检查 promtail
positions.yaml权限;确认 path 是否存在。 - 字段提取失败:regex 表达式与日志实际格式不一致。
链路(Traces)
链路追踪用于跨服务请求分析。以 OpenTelemetry + Jaeger 为例。
- 安装与采集示例(Jaeger + OTel Collector)
# 1) 运行 Jaeger(All-in-One)
docker run -d --name jaeger -p 16686:16686 -p 14250:14250 jaegertracing/all-in-one:1.52
# 2) OTel Collector 配置
cat >/opt/otel/otel-collector.yml <<'EOF'
receivers:
otlp:
protocols:
grpc:
exporters:
jaeger:
endpoint: "127.0.0.1:14250"
tls:
insecure: true
service:
pipelines:
traces:
receivers: [otlp]
exporters: [jaeger]
EOF
/opt/otel/otelcol --config /opt/otel/otel-collector.yml &
# 预期效果:应用上报 OTLP 后,Jaeger UI 16686 可见 Trace
- Java 应用示例(OTLP 上报)
export OTEL_SERVICE_NAME=order-service
export OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4317
export OTEL_TRACES_EXPORTER=otlp
java -javaagent:/opt/otel/opentelemetry-javaagent.jar -jar app.jar
# 解释:通过 JavaAgent 自动注入 Trace/Span 并上报 OTLP
- 排错要点
- Jaeger 无数据:确认应用 OTEL_EXPORTER_OTLP_ENDPOINT 与 Collector 端口一致。
- Trace 不完整:检查服务间是否传递 trace_id(HTTP Header: traceparent)。
三者关联与统一治理
- 统一标签:env、region、cluster、app、version、instance。
- 关联键:trace_id、request_id、user_id。
- 统一入口:从告警指标下钻到日志、链路(Grafana + Loki + Jaeger)。
告警与降噪示例(Prometheus Rule)
# /opt/prometheus/rules/alerts.yml
groups:
- name: node_alerts
rules:
- alert: HighCPU
expr: 100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85
for: 5m
labels:
severity: warning
annotations:
summary: "CPU过高 {{ $labels.instance }}"
description: "CPU使用率超过85%持续5分钟"
练习
1. 安装 node_exporter 与 Prometheus,写出 CPU 使用率 > 80% 的告警规则并验证触发。
2. 用 promtail 采集 Nginx access.log,提取 status 字段并在 Loki 中查询 status="500"。
3. 使用 OTel Java Agent 启动一个示例服务,确保 Jaeger 中出现完整的 Trace。
常见问题速查
- Prometheus 采集不到:检查 targets、端口、防火墙与服务状态。
- Loki 查询为空:确认 __path__、日志权限与时间范围。
- Trace 缺失:检查服务间 Header 透传与采样率配置。