使用Elasticsearch+filebeat+logstach+kibana构建日志服务平台

背景

  • devops中日志服务的搭建
  • 收集各个节点(agent)的日志文件进ES集群,并提供分析和查询的服务
  • 各个agent的filebeat收集服务不能终断,也就是需要动态reload配置文件
  • 支持用户设置分隔符划分和正则匹配两种方式添加field字段

技术方案

  • 将filebeat部署在agent节点,master节点控制agent节点的配置文件,filebeat很轻量
  • 因为filebeat的配置文件支持reload的只有input和moudel两个模块,但是需要对用户提供的分隔符和正则表达式进行处理,可以完成这个操作的processors模块不支持动态reload,所以filebeat只收集日志,处理日志的任务交给logstach,logstach支持整个配置文件的动态reload

Filebeat安装以及使用

  • Filebeat是一个轻量化的日志收集工具,对标Logstach,filebeat只有30M,而logstach有300M

  • 调试启动命令:./filebeat -e -c filebeat.yml,-c指明配置文件路径,-e表示记录到stderr,并禁用syslog文件输出

  • 启动命令相关:https://johng.cn/filebeat-command-configuration/

  • 后台启动方式:nohup ./filebeat -e -c filebeat.yml > filebeat.log &

  • filebeat启动可以使用root用户,但是ES启动不能使用root用户

  • reload相关写法参考:https://blog.csdn.net/junxuezheng/article/details/108349689

  • filebeat.yml配置文件

    filebeat.config.inputs:
      enable: true
      path: /usr/local/xxx/input.yml
      reload.enable: true
      reload.period: 5s
    
    output.console:
      pretty: true
      
    #output.elasticsearch:
    #  hosts: ["10.243.65.186:9200"]
    
    output.logstash:
      hosts: ["1.1.1.186:5044"]
    processors:
    - rename:
        fields:
        - from: host
          to: _host
        - from: message
          to: _message
        ignore_missing: false
        fail_on_error: true
    - drop_fields:
        fields:
        - ecs
        - log
        - input
    
  • input.yml文件

    - type: log
    
      # Change to true to enable this input configuration.
      enabled: true
    
      # Paths that should be crawled and fetched. Glob based paths.
      paths:
        - /usr/local/xxx
      tags: c7f1771f-0c8f-4c75-9d71-3b8c4b6bd191
      fields: 
        source: wang_test
      fields_under_root: true
    
  • filebeat只能输出到一个地方,logstach可以输出到多个地方

  • fields_under_root,这个字段如果设置为true,则新增的字段成为顶级目录,和message平级,如果为false,则会多出一个fields字段,这个fields字段和message字段平级,我们自定义的字段都存放在fields字段下

  • 注意,filebeat文件夹下有一个data的文件夹,可以记录哪些行传输过,所以如果ctrl+c之后再重开,不会把之前传过的内容再传一遍,除非删除这个data文件夹

