我目前正在尝试使用promtail、loki和grafana为docker集群设置日志监控。日志从promtail到loki的转发以及在graphana中的可视化都很好。
然而,在我当前的promtail配置中,所有容器日志都被不隔离地发送到loki。因此,我的问题是,如果有人知道promtail配置,它会发送由他们所属的docker swarm服务聚合的容器日志?
当前的promtail config.yml如下所示:
- job_name: system
static_configs:
- targets:
- localhost
labels:
job: varlogs_prom
__path__: /var/log/*log
- job_name: containers
static_configs:
- targets:
- localhost
labels:
job: containerlogs_prom
__path__: /var/lib/docker/containers/*/*log
pipeline_stages:
- json:
expressions:
output: log
stream: stream
attrs:
- json:
expressions:
tag:
source: attrs
- regex:
expression: (?P<image_name>(?:[^|]*[^|])).(?P<container_name>(?:[^|]*[^|])
).(?P<image_id>(?:[^|]*[^|])).(?P<container_id>(?:[^|]*[^|]))
source: tag
- timestamp:
format: RFC3339Nano
source: time
- labels:
tag_prom:
stream_prom:
image_name_prom:
container_name_prom:
image_id_prom:
container_id_prom:
- output:
source: output
提前感谢!!
我发现你可以使用Docker驱动程序而不是Promtail。您可以使用以下工具轻松安装:
$ docker plugin install grafana/loki-docker-driver:latest --alias loki --grant-all-permissions
并使用验证安装
docker plugin ls
然后,您可以为所有具有默认日志配置的容器配置使用loki日志驱动程序:
{
"debug" : true,
"log-driver": "loki",
"log-opts": {
"loki-url": "https://<user_id>:<password>@logs-us-west1.grafana.net/loki/api/v1/push",
"loki-batch-size": "400"
}
}
根据文档,我不确定在这种情况下日志是否也保存在localhost上,但如果您只是将日志驱动程序手动设置到docker-compose.yml文件中,它将被发送到Loki中,也保存在本地主机上。来自文件:
version: "3.7"
services:
logger:
image: grafana/grafana
logging:
driver: loki
options:
loki-url: "https://<user_id>:<password>@logs-prod-us-central1.grafana.net/loki/api/v1/push"
此配置还保留堆栈和服务名称:
每个群服务的堆栈名称和服务名称以及每个组合服务的项目名称和服务名都会自动发现并作为Loki标签发送,这样您就可以在Grafana中根据它们进行过滤。
我希望这能有所帮助。
第1版:我在GrafanaLabs网站上发现了类似的问题:将容器名称添加到promtail docker日志
第2版:来自已知问题:
驱动程序将所有日志保存在内存中,如果无法访问Loki并且超过了最大重试次数,则会删除日志条目。为了避免日志条目丢失,将max_retrys设置为零允许无限制的重试;驱动器将永远尝试,直到洛基再次可用。永远尝试可能会产生不希望的后果,因为Docker守护进程将等待Loki驱动程序处理容器的所有日志,直到容器被删除。因此,如果容器被卡住,Docker守护进程可能会永远等待。
结果是,如果docker loki驱动程序无法连接到loki,它将被阻塞为不将任何日志打印到docker容器的stdout。它也将无法停止容器,因此可能会导致应用程序部署出现问题。正如doc中提到的,建议使用docker target,甚至更好的docker服务discover。它可以从docker中获取元数据,如容器名称、id、网络、标签等。要使用它,必须使用replabel-config,例如来自doc:
scrape_configs:
- job_name: flog_scrape
docker_sd_configs:
- host: unix:///var/run/docker.sock
refresh_interval: 5s
filters:
- name: name
values: [flog]
relabel_configs:
- source_labels: ['__meta_docker_container_name']
regex: '/(.*)'
target_label: 'container'
注意这个配置,标签container
,即使是一个应用程序,也可能包含很多uniq值,因为docker哈希名称类似于:
- nginx.nginx.1.0zwo879s92fk38o07a65uzolc-复制部署
- minio_minio.wy6c6pk1arod6vbqeem8iyosj.t9mdy2gnv2upqwmrh0fo2c9p-全球部署
根据Grafana Loki标签的最佳实践,不建议这样做。我用regexp relabel config修复了这个问题,该配置过滤容器的名称,在上面的示例中为nginx_nginx
或minio_minio
,以及副本编号(如果存在(:
relabel_configs:
- source_labels: ['__meta_docker_container_name']
regex: '/(.*).[0-9]..*'
target_label: 'name'
- source_labels: ['__meta_docker_container_name']
regex: '/(.*).[0-9a-z]*..*'
target_label: 'name'
- source_labels: ['__meta_docker_container_name']
regex: '/.*.([0-9]{1,2})..*'
target_label: 'replica'