☰
可观测性与监控的区别:Prometheus+Grafana+Loki+OpenTelemetry实践
2026/10/16 3:45:16 网站建设 项目流程

这次我们来看一个很多团队容易混淆的概念:可观测性与 Monitor(监控)。两者经常被放在同一个文件目录下,但解决的问题完全不同。监控是“我知道它挂了”,可观测性是“我知道它为什么挂”。如果你正在搭告警体系、做日志采集、排查链路瓶颈,或者刚从“只看 CPU 和内存”的阶段往“全链路可观测”的方向升级,这篇文章可以直接收藏。

我们先说结论:可观测性不是采购一个大屏监控工具就算完成,它由 Logs(日志)、Metrics(指标)、Traces(链路)三部分组成,习惯上称为“三大支柱”。而 Monitor 通常指持续采集、聚合、展示指标并触发告警的系统,比如 Prometheus、Grafana、Zabbix。这篇文章会基于一套主流开源实践,演示如何在本地环境部署 Prometheus + Grafana + Loki + OpenTelemetry,完成从指标监控、日志采集到链路追踪的一整套可观测性平台搭建,并把常见问题和性能观察方法一并梳理清楚。

1. 核心能力速览

能力项说明
项目类型可观测性平台搭建实践,覆盖 Metrics、Logs、Traces 三大支柱
核心组件Prometheus、Grafana、Loki、Promtail、OpenTelemetry Collector、Alertmanager
主要功能指标采集与告警、日志聚合检索、分布式链路追踪、可视化大屏
推荐硬件8GB 内存以上,2 核 CPU 以上,磁盘预留 50GB(按日志量评估)
数据存储Prometheus TSDB、Loki 日志存储,默认本地磁盘,可接对象存储
支持平台Linux / Windows / macOS,推荐 Linux 服务器长期运行
启动方式Docker Compose 一键拉起,或二进制 / systemd 分别部署
是否支持 API支持。Prometheus / Alertmanager / Loki / Grafana 均提供 HTTP API
是否支持批量任务支持批量采集、批量告警规则加载、多实例抓取
适合场景微服务监控、容器平台观测、传统 IDC 基础设施监控、日志排查与链路诊断

从材料看,这类方案适合已经有基础服务、但监控能力分散在多个平台的团队,也适合刚开始建设统一可观测性的个人开发者。

2. 适用场景与使用边界

可观测性平台不是越大越好,先明确它适合什么、不适合什么。

2.1 适合什么

  • 现有服务只有零散日志,缺少统一检索入口,排查问题靠翻文件。
  • 已经用 Kubernetes 或其他容器平台,需要监控 Pod、Node、应用指标。
  • 微服务调用链路过长,接口变慢时无法快速定位是哪个环节导致的。
  • 需要把告警发到钉钉、企业微信、邮件,并且对告警做去重和静默管理。

2.2 不适合什么

  • 业务规模很小、只有一台服务器且不需要长期留存日志,直接用云厂商自带监控更省事。
  • 需要 APM 级别的代码级性能分析,单靠 Prometheus 指标不够,要结合 SkyWalking 或商业 APM 工具。
  • 团队没有精力维护中间件,更建议使用托管的云可观测服务。
  • 日志量为 PB 级且需要复杂分析,Loki 会显得吃力,这类场景一般要引入专门的日志分析平台。

2.3 合规与安全边界

部署可观测性平台会采集大量日志和指标,其中可能包含用户 IP、请求路径、错误堆栈等敏感信息。建议:

  • 日志采集前做脱敏处理,避免记录完整 Cookie、Token、身份证号等字段。
  • 监控平台本身要启用认证,Grafana 至少设置强密码或接入统一身份认证。
  • 链路追踪数据中避免透传业务敏感字段。
  • 对外提供监控面板或 API 时,只暴露必要数据,并确认已获得业务方授权。

3. 环境准备与前置条件

建议使用 Linux 服务器部署,版本不限,关键是 Docker 环境可用。这里给出一套通用检查清单。

