期望的日志未能搜索到

日志易技术支持发表于:2019年04月02日 11:59:50更新于:2023年06月21日 10:20:22

背景

使用日志易过程中,不少用户会遇到“通过Agent管理界面添加了相应数据源,但是前台搜不到该新增的日志”的情况,本文档将介绍这种情况的一些常见排障手段,帮助用户快速定位原因。

数据流介绍

在开始排障前,用户需要了解日志易的数据流

     

如图所示,

1.  日志从日志源经采集Agent采集后上报至Collector

2.  Collector进行准入判断后,将日志发送给Kafka

3.  LogRiver读取Kakfa中的日志,进行解析处理后发送给es

可见,日志从采集到最终入库ES流经多个模块,因此查不到新添加的日志源,不能简单归因于Agent采集不正常,而需要通过一系列手段定位问题出在哪个模块。

排障方法

目前此类问题排障的典型思路,先查kafka,es有没有数据。kafka没有数据,需要查collector,agent。kafka有数据,es没数据,需要查logriver。es有数据,搜不到,需要查spl。因此下面会逐一对各模块“正常”的判断方法进行介绍。

采集Agent

目前的采集Agent分为Heka和RizhiyiAgent两种,其中RizhiyiAgent主要用于AIX/HP UX等小众OS下的日志文件采集。

Heka

Heka本身又分为Server (安装在日志易服务所在机器上) 和Agent(安装于用户服务器上)两种

背景介绍

·       Server Heka日志文件所在目录(后用${HEKA_LOG_DIR}表示):/data/rizhiyi/logs/heka/

·       Server Heka缓存文件所在目录(后用${HEKA_CACHE_DIR}表示): /data/rizhiyi/cache/hekad/

·       Agent Heka日志文件所在目录: Heka安装目录/logs/

·       Agent Heka缓存文件所在目录: Heka安装目录/cache/hekad/

·       ${HEKA_CACHE_DIR}子目录包括

o   logstreamer

§  记录文件和目录型数据源的采集情况,文件通常以文件路径名为后缀

§  文件内容中seek字段为采集到的位置(单位:字节)

§  该文件是定期更新(每100行更新一次),非实时

o   db

§  记录数据库类型数据源的采集情况(必须配置了增量采集字段才会有文件)

§  文件内容中last_scan_value, 表示最近一轮采集的增量字段的最大值

§  该文件在每轮采集结束时更新一次,非实时

o   winlog

§  记录eventlog类型数据源的采集情况

§  文件内容为上次采集的该Channel的eventlog的最大的record_id

§  该文件每轮采集完更新一次(每轮采集之间间隔5秒)

o   output_queue/RzyHttpOutput

§  记录等待发送的数据(pb格式),以及发送情况

§  x.log为等待发送的数据

§  checkpoint.txt 中记录两个数字:

§  第一个数字表示发送到了哪一个.log

§  第二个数字表示发送到了这个.log的什么位置(单位:字节)

1.确认hekad进程是否正常

1.1.通过Agent管理界面确认对应Heka的启动状态是“已启动", 如果是,则表示进程正常,继续  后续步骤的确认,如果是"已停止", 则排查1.2

1.2.登陆Heka所在服务器,使用ps命令确认hekad-daemon进程是否存在,如果hekad-daemon存在,则查看${HEKA_LOG_DIR}/hekad-daemon.log,确认hekad停止原因,如果hekad-daemon不存在,则排查1.3

1.3.Server Heka通过Manger界面启动Heka,然后在Manager页面看对应heka实例的Stderr和Stdout,里面记录启动失败的原因; Agent Heka则进入Heka安装目录/bin/ 下, 使用./heka_ctl start 命令启动,查看启动失败原因

2.确认日志是否正常

2.1.查看${HEKA_LOG_DIR}/hekad.stderr 的日志,如果存在持续打印的类似如下日志

2018/01/13 05:15:07 Plugin 'RzyHttpOutput' error: can't send record: Error making HTTP request: Post http://192.168.1.54:5180/proto/?compressed=false: read tcp 192.168.1.54:55077->192.168.1.54:5180: read: connection reset by peer


则需要查看Collector日志进行后续模块的排查,这种情况表示Heka到Collector发送异常。但是,如果只是偶尔出现这种日志,或是没有该错误日志,则表示发送正常。进行步骤3.1排查。

3.确认缓存文件是否正常

3.1.如果是会记录偏移量的数据源(文件/数据库/eventlog),确认${HEKA_CACHE_DIR}对应子目录下是否有预期的缓存文件,如果没有,表示没有采集对应文件,这时要确认白名单以及oldest_duration是否配置正常

3.2.如果是不记录偏移量的数据源(syslog) 或者是3.1排查正常,那么确认${HEKA_CACHE_DIR}/output_queue/RzyHttpOutput下 :1. x.log是否在持续增长滚动,且其中是否包含期望的数据 2. checkpoint.txt是否在持续变化

RizhiyiAgent

背景介绍

