Loki的原理及使用

为什么做监控
核心目标:保障站点可靠,从而保障业务稳定及保障业务迭代效率

什么决定了站点“可靠”:系统可用度

系统可用度取决于什么:多长时间坏一次;一旦坏了之后,多长时间可以恢复

监控,即是服务于“可观察性”

覆盖面:硬件/系统级监控、应用服务指标监控、程序运行日志监控、业务监控、链路监控

关于日志监控

核心目标:程序运行日志监控,关注程序运行状态

如何做:日志的采集 -> 转换 -> 存储 ->可视化

ELK Stack:

ELK系统通常包含较多需求场景:“日志”(程序的运行信息)的监控、接口调用的指标统计分析、离线数据保存、业务数据分析等
当数据量级上来,在每个需求场景下都很难达到满意

ELK系统的需求做分化,让各自的技术方案适配各自的场景需求

ES存储日志数据成本高:尽量避免使用昂贵的全文索引或列式存储引擎来存储大量低价值的日志信息通常情况下查看频率较低

ES集群部署、扩缩容的运维成本较高

日志告警功能不完善

Loki是什么

Loki一个可水平伸缩、高可用、支持多租户的日志聚合系统。

Loki的灵感来源于Prometheus,它的设计极具成本效益并且易于操作,可以认为是日志版的Prometheus。

Loki的特殊之处

Loki不会对日志数据建立全文索引,也不支持Multiline:

取而代之的是:对非结构化的日志数据进行压缩存储并且只对日志数据的metadata(包括:时间戳、 labels等)建立索引。
                         存储、查询成本较低

Loki可以跟Prometheus中的监控指标进行关联:Loki可以使用与Prometheus相同的label定义和设计。

Loki的查询语法LogQL简单:日志数据查询分析心智负担低,便于在此之上建立告警统计机制

Grafana原生支持Loki:Grafana中原生支持Loki作为数据源进行查询

Loki的功能组件

Promtail、Distributor、Ingester、Querier、Query Frontend、Overrides、TableManager、RuntimeConfig

Loki的功能组件的架构

Loki的功能组件-Promtail

日志数据:采集、提取、匹配、过滤、打Labels、批量Push To Loki

支持的采集方式:File Traget、Journal Traget、Syslog Traget、Stdin Traget

Loki的功能组件-Promtail-处理流程

