跳转至

日志采集快速排障指南

为什么我的日志没有采集?

日志采集中,最为关键核心的问题是,日志有没有被采集到,为什么我配置的日志没有发送过去?
下面提供了核心的排查思路和手段供参考。
另外,最重要的是,在环境里配置Loggie的Prometheus监控和Grafana图表,可以快速发现问题。

日志采集核心机制

了解实现机制是排障的基础:

  1. 下发采集任务:创建日志采集任务LogConfig CR至Kubernetes
  2. 接收日志配置:节点的Agent Loggie监听到K8s相应事件,将LogConfig转换成Pipelines配置文件
  3. 采集日志文件:Loggie会自动Reload然后读取配置文件,然后根据配置发送相应的日志数据到下游服务

(针对非Kubernetes的主机场景,只是少了LogConfig CRD配置下发的步骤,其余类似)

Loggie dashboard

在Kubernetes的场景下,目前Loggie提供了一个基于terminal的可交互式dashboard,可以更好的帮助我们便捷的排查问题。

进入dashboard

  • 找到任意一个Loggie Pod

    kubectl -nloggie get po -owide
    

  • 进入其中一个Loggie Pod

    kubectl -nloggie exec -it ${podName} bash
    

  • 运行dashboard

    ./loggie inspect
    

使用terminal

terminal首页展示示例如下所示: dashboard

具体请参考使用说明视频

Tips

Loggie terminal功能仅从v1.4版本开始提供,如果从低版本升级,需增加clusterrole配置,请参考这里

手动排查步骤

排查问题关键先要确定是哪一步出现了问题。

日志采集任务排查

查看我们要排查的日志采集任务LogConfig/ClusterLogConfig的Events事件:

kubectl -n ${namespace} describe lgc ${name}

如果没有events,则可能为:

  • ❓ Pod Label未匹配:
    logConfig中labelSelector指定的label未和我们期望的Pod匹配。通过以下命令查看
    kubectl -n ${namespace} get po -owide -l ${labels}
    
    比如kubectl -n ns1 get po -owide -l app=tomcat,service=web 来判断一下是否有匹配的Pod。

如果没有类似sync success的events,可根据events同时结合Loggie日志排查问题:

  • ❓ 配置问题或者Loggie异常:
    通过下面命令查看
    kubectl -n ${loggie-namespace} logs -f ${loggie-pod-name} —-tail=${N}
    
    比如kubectl -nloggie logs -f loggie-5x6vf --tail=100。 查看对应节点的Loggie日志,根据日志情况进行处理。

常见的异常有:

  • 找不到日志路径:填写的path没有使用volume挂载,可以仔细检查一下path和volumeMount的路径,path是否包含在volumeMount内部。
  • 日志path未匹配到具体的日志文件:path需要填写glob表达式,例如/var/log/*.log。最快速的做法是,在需要采集的业务的Pod里,执行ls <path>,因为ls也是使用的glob表达式去匹配日志文件。另外也需额外注意是否配置了ignoreOlder/excludeFiles等参数,忽略或者排除了我们希望采集的日志文件。

节点日志Agent排查

1. 🔎 找到logConfig匹配的pod所在节点的日志Agent

根据在logConfig的labelSelector找到一个匹配的业务pod:

kubectl -n ${namespace} get po -owide -l ${labels}
找到任意一个所在的Node节点${node-name},然后通过:
kubectl -n ${loggie-namespace} get po -owide |grep ${node-name}
找到该节点所在的Loggie。

2. 🔎 查看对应节点的Loggie日志

检查是否有异常,如果有异常,则需根据异常日志再做分析判断

kubectl -n ${loggie-namespace} logs -f ${loggie-pod-name} —-tail=${N}

3. 🔎 查看采集情况

调用自动排障接口

针对对应的Agent,调用help接口:

curl <ip>:9196/api/v1/help

接口返回里最开头包括了一个使用提示:

--------- Usage: -----------------------
|--- view details: /api/v1/help?detail=<module>, module is one of: all/pipeline/log
|--- query by pipeline name: /api/v1/help?pipeline=<name>
|--- query by source name: /api/v1/help?source=<name>
我们可以使用curl <ip>:9196/api/v1/help?detail=all来查询所有的细节详情,也可以使用根据pipeline或者source的名称来搜索。

目前返回主要包括两部分:

  • Pipeline Status:整体的pipeline运行情况,配置以及一些一致性的检查
  • Log Collection Status:file source日志采集的详情,详细列举了每个pipeline/source下的日志文件的采集情况和进度等。

正常情况下,该接口覆盖了以下操作得到的内容,无需继续进行以下操作,下文步骤仅供参考。


查看节点Loggie渲染生成的配置

进入到容器中:

kubectl -n ${loggie-namespace} exec -it ${loggie-pod-name} bash
查看渲染生成的Pipeline配置:
ls /opt/loggie/pipeline/
当然,你也可以选择通过调用Loggie接口来查看渲染生成的Pipeline配置:
curl ${loggie-pod-ip}:9196/api/v1/reload/config

确认日志采集配置

cat /opt/loggie/pipeline/
查看现在渲染后的日志配置,这里的path为根据logconfig里填写的容器里path转换后的路径,为实际节点的path,正常可以在节点上找到。
当然,因为Loggie使用容器化部署,Loggie Pod里无法查看到节点所有的配置,需要确保Loggie也挂载了相关的路径前缀。

查看日志采集持久化状态

Loggie会记录每个日志文件的采集状态,这样即使Loggie重启后,也可以继续保持上一次的采集进度,避免重新采集日志文件。 可以通过调用接口来查看:

curl ${loggie-pod-ip}:9196/api/v1/source/file/registry?format=text | grep XXX
一般返回的类似:
  {
    "id": 85,
    "pipelineName": "default/tomcat",
    "sourceName": "tomcat-7d64c4f6c9-cm8jm/tomcat/common",
    "filename": "/var/lib/kubelet/pods/9397b8be-8927-44ba-8b94-73e5a4459377/volumes/kubernetes.io~empty-dir/log/catalina.2022-06-02.log",
    "jobUid": "3670030-65025",
    "offset": 4960,
    "collectTime": "2022-06-06 12:44:12.861",
    "version": "0.0.1"
  },
其中的filename为Loggie转换后的实际节点上的日志路径,jobUid组成为文件的inode-deviceIdoffset为sink发送成功接收到ack后的offset。
另外,我们可以通过在Loggie容器中执行:
stat ${filename}
查看文件的size/inode等信息,例如:

stat

  File: /var/lib/kubelet/pods/9397b8be-8927-44ba-8b94-73e5a4459377/volumes/kubernetes.io~empty-dir/log/catalina.2022-06-02.log
  Size: 4960        Blocks: 16         IO Block: 4096   regular file
Device: fe01h/65025d    Inode: 3670030     Links: 1
Access: (0640/-rw-r-----)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2022-06-06 12:44:12.859236003 +0000
Modify: 2022-06-02 08:54:33.177240007 +0000
Change: 2022-06-02 08:54:33.177240007 +0000

可通过比较size和offset来判断采集进度。如果size=offset,则说明已经文件已经全部采集并发送成功。