3.1 硬件与系统要求

  • CPU:2 核以上,多任务采集建议 4 核。
  • 内存:8GB 起步。Prometheus、Loki、Grafana 同时运行,叠加采集任务,4GB 会比较紧张。
  • 磁盘:SSD 更稳。Prometheus 默认保留 15 天数据,Loki 按日志量增长,建议预留 50GB 以上。
  • 系统:CentOS 7+、Ubuntu 20.04+、Debian 11+ 均可,Windows 也能跑但生产环境不推荐。

3.2 软件依赖清单

组件版本建议说明
Docker20.10+容器运行基础
Docker Composev2 以上一键编排服务
Prometheus2.47+指标采集与存储
Grafana10.x可视化查询与告警展示
Loki2.9.x日志存储与查询
Promtail2.9.x日志采集 Agent
OpenTelemetry Collector0.88+链路与指标转发

如果不用 Docker,也可以直接下载各组件二进制包,但依赖管理更繁琐。个人建议先用 Docker Compose 建一套最小可用环境。

3.3 端口规划

默认端口如下:

服务端口用途
Prometheus9090Web UI 与 API
Grafana3000可视化控制台
Loki3100日志写入与查询 API
Alertmanager9093告警统一管理
OpenTelemetry Collector4317 / 4318OTLP gRPC / HTTP 接收

实际部署时,如果端口冲突,用环境变量或 docker-compose 里的 ports 映射修改即可。

4. 一键部署与启动方式

下面用 Docker Compose 搭建一套基础可观测性平台。这里采用通用配置模板,实际使用时要按你的服务目录和日志路径调整。

4.1 创建项目目录

mkdir -p ~/observability/{prometheus,grafana,loki,promtail,otel-collector} cd ~/observability

4.2 编写 docker-compose.yml

version: "3.8" services: prometheus: image: prom/prometheus:latest container_name: prometheus restart: unless-stopped ports: - "9090:9090" volumes: - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml - prometheus-data:/prometheus command: - "--config.file=/etc/prometheus/prometheus.yml" - "--storage.tsdb.retention.time=15d" grafana: image: grafana/grafana:latest container_name: grafana restart: unless-stopped ports: - "3000:3000" environment: - GF_SECURITY_ADMIN_USER=admin - GF_SECURITY_ADMIN_PASSWORD=admin123 volumes: - grafana-data:/var/lib/grafana loki: image: grafana/loki:latest container_name: loki restart: unless-stopped ports: - "3100:3100" volumes: - ./loki/loki-config.yaml:/etc/loki/loki-config.yaml - loki-data:/loki command: - "-config.file=/etc/loki/loki-config.yaml" promtail: image: grafana/promtail:latest container_name: promtail restart: unless-stopped volumes: - ./promtail/promtail-config.yaml:/etc/promtail/promtail-config.yaml - /var/log:/var/log:ro command: - "-config.file=/etc/promtail/promtail-config.yaml" otel-collector: image: otel/opentelemetry-collector-contrib:latest container_name: otel-collector restart: unless-stopped ports: - "4317:4317" - "4318:4318" volumes: - ./otel-collector/otel-config.yaml:/etc/otel-collector-config.yaml command: - "--config=/etc/otel-collector-config.yaml" alertmanager: image: prom/alertmanager:latest container_name: alertmanager restart: unless-stopped ports: - "9093:9093" volumes: - ./prometheus/alertmanager.yml:/etc/alertmanager/alertmanager.yml command: - "--config.file=/etc/alertmanager/alertmanager.yml" volumes: prometheus-data: grafana-data: loki-data:

这里把核心组件都编排到一个栈里。实际工作中,如果你只想先验证指标监控,可以只启动 Prometheus 和 Grafana,其他组件按需追加,减少资源占用。

4.3 编写 Prometheus 配置

