菜单
开源

Loki 教程

本快速入门指南将引导您使用 Docker Compose 在单体模式(也称为 monolithic mode)下部署 Loki。Grafana Loki 是 Grafana 日志可观测性技术栈的其中一个组件。在本教程中,我们将此技术栈称为 Loki 技术栈

Loki stack
Loki 技术栈

Loki 技术栈包含以下组件

  • Alloy: Grafana Alloy 是一款开源的遥测数据收集器,用于收集指标、日志、追踪和持续性能分析数据。在本快速入门指南中,Grafana Alloy 已被配置为跟踪所有 Docker 容器的日志并将其转发到 Loki。
  • Loki: 一个日志聚合系统,用于存储收集的日志。有关 Loki 的更多信息,请参阅 Loki 概述
  • Grafana: Grafana 是一个用于监控和可观测性的开源平台。Grafana 将用于查询和可视化存储在 Loki 中的日志。

开始之前

开始之前,您需要在本地系统上安装以下软件

提示

或者,您可以在我们的交互式学习环境中尝试此示例:Loki 快速入门沙箱

这是一个完全配置好的环境,所有依赖项已安装完毕。

Interactive

Grafana Killercoda 仓库中提供反馈、报告错误并提出问题。

部署 Loki 技术栈

注意

本快速入门假定您正在运行 Linux 或 MacOS。Windows 用户可以使用 Windows Subsystem for Linux 执行相同的步骤。

要在本地部署 Loki 技术栈,请执行以下步骤

  1. 克隆 Loki fundamentals 仓库并切换到 getting-started 分支

    bash
    git clone https://github.com/grafana/loki-fundamentals.git -b getting-started
  2. 切换到 loki-fundamentals 目录

    bash
    cd loki-fundamentals
  3. loki-fundamentals 设置为当前工作目录,然后使用 Docker Compose 部署 Loki、Alloy 和 Grafana

    bash
    docker compose up -d

    运行命令后,您应该看到类似如下的输出

    console
     ✔ Container loki-fundamentals-grafana-1  Started  0.3s 
     ✔ Container loki-fundamentals-loki-1     Started  0.3s 
     ✔ Container loki-fundamentals-alloy-1    Started  0.4s
  4. Loki 技术栈运行后,您现在可以验证每个组件是否正常运行

    • Alloy: 打开浏览器并导航到 https://:1245/graph。您应该能看到 Alloy 用户界面。
    • Grafana: 打开浏览器并导航到 https://:3000。您应该能看到 Grafana 主页。
    • Loki: 打开浏览器并导航到 https://:3100/metrics。您应该能看到 Loki 指标页面。

由于 Grafana Alloy 被配置为跟踪所有 Docker 容器的日志,Loki 应该已经开始接收日志了。验证日志收集的最佳方法是使用 Grafana Logs Drilldown 功能。为此,请导航到 https://:3000/drilldown。选择 日志。您应该能看到 Grafana Logs Drilldown 页面。

Grafana Logs Drilldown
Grafana Logs Drilldown

如果您在 Docker 环境中只部署了入门演示,您应该会看到三个容器及其日志;loki-fundamentals-alloy-1loki-fundamentals-grafana-1loki-fundamentals-loki-1。在 loki-fundamentals-loki-1 容器中,点击显示日志以钻取查看该容器的日志。

Grafana Drilldown Service View
Grafana Drilldown 服务视图

本快速入门指南中将不再介绍 Grafana Logs Drilldown 的其他功能。有关如何使用 Grafana Logs Drilldown 功能的更多信息,请参阅 Grafana Logs Drilldown 入门

收集示例应用的日志

目前,Loki 技术栈正在收集自身的日志。为了提供一个更真实的示例,您可以部署一个生成日志的示例应用。该示例应用名为食肉植物温室,它是一个微服务应用,允许用户登录并模拟一个带有食肉植物的温室进行监控。该应用包含七个服务

  • 用户服务:管理应用的用户数据和认证。例如创建用户和登录。
  • 植物服务:管理新植物的创建,并在创建新植物时更新其他服务。
  • 模拟服务:为每种植物生成传感器数据。
  • WebSocket 服务:管理应用的 websocket 连接。
  • Bug 服务:启用后,该服务会随机导致服务失败并生成额外的日志。
  • 主应用:连接所有服务的主应用。
  • 数据库:一个存储用户和植物数据的 PostgreSQL 数据库。