Logstach安装以及使用

  • 二进制安装,解压即用

  • 可以用root用户启动

  • 部署命令:`bin/logstash -f config/xxx.conf

  • 测试config文件是否写的正确bin/logstash -t -f config/xxx.conf

  • 配置logstash自动刷新配置文件:bin/logstash -f config/xxx.conf --config.reload.automatic

  • 配置文件如下:

    input {
      beats {
        port => 5044
      }
    }
    
    filter {
      mutate{
        rename => {"host" => "_host"}
        rename => {"message" => "_message"}
        rename => {"tags" => "_tags"}
        remove_field => ["@version", "ecs"]
      }
      if [log][file][path] == "/usr/local/dashuaibi/log/wang.log"{
        dissect {
          mapping => {
            "message" => "%{wang_time} %{wang_pid} %{wang_level} %{comtent}"
          }
        }
      }
    }
    
    output {
      if [log][file][path] == "/usr/local/dashuaibi/log/wang.log"{
        elasticsearch {
        hosts => "10.1.1.186:9200"
          index => "wang_test_666"
        }
      }
    }
    
    • 注意:mapping里的分隔符表达式,最后一个字段默认会把后面所有的内容都接收下来
    • field字段的增删改在filebeat和logstash中都可以做,看业务需求。

Elasticsearch安装以及使用

  • 二进制安装,解压即用tar -zxf xxx.tar.gz

  • 先在root用户下修改权限chown -R elastic:elastic elastic

    • 最后一个elastic是文件夹的名字
    • -R表示处理指定目录以及其子目录下的所有文件
  • vim config/elasticsearch.yml,将network.host: 0.0.0.0,让外部可以访问到

  • node.name: node-1这行的注释也打开,下面这个操作要用

  • vim config/elasticsearch.yml,将cluster.initial_master_nodes: ["node-1"]这行的注释打开,有几个节点就在list里写几个值,否则master节点会一直搜索另一个节点,"node-1"是本台机器的hostname,需要提前在/etc/hosts里定义(如果默认没有添加的话),文件里写的是ip + hostname

  • 启动命令:bin/elasticsearch

  • ES不能使用root用户启动

  • 可以在创建ES索引的时候指定分片的参数,wangtest是要创建的索引名

    PUT wangtest
    {
      "settings": {
        "index": {
          "number_of_shards": 3,
          "number_of_replicas": 1
        }
      }
    }
    

Kibana安装以及使用

  • 二进制安装,解压即用
  • vim config/kibana.yml,将server.host:"0.0.0.0",让外部可以访问到
  • 启动命令:./bin/kibana,注意这个.必须带
  • Kibana也不能使用root用户启动,但是根据提示,好像有开关可以控制使用root启动

监控软件cerebro的安装和使用

  • 下载压缩包,解压

  • bin/cerebro

  • 非必须:如果经常使用的话,可以先在conf/application.conf中配置好ElasticSearch服务器地址

    hosts = [
      {
        host = "http://localhost:9200"
        name = "Some Cluster"
      }
    ]
    
  • 参考:https://www.jianshu.com/p/433d821f9667

如何在脚本里启动filebeat

  • 前提背景:有一些场景是需要在脚本里自动启动的 ,且希望在后台运行,所以我想到了nohup

    nohup ./filebeat -e -c /usr/local/sahoc/filebeat.yml &

    这个做法可以后台起一个进程运行filebeat,但是主进程不会退出,因为启动的filebeat在另一个进程里有终端输出

  • 解决方案:nohup ./filebeat -e -c /usr/local/sahoc/filebeat.yml >> $FILEBEAT_LOG 2>&1 &

    这样把终端的输出重定向到一个文件,主进程就不会持续监听了,注意2>&1必须加,必须把所有的输出都追加到文件,文件地址可以是/dev/null

关于ES查询的分页问题

这里的查询分为两种,一种是基于ES的DQL,就是用restfulAPI的调用方式,另一种是说使用SQL语言进行查询。众所周知在MYSQL里分页可以使用limit 10,5来解决,第一个10是偏移量(offset),从第十个数据开始读取,第二个参数5说明是一次取5个值,通过这种方式可以实现分页。但是使用

POST /_sql?format=txt{
  "query": "SELECT CONTENT FROM XXX LIMIT 10,5"
}

ES报错,不能识别逗号,所以说这个接口里的limit后面只支持一个参数。下面说分别对应这两种方法的解决方案

  • DQL查询方式

    • from+size方式
    • scroll方式
    • search_after方式
    • 参考:https://chunsoft.blog.csdn.net/article/details/91406928
  • SQL的查询方式

    • cursor(游标)方式
    • 参考:https://blog.csdn.net/qq_42569136/article/details/115465322
    • 参考:https://www.elastic.co/guide/en/elasticsearch/reference/current/sql-pagination.html
    • 感觉这种方式和上面的search_after是一样的,多用于数据导出,并不适用这种场景,且不能跳转,只能一页一页的读
    • fetch_size方案
    • 参考:https://www.elastic.co/guide/en/elasticsearch/reference/current/sql-search-api.html#sql-search-api-request-body
    • 可以看到这里有一个fetch_size的参数,讲道理应该和上面一样还有一个fetch_from就完美了,可惜是官方并没有提供这个参数,想不明白是为什么
  • 最终的方案,使用先用/_sql/translate把SQL查询变成DQL之后,再在DQL里面补充from和size字段,默认情况下使用translate会自动有一个size:1000的对象,如果SQL语句里有limit 100,这个1000就变成100了,但是不会自动添加from

如果一行数据,用指定的分割方式没有分割出来怎么办

直接把这个数据添加到message里,并不会丢弃

如果之前我们的filebeat的input.yml文件有一段时间为空,后面再加上还能正常工作吗?

可以

采用上面的方案会导致,每次有新的数据加入log文件,都会把之前的所有内容再重新传一遍,导致重复采集

  • 问题出在vim编辑器,用echo添加就不会有问题,估计是vim保存的时候创建了一个新的文件或者链接
  • 参考:https://elasticsearch.cn/question/2533

vi指令保存后,会重复发送,用echo写东西测试没问题,类似vi估计都会有问题。官方论坛翻译内容如下:

你怎么修改文件。你试过了$ echo ‘new line’ >> /usr/src/app/log.log吗?filebeat试图根据元数据来检测文件是否是新的。一些工具/编辑器创建一个全新的文件保存并取消旧链接。这被filebeat检测为新文件,迫使它重新发送所有内容。

上面使用[log][file][path]不太严谨

  • 如果不同机器上有不同的业务,但是log文件名都一样,这样就会把这些日志放在一个索引,其实不应该放在一起

  • 采用打tags的方式解决

  • filebeat_input.yml文件里加入tag

    - type: log
    
      # Change to true to enable this input configuration.
      enabled: true
    
      # Paths that should be crawled and fetched. Glob based paths.
      paths:
        - /usr/local/xxx
      tags: wang1
      fields: 
        source: wang_test
    - type: log
    
      # Change to true to enable this input configuration.
      enabled: true
    
      # Paths that should be crawled and fetched. Glob based paths.
      paths:
        - /usr/local/xxx
      tags: wang2
      fields: 
        source: wang_test
    

    tags后面的值可以不带引号

  • logstash配置文件根据这个tag去做相应的处理

    inputs {
      beats {
        port => 5044
      }
    }
    
    filter {
      if "wang1" in [tags]{
        dissect {
          mapping => {
            "message" => "%{wang_time} %{wang_pid} %{wang_level} %{comtent}"
          }
        }
      }
    }
    
    output {
      if "wang1" in [tags]{
        elasticsearch {
          hosts => "10.1.1.186:9200"
          index => "wang_test_666"
        }
      }
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值