`Prometheus + Loki + Tempo` 是 **CNCF(云原生计算基金会)** 推荐的“黄金组合”——合称 **"The Observability Stack" 或 "PLT Stack"**,用于实现云原生环境下的全面可观测性。它们分别负责: - **Prometheus**:监控与指标(Metrics) - **Loki**:日志聚合(Logs) - **Tempo**:分布式追踪(Traces) 这三者共同构成了现代微服务架构中 **Metrics、Logs、Traces 三大支柱** 的完整解决方案。 --- ## 🔍 一、整体架构概览 ``` +------------------+ +------------------+ +------------------+ | Prometheus | | Loki | | Tempo | | (Metrics) | | (Log Aggregation)| | (Tracing) | +------------------+ +------------------+ +------------------+ ↑ ↑ ↑ 指标数据采集 日志数据采集 分布式追踪数据 | | | ↓ ↓ ↓ 应用暴露/metrics 应用写入stdout/stderr 应用集成OpenTelemetry/Sidecar | | | +----------+-------------+------------+----------+ | | 统一查询层(Grafana) | 用户通过 Grafana 查询 M-L-T 数据 ``` 所有组件均可通过 **Grafana** 进行统一可视化和关联分析。 --- ## ✅ 1. Prometheus:指标监控系统 ### 📌 核心功能 收集并存储时间序列数据(Time Series Data),如 CPU 使用率、请求延迟、QPS 等。 ### ⚙️ 工作原理 #### (1)数据模型 - 时间序列 = `metric_name{label1="value1", label2="value2"} -> (timestamp, value)` - 示例: ``` http_requests_total{job="api-server", method="POST", handler="/submit"} 123456 ``` #### (2)抓取机制(Pull-based) - Prometheus 主动从目标服务的 `/metrics` 端点拉取数据(HTTP GET) - 支持静态配置或服务发现(Kubernetes SD、Consul 等) ```yaml # prometheus.yml 示例 scrape_configs: - job_name: 'kubernetes-pods' kubernetes_sd_configs: - role: pod relabel_configs: - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] action: keep regex: true ``` #### (3)存储 - 本地磁盘存储(TSDB 引擎) - 可扩展至远程写入(Remote Write)到 Thanos、Cortex、Mimir 等长期存储系统 #### (4)查询语言:PromQL 支持强大的表达式查询: ```promql rate(http_requests_total[5m]) # 最近5分钟每秒请求数 histogram_quantile(0.95, sum(rate(latency_bucket[5m])) by (le)) # P95 延迟 ``` #### (5)告警 通过 Alertmanager 实现规则触发、去重、通知(邮件、钉钉、Slack等) --- ## ✅ 2. Loki:日志聚合系统 ### 📌 核心理念 > “Like Prometheus, but for logs.” —— 高效、低成本、基于标签的日志系统 Loki 不索引日志内容本身,而是仅对 **日志的元数据(标签)进行索引**,原始日志以压缩块形式存储在对象存储(S3、MinIO、GCS)中。 ### ⚙️ 工作原理 #### (1)架构组成 | 组件 | 功能 | |------|------| | **Promtail** | 日志采集 Agent,读取容器日志并发送给 Loki | | **Loki** | 后端服务,接收、索引、存储日志 | | **Ingester** | 写入日志流,构建 chunks | | **Querier** | 处理查询请求 | | **Ruler** | 执行日志级别告警规则 | #### (2)日志流(Log Stream) = 标签唯一标识 每个日志流是一个带标签的序列: ```text {job="kubelet", container="runtime", node="ip-10-0-0-1"} => [ "time=... level=info msg='Container started'", "time=... level=error msg='Failed to pull image'" ] ``` #### (3)日志采集:Promtail 配置示例 ```yaml scrape_configs: - job_name: kubernetes-pods pipeline_stages: - docker: {} kubernetes_sd_configs: - role: pod relabel_configs: - source_labels: ['__meta_kubernetes_pod_container_name'] target_label: 'container' - action: drop regex: '' source_labels: ['__meta_kubernetes_pod_label_present'] ``` #### (4)查询语言:LogQL 类似 PromQL,但用于日志过滤与统计: ```logql # 查询某个服务的错误日志 {namespace="prod", container="user-service"} |= "ERROR" # 统计各级别的日志数量 {job="api"} |~ "timeout" | logfmt | line_format "{{.msg}}" | count by (level) # 关联指标(与 Prometheus 联查) rate({container="nginx"} |= "GET" [5m]) ``` > 💡 优势:成本低(不全文索引)、与 Prometheus 风格一致、易于集成 Grafana。 --- ## ✅ 3. Tempo:分布式追踪系统 ### 📌 核心功能 记录一次请求在多个微服务之间的完整调用链路(Trace),帮助定位性能瓶颈。 ### ⚙️ 工作原理 #### (1)基本概念 - **Trace**:一次完整请求的调用链(如 HTTP → Service A → B → DB) - **Span**:一个操作单元(如 API 调用、数据库查询) - **Span Context**:包含 TraceID、SpanID、ParentSpanID,用于传播 #### (2)数据格式 支持 OpenTelemetry、Jaeger、Zipkin 等标准格式。 #### (3)架构组件 | 组件 | 功能 | |------|------| | **Collector** | 接收、处理、导出追踪数据(可选 Kafka 缓冲) | | **Distributor** | 接收客户端发送的 trace,做负载均衡 | | **Ingester** | 将 spans 构建成 trace blocks 并写入后端存储 | | **Querier** | 查询 trace,从 backend 加载数据 | | **Query Frontend** | 缓存和拆分查询 | #### (4)存储后端(Object Storage Only) Tempo 不使用数据库,直接将 trace 存储为 Parquet 或 JSON 块文件在 S3/MinIO/GCS 上,成本极低。 #### (5)采样策略 支持动态采样(Dynamic Sampling)避免数据爆炸: ```yaml target_ingestion_rate: 100 # 目标每秒摄入 100 条 traces sampling_fraction: 0.1 # 初始采样率 10% ``` #### (6)OpenTelemetry 集成示例(Go) ```go import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.17.0" ) func initTracer() { ctx := context.Background() exporter, _ := otlptracegrpc.New(ctx, otlptracegrpc.WithInsecure(), otlptracegrpc.WithEndpoint("tempo.default:4317"), ) tp := sdktrace.NewTracerProvider( sdktrace.WithBatcher(exporter), sdktrace.WithResource(resource.NewWithAttributes( semconv.SchemaURL, semconv.ServiceName("my-service"), )), ) otel.SetTracerProvider(tp) } ``` 然后通过 gRPC Header 自动传播 TraceContext。 --- ## 🔄 三者如何协同工作?(M-L-T 关联) 关键在于 **TraceID 的贯通**,实现跨维度下钻分析。 ### 场景示例:排查慢请求 1. 在 **Grafana** 中查看 Prometheus 指标: ```promql histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m])) ``` 发现 P99 延迟突增。 2. 切换到 **Loki**,搜索该时间段内的慢日志: ```logql {service="order"} |= "duration>1s" ``` 提取出对应的 `trace_id=abc123` 3. 在 **Tempo** 中输入 `abc123`,查看完整调用链: - 发现 `payment-service` 耗时 800ms - 下钻查看其 span 日志,发现数据库锁等待 ✅ 实现“从指标发现问题 → 查日志定位上下文 → 看追踪找到根因”的闭环。 --- ## 🧩 四、典型部署方式(Kubernetes + Helm) ```bash # 安装 Prometheus helm install prometheus prometheus-community/kube-prometheus-stack # 安装 Loki helm repo add grafana https://grafana.github.io/helm-charts helm install loki grafana/loki-stack --set promtail.enabled=true # 安装 Tempo helm install tempo grafana/tempo-distributed ``` 并在 Grafana 中添加数据源: - Prometheus URL: `http://prometheus-server` - Loki URL: `http://loki:3100` - Tempo URL: `http://tempo:3200` --- ## ✅ 总结对比表 | 组件 | 数据类型 | 查询语言 | 存储特点 | 典型用途 | |------|---------|----------|-----------|------------| | **Prometheus** | 指标(Metrics) | PromQL | 本地 TSDB / 远程写入 | 资源使用率、QPS、延迟 | | **Loki** | 日志(Logs) | LogQL | 对象存储(仅索引标签) | 错误日志、审计日志 | | **Tempo** | 追踪(Traces) | TraceID 查询 | 对象存储(Parquet 块) | 调用链分析、性能瓶颈定位 | --- ## ✅ 优势总结 | 优点 | 说明 | |------|------| | **轻量高效** | Loki 和 Tempo 不索引内容,节省资源 | | **统一栈** | 全部由 Grafana 支持,界面一致 | | **开放标准** | 支持 OpenTelemetry、Prometheus、CNCF 生态 | | **低成本** | 可运行在廉价存储上,适合大规模场景 | | **深度集成** | 在 Grafana 中可一键跳转 Metrics → Logs → Traces | ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值