应用架构如下图所示

Sample Microservice Architecture
示例微服务架构

要部署示例应用,请执行以下步骤

  1. loki-fundamentals 设置为当前工作目录,然后使用 Docker Compose 部署示例应用

    bash
    docker compose -f greenhouse/docker-compose-micro.yml up -d --build  

    注意

    这可能需要几分钟才能完成,因为需要构建示例应用的镜像。去喝杯咖啡再回来吧。

    命令完成后,您应该看到类似如下的输出

    console
      ✔ Container greenhouse-websocket_service-1   Started   0.7s 
      ✔ Container greenhouse-db-1                  Started   0.7s 
      ✔ Container greenhouse-user_service-1        Started   0.8s 
      ✔ Container greenhouse-bug_service-1         Started   0.8s 
      ✔ Container greenhouse-plant_service-1       Started   0.8s 
      ✔ Container greenhouse-simulation_service-1  Started   0.7s 
      ✔ Container greenhouse-main_app-1            Started   0.7s
  2. 为了验证示例应用正在运行,请打开浏览器并导航到 https://:5005。您应该能看到食肉植物温室应用的登录页面。

    示例应用正在运行后,在应用中执行一些操作以生成日志。以下是操作列表

    1. 创建用户:点击注册并创建一个新用户。添加用户名和密码后点击注册
    2. 登录:使用您创建的用户名和密码登录。添加用户名和密码后点击登录
    3. 创建植物:登录后,给您的植物命名,选择植物类型并点击添加植物。如果您喜欢,可以多次执行此操作。

您的温室应该看起来像这样

Greenhouse Dashboard
温室仪表盘

现在您已经生成了一些日志,您可以返回 Grafana Logs Drilldown 页面 https://:3000/drilldown。您应该会看到七个新服务,例如 greenhouse-main_app-1greenhouse-plant_service-1greenhouse-user_service-1 等。

查询日志

至此,您已使用 Grafana Logs Drilldown 功能查看了日志。在许多情况下,这会提供您所需的所有信息。但是,我们也可以手动查询 Loki,以提出关于日志的更高级问题。这可以通过 Grafana Explore 完成。

  1. 打开浏览器并导航到 https://:3000 以打开 Grafana。

  2. 在 Grafana 主菜单中,点击Explore 图标 (1) 以打开 Explore 选项卡。

    要了解有关 Explore 的更多信息,请参阅 Explore 文档。

    Grafana Explore
    Grafana Explore
  3. 从仪表盘头部的菜单中,选择 Loki 数据源 (2)。

    这将显示 Loki 查询编辑器。

    在查询编辑器中,您可以使用 Loki 查询语言 LogQL 查询您的日志。要了解有关查询编辑器的更多信息,请参阅查询编辑器文档

  4. Loki 查询编辑器有两种模式 (3)

    • Builder 模式,提供可视化查询设计器。
    • Code 模式,提供功能丰富的编辑器,用于编写 LogQL 查询。

    接下来,我们将通过代码视图介绍一些查询示例。

  5. 点击Code (3) 以在查询编辑器中切换到 Code 模式。

    以下是一些示例查询,帮助您开始使用 LogQL。将任何查询复制到查询编辑器后,点击运行查询 (4) 执行查询。

    1. 查看所有具有 container 标签值 greenhouse-main_app-1 的日志行

      logql
      {container="greenhouse-main_app-1"}

      在 Loki 中,这是一个日志流。

      Loki 使用标签作为元数据来描述日志流。

      Loki 查询总是以标签选择器开始。在上面的查询中,标签选择器是 {container="greenhouse-main_app-1"}

    2. 查找 {container="greenhouse-main_app-1"} 流中包含字符串 POST 的所有日志行

      logql
      {container="greenhouse-main_app-1"} |= "POST"