·       RizhiyiAgent日志文件所在目录(后用${AGENT_LOG_DIR}表示):RizhiyiAgent安装目录/log

·       RizhiyiAgent缓存文件所在目录(后用${AGENT_CACHE_FILE}表示): RizhiyiAgent安装目录/bin/.logstash-forwarder-java

·       .logstash-forwarder-java中为json格式的文件,记录了采集的文件,已经采集到的偏移量

1.确认进程是否正常

1.1.通过Agent管理界面确认对应RizhiyiAgent的启动状态是“已启动", 如果是,则表示进程正常,继续  后续步骤的确认,如果是"已停止", 则排查1.2

1.2.登陆RizhiyiAgent所在服务器,使用ps命令确认forwarder-daemon进程是否存在,如果forwarder-daemon存在,则查看${AGENT_LOG_DIR}/log/forwarder.log,确认RizhiyiAgent停止原因,如果forwarder-daemon不存在,则查看${AGENT_LOG_DIR}/log/daemon.log

2.确认日志是否正常

2.1.确认${AGENT_LOG_DIR}/log/forwarder.log 中是否存在发送失败日志,如果存在,则排查Collector是否正常

3.确认缓存文件是否正常

3.1.确认${AGENT_CACHE_FILE}中是否包含期望的文件,如果不存在,则表示没采集该文件,这时请确认白名单以及oldest_duration是否能匹配上期望文件

3.2.确认对应期望文件的那项中seek是否在变化,如果未变化,则确认是否是因为采集文件过多,导致每轮到该文件导致,如果有变化,则表示采集正常

如果上述排查结果都正常,则表示采集Agent正常,需要排查下一个流经模块

Collector

Collector的问题都可以在Manager上进行检查和确认:

Manager——Collector——性能

·       接收日志条速率 (collector.source.AcceptEventCountSpeed)

·       丢弃日志条数速率 (collector.source.DescardEventCountSpeed)

·       插入kafka失败数速率 (collector.source.SinkKafkaFailCountSpeed)

0015ca2d5312f1cac2e1dac6fcd480e

0015ca2d5574c6d0854502f15897dd5

0015ca2d5a55ded7dd2784e15601593

可以通过Manager直接查看Collector的WARN/ERROR日志

0015ca2d5c1978c44945bbe3e849021

如果刚好在终端,也可以直接通过脚本 /opt/rizhiyi/tools/collector/status.sh 查看这三个指标

·       AcceptEventCount

·       DescardEventCount

·       SinkKafkaFailCount

0015ca2d5dfdd7cdb1e1b80e57bf121

另外注意一种情况:

1.  系统日志量较大 >10K EPS

2.  前台查看日志显示有较大延迟

3.  Collector工作正常,有数据进入,且日志没有任何WARN/ERROR日志

4.  其他模块工作正常,只有Heka Agent提示发送数据timeout

此时要检查Collector的配置内存值,默认512MB,如果日志量达到10K EPS需要将内存最少加到1024MB。

 

Kafka

kafka通常不会有问题,主要排障场景为使用kafka工具确认对应日志是否入kafka,

一般有两种查法

1.扫描历史数据,检查是否有指定的日志

1.10.1及以后版本

一般可以使用命令

/opt/rizhiyi/tools/kafka/bin/kafka_consumer_tool.py --topic raw_message --consumer=logriver --broker 127.0.0.1:9092  --max_messages 1 --offset start --filter_rule "domain=ops,appname=packet"

1.10.1及以前版本

1.10.1以前版本的 kafka_consumer_tool.py 没有办法精确指定从头开始消费,建议升级到1.10.1之后的版本(无需更新其他模块,从1.10.1之后的环境上拷贝这个文件就可以),或者使用 kafka自带的log转换工具进行扫描,具体命令如下。

/opt/rizhiyi/tools/kafka/bin/kafka-run-class.sh kafka.tools.DumpLogSegments  --deep-iteration --print-data-log --files /data/rizhiyi/kafka/raw_message-xxx/xxxxxxx.log |less

需要注意的是,不管是哪个工具,分析速度都不会太高,默认情况下,kafka内保存了6小时数据,完整扫描一遍用时会比较长,需要耐心等待。

如果可以精确确认日志的入库时间的话,可以考虑到manager上查出对应时刻的每个partition的offset,然后使用命令从对应的offset开始扫描,这样效率会更高一些。具体命令如下

/opt/rizhiyi/tools/kafka/bin/kafka_consumer_tool.py --topic raw_message --consumer=logriver --broker 127.0.0.1:9092  --max_messages 1 --offset 查到的offset --partition 对应partitionID  --filter_rule "domain=ops,appname=packet"

2.使用工具分析新入库的日志,然后制造日志,看是否可以收到

命令如下(所有版本的kafka_consumer_tool.py都支持,但1.10.1之后的工具显示的更清楚一些,推荐使用)

/opt/rizhiyi/tools/kafka/bin/kafka_consumer_tool.py --topic raw_message --consumer=logriver --broker 127.0.0.1:9092  --max_messages 1 --offset latest --filter_rule "domain=ops,appname=packet"

