乐趣区

ES-慢查询日志收集实战总结

前言

在执行 elasticsearch 查询的时候,有些查询会占用大量的资源导致响应很慢,这个时候就需要 ES 对慢查询进行监控。找到那些响应很慢的请求。ES 的请求主要分为搜索和索引,ES 也分别提供了这两种类型请求的慢查询日志。

搜索慢日志

慢搜索日志配置可以记录响应慢的搜索(查询和获取阶段)并将其放到一个专门的日志文件,这个配置只针对当前分片节点有效。

# vim /etc/elasticsearch/elasticsearch.yml
#记录获取慢日志
index.search.slowlog.threshold.fetch.warn: 1s
index.search.slowlog.threshold.fetch.info: 200ms
index.search.slowlog.threshold.fetch.debug: 60ms
index.search.slowlog.threshold.fetch.trace: 50ms
#记录查询慢日志
index.search.slowlog.threshold.query.warn: 1s
index.search.slowlog.threshold.query.debug: 500ms

日志级别为(warn、info、debug、trace)可以通过给日志分级来控制日志的记录。不是所有级别的日志都需要记录,多个级别记录的好处是可以根据级别减少日志的数量,根据业务需要只关注重点的日志。日志记录是在分片级别范围完成的,意味着在特定分片中执行查询请求,不包含整个可以广播到多个分片执行的搜索请求,分片级别的日志记录好处是关联特定机器上的时机执行操作。

索引慢日志

索引慢日志类似于搜索慢日志的功能。日志文件以_index_indexing_slow_log_file.log 结尾,日志和阀值可以在 elasticsearch.yml 文件中配置。

# vim /etc/elasticsearch/elasticsearch.yml
index.search.slowlog.threshold.index.warn: 10s
index.search.slowlog.threshold.index.info: 5s
index.search.slowlog.threshold.index.debug: 2s
index.search.slowlog.threshold.index.trace: 500ms
index.search.slowlog.level: info
index.search.slowlog.source: 1000

默认情况下,ES 会记录_source 中前 1000 个字符到慢日志中。可以用 index.search.slowlog.source 进行修改。设置为 false 或 0 完全跳过日志记录源,设置为 true 会记录整个源(无论有多大)。

Logging 配置

搜索慢日志和索引慢日志在 elasticsearch.yml 中开启后,还需要在 logging.yml 中配置,配置如下:

# vim /etc/elasticsearch/logging.yml
index.search.slowlog: TRACE, index_search_slow_log_file
index.indexing.slowlog: TRACE, index_indexing_slow_log_file
additivity:
  index.search.slowlog: true
  index.indexing.slowlog: true
  deprecation: false
 
index_search_slow_log_file:
  type: dailyRollingFile # 日志类型,每天一个文件
  file: ${path.logs}/${cluster.name}_index_search_slowlog.log   # 文件命名格式
  datePattern: "'.'yyyy-MM-dd"  # 每日备份的后缀
  layout:
type: pattern
     conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"   #记录日志的开头格式
 
index_indexing_slow_log_file:
   type: dailyRollingFile
   file: ${path.logs}/${cluster.name}_index_indexing_slowlog.log
   datePattern: "'.'yyyy-MM-dd"
   layout:
     type: pattern
     conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"

通过 API 动态设置慢日志

这时一个索引级别的日志,也就是说可以独立应用给索引:

PUT /my_index/_settings
{
    "index.search.slowlog.threshold.query.warn" : "10s", # 查询慢于 10 秒输出一个 WARN 日志
    "index.search.slowlog.threshold.fetch.debug": "500ms", # 获取慢于 500 毫秒输出一个 DEBUG 日志
    "index.indexing.slowlog.threshold.index.info": "5s"     # 索引慢于 5 秒输出一个 INFO 日志
}

logstash 收集 ES 慢日志到 ES 存储中

这里仅提供一个 logstash 配置文件,你只需要修改此配置文件的慢查询日志路径和 ES 服务器集群信息,即可应用到你的 ELK 环境中。

input{
    file{
        start_position => "beginning"   
        path=> ["填入你的 ES 慢日志路径"]
        sincedb_path => "./slowlogdb"
}
}
filter {
ruby{code => "temp=event['message'].split(', ');
 
  t1= temp[0]
  common_attr=t1.split(']')
  event['time']=common_attr[0].split('[')[1]
  event['loglevel']=common_attr[1].split('[')[1]
  event['slowtype']=common_attr[2].split('[')[1]
  event['indexname']=common_attr[3].split('[')[1]
 
  t2= temp[1]
  time_attr=t2.split('[')
  event['took_millis']= time_attr[1].split(']')[0]
 
  t3= temp[2]
  t4= temp[3]
  t5= temp[4]
  t6= temp[5]
  shards_attr=t6.split('[')
  event['total_shards']= shards_attr[1].split(']')[0]
 
  t7= temp[6]
  t8= temp[7]
  event['search_type']= t5
  event['message']= t7
  event['extra_source']= t8
 "}
 
   mutate{convert => ["took_millis","integer"] #设置 took_millis 的类型为 integer 类型
   }
 
   mutate{convert => ["total_shards","integer"] #设置 total_shards 的类型为 integer 类型
   }
}
 
output{
  elasticsearch{index => "es-slowlog-%{+YYYY-MM}"
   hosts=> [填入你的 ES 集群主机列表]
   flush_size => 3000
   }
}

在 logstash 调试模式输出 ES 慢日志各字段含义说明:

{
        # 慢查询的语句
         "message" => "source[{\"fields\":[\"_parent\",\"_source\"],\"query\":{\"bool\":{\"must\":[],\"must_not\":[],\"should\":[{\"match_all\":{}}]}},\"from\":0,\"size\":50,\"sort\":[],\"aggs\":{},\"version\":true}]",
        "@version" => "1",
"@timestamp" => "2018-03-15T12:20:40.091Z",
       # 慢查询日志路径
"path" => "/root/test.log",
# 慢查询主机名
"host" => "c7-node1.fblinux.com",
# 慢查询产生时间
"time" => "2018-03-15 11:26:30,318",
# 慢查询级别
        "loglevel" => "INFO",
           # 慢查询类型
        "slowtype" => "index.search.slowlog.query",
          # 索引名称
"indexname" => "test-2018-03",
      # 慢查询时间,单位毫秒
"took_millis" => 64,
     # 总 shards 数量
    "total_shards" => 1188,
     "search_type" => "search_type[QUERY_THEN_FETCH]",
    "extra_source" => "extra_source[],"}

版权申明:作者:西门飞冰,一名 90 后 it 男,一直在北京工作,热爱运动,热爱冒险,热爱旅行。由作者原创投稿,版权归原创者所有。首先于微信公众号:民工哥技术之路,如需转载请联系授权!

关注 民工哥技术之路 微信公众号对话框回复关键字:1024 可以获取一份最新整理的技术干货:包括系统运维、数据库、redis、MogoDB、电子书、Java 基础课程、Java 实战项目、架构师综合教程、架构师实战项目、大数据、Docker 容器、ELK Stack、机器学习、BAT 面试精讲视频等。

退出移动版