从日志中提取属性

Loki 的设计理念是不强制日志行遵循特定的 schema 格式。无论您使用的是 JSON、键值对、纯文本、Logfmt 或任何其他格式,Loki 都会将这些日志行作为字符流摄取。我们使用的示例应用以 Logfmt 格式存储日志

bash
ts=2025-02-21 16:09:42,176 level=INFO line=97 msg="192.168.65.1 - - [21/Feb/2025 16:09:42] "GET /static/style.css HTTP/1.1" 304 -"

分解如下

  • ts=2025-02-21 16:09:42,176 是日志行的时间戳。
  • level=INFO 是日志级别。
  • line=97 是代码中的行号。
  • msg="192.168.65.1 - - [21/Feb/2025 16:09:42] "GET /static/style.css HTTP/1.1" 304 -" 是日志消息。

查询 Loki 时,您可以通过解析器管道处理标签选择器的结果。这将从日志行中提取属性以进行进一步处理。例如,让我们将 {container="greenhouse-main_app-1"} 通过 logfmt 解析器进行管道处理,以提取 levelline 属性

logql
{container="greenhouse-main_app-1"} | logfmt

现在,当您展开查询结果中的日志行时,您将看到提取的属性。

提示

在我们继续下一节之前,让我们生成一些错误日志。为此,请在示例应用中启用 bug 服务。这可以通过在食肉植物温室应用中将 Toggle Error Mode 设置为 On 来完成。这将导致 bug 服务随机导致服务失败。

高级查询和指标查询

启用 Error Mode 后,bug 服务将开始导致服务失败。在接下来的几个 LogQL 示例中,我们将追踪其中一些错误。首先,让我们解析日志以提取 level 属性,然后过滤具有 ERROR 级别的日志

logql
{container="greenhouse-plant_service-1"} | logfmt | level="ERROR"

此查询将返回来自 greenhouse-plant_service-1 容器中所有具有 ERROR 级别属性的日志。您可以通过过滤特定代码行来进一步细化此查询

logql
{container="greenhouse-plant_service-1"} | logfmt | level="ERROR", line="58"

此查询将返回来自 greenhouse-plant_service-1 容器中所有具有 ERROR 级别属性和 line 属性为 58 的日志。

LogQL 也支持指标查询。指标对于抽象原始日志数据、将属性聚合为数值非常有用。这使您可以在 Grafana 中利用更多可视化选项,以及基于日志生成告警。

例如,您可以使用指标查询计算每秒具有特定属性的日志数量

logql
sum(rate({container="greenhouse-plant_service-1"} | logfmt | level="ERROR" [$__auto]))

由于错误计数相当低,最好将可视化方式从 lines 更改为 bars,以便随时间可视化错误率。

另一个示例是获取错误率最高的 10 个服务

logql
topk(10,sum(rate({level="error"} | logfmt [5m])) by (service_name))

注意

service_name 是 Loki 在日志行中未提供服务名称时创建的标签。它将使用容器名称作为服务名称。所有自动生成的标签列表可以在标签中找到。

最后,让我们看看生产环境中每个容器的总日志吞吐量

logql
sum by (service_name) (rate({env="production"} | logfmt [$__auto]))

这得益于我们添加到日志行中的 service_name 标签和 env 标签。请注意,env 是一个静态标签,我们在 Alloy 处理所有日志行时添加了它。

幕后一探

至此,您已经拥有一个运行中的 Loki 技术栈和一个生成日志的示例应用。您还使用 Grafana Logs Drilldown 和 Grafana Explore 查询了 Loki。在下一节中,我们将深入探讨 Loki 技术栈如何配置以收集日志,Loki 配置文件以及 Grafana 中 Loki 数据源的配置方式。

Grafana Alloy 配置

Grafana Alloy 正在收集所有 Docker 容器的日志并将其转发到 Loki。它需要一个配置文件来知道收集哪些日志以及转发到何处。在 loki-fundamentals 目录下,您会找到一个名为 config.alloy 的文件

alloy
// This component is responsible for discovering new containers within the Docker environment
discovery.docker "getting_started" {
	host             = "unix:///var/run/docker.sock"
	refresh_interval = "5s"
}

