Gitlab 如何使用logstash解析从多个文件聚合的日志流?

Gitlab 如何使用logstash解析从多个文件聚合的日志流?,gitlab,logstash,logstash-grok,logstash-configuration,filebeat,Gitlab,Logstash,Logstash Grok,Logstash Configuration,Filebeat,我在Kubernetes上安装了GitLab的日志。在其他pod中,有一个Sidekiq,它有一个非常特殊的日志结构——它收集多个文件,然后全部进入stdout(参见末尾或后面的示例)。我想通过Filebeat收集所有这些日志,将它们发送到Logstash,并以合理的方式处理它们(解析JSON,从行日志中获取重要数据,等等。此外,我还想添加关于原始文件的信息),并将输出发送到elasticsearch 然而,我正在为如何做到这一点而挣扎——作为一个关于Logstash的新手,我不确定它在引擎盖下

我在Kubernetes上安装了GitLab的日志。在其他pod中,有一个Sidekiq,它有一个非常特殊的日志结构——它收集多个文件,然后全部进入stdout(参见末尾或后面的示例)。我想通过Filebeat收集所有这些日志,将它们发送到Logstash,并以合理的方式处理它们(解析JSON,从行日志中获取重要数据,等等。此外,我还想添加关于原始文件的信息),并将输出发送到elasticsearch

然而,我正在为如何做到这一点而挣扎——作为一个关于Logstash的新手,我不确定它在引擎盖下是如何工作的——到目前为止,我只能找到与文件名匹配的grok

从一个角度来看,这应该相对容易-我只需要使用某种状态来标记日志流中正在处理的文件,但首先我不确定Filebeat是否以某种方式将有关流的信息传递给Logstash(区分pod日志的来源很重要)其次,Logstash是否允许这种基于状态的日志流处理

是否可以解析这些日志并以这种基于状态的方式将原始文件名添加为字段?你能给我指一下正确的方向吗

    filter {
        grok {
            match => {"message" => "\*\*\* %{PATH:file} \*\*\*"}
        }

        if [file] == "/var/log/gitlab/production_json.log" {
            json {
                match => { ... }
            }
        }
        else if [file] == "/var/log/gitlab/application_json.log" {
             grok {
                match => { ... }
            }
        }
    }
请注意,即使对于每个文件,也可能有多种类型的日志(/var/log/gitlab/sidekiq_exporter.log)


您可以在
filebeat.yml
中为filebeat提供所有日志路径,以便读取日志并将其发送到logstash

gitlab的示例
filebeat.yml

