标准化日志采集配置指南适用于基于 Promtail Loki 的日志收集架构。 --- ## 目录 - [架构概览](#架构概览) - [配置结构说明](#配置结构说明) - [标签规范](#标签规范) - [Pipeline Stages 详解](#pipeline-stages-详解) - [标准配置模板通用版](#标准配置模板通用版) - [现有配置分析与优化](#现有配置分析与优化) - [运维操作手册](#运维操作手册) - [常见问题排查](#常见问题排查) --- ## 架构概览 Application Logs (file) └─ Promtail (tail label pipeline) └─ Loki Gateway (push API) └─ Loki (存储 索引) └─ Grafana (查询 告警) **核心流程** 1. 应用将日志写入本地文件按约定目录结构 2. Promtail 以 tail 方式持续读取日志文件 3. Pipeline stages 对日志行进行解析、打标签、多行合并 4. 带标签的日志推送至 Loki Gateway --- ## 配置结构说明 Promtail 配置分为四大块 yaml server: # HTTP/gRPC 监听端口 positions: # 读取位置记录断点续传 clients: # Loki 推送目标 scrape_configs: # 日志采集任务定义 ### server yaml server: http_listen_port: 3100 # Promtail 自身 metrics/health 端口 grpc_listen_port: 0 # 0 禁用 gRPC ### positions yaml positions: filename: /var/lib/promtail/positions.yaml # 记录每个文件的读取偏移量 sync_period: 10s # 刷盘周期 **重要** positions 保证 Promtail 重启后从上次位置继续读取不丢失也不重复。生产环境必须配置。 ### clients yaml clients: - url: http://loki-gateway.example.com/loki/api/v1/push external_labels: env: prod # 全局标签标识环境 region: ap-northeast-1 # 全局标签标识区域 batchwait: 1s # 批量发送等待时间 batchsize: 1048576 # 批量大小1MB timeout: 10s # 推送超时 ### scrape_configs 每个 job_name 定义一组采集任务包含 - static_configs目标文件路径和静态标签 - pipeline_stages日志处理管道 --- ## 标签规范 ### 原则 | 原则 | 说明 | |------|------| | 低基数 | 标签值种类应有限 100避免高基数导致 Loki 索引膨胀 | | 稳定性 | 标签值不应频繁变化IP、时间戳等**不可**作为标签 | | 可查询 | 标签应服务于常见查询场景按环境、应用、日志级别过滤 | ### 标准标签集 | 标签 | 来源 | 示例 | 说明 | |------|------|------|------| | env | external_labels | prod, uat, sit | 部署环境 | | region | external_labels | ap-northeast-1 | 区域 | | app | pipeline 动态提取 | trading-gateway | 应用名称 | | severity | pipeline 动态提取 | info, warn, error | 日志级别 | | job | job_name 自动生成 | java-app-logs | 采集任务名 | ### 反模式 yaml # BAD - 高基数标签会导致 Loki 性能严重下降 labels: pod_ip: 10.0.1.23 request_id: abc-123 user_id: 12345 timestamp: 2026-04-10T12:00:00Z # GOOD - 低基数、稳定、可查询 labels: app: trading-gateway severity: error --- ## Pipeline Stages 详解 Pipeline stages 按顺序处理每一行日志常用 stage 如下 ### multiline — 多行合并 Java 堆栈跟踪等跨行日志必须合并为单条 yaml pipeline_stages: - multiline: firstline: ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3} # 新日志行的起始模式 max_wait_time: 3s # 等待下一行的最大时间 max_lines: 128 # 单条日志最大行数 | 参数 | 推荐值 | 说明 | |------|--------|------| | firstline | 按日志框架调整 | 匹配新日志条目的首行 | | max_wait_time | 3s | 太短会截断堆栈太长会增加延迟 | | max_lines | 128 | 防止异常情况下无限合并 | ### regex — 正则提取 从文件名或日志内容中提取标签值 yaml # 从文件名提取 app 和 severity - regex: expression: ^/data/logs/(?Papp[^/])/.\.log$ source: filename - regex: expression: .*(?Pseverityerror|info|warn|debug|fatal)\.log$ source: filename ### labels — 设置标签 将提取的值设为 Loki 标签 yaml - labels: app: # 使用 regex 阶段提取的 app 值 severity: # 使用 regex 阶段提取的 severity 值 ### template — 值转换 对提取的值进行格式化 yaml - template: source: app template: myprefix-{{ .Value }} # 添加前缀 ### drop — 丢弃日志 过滤掉不需要的日志如健康检查 yaml - drop: expression: .*healthcheck.* drop_counter_reason: healthcheck ### limit_stage — 速率限制 防止日志洪泛打爆 Loki yaml - limit: rate: 100 # 每秒最大行数 burst: 200 # 突发容量 drop: true # 超限丢弃false 背压 --- ## 标准配置模板通用版 以下为优化后的通用模板采用**统一目录规范 动态标签提取**新增应用无需修改 Promtail 配置。 ### 日志目录规范前提 /data/logs/{app-name}/{app-name}-{severity}.log 示例 /data/logs/trading-gateway/trading-gateway-info.log /data/logs/trading-gateway/trading-gateway-error.log /data/logs/trading-gateway/trading-gateway-warn.log /data/logs/order-service/order-service-info.log /data/logs/order-service/order-service-error.log 只要应用按此目录结构输出日志Promtail 自动识别**零配置接入**。 ### 完整配置 yaml # # Promtail 标准配置模板 # 适用Java / Go / Python 应用日志采集 # 要求日志输出至 /data/logs/{app-name}/ 目录 # server: http_listen_port: 3100 grpc_listen_port: 0 log_level: warn # promtail 自身日志级别 positions: filename: /var/lib/promtail/positions.yaml sync_period: 10s # ----------------------------------------------------------------------------- # Loki 推送目标 # ----------------------------------------------------------------------------- clients: - url: http://loki-gateway.example.com/loki/api/v1/push external_labels: env: prod # 按环境修改prod / uat / sit / dev region: ap-northeast-1 # 按区域修改 batchwait: 1s batchsize: 1048576 # 1MB timeout: 10s # ----------------------------------------------------------------------------- # 采集任务 # ----------------------------------------------------------------------------- scrape_configs: # # Job 1: 标准应用日志通用自动发现 # 目录结构: /data/logs/{app-name}/*{severity}.log # - job_name: app-logs static_configs: - targets: [localhost] labels: __path__: /data/logs/*/*info.log - targets: [localhost] labels: __path__: /data/logs/*/*warn.log - targets: [localhost] labels: __path__: /data/logs/*/*error.log - targets: [localhost] labels: __path__: /data/logs/*/*debug.log - targets: [localhost] labels: __path__: /data/logs/*/*fatal.log pipeline_stages: # Step 1: 多行合并Java 堆栈跟踪 - multiline: firstline: ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2} max_wait_time: 3s max_lines: 128 # Step 2: 从文件路径提取 app 名称 - regex: expression: ^/data/logs/(?Papp[^/])/.\.log$ source: filename # Step 3: 从文件名提取日志级别 - regex: expression: .*(?Pseverityerror|info|warn|debug|fatal)\.log$ source: filename # Step 4: 设置标签 - labels: app: severity: # Step 5: 丢弃健康检查等噪音日志按需启用 # - drop: # expression: .*(healthcheck|readiness|liveness).* # drop_counter_reason: health_probe # Step 6: 速率限制按需启用 # - limit: # rate: 500 # burst: 1000 # drop: true # # Job 2: 遗留应用日志兼容旧目录结构 # 目录结构: /data/api/{app-name}-{severity}.log # - job_name: legacy-app-logs static_configs: - targets: [localhost] labels: __path__: /data/api/*info.log - targets: [localhost] labels: __path__: /data/api/*warn.log - targets: [localhost] labels: __path__: /data/api/*error.log - targets: [localhost] labels: __path__: /data/api/*debug.log pipeline_stages: - multiline: firstline: ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2} max_wait_time: 3s max_lines: 128 - regex: expression: ^/data/api/(?Papp.)-(?Pseverityerror|info|warn|debug)\.log$ source: filename # 添加统一前缀可选与新目录区分 # - template: # source: app # template: legacy-{{ .Value }} - labels: app: severity: # # Job 3: 专用应用日志特殊日志文件名不符合通用规则时使用 # - job_name: special-app-logs static_configs: - targets: [localhost] labels: __path__: /data/api/**/logs/rapidtrade_server.log app: rapidtrade-server severity: all - targets: [localhost] labels: __path__: /data/api/**/logs/exchange.log app: rapidtrade-server severity: all pipeline_stages: - multiline: firstline: ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2} max_wait_time: 3s max_lines: 128 --- ## 现有配置分析与优化 ### 原始配置问题 | 问题 | 影响 | 优化方案 | |------|------|----------| | 缺少 positions 配置 | Promtail 重启后重头读取日志重复推送 | 添加 positions 段 | | 多个 job 重复定义相同 pipeline | 维护成本高修改需改多处 | 合并为通用 job 动态标签提取 | | max_wait_time 不一致1s / 4s | 行为不可预测 | 统一为 3s | | 缺少 max_lines 限制 | 异常堆栈可能无限合并 | 添加 max_lines: 128 | | firstline 正则不兼容 ISO 8601 | 2026-04-10T12:00:00 格式无法匹配 | 改为 ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2} | | 无速率限制 | 日志洪泛可能打爆 Loki | 按需添加 limit stage | | 无噪音过滤 | 健康检查日志浪费存储 | 添加 drop stage | | rapidx-log 与 rapidx-log-new 功能重叠 | 同一日志可能被采集两次 | 按目录结构拆分为两个不重叠的 job | ### 优化前后对比 优化前6 个 job大量重复 ├── rapidtrade-server-log # 硬编码 app 标签 ├── rapidtrade-quote-log # 硬编码 app 标签 ├── rapidtrade-order-log # 硬编码 app 标签 ├── rapidx-log-new # /data/logs/ 动态提取好 ├── rapidx-log # /data/api/ 动态提取好 └── 缺 positions 优化后3 个 job通用 兼容 特殊 ├── app-logs # /data/logs/ 通用动态提取 app severity ├── legacy-app-logs # /data/api/ 兼容旧结构 ├── special-app-logs # 特殊命名文件手动指定标签 └── positions ✓ --- ## 运维操作手册 ### 部署 Promtail bash # 1. 安装以 systemd 为例 sudo useradd --system --no-create-home promtail sudo mkdir -p /var/lib/promtail /etc/promtail # 2. 放置配置文件 sudo cp promtail-config.yaml /etc/promtail/config.yaml # 3. 创建 systemd service cat EOF | sudo tee /etc/systemd/system/promtail.service [Unit] DescriptionPromtail Log Collector Afternetwork.target [Service] Typesimple Userpromtail ExecStart/usr/local/bin/promtail -config.file/etc/promtail/config.yaml Restarton-failure RestartSec5s LimitNOFILE65536 [Install] WantedBymulti-user.target EOF # 4. 启动 sudo systemctl daemon-reload sudo systemctl enable --now promtail # 5. 验证 curl -s http://localhost:3100/ready # 就绪检查 curl -s http://localhost:3100/metrics # Prometheus 指标 ### 新应用接入 **场景 A符合目录规范零配置** bash # 应用只需将日志输出到指定目录无需修改 Promtail mkdir -p /data/logs/my-new-app/ # 应用配置日志输出 # /data/logs/my-new-app/my-new-app-info.log # /data/logs/my-new-app/my-new-app-error.log # Promtail 自动发现并采集appmy-new-app, severityinfo/error **场景 B特殊日志路径** yaml # 在 special-app-logs job 的 static_configs 中追加 - targets: [localhost] labels: __path__: /opt/custom-app/output/*.log app: custom-app severity: all ### 配置变更流程 bash # 1. 编辑配置 vim /etc/promtail/config.yaml # 2. 语法检查dry-run promtail -config.file/etc/promtail/config.yaml -dry-run # 3. 重载配置无需重启 curl -X POST http://localhost:3100/reload # 或 sudo systemctl reload promtail # 4. 验证采集状态 curl -s http://localhost:3100/targets | python3 -m json.tool ### 关键监控指标 promql # Promtail 推送到 Loki 的速率 rate(promtail_sent_entries_total[5m]) # 推送失败率 rate(promtail_dropped_entries_total[5m]) # 文件读取延迟tail 落后字节数 promtail_file_bytes_total - promtail_read_bytes_total # 目标文件数量 promtail_targets_active_total --- ## 常见问题排查 ### 日志未被采集 bash # 1. 检查文件权限 ls -la /data/logs/my-app/ # promtail 用户需有读权限 # 2. 检查 target 状态 curl -s http://localhost:3100/targets | grep my-app # 3. 检查 glob 是否匹配 # __path__ 支持 * 和 **但不支持 {} # * 匹配单层目录** 匹配多层目录 # 4. 检查 positions 文件 cat /var/lib/promtail/positions.yaml | grep my-app ### 日志重复 bash # 原因多个 job 的 __path__ 匹配了同一个文件 # 排查检查各 job 的 __path__ 是否存在重叠 # 修复确保每个文件只被一个 job 匹配 # 验证当前 target 分配 curl -s http://localhost:3100/targets | python3 -c import sys, json data json.load(sys.stdin) paths {} for target in data: path target.get(labels, {}).get(__path__, ) job target.get(labels, {}).get(job, ) paths.setdefault(path, []).append(job) for path, jobs in paths.items(): if len(jobs) 1: print(fDUPLICATE: {path} - {jobs}) ### Java 堆栈被拆成多条 yaml # 原因multiline firstline 正则不匹配或 max_wait_time 太短 # 排查 # 1. 确认日志首行格式 head -5 /data/logs/my-app/my-app-error.log # 2. 测试正则是否匹配 echo 2026-04-10 12:00:00.123 ERROR ... | grep -P ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2} # 3. 如使用 logback/log4j2常见 firstline 模式 # ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2} # 通用 # ^\[\d{4}-\d{2}-\d{2} # 带方括号 # ^\d{2}:\d{2}:\d{2}\.\d{3} # 仅时间 ### Promtail 内存占用过高 bash # 原因采集文件过多或日志量过大 # 排查 curl -s http://localhost:3100/metrics | grep promtail_targets_active # 优化 # 1. 收窄 __path__ glob 范围 # 2. 启用 limit stage 限速 # 3. 启用 drop stage 过滤噪音 # 4. 减少 batchsize
Promtail 日志采集配置规范与实践
标准化日志采集配置指南适用于基于 Promtail Loki 的日志收集架构。 --- ## 目录 - [架构概览](#架构概览) - [配置结构说明](#配置结构说明) - [标签规范](#标签规范) - [Pipeline Stages 详解](#pipeline-stages-详解) - [标准配置模板通用版](#标准配置模板通用版) - [现有配置分析与优化](#现有配置分析与优化) - [运维操作手册](#运维操作手册) - [常见问题排查](#常见问题排查) --- ## 架构概览 Application Logs (file) └─ Promtail (tail label pipeline) └─ Loki Gateway (push API) └─ Loki (存储 索引) └─ Grafana (查询 告警) **核心流程** 1. 应用将日志写入本地文件按约定目录结构 2. Promtail 以 tail 方式持续读取日志文件 3. Pipeline stages 对日志行进行解析、打标签、多行合并 4. 带标签的日志推送至 Loki Gateway --- ## 配置结构说明 Promtail 配置分为四大块 yaml server: # HTTP/gRPC 监听端口 positions: # 读取位置记录断点续传 clients: # Loki 推送目标 scrape_configs: # 日志采集任务定义 ### server yaml server: http_listen_port: 3100 # Promtail 自身 metrics/health 端口 grpc_listen_port: 0 # 0 禁用 gRPC ### positions yaml positions: filename: /var/lib/promtail/positions.yaml # 记录每个文件的读取偏移量 sync_period: 10s # 刷盘周期 **重要** positions 保证 Promtail 重启后从上次位置继续读取不丢失也不重复。生产环境必须配置。 ### clients yaml clients: - url: http://loki-gateway.example.com/loki/api/v1/push external_labels: env: prod # 全局标签标识环境 region: ap-northeast-1 # 全局标签标识区域 batchwait: 1s # 批量发送等待时间 batchsize: 1048576 # 批量大小1MB timeout: 10s # 推送超时 ### scrape_configs 每个 job_name 定义一组采集任务包含 - static_configs目标文件路径和静态标签 - pipeline_stages日志处理管道 --- ## 标签规范 ### 原则 | 原则 | 说明 | |------|------| | 低基数 | 标签值种类应有限 100避免高基数导致 Loki 索引膨胀 | | 稳定性 | 标签值不应频繁变化IP、时间戳等**不可**作为标签 | | 可查询 | 标签应服务于常见查询场景按环境、应用、日志级别过滤 | ### 标准标签集 | 标签 | 来源 | 示例 | 说明 | |------|------|------|------| | env | external_labels | prod, uat, sit | 部署环境 | | region | external_labels | ap-northeast-1 | 区域 | | app | pipeline 动态提取 | trading-gateway | 应用名称 | | severity | pipeline 动态提取 | info, warn, error | 日志级别 | | job | job_name 自动生成 | java-app-logs | 采集任务名 | ### 反模式 yaml # BAD - 高基数标签会导致 Loki 性能严重下降 labels: pod_ip: 10.0.1.23 request_id: abc-123 user_id: 12345 timestamp: 2026-04-10T12:00:00Z # GOOD - 低基数、稳定、可查询 labels: app: trading-gateway severity: error --- ## Pipeline Stages 详解 Pipeline stages 按顺序处理每一行日志常用 stage 如下 ### multiline — 多行合并 Java 堆栈跟踪等跨行日志必须合并为单条 yaml pipeline_stages: - multiline: firstline: ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3} # 新日志行的起始模式 max_wait_time: 3s # 等待下一行的最大时间 max_lines: 128 # 单条日志最大行数 | 参数 | 推荐值 | 说明 | |------|--------|------| | firstline | 按日志框架调整 | 匹配新日志条目的首行 | | max_wait_time | 3s | 太短会截断堆栈太长会增加延迟 | | max_lines | 128 | 防止异常情况下无限合并 | ### regex — 正则提取 从文件名或日志内容中提取标签值 yaml # 从文件名提取 app 和 severity - regex: expression: ^/data/logs/(?Papp[^/])/.\.log$ source: filename - regex: expression: .*(?Pseverityerror|info|warn|debug|fatal)\.log$ source: filename ### labels — 设置标签 将提取的值设为 Loki 标签 yaml - labels: app: # 使用 regex 阶段提取的 app 值 severity: # 使用 regex 阶段提取的 severity 值 ### template — 值转换 对提取的值进行格式化 yaml - template: source: app template: myprefix-{{ .Value }} # 添加前缀 ### drop — 丢弃日志 过滤掉不需要的日志如健康检查 yaml - drop: expression: .*healthcheck.* drop_counter_reason: healthcheck ### limit_stage — 速率限制 防止日志洪泛打爆 Loki yaml - limit: rate: 100 # 每秒最大行数 burst: 200 # 突发容量 drop: true # 超限丢弃false 背压 --- ## 标准配置模板通用版 以下为优化后的通用模板采用**统一目录规范 动态标签提取**新增应用无需修改 Promtail 配置。 ### 日志目录规范前提 /data/logs/{app-name}/{app-name}-{severity}.log 示例 /data/logs/trading-gateway/trading-gateway-info.log /data/logs/trading-gateway/trading-gateway-error.log /data/logs/trading-gateway/trading-gateway-warn.log /data/logs/order-service/order-service-info.log /data/logs/order-service/order-service-error.log 只要应用按此目录结构输出日志Promtail 自动识别**零配置接入**。 ### 完整配置 yaml # # Promtail 标准配置模板 # 适用Java / Go / Python 应用日志采集 # 要求日志输出至 /data/logs/{app-name}/ 目录 # server: http_listen_port: 3100 grpc_listen_port: 0 log_level: warn # promtail 自身日志级别 positions: filename: /var/lib/promtail/positions.yaml sync_period: 10s # ----------------------------------------------------------------------------- # Loki 推送目标 # ----------------------------------------------------------------------------- clients: - url: http://loki-gateway.example.com/loki/api/v1/push external_labels: env: prod # 按环境修改prod / uat / sit / dev region: ap-northeast-1 # 按区域修改 batchwait: 1s batchsize: 1048576 # 1MB timeout: 10s # ----------------------------------------------------------------------------- # 采集任务 # ----------------------------------------------------------------------------- scrape_configs: # # Job 1: 标准应用日志通用自动发现 # 目录结构: /data/logs/{app-name}/*{severity}.log # - job_name: app-logs static_configs: - targets: [localhost] labels: __path__: /data/logs/*/*info.log - targets: [localhost] labels: __path__: /data/logs/*/*warn.log - targets: [localhost] labels: __path__: /data/logs/*/*error.log - targets: [localhost] labels: __path__: /data/logs/*/*debug.log - targets: [localhost] labels: __path__: /data/logs/*/*fatal.log pipeline_stages: # Step 1: 多行合并Java 堆栈跟踪 - multiline: firstline: ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2} max_wait_time: 3s max_lines: 128 # Step 2: 从文件路径提取 app 名称 - regex: expression: ^/data/logs/(?Papp[^/])/.\.log$ source: filename # Step 3: 从文件名提取日志级别 - regex: expression: .*(?Pseverityerror|info|warn|debug|fatal)\.log$ source: filename # Step 4: 设置标签 - labels: app: severity: # Step 5: 丢弃健康检查等噪音日志按需启用 # - drop: # expression: .*(healthcheck|readiness|liveness).* # drop_counter_reason: health_probe # Step 6: 速率限制按需启用 # - limit: # rate: 500 # burst: 1000 # drop: true # # Job 2: 遗留应用日志兼容旧目录结构 # 目录结构: /data/api/{app-name}-{severity}.log # - job_name: legacy-app-logs static_configs: - targets: [localhost] labels: __path__: /data/api/*info.log - targets: [localhost] labels: __path__: /data/api/*warn.log - targets: [localhost] labels: __path__: /data/api/*error.log - targets: [localhost] labels: __path__: /data/api/*debug.log pipeline_stages: - multiline: firstline: ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2} max_wait_time: 3s max_lines: 128 - regex: expression: ^/data/api/(?Papp.)-(?Pseverityerror|info|warn|debug)\.log$ source: filename # 添加统一前缀可选与新目录区分 # - template: # source: app # template: legacy-{{ .Value }} - labels: app: severity: # # Job 3: 专用应用日志特殊日志文件名不符合通用规则时使用 # - job_name: special-app-logs static_configs: - targets: [localhost] labels: __path__: /data/api/**/logs/rapidtrade_server.log app: rapidtrade-server severity: all - targets: [localhost] labels: __path__: /data/api/**/logs/exchange.log app: rapidtrade-server severity: all pipeline_stages: - multiline: firstline: ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2} max_wait_time: 3s max_lines: 128 --- ## 现有配置分析与优化 ### 原始配置问题 | 问题 | 影响 | 优化方案 | |------|------|----------| | 缺少 positions 配置 | Promtail 重启后重头读取日志重复推送 | 添加 positions 段 | | 多个 job 重复定义相同 pipeline | 维护成本高修改需改多处 | 合并为通用 job 动态标签提取 | | max_wait_time 不一致1s / 4s | 行为不可预测 | 统一为 3s | | 缺少 max_lines 限制 | 异常堆栈可能无限合并 | 添加 max_lines: 128 | | firstline 正则不兼容 ISO 8601 | 2026-04-10T12:00:00 格式无法匹配 | 改为 ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2} | | 无速率限制 | 日志洪泛可能打爆 Loki | 按需添加 limit stage | | 无噪音过滤 | 健康检查日志浪费存储 | 添加 drop stage | | rapidx-log 与 rapidx-log-new 功能重叠 | 同一日志可能被采集两次 | 按目录结构拆分为两个不重叠的 job | ### 优化前后对比 优化前6 个 job大量重复 ├── rapidtrade-server-log # 硬编码 app 标签 ├── rapidtrade-quote-log # 硬编码 app 标签 ├── rapidtrade-order-log # 硬编码 app 标签 ├── rapidx-log-new # /data/logs/ 动态提取好 ├── rapidx-log # /data/api/ 动态提取好 └── 缺 positions 优化后3 个 job通用 兼容 特殊 ├── app-logs # /data/logs/ 通用动态提取 app severity ├── legacy-app-logs # /data/api/ 兼容旧结构 ├── special-app-logs # 特殊命名文件手动指定标签 └── positions ✓ --- ## 运维操作手册 ### 部署 Promtail bash # 1. 安装以 systemd 为例 sudo useradd --system --no-create-home promtail sudo mkdir -p /var/lib/promtail /etc/promtail # 2. 放置配置文件 sudo cp promtail-config.yaml /etc/promtail/config.yaml # 3. 创建 systemd service cat EOF | sudo tee /etc/systemd/system/promtail.service [Unit] DescriptionPromtail Log Collector Afternetwork.target [Service] Typesimple Userpromtail ExecStart/usr/local/bin/promtail -config.file/etc/promtail/config.yaml Restarton-failure RestartSec5s LimitNOFILE65536 [Install] WantedBymulti-user.target EOF # 4. 启动 sudo systemctl daemon-reload sudo systemctl enable --now promtail # 5. 验证 curl -s http://localhost:3100/ready # 就绪检查 curl -s http://localhost:3100/metrics # Prometheus 指标 ### 新应用接入 **场景 A符合目录规范零配置** bash # 应用只需将日志输出到指定目录无需修改 Promtail mkdir -p /data/logs/my-new-app/ # 应用配置日志输出 # /data/logs/my-new-app/my-new-app-info.log # /data/logs/my-new-app/my-new-app-error.log # Promtail 自动发现并采集appmy-new-app, severityinfo/error **场景 B特殊日志路径** yaml # 在 special-app-logs job 的 static_configs 中追加 - targets: [localhost] labels: __path__: /opt/custom-app/output/*.log app: custom-app severity: all ### 配置变更流程 bash # 1. 编辑配置 vim /etc/promtail/config.yaml # 2. 语法检查dry-run promtail -config.file/etc/promtail/config.yaml -dry-run # 3. 重载配置无需重启 curl -X POST http://localhost:3100/reload # 或 sudo systemctl reload promtail # 4. 验证采集状态 curl -s http://localhost:3100/targets | python3 -m json.tool ### 关键监控指标 promql # Promtail 推送到 Loki 的速率 rate(promtail_sent_entries_total[5m]) # 推送失败率 rate(promtail_dropped_entries_total[5m]) # 文件读取延迟tail 落后字节数 promtail_file_bytes_total - promtail_read_bytes_total # 目标文件数量 promtail_targets_active_total --- ## 常见问题排查 ### 日志未被采集 bash # 1. 检查文件权限 ls -la /data/logs/my-app/ # promtail 用户需有读权限 # 2. 检查 target 状态 curl -s http://localhost:3100/targets | grep my-app # 3. 检查 glob 是否匹配 # __path__ 支持 * 和 **但不支持 {} # * 匹配单层目录** 匹配多层目录 # 4. 检查 positions 文件 cat /var/lib/promtail/positions.yaml | grep my-app ### 日志重复 bash # 原因多个 job 的 __path__ 匹配了同一个文件 # 排查检查各 job 的 __path__ 是否存在重叠 # 修复确保每个文件只被一个 job 匹配 # 验证当前 target 分配 curl -s http://localhost:3100/targets | python3 -c import sys, json data json.load(sys.stdin) paths {} for target in data: path target.get(labels, {}).get(__path__, ) job target.get(labels, {}).get(job, ) paths.setdefault(path, []).append(job) for path, jobs in paths.items(): if len(jobs) 1: print(fDUPLICATE: {path} - {jobs}) ### Java 堆栈被拆成多条 yaml # 原因multiline firstline 正则不匹配或 max_wait_time 太短 # 排查 # 1. 确认日志首行格式 head -5 /data/logs/my-app/my-app-error.log # 2. 测试正则是否匹配 echo 2026-04-10 12:00:00.123 ERROR ... | grep -P ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2} # 3. 如使用 logback/log4j2常见 firstline 模式 # ^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2} # 通用 # ^\[\d{4}-\d{2}-\d{2} # 带方括号 # ^\d{2}:\d{2}:\d{2}\.\d{3} # 仅时间 ### Promtail 内存占用过高 bash # 原因采集文件过多或日志量过大 # 排查 curl -s http://localhost:3100/metrics | grep promtail_targets_active # 优化 # 1. 收窄 __path__ glob 范围 # 2. 启用 limit stage 限速 # 3. 启用 drop stage 过滤噪音 # 4. 减少 batchsize