1. 为什么选择LPG日志栈?

最近几年在日志监控领域,LPG(Loki+Promtail+Grafana)组合越来越受欢迎。相比传统的ELK方案,这套组合最大的优势就是轻量级和低成本。我最早接触这套方案是在一个物联网项目中,当时客户需要监控上千台设备的日志,但预算有限。测试后发现,同样的日志量下,Loki的存储空间只有Elasticsearch的1/10。

Loki的设计理念很特别:它只索引日志的元数据(比如时间戳、标签),而不索引日志内容本身。这就像图书馆只记录书的分类编号和位置,不记录书的具体内容。Promtail则是个轻量级的日志收集器,专门为Loki优化过。再加上Grafana强大的可视化能力,就组成了这个性价比超高的"三件套"。

2. 单机部署的完整流程

2.1 环境准备与目录结构

先说说我的目录规划习惯。我通常会在/opt下创建这样的结构:

/opt/docker/
├── loki/
│   ├── config/
│   └── data/
├── promtail/
│   └── config/
└── grafana/

这个结构有几个好处:首先所有配置集中管理;其次数据目录单独存放,方便备份;最后权限清晰,只需要给docker用户访问对应目录的权限就行。

2.2 Loki配置详解

loki.yml是整套系统的核心,这里分享几个关键配置项的经验:

schema_config:
  configs:
    - from: 2021-09-08  # 注意日期格式必须是YYYY-MM-DD
      store: boltdb-shipper
      object_store: filesystem
      schema: v11

storage_config:
  boltdb_shipper:
    active_index_directory: /loki/boltdb-shipper-active
    cache_location: /loki/boltdb-shipper-cache
    shared_store: filesystem
  filesystem:
    directory: /loki/chunks

ingester:
  wal:
    dir: /loki/wal  # WAL目录能显著提高稳定性

最容易踩坑的就是日期格式。我有次部署时写成"2021/09/08",结果Loki直接启动失败。另一个重点是WAL(Write-Ahead Log)配置,它能防止数据丢失,建议生产环境一定要加上。

2.3 Promtail配置技巧

promtail.yml的配置要特别注意路径映射:

scrape_configs:
- job_name: system
  static_configs:
  - targets:
      - localhost
    labels:
      job: app_logs
      __path__: /var/log/app/*.log  # 支持通配符

这里有个实用技巧:使用**可以匹配多级目录。比如/var/log/**/*.log会扫描所有子目录下的.log文件。但要注意,挂载目录时宿主机的路径要完全匹配。

2.4 Docker Compose编排

完整的docker-compose.yml示例:

version: "3"

services:
  loki:
    image: grafana/loki:2.6.1
    ports:
      - "3100:3100"
    volumes:
      - /opt/docker/loki/config:/etc/loki
      - /opt/docker/loki/data:/loki
    command: -config.file=/etc/loki/loki.yml

  promtail:
    image: grafana/promtail:2.6.1
    volumes:
      - /opt/docker/promtail/config:/etc/promtail
      - /var/log:/var/log:ro  # 只读挂载更安全
    command: -config.file=/etc/promtail/promtail.yml

  grafana:
    image: grafana/grafana:9.3.2
    ports:
      - "3000:3000"
    volumes:
      - /opt/docker/grafana/data:/var/lib/grafana

建议固定镜像版本号,避免自动升级带来意外。另外Promtail挂载日志目录时加上:ro(只读)更安全。

3. 那些年我踩过的坑

3.1 日期格式的坑

就像前文提到的,Loki对日期格式极其敏感。有次凌晨三点我还在调试,就因为写成了"2021/09/08"而不是"2021-09-08"。现在我的做法是直接在配置里加注释提醒自己。

3.2 目录权限问题

Loki需要写入WAL和chunks目录,常见错误是:

mkdir /loki/wal: permission denied

解决方案有两个:

  1. 提前创建目录并设置权限:
mkdir -p /opt/docker/loki/data/{wal,chunks}
chmod -R 777 /opt/docker/loki/data
  1. 或者直接在docker-compose里指定用户:
loki:
  user: "1000:1000"

3.3 数据源连接问题

在Grafana中添加Loki数据源时,经常遇到"Data source connected, but no labels received"错误。经过多次实践,我发现这是Promtail还没开始采集日志导致的。解决方法很简单:在监控目录下生成个测试日志:

echo "Test log entry" >> /var/log/app/test.log

4. 进阶:多机日志采集方案

4.1 网络架构设计

多机部署时,我推荐这种架构:

[服务器A] Promtail -> [服务器B] Loki
           ↑
[服务器C] Promtail

关键点是Loki要暴露接口给其他服务器的Promtail访问。需要修改两处配置:

  1. Loki的ingester监听地址:
ingester:
  lifecycler:
    address: 0.0.0.0  # 改为监听所有接口
  1. Promtail的客户端URL:
clients:
  - url: http://loki-server-ip:3100/loki/api/v1/push

4.2 跨服务器认证

生产环境建议开启基础认证。先在Loki端配置:

auth_enabled: true

然后在Promtail配置中添加认证信息:

clients:
  - url: http://loki-server:3100/loki/api/v1/push
    basic_auth:
      username: your_username
      password: your_password

4.3 服务发现与负载均衡

当Promtail实例较多时,可以在前面加个Nginx做负载均衡。这是我的Nginx配置片段:

upstream loki {
    server loki1:3100;
    server loki2:3100;
}

server {
    listen 3100;
    location / {
        proxy_pass http://loki;
    }
}

5. 性能调优实战

5.1 Loki参数优化

根据日志量调整这些参数:

limits_config:
  ingestion_rate_mb: 16  # 默认4MB
  ingestion_burst_size_mb: 32  # 默认6MB

chunk_store_config:
  max_look_back_period: 168h  # 查询时间范围

5.2 Promtail性能提升

对于高负载场景,可以:

  1. 增加批处理大小:
client:
  batchwait: 1s
  batchsize: 1048576  # 1MB
  1. 使用pipeline优化日志处理:
pipeline_stages:
  - regex:
      expression: '.*(?P<error>error).*'
  - labels:
      error:

5.3 Grafana监控看板

分享几个实用的Loki仪表盘:

  1. 日志量趋势:count_over_time({job="varlogs"}[1m])
  2. 错误日志统计:sum by (level) (count_over_time({job="varlogs"} |~ "error|warn|fatal"[1m]))
  3. 高频日志TOP10:topk(10, sum by (message) (count_over_time({job="varlogs"}[5m])))

6. 日常维护经验

6.1 日志轮转处理

对于使用logrotate的服务,需要配置copytruncate:

/var/log/app/*.log {
    daily
    rotate 7
    copytruncate
    delaycompress
}

6.2 存储清理策略

Loki默认不会自动清理旧日志,需要配置:

table_manager:
  retention_deletes_enabled: true
  retention_period: 720h  # 30天

6.3 备份与恢复

关键数据包括:

  1. Loki的chunks目录
  2. Grafana的数据库(默认在/var/lib/grafana)

建议每天用rsync备份:

rsync -avz /opt/docker/loki/data backup-server:/loki-backup

这套LPG方案在我负责的多个项目中表现稳定,特别是资源占用方面优势明显。记得第一次成功部署时,看着Grafana上跳动的日志曲线,那种成就感至今难忘。技术选型没有绝对的好坏,关键是要适合业务场景。对于中小规模的日志监控需求,LPG绝对值得一试。

更多推荐