loki学习

一、Loki + Promtail + Grafana 来收集并可视化 Nginx

使用 Docker Compose 搭建 Loki + Promtail + Grafana 来收集并可视化 Nginx 日志,是一个轻量级且高效的方案。以下是完整的部署步骤:

1. 准备 Nginx 容器

为了让 Promtail 能够读取 Nginx 的日志,需要将 Nginx 的日志目录挂载到宿主机上。
在你的业务 docker-compose.yml 中,配置 Nginx 服务并映射日志目录:

services:
  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "80:80"
    volumes:
      # 将宿主机的 ./nginx/logs 目录挂载到容器内的 /var/log/nginx
      - ./nginx/logs:/var/log/nginx 
    restart: always

2. 创建 Loki 配置文件

创建 loki-config.yml 文件,配置 Loki 的本地存储和保留策略(例如保留 7 天):

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: 2020-10-24
      store: boltdb-shipper
      object_store: filesystem
      schema: v11
      index:
        prefix: index_
        period: 24h
storage_config:
  boltdb_shipper:
    active_index_directory: /loki/boltdb-shipper-active
    cache_location: /loki/boltdb-shipper-cache
    cache_ttl: 24h
    shared_store: filesystem
limits_config:
  retention_period: 168h # 7天

3. 创建 Promtail 配置文件

创建 promtail-config.yml 文件,配置采集规则,读取挂载出来的 Nginx 日志并打上标签:

positions:
  filename: /tmp/positions.yaml
clients:
  - url: http://loki:3100/loki/api/v1/push
scrape_configs:
  - job_name: nginx
    static_configs:
      - targets:
          - localhost
        labels:
          job: nginx_access
          __path__: /var/log/nginx/access.log
      - targets:
          - localhost
        labels:
          job: nginx_error
          __path__: /var/log/nginx/error.log

4. 编写监控栈的 Docker Compose 配置

创建一个专门用于日志监控的 docker-compose.yml 文件:

networks:
  loki_net:
    driver: bridge
    name: loki_net 
services:
  loki:
    image: grafana/loki:2.9.2
    container_name: loki
    ports:
      - "3100:3100"
    volumes:
      - ./loki-config.yml:/etc/loki/local-config.yaml
      - ./loki-data:/loki
    command: -config.file=/etc/loki/local-config.yaml
    restart: always

  promtail:
    image: grafana/promtail:2.9.2
    container_name: promtail
    volumes:
      - ./promtail-config.yml:/etc/promtail/config.yml
      # 关键:将 Nginx 的日志目录只读挂载到 Promtail 容器中
      - ./nginx/logs:/var/log/nginx:ro 
    command: -config.file=/etc/promtail/config.yml
    depends_on:
      - loki
    restart: always

  grafana:
    image: grafana/grafana:9.5.5
    container_name: grafana
    ports:
      - "3000:3000"
    volumes:
      - ./grafana-data:/var/lib/grafana
    restart: always  

  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "80:80"
    volumes:
      # 将宿主机的 ./nginx/logs 目录挂载到容器内的 /var/log/nginx
      - ./nginx/logs:/var/log/nginx 
    restart: always

增加权限 

5. 启动服务

在包含上述 docker-compose.yml 的目录下,运行以下命令启动所有服务:

docker-compose up -d

6. 在 Grafana 中配置与查看

  1. 浏览器访问 http://<你的服务器IP>:3000,使用默认账号密码 admin/admin 登录。
  2. 进入 Configuration -> Data sources,点击 Add data source,选择 Loki
  3. 在 URL 处填写 http://loki:3100,点击 Save & Test,提示成功即可。
  4. 进入左侧菜单的 Explore,在顶部选择 Loki 数据源,输入查询语句:
    • 查看访问日志:{job="nginx_access"}
    • 查看错误日志:{job="nginx_error"}
  5. 点击 Run query 即可看到 Nginx 的实时日志流。你也可以在 Grafana 面板库中导入 Nginx 专属的 Dashboard(如 ID: 11055)来实现更直观的可视化监控。

二、通过docker socket读取Loki + Promtail + Grafana 来收集并可视化 Nginx

docker-compose.yaml

[root@ceph1 sot]# cat docker-compose.yaml 
networks:
  loki_net:
    driver: bridge
    name: loki_net 
