第五章:Promtail 配置
深入学习 Promtail 日志收集代理的配置和使用方法。
最后更新: 2024-01-19
页面目录
Promtail 配置
Promtail 是 Loki 的日志收集代理,负责发现日志文件并将其发送到 Loki。
Promtail 概述
┌─────────────────────────────────────────────────────────────────┐
│ Promtail 工作流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 配置文件 │ │ 日志发现 │ │ 日志处理 │ │
│ │ Config │ ──► │ Discovery │ ──► │ Pipeline │ │
│ └─────────────┘ └─────────────┘ └──────┬──────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ Loki │ │
│ │ Push │ │
│ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
配置文件结构
# /etc/promtail/config.yaml
---
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /var/lib/promtail/positions.yaml
client:
url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: system
static_configs:
- targets:
- localhost
labels:
job: system
host: {{ ansible_hostname }}
__path__: /var/log/*.log
完整配置示例
# /etc/promtail/config.yaml
---
# 服务器配置
server:
http_listen_address: 0.0.0.0
http_listen_port: 9080
grpc_listen_address: ""
grpc_listen_port: 0
http_server_read_timeout: 30s
http_server_write_timeout: 30s
http_server_idle_timeout: 30s
# 位置文件
positions:
filename: /var/lib/promtail/positions.yaml
ignore_invalid_yaml: false
max_line_size: 256kb
max_lines: 0
# Loki 客户端配置
client:
url: http://loki:3100/loki/api/v1/push
timeout: 10s
batchwait: 1s
batchsize: 102400
follow_redirects: true
backoff_config:
min_period: 500ms
max_period: 5m
max_retries: 20
stream_lag_labels: hostname
# 认证配置
basic_auth:
username: admin
password: admin
# TLS 配置
tls_config:
ca_file: /etc/promtail/certs/ca.crt
cert_file: /etc/promtail/certs/cert.crt
key_file: /etc/promtail/certs/key.key
server_name: loki.example.com
insecure_skip_verify: false
# Proxy 配置
proxy_url: http://proxy.example.com:8080
# 日志配置
log_level: info
log_format: logfmt
# 目标发现配置
target_config:
watch_config_changes: true
sync_period: 10s
# 采集配置
scrape_configs:
- job_name: local
static_configs:
- targets:
- localhost
labels:
job: local
env: production
__path__: /var/log/*.log
scrape_configs 配置
static_configs
# 静态文件配置
scrape_configs:
- job_name: nginx
static_configs:
- targets:
- localhost
labels:
job: nginx
service: web
environment: production
__path__: /var/log/nginx/*.log
kubernetes_sd_configs
# Kubernetes 服务发现
scrape_configs:
- job_name: kubernetes-pods
kubernetes_sd_configs:
- role: pod
api_server: https://kubernetes.default.svc:443
kubeconfig_file: /var/lib/promtail/kubeconfig
namespaces:
names:
- default
- production
selectors:
- role: pod
label: "app.*"
- role: pod
label: "app=nginx"
# Pipeline 阶段
pipeline_stages:
- docker: {}
- labels:
cluster: production
namespace: default
journal_config
# systemd Journal
scrape_configs:
- job_name: journal
journal:
max_age: 12h
labels:
job: journal
host: hostname
path: /var/log/journal
relabel_configs:
- source_labels: ['__journal__systemd_unit']
target_label: unit
- source_labels: ['__journal_priority']
target_label: priority
syslog_config
# Syslog
scrape_configs:
- job_name: syslog
syslog:
listen_address: 0.0.0.0:1514
listen_protocol: tcp
labels:
job: syslog
idle_timeout: 60s
label_structured_data: true
max_message_length: 2048
relabel_configs:
- source_labels: ['__syslog_message_hostname']
target_label: hostname
Pipeline 阶段
docker
# Docker 日志格式
pipeline_stages:
- docker: {}
cri
# CRI 日志格式
pipeline_stages:
- cri: {}
regex
# 正则解析
pipeline_stages:
- regex:
expression: '^(?P<time>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z)\s+(?P<level>\w+)\s+(?P<message>.*)$'
- labels:
level:
json
# JSON 解析
pipeline_stages:
- json:
expressions:
timestamp: ts
level: level
message: msg
user: user
service: service
- labels:
level:
service:
- timestamp:
source: timestamp
format: RFC3339Nano
- output:
source: message
logfmt
# logfmt 解析
pipeline_stages:
- logfmt: {}
- labels:
level:
service:
timestamp
# 时间戳处理
pipeline_stages:
- regex:
expression: '^(?P<time>\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})'
- timestamp:
source: time
format: '2006-01-02 15:04:05'
location: Asia/Shanghai
labels
# 标签处理
pipeline_stages:
- labels:
level: # 添加 level 标签
service: # 添加 service 标签
environment: # 添加 environment 标签
output
# 输出处理
pipeline_stages:
- json:
expressions:
message: msg
- output:
source: message
match
# 条件匹配
pipeline_stages:
- match:
selector: '{service="nginx"}'
stages:
- regex:
expression: '^(?P<ip>\d+\.\d+\.\d+\.\d+)'
- labels:
client_ip:
Relabel 配置
# Relabel 配置
scrape_configs:
- job_name: kubernetes-pods
kubernetes_sd_configs:
- role: pod
relabel_configs:
# 从标签提取信息
- source_labels: ['__meta_kubernetes_pod_label_app']
regex: '(.+)'
target_label: app
# 从元信息提取
- source_labels: ['__meta_kubernetes_namespace']
regex: '(.*)'
target_label: namespace
# 覆盖标签
- source_labels: ['__meta_kubernetes_pod_name']
regex: '(.*)'
target_label: pod
# 只保留 nginx pod
- source_labels: ['__meta_kubernetes_pod_label_app']
regex: 'nginx'
action: keep
# 移除不需要的标签
- regex: '__meta_kubernetes_pod_label_(.*)'
action: labeldrop
# 替换标签前缀
- regex: '__meta_kubernetes_(.*)'
replacement: 'kubernetes_$1'
action: labelmap
Kubernetes 部署
DaemonSet 部署
# promtail-daemonset.yaml
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: promtail
namespace: loki
spec:
selector:
matchLabels:
app: promtail
template:
metadata:
labels:
app: promtail
spec:
serviceAccountName: promtail
containers:
- name: promtail
image: grafana/promtail:2.9.0
args:
- -config.file=/etc/promtail/config.yml
- -config.expand-labels=true
volumeMounts:
- name: config
mountPath: /etc/promtail
- name: run
mountPath: /var/run/promtail
- name: containers
mountPath: /var/lib/docker/containers
readOnly: true
- name: pods
mountPath: /var/log/pods
readOnly: true
- name: syslog
mountPath: /var/log/syslog
readOnly: true
env:
- name: HOSTNAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
securityContext:
runAsUser: 0
privileged: true
volumes:
- name: config
configMap:
name: promtail
- name: run
hostPath:
path: /var/run/promtail
- name: containers
hostPath:
path: /var/lib/docker/containers
- name: pods
hostPath:
path: /var/log/pods
- name: syslog
hostPath:
path: /var/log/syslog
ConfigMap
# promtail-configmap.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: promtail
namespace: loki
data:
config.yml: |
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /var/run/promtail/positions.yaml
client:
url: http://loki:3100/loki/api/v1/push
timeout: 10s
batchwait: 1s
batchsize: 102400
scrape_configs:
- job_name: kubernetes-pods
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels:
- __meta_kubernetes_pod_label_name
regex: (.+)
target_label: service
- source_labels:
- __meta_kubernetes_namespace
target_label: namespace
- source_labels:
- __meta_kubernetes_pod_name
target_label: pod
- source_labels:
- __meta_kubernetes_pod_uid
regex: (.+)
target_label: __pod_uid__
- source_labels:
- __meta_kubernetes_pod_container_name
target_label: container
- source_labels:
- __meta_kubernetes_pod_container_name
regex: (.+)
target_label: __service_container__
- source_labels:
- __meta_kubernetes_pod_label_name
regex: ''
action: drop
- source_labels:
- __meta_kubernetes_pod_label_app
regex: (.+)
target_label: app
- source_labels:
- __meta_kubernetes_pod_label_controller
regex: (.+)
target_label: controller
Docker 日志收集
# /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3",
"labels": "production"
}
}
常用命令
# 查看日志
journalctl -u promtail -f
# 检查配置
promtail -config.file=/etc/promtail/config.yml -dry-run
# 查看帮助
promtail -help
下一步
接下来让我们学习客户端 SDK。
👉 客户端 SDK