global: scrape_interval: 15s evaluation_interval: 15s rule_files: - "/etc/prometheus/rules.yml" alerting: alertmanagers: - static_configs: - targets: ["alertmanager:9093"] scrape_configs: - job_name: "prometheus" static_configs: - targets: ["localhost:9090"] - job_name: "node-exporter" static_configs: - targets: ["node-exporter:9100"]

如果暂时没有 node-exporter,可以先把 node-exporter 的任务注释掉,避免启动后一直报抓取错误。

4.4 编写 Loki 配置

auth_enabled: false server: http_listen_port: 3100 common: path_prefix: /loki storage: filesystem: chunks_directory: /loki/chunks rules_directory: /loki/rules replication_factor: 1 ring: kvstore: store: inmemory schema_config: configs: - from: 2024-01-01 store: tsdb object_store: filesystem schema: v13 index: prefix: index_ period: 24h limits_config: retention_period: 168h ruler: alertmanager_url: http://alertmanager:9093

这里配置了 7 天日志保留时间。如果磁盘紧张,可以改为 24h 或 72h。

4.5 启动服务

docker compose up -d

启动后检查服务状态:

docker compose ps

正常情况下可以看到所有容器处于 Up 状态。访问以下地址验证基础服务:

  • Prometheus 控制台:http://服务器IP:9090
  • Grafana 登录页:http://服务器IP:3000
  • Alertmanager 界面:http://服务器IP:9093
  • Loki 健康检查:http://服务器IP:3100/ready

到这里,一套最小可运行的可观测性基础设施就起来了。

5. 功能测试与效果验证

部署完成不等于可用。下面按“指标 -> 日志 -> 链路”的顺序走一遍验证流程。

5.1 指标监控验证

Prometheus 自身会暴露prometheus_http_requests_total等指标。

在 Prometheus 控制台执行查询:

rate(prometheus_http_requests_total[5m])

如果返回非空数据,说明采集链路正常。接着在 Grafana 中添加 Prometheus 数据源:

  • URL 填写http://prometheus:9090
  • 请求头不需要额外配置

添加完成后新建一个 Dashboard,选择prometheus_http_requests_total指标,即可看到请求量曲线。

这一步验证的是整个指标链路是否通畅:抓取 -> 存储 -> 查询 -> 可视化。

5.2 日志采集验证

如果 Promtail 配置正确,Loki 中就能搜到本机/var/log下相关日志。在 Grafana 的 Explore 页面,数据源选择 Loki,在查询框中输入:

{job="varlogs"}

如果返回日志流,说明日志链路正常。

Loki 的查询语法也是生产环境排查问题的重要手段,比如按关键词过滤:

{job="varlogs"} |= "error"

这条查询会返回包含error的日志行,定位问题时非常实用。

5.3 链路追踪验证

链路追踪需要业务服务配合注入 OpenTelemetry SDK。这里先验证 OpenTelemetry Collector 是否正常接收数据。

启动后,向 Collector 发送 OTLP HTTP 请求:

curl -X POST http://127.0.0.1:4318/v1/traces \ -H "Content-Type: application/json" \ -d '{"resourceSpans":[]}'

返回200说明 Collector 已正常接收 Trace 数据。实际业务接入时,在服务中将 OTLP Endpoint 指向http://collector地址:4317或4318即可。

5.4 告警功能验证

告警规则的验证分为两步。

第一步,准备一个测试告警规则文件prometheus/rules.yml:

groups: - name: instance_down rules: - alert: InstanceDown expr: up == 0 for: 1m labels: severity: critical annotations: summary: "Instance {{ $labels.instance }} down"

第二步,重启 Prometheus 或热加载配置:

docker exec prometheus kill -HUP 1

在 Prometheus 的 Alerts 页面,如果能看到InstanceDown规则并且状态为firing,说明告警规则生效。

6. 接口 API 与批量任务

可观测性平台的核心价值之一是开放 API,方便接入自己的自动化体系。

6.1 Prometheus HTTP API

查询指标数据:

curl -G http://127.0.0.1:9090/api/v1/query \ --data-urlencode 'query=up'

返回格式为 JSON,包含status和data。这是最常用的 API,适合做自动化巡检和报告生成。

6.2 Alertmanager API

查看当前告警:

curl http://127.0.0.1:9093/api/v2/alerts

批量静默一个告警:

curl -X POST http://127.0.0.1:9093/api/v2/silences \ -H "Content-Type: application/json" \ -d '{ "matchers": [ {"name": "alertname", "value": "InstanceDown", "isRegex": false} ], "startsAt": "2024-01-01T00:00:00Z", "endsAt": "2024-01-02T00:00:00Z", "createdBy": "automation", "comment": "scheduled maintenance" }'

批量静默是发布窗口期最常用的能力,避免维护期间产生大量误报。

6.3 Loki API

按查询语句拉取日志:

curl -G http://127.0.0.1:3100/loki/api/v1/query_range \ --data-urlencode 'query={job="varlogs"}' \ --data-urlencode 'start=2024-01-01T00:00:00Z' \ --data-urlencode 'end=2024-01-02T00:00:00Z'

Python 脚本批量拉取多个服务的日志并生成报告,也是常见用法:

import requests import time loki_url = "http://127.0.0.1:3100" def query_logs(query, start_ns, end_ns): params = { "query": query, "start": start_ns, "end": end_ns } resp = requests.get(f"{loki_url}/loki/api/v1/query_range", params=params) return resp.json() # 查询最近 10 分钟的 varlogs 日志 end_ns = int(time.time()) * 1_000_000_000 start_ns = end_ns - 600 * 1_000_000_000 result = query_logs('{job="varlogs"}', start_ns, end_ns) print(result["data"]["result"])

这些 API 通常都有对应的 HTTP 客户端 SDK,接入后可以轻松完成批量拉取、批量告警操作、自动生成巡检报告等工作。

6.4 批量抓取与任务设计

Prometheus 的抓取本身就是批量任务,按job_name分组。实际使用中常见设计是:

  • 每类服务建一个 job,用target列表批量抓取多个实例。
  • 采集频率按业务重要性区分,核心服务 15s,非核心服务 30s 或 60s。
  • 告警规则按集群、环境、团队标签分组,便于批量管理和路由。

7. 资源占用与性能观察

部署可观测性平台本身也需要被监控,这里讲几个关键点。

7.1 内存与存储观察

Docker 部署下查看容器资源占用:

docker stats

不同组件的资源特点不同:

  • Prometheus 内存随序列数量和采样频率增长,采集的 target 越多,内存占用越高。
  • Loki 磁盘占用与日志写入量直接相关,日志标签设计不合理会导致索引膨胀。
  • Grafana 本身轻量,内存占用波动不大。

7.2 降低资源占用的方法

如果服务器配置不高,优先做三件事:

  1. 降低抓取频率:将scrape_interval从 15s 调整到 30s 或 60s。
  2. 减少序列数量:Prometheus 的存储压力主要来自唯一序列数量,标签值越多,序列越多。
  3. 缩短日志保留时间:Loki 的retention_period默认 168h,如果日志量大,可以先保留 24h 或 72h。

7.3 日志量与标签设计对性能的影响

这是最容易踩的坑。

Loki 不会对日志内容做全文索引,而是通过标签过滤日志流。如果给每条日志都打上动态标签,比如 request_id 或用户 id,会导致每个请求都产生独立的日志流,索引数量暴涨,查询性能急剧下降。

正确的做法是:静态标签用于分组,比如app、env、host;动态字段保留在日志行内容里,用 LogQL 的解析表达式过滤。

7.4 避免端口冲突与进程残留

多次重启 docker compose 后,偶尔会遇到端口被占用的问题。排查方式:

ss -lntp | grep 9090

找到占用进程后,对应停止或换端口。docker compose down 之后,建议用docker compose ps确认容器真正退出。

8. 常见问题与排查方法