// This component is responsible for relabeling the discovered containers
discovery.relabel "getting_started" {
	targets = []

	rule {
		source_labels = ["__meta_docker_container_name"]
		regex         = "/(.*)"
		target_label  = "container"
	}
}

// This component is responsible for collecting logs from the discovered containers
loki.source.docker "getting_started" {
	host             = "unix:///var/run/docker.sock"
	targets          = discovery.docker.getting_started.targets
	forward_to       = [loki.process.getting_started.receiver]
	relabel_rules    = discovery.relabel.getting_started.rules
	refresh_interval = "5s"
}

// This component is responsible for processing the logs (In this case adding static labels)
loki.process "getting_started" {
    stage.static_labels {
    values = {
      env = "production",
    }
}
    forward_to = [loki.write.getting_started.receiver]
}

// This component is responsible for writing the logs to Loki
loki.write "getting_started" {
	endpoint {
		url  = "http://loki:3100/loki/api/v1/push"
	}
}

// Enables the ability to view logs in the Alloy UI in realtime
livedebugging {
  enabled = true
}

可以通过 Alloy 用户界面在 https://:12345/graph 处可视化查看此配置文件。

Alloy UI
Alloy 用户界面

在此视图中,您可以看到 Alloy 配置文件的组件及其连接方式

  • discovery.docker: 此组件通过 Docker socket 查询 Docker 环境的元数据,发现新容器,并提供有关容器的元数据。
  • discovery.relabel: 此组件将元数据 (__meta_docker_container_name) 标签转换为 Loki 标签 (container)。
  • loki.source.docker: 此组件从发现的容器收集日志并将其转发到下一个组件。它从 discovery.docker 组件请求元数据,并应用 discovery.relabel 组件的重新标记规则。
  • loki.process: 此组件提供用于日志转换和提取的阶段。在此示例中,它为所有日志添加一个静态标签 env=production
  • loki.write: 此组件将日志写入 Loki。它将日志转发到 Loki 端点 http://loki:3100/loki/api/v1/push

实时查看日志

Grafana Alloy 提供了一个内置的实时日志查看器。这允许您查看当前日志条目以及它们如何通过管线中的特定组件进行转换。要查看实时调试模式,请打开浏览器选项卡并导航至:https://:12345/debug/loki.process.getting_started

Loki 配置

Grafana Loki 需要一个配置文件来定义如何运行。在 loki-fundamentals 目录下,您会找到一个名为 loki-config.yaml 的文件

yaml
auth_enabled: false

server:
  http_listen_port: 3100
  grpc_listen_port: 9096
  log_level: info
  grpc_server_max_concurrent_streams: 1000

common:
  instance_addr: 127.0.0.1
  path_prefix: /tmp/loki
  storage:
    filesystem:
      chunks_directory: /tmp/loki/chunks
      rules_directory: /tmp/loki/rules
  replication_factor: 1
  ring:
    kvstore:
      store: inmemory

query_range:
  results_cache:
    cache:
      embedded_cache:
        enabled: true
        max_size_mb: 100

limits_config:
  metric_aggregation_enabled: true
  allow_structured_metadata: true
  volume_enabled: true
  retention_period: 24h   # 24h

schema_config:
  configs:
    - from: 2020-10-24
      store: tsdb
      object_store: filesystem
      schema: v13
      index:
        prefix: index_
        period: 24h

pattern_ingester:
  enabled: true
  metric_aggregation:
    loki_address: localhost:3100

ruler:
  enable_alertmanager_discovery: true
  enable_api: true
  
frontend:
  encoding: protobuf

compactor:
  working_directory: /tmp/loki/retention
  delete_request_store: filesystem
  retention_enabled: true