文件节拍配置示例#########################
#==============================================文件节拍输入=============================
filebeat.inputs:
-
路径:
-/var/log/gitlab/gitlab rails/application_json.log
领域:
-类型:gitlab应用程序json
根目录下的字段:true
编码:utf-8
-
路径:
-/var/log/gitlab/sidekiq_exporter.log
领域:
-类型:gitlab sidekiq exporter
根目录下的字段:true
编码:utf-8
-
路径:
-/var/log/gitlab/gitlab rails/api_json.log
领域:
-类型:gitlab api json
根目录下的字段:true
编码:utf-8
-
路径:
-/var/log/gitlab/gitlab rails/application.log
领域:
-类型:gitlab应用程序
根目录下的字段:true
编码:utf-8
#====================================================文件节拍模块===============================
filebeat.config.modules:
#配置加载的Glob模式
路径:${path.config}/modules.d/*.yml
#设置为true以启用配置重新加载
重新加载。已启用:false
#-----------------------------对数存储输出--------------------------------
output.logstash:
#Logstash主机
主持人:[“10.127.55.155:5066”]
#==============================================处理器=====================================
#配置处理器以增强或操纵节拍生成的事件。
处理器:
-添加主机元数据:~
-添加云元数据:~
现在,在logstash中,您可以创建不同的grok模式来过滤这些日志

下面是一个示例
logstash.yml

input {

 beats {
        port => "5066"
    }
  }
  
filter {

      if [type] == "gitlab-sidekiq-exporter" {
      
            grok {
               match => { "message" => "\[%{TIMESTAMP_ISO8601:timestamp}\] %{IPORHOST:clientip} %{USER:ident} %{USER:auth} \[(?<timestamp>%{MONTHDAY}/%{MONTH}/%{YEAR}\:%{TIME}) %{TZ:timezone}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response} (?:%{NUMBER:bytes}|-) %{QS:referrer} %{QS:agent}" }
               overwrite => [ "message" ]
           }
    }
    
filter {
      mutate {
          remove_tag => [
              "_grokparsefailure"
          ]
      }
  }

output {
 
     #filtered logs are getting indexed in elasticsearch
     
        elasticsearch {
                hosts => ["10.127.55.155:9200"]
                user => elastic
                password => elastic
                action => "index"
                index => "gitlab"
        }
        stdout { codec => rubydebug }  #filtered logs can be seen as console output as well, you can comment this out as well, this is for debugging purpose only
 } 
输入{
击败{
端口=>“5066”
}
}
滤器{
如果[type]=“gitlab sidekiq导出器”{
格罗克{
“消息”匹配=>{{{{消息”收集收集{{{{{{消息”收集收集{{{{{{消息”收集收集{{{{{{消息“{{消息”收集收集{{{{{消息”{{{{消息”收集收集收集收集收集{{{{消息”消息“{{{{{{{时间戳时间戳时间戳戳戳戳:一一概概概{{{{{{{{{{{警察:客户端:客户端:客户:用户:身份:{{{{{{用户:用户:用户:用户:用户:auth}{{{{{{{{{{用户:用户:用户:用户:auth}}}}}}}}}}{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{}}}}}}}}}}}}}{{{{{{{{{{{{{}}}}}.QS:agent}“}
覆盖=>[“消息”]
}
}
滤器{
变异{
删除标签=>[
“_grokparsefailure”
]
}
}
输出{
#已筛选日志在elasticsearch中被索引
弹性搜索{
主机=>[“10.127.55.155:9200”]
用户=>elastic
密码=>elastic
操作=>“索引”
索引=>“gitlab”
}
stdout{codec=>rubydebug}#过滤的日志也可以看作是控制台输出,您也可以对此进行注释,这仅用于调试目的
} 
注意:
logstash.yml
中的节拍输入端口应与
filebeat.yml
中的output.logstash中给出的相同

您可以附加
logstash.yml
以过滤出application_json.logapplication.log,类似于sidekiq_exporter.log

要创建和验证grok模式以过滤日志,可以使用online

在这里,我使用Grok调试器创建了一个模式,用于过滤sidekiq\u exporter.log

模式:
%{IPORHOST:clientip}%{USER:ident}%{USER:auth}\[%{HTTPDATE:timestamp}]”(?:%{WORD:verb}%{NOTSPACE:request}(?HTTP/%{NUMBER:httpversion}){DATA:rawrequest})%{NUMBER:response}({NUMBER:response}({NUMBER:bytes:bytes})%{


我明白了,非常积极的一点是那些文件节拍标记。这肯定会很有用。不幸的是,这种方法稍微绕过了这个问题。我们将GitLab安装为helm图表,它并不完全像您想象的那样支持每个文件的日志记录。我的意思是,它在pod内部支持日志记录,但随后会将日志收集并聚合到无法从Kubernetes群集的节点访问容器的标准输出和原始文件。
input {

 beats {
        port => "5066"
    }
  }
  
filter {

      if [type] == "gitlab-sidekiq-exporter" {
      
            grok {
               match => { "message" => "\[%{TIMESTAMP_ISO8601:timestamp}\] %{IPORHOST:clientip} %{USER:ident} %{USER:auth} \[(?<timestamp>%{MONTHDAY}/%{MONTH}/%{YEAR}\:%{TIME}) %{TZ:timezone}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response} (?:%{NUMBER:bytes}|-) %{QS:referrer} %{QS:agent}" }
               overwrite => [ "message" ]
           }
    }
    
filter {
      mutate {
          remove_tag => [
              "_grokparsefailure"
          ]
      }
  }

output {
 
     #filtered logs are getting indexed in elasticsearch
     
        elasticsearch {
                hosts => ["10.127.55.155:9200"]
                user => elastic
                password => elastic
                action => "index"
                index => "gitlab"
        }
        stdout { codec => rubydebug }  #filtered logs can be seen as console output as well, you can comment this out as well, this is for debugging purpose only
 }