问题现象可能原因排查方式解决方案
服务启动后立即退出配置格式错误或端口冲突docker compose logs 服务名查看日志修正 YAML 缩进,换端口
Grafana 无法连接 Prometheus网络未连通或数据源地址错误在 Grafana 容器内测试curl prometheus:9090数据源使用容器网络地址,不用 localhost
Prometheus 页面up == 0目标服务未启动或抓取路径错误在 Targets 页面查看错误信息确认 target 地址能访问,URL 路径正确
Loki 查询无数据Promtail 未采集到日志或标签写法错误检查 Promtail 日志,确认日志路径存在调大 Promtail 抓取范围,确认主机日志目录已挂载
告警不触发规则文件未加载或阈值不对查看 Prometheus Alerts 页面和规则状态热加载配置,检查表达式语法
OTLP Collector 收不到 Trace业务 SDK 未配置或端口不通journalctl -u otel-collector或容器日志确认 SDK 指向 4317/4318 端口
内存占用持续上涨抓取目标过多或保留时间过长docker stats观察对应容器降低采集频率,缩短保留时间

这里最常见的就是“服务间地址写错”问题。容器部署环境下,服务之间要用容器名访问,localhost只代表某个容器内部。

9. 最佳实践与使用建议

9.1 先小规模跑通,再横向扩展

不要第一天就把所有服务、所有日志全量接入。先接 1 到 2 个服务,走通指标、日志、链路三条链路,确认存储增长和查询体验可接受,再逐步扩容。

9.2 目录与配置统一管理

把 Prometheus、Loki、Promtail 等配置文件纳入 Git 管理,每一次变更都记录在案。生产环境建议用命名规范区分不同集群:

job_name: "prod-api" job_name: "prod-worker" job_name: "staging-api"

9.3 告警规则设置分级

建议至少分三级:

  • 紧急告警:核心服务不可用,需要立即处理。
  • 警告告警:资源利用率高或错误率上升,需要关注。
  • 信息告警:用于自动化和记录,不直接打扰人。

告警不是越多越好,规则太多只会导致全员告警疲劳。

9.4 日志脱敏与隐私保护

用户请求日志、错误堆栈中可能包含敏感信息。建议在 Promtail 或应用侧做脱敏,规则可以写到日志输出端,避免 Token、密码等字段进入日志系统。

9.5 接口服务访问控制

Grafana、Prometheus API 不建议直接暴露公网。需要使用时有几个选择:

  • 反向代理增加认证。
  • 通过 Tailscale 等内网方案访问。
  • 只开放 API 端口给内网监控网段。

10. 总结与下一步

可观测性与 Monitor 是两件不同的事,但需要一起建设。Monitor 告诉你服务状态,Logger 记录发生了什么,Trace 还原整个调用过程,三者结合才是真正可用的可观测性平台。

这篇文章里留下的最小可用演示栈是 Prometheus + Grafana + Loki + OpenTelemetry Collector + Alertmanager。值得最先验证的功能是:Prometheus 指标是否能正常抓取、Grafana 是否能画出第一张曲线、Loki 是否能搜到第一条日志。这三个场景跑通后,平台的地基就稳了。

最容易踩的坑集中在三处:容器间地址写错、日志标签设计不合理导致索引膨胀、告警规则一次加太多导致告警风暴。

后续可以继续扩展的方向包括:

  • 接入 Alertmanager 的企业微信、钉钉、飞书告警通道。
  • 将 OpenTelemetry SDK 集成到实际业务服务中,打通 Trace 到 Metrics 的关联。
  • 部署 node-exporter 和 cAdvisor,纳入服务器与容器的基础监控。
  • 将 Loki 存储切换到对象存储,延长日志保留周期。

建议把这套环境保存成可复用的 Compose 模板,后续新服务接入时直接复制配置、替换抓取目标和标签即可。监控平台不是装完就完,它是一个需要持续调整数据采集、保留策略和告警规则的基础设施。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询