配置文件摘要如下

  • auth_enabled: 此项设置为 false,意味着 Loki 在摄取或查询时不需要租户 ID。请注意,生产环境不建议这样做。部署 Loki Helm Chart 时,此项默认为 true
  • server: 定义 Loki 监听的端口、日志级别以及最大并发 gRPC 流数量。
  • common: 定义 Loki 的通用配置。这包括实例地址、存储配置、复制因子和环配置。
  • query_range: 此项配置告知 Loki 对查询结果使用内置缓存。在 Loki 生产环境中,这由单独的缓存服务处理,例如 memcached。
  • limits_config: 定义所有 Loki 租户的全局限制。这包括启用特定功能,例如指标聚合和结构化元数据。限制可以按租户定义,但这被视为高级配置,对于大多数用例,全局限制已足够。
  • schema_config: 定义 Loki 的 schema 配置。这包括 schema 版本、对象存储和索引配置。
  • pattern_ingester: 启用模式摄取器,用于发现日志模式。主要用于 Grafana Logs Drilldown。
  • ruler: 启用 Loki 的 Ruler 组件。这用于基于日志查询创建告警。
  • frontend: 定义前端的编码格式。在此示例中,设置为 protobuf
  • compactor: 定义 Compactor 配置。用于压缩索引和管理数据块保留。

以上配置文件是 Loki 的基本配置文件。有关更高级的配置选项,请参阅 Loki Configuration 文档。

Grafana Loki 数据源

最后一部分是 Grafana Loki 数据源。Grafana 使用它来连接到 Loki 并查询日志。Grafana 有多种定义数据源的方式;

  • 直接方式: 在 Grafana 用户界面中定义数据源。
  • 配置提供方式 (Provisioning): 在配置文件中定义数据源,并让 Grafana 自动创建数据源。
  • API 方式: 使用 Grafana API 创建数据源。

在此示例中,我们使用配置提供方式 (provisioning)。我们没有挂载 Grafana 配置目录,而是在 docker-compose.yml 文件的这部分定义了数据源

yaml
  grafana:
    image: grafana/grafana:latest
    environment:
      - GF_FEATURE_TOGGLES_ENABLE=grafanaManagedRecordingRules
      - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
      - GF_AUTH_ANONYMOUS_ENABLED=true
      - GF_AUTH_BASIC_ENABLED=false
    ports:
      - 3000:3000/tcp
    entrypoint:
       - sh
       - -euc
       - |
         mkdir -p /etc/grafana/provisioning/datasources
         cat <<EOF > /etc/grafana/provisioning/datasources/ds.yaml
         apiVersion: 1
         datasources:
         - name: Loki
           type: loki
           access: proxy
           orgId: 1
           url: 'http://loki:3100'
           basicAuth: false
           isDefault: true
           version: 1
           editable: true 
         EOF
         /run.sh
    networks:
      - loki

docker-compose.yml 文件的 entrypoint 部分,我们定义了一个名为 run.sh 的文件,该文件在启动时运行并在 Grafana provisioning 目录中创建数据源配置文件 ds.yaml。此文件定义了 Loki 数据源并告知 Grafana 使用它。由于 Loki 与 Grafana 在同一个 Docker 网络中运行,我们可以使用服务名称 loki 作为 URL。

接下来?

您已完成了 Loki 快速入门演示。那么接下来该去哪里呢?以下是一些建议

  • 部署:Loki 可以通过多种方式部署。对于生产用例,我们建议通过Helm chart 部署 Loki。
  • 发送日志:在此示例中,我们使用 Grafana Alloy 收集日志并将其发送到 Loki。但是,根据您的需求,还有许多其他方法可以使用。更多信息请参阅发送数据
  • 查询日志:LogQL 是一种功能强大的日志查询语言,包含许多用于改进日志检索和生成洞察的工具。更多信息请参阅查询部分
  • 告警:最后,您可以使用 Loki 的 ruler 组件根据日志查询创建告警。更多信息请参阅告警

完整的指标、日志、追踪和性能分析示例

如果您想运行一个包含 Mimir、Loki、Tempo 和 Grafana 的演示环境,您可以使用 Grafana 中的指标、日志、追踪和性能分析介绍。这是一个独立的学习 Mimir、Loki、Tempo 和 Grafana 的环境。

该项目包含每个组件的详细解释以及单实例部署的带注释配置。您还可以将环境中的数据推送到 Grafana Cloud