services:
  # 1. Loki:日志存储引擎
  loki:
    image: grafana/loki:2.9.2
    container_name: loki
    ports:
      - "3100:3100"
    volumes:
      - ./loki-config.yml:/etc/loki/local-config.yaml
      - loki-data:/loki
    command: -config.file=/etc/loki/local-config.yaml
    restart: always

  # 2. Promtail:日志采集器(通过 Docker Socket 采集)
  promtail:
    image: grafana/promtail:2.9.2
    container_name: promtail
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock  # 关键!挂载 Docker Socket
      - ./promtail-config.yml:/etc/promtail/config.yaml
    command: -config.file=/etc/promtail/config.yaml
    restart: always

  # 3. Grafana:可视化面板
  grafana:
    image: grafana/grafana:9.5.5
    container_name: grafana
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin  # 默认密码
    volumes:
      - grafana-data:/var/lib/grafana
    restart: always

  # 4. 示例 Nginx 服务(无需挂载日志目录)
  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "80:80"
    restart: always

volumes:
  loki-data:
  grafana-data:

promtail.yml 配置文件

[root@ceph1 sot]# cat promtail-config.yml 
server:
  http_listen_port: 9080
  grpc_listen_port: 0

positions:
  filename: /tmp/positions.yaml

clients:
  - url: http://loki:3100/loki/api/v1/push

scrape_configs:
  - job_name: docker
    docker_sd_configs:
      - host: unix:///var/run/docker.sock
        refresh_interval: 5s
    relabel_configs:
      - source_labels: ['__meta_docker_container_name']
        regex: '/(.*)'
        target_label: 'container'
      - source_labels: ['__meta_docker_container_log_stream']
        target_label: 'logstream'
      - source_labels: ['__meta_docker_container_label_com_docker_compose_service']
        target_label: 'service'

loki.yml配置文件 保持不变

[root@ceph1 sot]# cat loki-config.yml 
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: 2020-10-24
      store: boltdb-shipper
      object_store: filesystem
      schema: v11
      index:
        prefix: index_
        period: 24h
storage_config:
  boltdb_shipper:
    active_index_directory: /loki/boltdb-shipper-active
    cache_location: /loki/boltdb-shipper-cache
    cache_ttl: 24h
    shared_store: filesystem
limits_config:
  retention_period: 168h # 7天

启动 docker-compose up -d

访问

三、告警钉钉版本alertmanager

所有文件 

docker-compose.yml


networks:
  loki_net:
    driver: bridge
    name: loki_net 
services:
  # 1. Loki:日志存储 + 告警规则评估(Ruler)
  loki:
    image: grafana/loki:2.9.2
    container_name: loki
    ports:
      - "3100:3100"
    volumes:
      - ./loki-config.yaml:/etc/loki/local-config.yaml
      - ./rules:/etc/loki/rules
      - loki-data:/loki
    command: -config.file=/etc/loki/local-config.yaml
    restart: always

  # 2. Promtail:通过 Docker Socket 采集容器日志
  promtail:
    image: grafana/promtail:2.9.2
    container_name: promtail
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./promtail-config.yaml:/etc/promtail/config.yaml
    command: -config.file=/etc/promtail/config.yaml
    restart: always

  # 3. Alertmanager:独立告警通知服务
  alertmanager:
    image: prom/alertmanager:v0.26.0
    container_name: alertmanager
    ports:
      - "9093:9093"
    volumes:
      - ./alertmanager-config.yml:/etc/alertmanager/alertmanager.yml
      - alertmanager-data:/alertmanager
    command: --config.file=/etc/alertmanager/alertmanager.yml --storage.path=/alertmanager
    restart: always

  # 4. Grafana:可视化面板(可选,用于查看日志和告警状态)
  grafana:
    image: grafana/grafana:9.5.5
    container_name: grafana
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - grafana-data:/var/lib/grafana
    restart: always

    # 4. 示例 Nginx 服务(无需挂载日志目录)
  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "80:80"
    restart: always
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf

  dingtalk-webhook:
    image: timonwong/prometheus-webhook-dingtalk:v2.1.0
    container_name: dingtalk-webhook
    restart: always
    ports:
      - "8060:8060"
    volumes:
      - ./dingding-config.yaml:/etc/prometheus-webhook-dingtalk/config.yml:ro
volumes:
  loki-data:
  alertmanager-data:
  grafana-data:
promtail-config.yaml
server:
  http_listen_port: 9080
  grpc_listen_port: 0

positions:
  filename: /tmp/positions.yaml

clients:
  - url: http://loki:3100/loki/api/v1/push

scrape_configs:
  - job_name: docker
    docker_sd_configs:
      - host: unix:///var/run/docker.sock
        refresh_interval: 5s
    pipeline_stages:
      - regex:
          # 精准匹配你当前日志格式
          expression: '^(?P<remote_addr>\S+) \S+ \S+ \[(?P<time>.+?)\] "(?P<method>\S+) (?P<path>\S+) \S+" (?P<status>\d{3}) \d+ ".+?" ".+?"'
      # 将捕获的status存入日志标签,Loki可直接筛选
      - labels:
          status:
    relabel_configs:
      - source_labels: ['__meta_docker_container_name']
        regex: '/(.*)'
        target_label: 'container'
      - source_labels: ['__meta_docker_container_log_stream']
        target_label: 'logstream'
      - source_labels: ['__meta_docker_container_label_com_docker_compose_service']
        target_label: 'service'