这个也有类似的性能问题,因为这里是单机扫描所有的新增数据,集群新增日志速率特别高时,可能要等很久。需要耐心等待。

 

 

LogRiver

如果kafka能搜到,es搜不到,排查logriver

写入失败可能的原因和排查方法:

1.logriver消费慢或者消费卡住,还没有消费到

logriver的消费满可以通过查看kafka consumer的lag来看,在kafka所在机器上执行
/opt/rizhiyi/tools/kafka/bin/kafka_monitor.py --broker 127.0.0.1:9092 --topic raw_message --consumer logriver --mode topic
观察in-speed out-speed和lag的变化。
lag太大的话可能的等一段时间才能搜到数据。
out-speed一直为0说明logriver写入卡住,需要排查具体卡住原因,通常是等待es集群恢复


2.logriver积压时间太长,超过kafka保存时间,kafka把数据清理了

查看manager kafka的性能指标:原始消息队列未处理的数量(kafka.topic.lag.raw_message)
如果kafka把数据丢了,现象是lag一直在上涨,一下降非常多,然后继续上涨


3. logriver把数据丢了

logriver丢数据的原因包括:
- 超出配置的before_duration/after_duration时间范围,并且开启discard选项
- 索引关闭
丢弃的数量统计在manager上logriver性能指标
logriver.discard_message_num_exceed_range.count
索引关闭导致的写失败统计在manager上logriver性能指标
写入es失败数量 (logriver.sink_es_fail.count)


 其他排查工具

1. 2.0之后加上了每个appname的统计

curl http://127.0.0.1:54400/dump/metrics_by_appname?pretty=true&merge


可以看出来从最近一段时间里所有appname,tag的统计

2. 1.10.1之后加了上传日志trace功能

如果怀疑是logriver到es这段时间有问题,可以通过页面上传一个文件的方式来排查问题

上传文件后搜索所有的logriver日志,关键字LogEventTracker

可以获取的信息包括:匹配的规则,解析的状态,写入的索引,写入结果等

 

ES

如果前台搜不到期望的数据 一般是以下几种情况

不管哪种情况,都先直接在后台 curl es的索引,看数据是否已经入进,

下面是后台curl的命令,具体的query和时间戳 索引名,需要跟客户情况修改

建议从kafka拿到的日志按context id搜索,context id不保证唯一,需要排查下搜到的是不是所需要的日志 
curl '192.168.1.140:9200/_search?pretty&q=context_id:xxx'
curl '192.168.1.140:9200/yotta*/_search?pretty' -d '{
  "size" : 0,
    "query" : {
        "bool" : {
              "must" : [
                      {
                        "match_all" : {
                       }
                  }
               ],
               "filter" : [
                {
                 "range" : {
                            "timestamp" : {
                               "from" : 1516267072000,
                               "to" : 1516267672000,
                               "include_lower" : true,
                               "include_upper" : false            
                               }
                            }        
                           }      
                          ]    
                 }  
             }
 }'


执行后的返回值有个total字段 值就是命中查询条件的所有记录数

如果执行后 total是0 就是没查到,有几种可能,

数据进到es:

数据入进来了 但是timestamp字段解析后的值不在前台搜索传入的值范围内,这个要么解析时间戳有误,要么前台输错了。

 数据没进到es里,

需要查看kafka是否有积压,如果没有积压,需要看logriver日志,判断是否日志被丢弃,被丢弃就是数据入的索引被logriver认为应该抛弃,需要看logriver的丢弃数据的配置。

还有一种情况,索引有部分shard损坏,这时如果没有副本,查出的数据会不全,也会查询结果不全,这种情况需要先修复索引,如果数据可以重入,就把索引删掉 重入,如果修复不了联系研发。

还有一种情况是yottasearch的 template没起作用,需要重新初始化template并下发,然后删掉索引重入。

如果kafka积压了大量数据,需要先定位积压原因,这个情况太多了,

先看集群的状态是否green 是否最近有掉节点的情况发生,掉节点可能导致数据积压

如果集群状态正常 再看yottasearch集群的各项指标是否正常,jvm内存 cpu负载,磁盘IO,有可能是集群的处理能力不够,这时需要研发调整一些参数,如果调整参数后观察还不行,就是集群达到瓶颈了,只能从别的地方想办法。

SPL

如果es能搜到,spl搜不到,需要排查spl

可能的问题:

·       看从es搜出来日志的索引名(_index),如果不是yotta索引,需要在spl语句指定index=xxx。也可以参考spl配置项query.default_index

·       看日志的时间戳(timestamp),转成可以理解的时间戳,看看spl的搜索时间是不是在这个范围内。如果时间戳错误,需要检查抽取规则配置。需要注意的是:时间戳可能因为时区错误,多加了8小时,是明天的时间戳,搜索范围需要扩大到明天。

·       看日志的_type,_type格式是domain_appname,看这个用户是否有搜索这个domain,这个appname的权限


日志分析更容易
    您需要登录后才可以回复