loki-config.yaml
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

ruler:
  alertmanager_url: http://alertmanager:9093  # ← 关键!指向 Alertmanager 容器
  storage:
    type: local
    local:
      directory: /etc/loki/rules
  rule_path: /tmp/loki/rules-temp
  enable_api: true
  enable_alertmanager_v2: true

schema_config:
  configs:
    - from: 2020-10-24
      store: boltdb-shipper
      object_store: filesystem
      schema: v11
      index:
        prefix: index_
        period: 24h
alertmanager-config.yml
global:
  resolve_timeout: 5m

route:
  group_by: ['alertname', 'job']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 1h
  receiver: 'webhook'

receivers:
  - name: 'webhook'
    webhook_configs:
      - url: 'http://dingtalk-webhook:8060/dingtalk/webhook1/send' 
        send_resolved: true

inhibit_rules:
  - source_match:
      severity: 'critical'
    target_match:
      severity: 'warning'
    equal: ['alertname', 'job']
Loki 告警规则文件 ( rules/fake/nginx-alerts.yml) 必须要有fake这个目录

定义具体的告警逻辑,例如 Nginx 5xx 错误率过高:

groups:
  - name: nginx-alerts
    rules:
      - alert: NginxHigh5xxRate
        expr: |
          sum(rate({container="nginx"} | status >= 500 [1m])) 
          / 
          sum(rate({container="nginx"} [1m])) > 0
          > 0.05
        for: 30s
        labels:
          severity: critical
        annotations:
          summary: "{告警}Nginx 5xx 错误率超过 5%"
          description: "{告警}过去 1 分钟内,Nginx 5xx 错误请求占比超过 5%,当前值: {{ $value }}"

nginx.conf 配置文件

server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    # 新增500接口
    location /500 {
        return 500;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

钉钉配置文件  dingding-config.yaml

targets:
  webhook1:
    url: https://oapi.dingtalk.com/robot/send?access_token=a9ae2327f363d0e27497203626793e6b64ae594b9d0e17bbb7c034c5eb3c6ec1
    secret: SEC7d23961c56aa0060fd9b29c06321f2808387578f51a4eb8ebbd1c3e4a75054c1

启动与验证

  1. 创建目录结构:
mkdir -p rules/fake
touch rules/fake/nginx-alerts.yml
  1. 启动所有服务:
docker-compose up -d
  1. 验证告警是否生效:
    • 访问 http://localhost:3100/loki/api/v1/rules 查看 Loki 是否加载了规则。
    • 访问 http://localhost:9093 查看 Alertmanager 是否接收到告警。
    • 触发一个 5xx 错误(如访问一个不存在的页面),等待 2 分钟后检查 Alertmanager 是否发出通知。

完整告警链路总结

整个流程分为四个阶段,数据流向如下:

1. 数据采集与存储(眼睛)
  • 源头:业务服务器(如 Nginx)产生日志文件。
  • 采集Promtail 实时监控日志文件变化,将日志流式传输给 Loki。
  • 存储Loki 接收并索引这些日志数据,等待被查询或评估。
2. 规则评估与触发(大脑)—— 核心环节
  • 加载规则Loki (Ruler 组件) 启动时,会去指定目录(如 /etc/loki/rules/fake/)加载你写的 .yml 告警规则文件。
  • 实时计算:Ruler 周期性(默认 1 分钟)执行 LogQL 语句(例如 count_over_time(...))。
  • 触发告警:如果计算结果满足阈值(例如 5xx 错误数 > 5),Loki 就会生成一个标准的“告警事件”。
3. 告警路由与分发(中枢神经)
  • 发送:Loki 将生成的告警事件通过 HTTP POST 请求发送给 Alertmanager
  • 处理Alertmanager 接收告警,根据配置进行分组、静默或抑制处理。
  • 转发:Alertmanager 匹配到 Webhook 路由,将告警 JSON 数据包转发给钉钉适配器。
4. 消息格式化与通知(嘴巴)
  • 接收prometheus-webhook-dingtalk 监听端口(如 8060),收到 Alertmanager 发来的数据。
  • 翻译:它将复杂的 Prometheus/Loki 格式 JSON 转换为钉钉机器人支持的 Markdown 或 Text 格式。
  • 触达:调用钉钉 API,最终在你的钉钉群里弹出消息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值