ELK之logstash

Logstash学习整理


1. 使用logstash解析日志

通常logstash管道具有一个或多个输入,过滤器和输出插件,在本节中,将创建一个使用Filebeat将Apache Web日志作为输入的Logstash管道,解析这些日志以从日志中创建特定的命名字段,并将解析后的数据写入Elasticsearch群集

要点:

  • logstash启用自动配置重新加载 (–config.reload.automatic)
  • 强制Filebeat从头开始读取日志文件(删除Filebeat注册表文件)
  • logstash过滤插件(Grok、Geoip)

1.1 配置filebeat以将日志发送到logstash

案例数据可以直接从官网下载

filebeat.prospectors:
- type: log
  enabled: true
  paths:
- /home/test/logstash-tutorial.log 
output.logstash:
  hosts: ["192.168.20.60:5044"]

1.2 为filebeat输入配置logstash输出

# cat first-pipeline.conf 
input {
    beats {
        port => "5044"
    }
}
# The filter part of this file is commented out to indicate that it is
# optional.
# filter {
#
# }
output {
    stdout { codec => rubydebug }
}

验证配置:

/usr/local/elk/logstash-6.2.3/bin/logstash -f first-pipeline.conf --config.test_and_exit
#--config.test_and_exit选项解析配置文件并报告任何错误

如果配置文件通过配置测试,请使用以下命令启动Logstash:

/usr/local/elk/logstash-6.2.3/bin/logstash -f first-pipeline.conf --config.reload.automatic
#--config.reload.automatic选项启用自动配置重新加载,因此每次修改配置文件时都不必停止并重新启动Logstash

如果你的管道工作正常,你应该看到一系列事件写入控制台:

{
    "@timestamp" => 2017-11-09T01:44:20.071Z,
        "offset" => 325,
      "@version" => "1",
          "beat" => {
            "name" => "My-MacBook-Pro.local",
        "hostname" => "My-MacBook-Pro.local",
         "version" => "6.0.0"
    },
          "host" => "My-MacBook-Pro.local",
    "prospector" => {
        "type" => "log"
    },
        "source" => "/path/to/file/logstash-tutorial.log",
       "message" => "83.149.9.216 - - [04/Jan/2015:05:13:42 +0000] \"GET /presentations/logstash-monitorama-2013/images/kibana-search.png HTTP/1.1\" 200 203023 \"http://semicomplete.com/presentations/logstash-monitorama-2013/\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36\"",
          "tags" => [
        [0] "beats_input_codec_plain_applied"
    ]
}
...

1.3 使用Grok过滤器插件解析Web日志

Grok过滤器插件是Logstash中默认可用的几个插件之一,能够将非结构化日志数据解析为结构化和可查询的内容。
要解析apache日志数据可以使用%{COMBINEDAPACHELOG} grok模式,该模式使用以下模式构建Apache日志中的行:

#信息               #字段名称
IP Address          #clientip    
User ID             #ident    
User Authentication #auth    
timestamp           #timestamp    
HTTP Verb           #verb    
Request body        #request    
HTTP Version        #httpversion    
HTTP Status Code    #response   
Bytes served        #bytes    
Referrer URL        #referrer    
User agent          #agent  

编辑first-pipeline.conf文件,添加过滤规则:

input {
    beats {
        port => "5044"
    }
}
filter {
    grok {
        match => { "message" => "%{COMBINEDAPACHELOG}"}
    }
}
output {
    stdout { codec => rubydebug }
}   

在/usr/local/elk/logstash-6.2.3/vendor/bundle/jruby/2.3.0/gems/logstash-patterns-core-4.1.2/patterns目录下查看匹配规则

由于启用了自动配置重新加载,因此不必重新启动Logstash即可获取更改。 但是需要强制Filebeat从头开始读取日志文件。(关闭Filebeat。然后删除Filebeat注册表文件)

/etc/init.d/filebeat stop
rm /var/lib/filebeat/registry   #rpm安装的注册表路径
/etc/init.d/filebeat start      #启动

由于Filebeat存储它在注册表中收获的每个文件的状态,因此删除注册表文件将强制Filebeat读取从头开始收集的所有文件。

Logstash应用grok模式后,事件将具有以下JSON表示形式:

{
        "request" => "/presentations/logstash-monitorama-2013/images/kibana-search.png",
          "agent" => "\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36\"",
         "offset" => 325,
           "auth" => "-",
          "ident" => "-",
           "verb" => "GET",
     "prospector" => {
        "type" => "log"
    },
         "source" => "/path/to/file/logstash-tutorial.log",
        "message" => "83.149.9.216 - - [04/Jan/2015:05:13:42 +0000] \"GET /presentations/logstash-monitorama-2013/images/kibana-search.png HTTP/1.1\" 200 203023 \"http://semicomplete.com/presentations/logstash-monitorama-2013/\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36\"",
           "tags" => [
        [0] "beats_input_codec_plain_applied"
    ],
       "referrer" => "\"http://semicomplete.com/presentations/logstash-monitorama-2013/\"",
     "@timestamp" => 2017-11-09T02:51:12.416Z,
       "response" => "200",
          "bytes" => "203023",
       "clientip" => "83.149.9.216",
       "@version" => "1",
           "beat" => {
            "name" => "My-MacBook-Pro.local",
        "hostname" => "My-MacBook-Pro.local",
         "version" => "6.0.0"
    },
           "host" => "My-MacBook-Pro.local",
    "httpversion" => "1.1",
      "timestamp" => "04/Jan/2015:05:13:42 +0000"
}

注意该事件包含原始消息,但日志消息也被分解为特定字段。

1.4 使用Geoip过滤器插件增强你的数据

除了解析日志数据以获得更好的搜索外,过滤器插件还可以从现有数据中获取补充信息。作为示例,geoip插件查找IP地址,从地址派生地理位置信息,并将该位置信息添加到日志中。将Logstash实例配置为使用geoip过滤器插件,方法是将以下行添加到文件的filter部分中first-pipeline.conf:

geoip {
        source => "clientip"
    }   

geoip插件配置要求您指定包含要查找的IP地址的源字段的名称。在本例中,clientip字段包含IP地址。由于按顺序评估了过滤器,请确保geoip部分位于配置文件的grok部分之后,并且grok和geoip部分都嵌套在过滤器部分中。

input {
    beats {
        port => "5044"
    }
}
filter {
    grok {
        match => { "message" => "%{COMBINEDAPACHELOG}"}
    }
    geoip {
        source => "clientip"
    }
}
output {
    stdout { co dec => rubydebug }
}    

修改完成后,关闭filebeat,删除注册表然后重新启动filebeat。

注意事件现在包含地理位置信息:

{
        "request" => "/blog/geekery/solving-good-or-bad-problems.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+semicomplete%2Fmain+%28semicomplete.com+-+Jordan+Sissel%29",
           "verb" => "GET",
       "response" => "200",
           "beat" => {
         "version" => "6.2.3",
            "name" => "192.168.20.60",
        "hostname" => "ELK"
    },
           "tags" => [
        [0] "beats_input_codec_plain_applied"
    ],
       "clientip" => "198.46.149.143",
     "@timestamp" => 2018-04-24T12:20:20.276Z,
       "referrer" => "\"-\"",
         "offset" => 23080,
           "host" => "ELK",
      "timestamp" => "04/Jan/2015:05:29:13 +0000",
       "@version" => "1",
        "message" => "198.46.149.143 - - [04/Jan/2015:05:29:13 +0000] \"GET /blog/geekery/solving-good-or-bad-problems.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+semicomplete%2Fmain+%28semicomplete.com+-+Jordan+Sissel%29 HTTP/1.1\" 200 10756 \"-\" \"Tiny Tiny RSS/1.11 (http://tt-rss.org/)\"",
          "ident" => "-",
           "auth" => "-",
         "source" => "/home/test/logstash-tutorial.log",
     "prospector" => {
        "type" => "log"
    },
          "bytes" => "10756",
          "geoip" => {
              "timezone" => "America/New_York",
         "country_code3" => "US",
         "country_code2" => "US",
              "location" => {
            "lat" => 42.8864,
            "lon" => -78.8781
        },
           "region_name" => "New York",
        "continent_code" => "NA",
           "postal_code" => "14202",
              "latitude" => 42.8864,
              "dma_code" => 514,
             "city_name" => "Buffalo",
           "region_code" => "NY",
                    "ip" => "198.46.149.143",
             "longitude" => -78.8781,
          "country_name" => "United States"
    },
    "httpversion" => "1.1",
          "agent" => "\"Tiny Tiny RSS/1.11 (http://tt-rss.org/)\""
}

1.5 将数据编入elasticsearch

现在网络日志被分解成特定的字段,Logstash管道可以将数据索引到Elasticsearch集群中。编辑first-pipeline.conf文件并用output以下文本替换整个部分:

output {
    elasticsearch {
        hosts => [ "localhost:9200" ]
    }
}   

通过这种配置,Logstash使用http协议连接到Elasticsearch。
此时first-pipeline.conf文件具有正确配置的输入,过滤器和输出部分,如下所示:

input {
    beats {
        port => "5044"
    }
}
filter {
    grok {
        match => { "message" => "%{COMBINEDAPACHELOG}"}
    }
    geoip {
        source => "clientip"
    }
}
output {
    elasticsearch {
        hosts => [ "192.168.20.60:9200" ]
    }
}   

修改完成后,关闭filebeat,删除注册表然后重新启动filebeat。

1.6 测试管道

现在Logstash管道已配置为将数据索引到Elasticsearch集群中,您可以查询Elasticsearch。根据grok过滤器插件创建的字段,尝试对Elasticsearch进行测试查询。用YYYY.MM.DD格式的当前日期替换$DATE:

curl -XGET 'localhost:9200/logstash-$DATE/_search?pretty&q=response=200'
curl -XGET '192.168.20.60:9200/logstash-2018.04.24/_search?pretty&q=response=200'

索引名称中使用的日期是基于UTC,而不是Logstash正在运行的时区。如果查询返回index_not_found_exception,请确保logstash-$DATE反映索引的实际名称。

要查看可用索引的列表,请使用以下查询:

curl 'localhost:9200/_cat/indices?v'

尝试另外搜索从IP地址派生的地理信息。用YYYY.MM.DD格式替换$ DATE和当前日期:

curl -XGET 'localhost:9200/logstash-$DATE/_search?pretty&q=geoip.city_name=Buffalo'

到此已经成功创建了一个管道,该管道使用Filebeat将Apache Web日志作为输入,解析这些日志以从日志创建特定的命名字段,并将解析的数据写入Elasticsearch群集。

2. Logstash是如何工作的

Logstash事件处理管道有三个阶段:输入→过滤器→输出。输入生成事件,过滤器修改它们,并将输出发送到别处。输入和输出支持编解码器,使您可以在数据进入或退出流水线时对数据进行编码或解码,而无需使用单独的过滤器。

INPUT
使用输入将数据导入Logstash。一些常用的输入:

file     #从文件系统上的文件读取,非常类似于UNIX命令tail -F
syslog   #在众所周知的端口514上侦听系统日志消息,并根据RFC3164格式进行解析
redis    #用redis通道和redis列表从redis服务器读取数据。 Redis经常用作集中式Logstash安装中的“broker”,它将来自远程Logstash“shippers”的Logstash事件排队。
beats    #处理由Filebeat发送的事件。

FILTER
过滤器是Logstash管道中的中间处理设备。如果符合特定条件,您可以将条件与过滤条件结合使用以对事件执行操作。一些有用的滤镜包括:

grok   #解析和结构任意文本。Grok目前是Logstash中将非结构化日志数据解析为结构化和可查询的最佳方法。Logstash内置了120个模式,这很可能会找到满足您需求的模式!
mutate  #对事件字段执行一般转换。可以重命名,删除,替换和修改事件中的字段。
drop    #完全删除一个事件,例如,调试事件。
clone   #制作一个事件的副本,可能会添加或删除字段。
geoip   #添加有关IP地址的地理位置信息(也可以在Kibana中显示惊人的图表!)   

OUTPUT
输出是Logstash管道的最后阶段。一个事件可以通过多个输出,但是一旦所有输出处理完成,事件就完成了它的执行。一些常用的输出包括:

elasticsearch  #将事件数据发送给Elasticsearch。如果打算以高效方便和易于查询的格式保存您的数据,那么Elasticsearch是一条可行的路线。)
file           #将事件数据写入磁盘上的文件。
graphite       #将事件数据发送给graphite ,graphite 是一种流行的开源工具,用于存储和绘制指标
statsd         #将事件数据发送到statsd,这是一种“侦听统计信息(如计数器和定时器,通过UDP发送并将聚合发送到一个或多个可插入的后端服务”)的服务。如果你已经使用statsd,这可能对你有用! 

CODECS
编解码器基本上是可以作为输入或输出的一部分操作的流过滤器。 使用编解码器,可以轻松地将消息从序列化过程中分离出来。 流行的编解码器包括json,msgpack和普通(文本)

json:     #以JSON格式对数据进行编码或解码。
multiline:#将多行文本事件(如java异常和堆栈跟踪消息)合并到单个事件中

Codec Plugin作用于input和output plugin,负责将数据在原始与Logstash Event之间转换,常见的codec有:

plain   #读取原始内容
dots    #将内容简化为点进行输出
Rubydebug   #将Logstash Events按照ruby格式输出,方便调试
line   #处理带有换行符的内容
json   #处理json格式的内容
multiline  #处理多行数据的内容

默认情况下,Logstash在流水线阶段(输入→过滤器和过滤器→输出)之间使用内存有界队列来缓冲事件。如果Logstash不安全地终止,则存储在内存中的任何事件都将丢失。为了帮助防止数据丢失,可以启用Logstash将正在进行的事件保存到磁盘

3. 配置示例

使用条件来控制过滤器或输出处理的事件。 例如,您可以根据每个事件出现在哪个文件(access_log,error_log和其他以“log”结尾的随机文件)来标记每个事件。

input {
  file {
    path => "/var/log/httpd/*_log"
  }
}
filter {
  if [path] =~ "access" {
    mutate { replace => {"type" => "apache_access"} }
    grok { match => { "message" => "%{COMBINEDAPACHELOG}"} }
    date { match => [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ] }
  }else if [path] =~ "error" {
        mutate { replace => { type => "apache_error" } }
  }else {
        mutate { replace => { type => "random_logs" } }
  }
}
output {
   stdout { codec => rubydebug }
}    

date filter:解析出一个时间戳并将其用作事件的时间戳)
mutate filter :可以重命名,删除,替换和修改事件中的字段

输出:使用类型字段标记所有事件,但实际上不分析错误或随机文件

{
       "message" => "[Wed Apr 25 11:26:26 2018] [error] [client 192.168.20.111] File does not exist: /var/www/html/favicon.ico, referer: http://192.168.20.60/",
          "path" => "/var/log/httpd/error_log",
          "host" => "ELK",
      "@version" => "1",
          "type" => "apache_error",
    "@timestamp" => 2018-04-25T03:26:27.678Z
}
{
           "path" => "/var/log/httpd/access_log",
        "request" => "/favicon.ico",
       "clientip" => "192.168.20.111",
    "httpversion" => "1.1",
          "bytes" => "288",
          "agent" => "\"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36\"",
           "verb" => "GET",
       "referrer" => "\"http://192.168.20.60/\"",
     "@timestamp" => 2018-04-25T03:26:26.000Z,
        "message" => "192.168.20.111 - - [25/Apr/2018:11:26:26 +0800] \"GET /favicon.ico HTTP/1.1\" 404 288 \"http://192.168.20.60/\" \"Mozilla/5.0 (Windows NT 6.1; Win64; x64) 
           "host" => "ELK",
          "ident" => "-",
      "timestamp" => "25/Apr/2018:11:26:26 +0800",
       "@version" => "1",
           "type" => "apache_access",
       "response" => "404",
           "auth" => "-"
}   

此示例使用类型字段标记所有事件,但实际上不分析错误或随机文件。有很多类型的错误日志,他们应该如何标记真正取决于你正在使用的日志。同样,可以使用条件将事件定向到特定的输出。 例如:

状态为5xx的任何apache事件的输出到监控平台、zabbix等监控平台
将任何4xx状态记录到Elasticsearch
通过statsd记录所有的状态码命中

要告诉监控平台任何具有5xx状态码的http事件,首先需要检查type字段的值。 如果是apache,那么可以检查状态字段是否包含5xx错误。 如果是,请将其发送给监控平台。 如果不是5xx错误,请检查状态字段是否包含4xx错误。 如果是的话,把它发送给Elasticsearch。 最后,无论状态字段包含什么,都将所有的apache状态码发送到statsd:

output {
  if [type] == "apache" {
    if [status] =~ /^5\d\d/ {
      nagios { ...  }
    } else if [status] =~ /^4\d\d/ {
      elasticsearch { ... }
    }
    statsd { increment => "apache.%{status}" }
  }
}   

处理syslog消息
系统日志是Logstash最常见的用例之一,它处理得非常好(只要日志行大致符合RFC3164)。Syslog是事实上的UNIX联网日志记录标准,可以将消息从客户机发送到本地文件,或通过rsyslog发送到集中式日志服务器。

input {
  tcp {
    port => 5000
    type => syslog
  }
  udp {
    port => 5000
    type => syslog
  }
}

filter {
  if [type] == "syslog" {
    grok {
      match => { "message" => "%{SYSLOGTIMESTAMP:syslog_timestamp} %{SYSLOGHOST:syslog_hostname} %{DATA:syslog_program}(?:\[%{POSINT:syslog_pid}\])?: %{GREEDYDATA:syslog_message}" }
      add_field => [ "received_at", "%{@timestamp}" ]
      add_field => [ "received_from", "%{host}" ]
    }
    date {
      match => [ "syslog_timestamp", "MMM  d HH:mm:ss", "MMM dd HH:mm:ss" ]
    }
  }
}

output {
  stdout { codec => rubydebug }
}

测试:客户端机器将连接到端口5000上的Logstash实例并发送其消息

telnet localhost 5000

官网示例:也可以直接input系统日志进行测试

Dec 23 12:11:43 louis postfix/smtpd[31499]: connect from unknown[95.75.93.154]
Dec 23 14:42:56 louis named[16000]: client 199.48.164.7#64817: query (cache) 'amsterdamboothuren.com/MX/IN' denied
Dec 23 14:30:01 louis CRON[619]: (www-data) CMD (php /usr/share/cacti/site/poller.php >/dev/null 2>/var/log/cacti/poller-error.log)
Dec 22 18:28:06 louis rsyslogd: [origin software="rsyslogd" swVersion="4.2.0" x-pid="2253" x-info="http://www.rsyslog.com"] rsyslogd was HUPed, type 'lightweight'.

输出:

{
    "syslog_timestamp" => "Dec 23 12:11:43",
     "syslog_hostname" => "louis",
          "@timestamp" => 2018-12-23T04:11:43.000Z,
      "syslog_message" => "connect from unknown[95.75.93.154]\r",
             "message" => "Dec 23 12:11:43 louis postfix/smtpd[31499]: connect from unknown[95.75.93.154]\r",
          "syslog_pid" => "31499",
                "host" => "localhost",
                "port" => 48141,
            "@version" => "1",
                "type" => "syslog",
      "syslog_program" => "postfix/smtpd",
       "received_from" => "localhost",
         "received_at" => "2018-04-25T05:01:19.688Z"
}   

4.多个管道

如果您需要在同一进程中运行多个管道,Logstash提供了一种通过名为pipelines.yml的配置文件来完成此操作的方法。 该文件必须放置在path.settings文件夹中,并遵循以下结构:

- pipeline.id: my-pipeline_1
  path.config: "/etc/path/to/p1.config"
  pipeline.workers: 3
- pipeline.id: my-other-pipeline
  path.config: "/etc/different/path/p2.cfg"
  queue.type: persisted 

该文件在YAML中格式化,并包含一个字典列表,其中每个字典描述一个管道,每个键/值对指定该管道的设置。该示例显示了由它们的ID和配置路径描述的两个不同的管道。对于第一个管道,pipeline.workers的值设置为3,而另一个则启用持续队列功能。 未在pipelines.yml文件中明确设置的设置的值将回退到logstash.yml设置文件中指定的默认值。
在不带参数的情况下启动Logstash时,它将读取pipelines.yml文件并实例化文件中指定的所有管道。 另一方面,当使用-e或-f时,Logstash会忽略pipelines.yml文件并记录警告。

注意事项:

如果当前的配置具有不共享相同inputs/filters and outputs并且使用标记和条件相互分离的事件流,则使用多个管道尤其有用。在单个实例中具有多个管道还允许这些事件流具有不同的性能和持久性参数(例如,different settings for pipeline workers and persistent queues)。这种分离意味着一个管道中的阻塞输出不会对另一个管道产生反压力。
也就是说,考虑到管道之间的资源竞争是重要的,因为默认值是针对单一管道进行调整的。 因此,例如,考虑减少每个管道使用的管道工的数量,因为每个管道默认使用每个CPU核心1个worker。
持久队列和死信队列在每个流水线上是隔离的,它们的位置由pipeline.id值隔开。

5. 重新加载配置文件

从Logstash 2.3开始,可以将Logstash设置为自动检测并重新加载配置更改。要启用自动配置重新加载,请使用指定的–config.reload.automatic(或-r)命令行选项启动Logstash。 例如:

bin/logstash -f apache.config --config.reload.automatic

默认情况下,Logstash每3秒检查一次配置更改。要更改此时间间隔,请使用–config.reload.interval <interval>选项,其中interval指定Logstash检查配置文件更改的频率。
如果Logstash已经在未启用自动重新加载的情况下运行,您可以强制Logstash重新加载配置文件,并通过向运行Logstash的进程发送SIGHUP(信号挂起)重新启动管道。例如:

kill -1 14175   #其中14175是运行Logstash的进程的ID。

6. 管理多行事件

多行编解码器是处理Logstash流水线中多行事件的首选工具。 多行编解码器使用一组简单的规则合并来自单个输入的行。如果正在使用支持多个主机的Logstash输入插件(如beats输入插件),则不应使用多行编解码器来处理多行事件。 这样做可能会导致混合的流和损坏的事件数据。 在这种情况下,您需要在将事件数据发送到Logstash之前处理多行事件。

  • 该pattern选项指定一个正则表达式。与指定的正则表达式匹配的行被认为是前一行的延续或新多行事件的开始。您可以使用grok正则表达式模板和该配置选项。
  • 该what选项有两个值:previous或next。该previous值指定与pattern选项中的值匹配的行是上一行的一部分。该next值指定与pattern选项中的值匹配的行是以下行的一部分。*该negate选项将多行编解码器应用于与pattern选项中指定的正则表达式不匹配的行。

多线编解码器配置示例

将Java堆栈跟踪组合成一个事件
将C风格的线条连续组合成一个单独的事件
结合时间戳事件的多行

Java stack traces:
Java堆栈跟踪由多行组成,每行以最后一行开头,如下例所示:

Exception in thread "main" java.lang.NullPointerException
        at com.example.myproject.Book.getTitle(Book.java:16)
        at com.example.myproject.Author.getBookTitles(Author.java:25)
        at com.example.myproject.Bootstrap.main(Bootstrap.java:14)

要将这些行整合到Logstash中的单个事件中,请对多行编解码器使用以下配置:

input {
  stdin {
    codec => multiline {
      pattern => "^\s"      #\s 匹配任意的空白符,将以空格开头的所有行合并到上一行
      what => "previous"
    }
  }
}   

线路延续:
几种编程语言使用行尾的\字符来表示该行继续,如下例所示:

printf ("%10.10ld  \t %10.10ld \t %s\
  %f", w, x, y, z );

要将这些行整合到Logstash中的单个事件中,请对多行编解码器使用以下配置:

input {
  stdin {
    codec => multiline {
      pattern => "\\$" #将以\字符结尾的任何行与以下行合并
      what => "next"
    }
  }
}

Timestamps(时间戳):
来自Elasticsearch等服务的活动日志通常以时间戳开始,然后是关于特定活动的信息,如下例所示:

[2015-08-24 11:49:14,389][INFO ][env                      ] [Letha] using [1] data paths, mounts [[/
(/dev/disk1)]], net usable_space [34.5gb], net total_space [118.9gb], types [hfs]

要将这些行整合到Logstash中的单个事件中,请对多行编解码器使用以下配置:

input {
  file {
    path => "/var/log/someapp.log"
    codec => multiline {
      pattern => "^%{TIMESTAMP_ISO8601} "
      negate => true        #使用negate选项来指定任何不以时间戳开头的行都属于previous。
      what => previous
    }
  }
}

7. 与消息队列集成

如果将消息队列技术作为现有基础架构的一部分,那么将这些数据存入Elastic Stack很容易。 对于正在使用Redis或RabbitMQ等外部队列层的现有用户来说,只是为了使用Logstash进行数据缓冲,建议使用Logstash持久队列而不是外部队列层。 通过消除摄取体系结构中不必要的复杂层次,这将有助于简化管理。

8. 常用插件

执行核心操作

  • date filter、 drop filter、 mutate filter …

反序列化数据

  • avro codec、csv filter、json codec、xml filter …

提取字段和Wrangling数据

  • dissect filter、kv filter、grok filter …

丰富的数据查找

  • dns filter、elasticsearch、geoip filter、jdbc_streaming、translate filter

date filter
从字段解析日期以用作事件的Logstash时间戳。以下配置解析名为logdate的字段以设置Logstash时间戳:

filter {
  date {
    match => [ "logdate", "MMM dd yyyy HH:mm:ss" ]
  }
}

drop filter
drops事件。该过滤器通常与条件结合使用。以下配置将删除调试级别的日志消息:

filter {
  if [loglevel] == "debug" {
    drop { }
  }
}

mutate filter
在字段上执行常规突变。 可以重命名,删除,替换和修改事件中的字段。以下配置将HOSTORIP字段重命名为client_ip:

filter {
  mutate {
    rename => { "HOSTORIP" => "client_ip" }
  }
}

avro codec
将序列化的Avro记录作为Logstash事件读取。 这个插件反序列化个别Avro记录。 这不适用于阅读Avro文件。 Avro文件具有必须在输入时处理的唯一格式。以下配置反序列化来自Kafka的输入:

input {
  kafka {
    codec => {
      avro => {
        schema_uri => "/tmp/schema.avsc"
      }
    }
  }
}
...

csv filter
将逗号分隔的值数据分析为单个字段。 默认情况下,筛选器自动生成字段名称(column1,column2等),或者可以指定一个名称列表。 您也可以更改列分隔符。以下配置将CSV数据分析为列字段中指定的字段名称:

filter {
  csv {
    separator => ","
    columns => [ "Transaction Number", "Date", "Description", "Amount Debit", "Amount Credit", "Balance" ]
  }
}

json codec
解码(通过输入)并编码(通过输出)JSON格式的内容,在JSON数组中为每个元素创建一个事件。以下配置解码文件中的JSON格式的内容:

input {
  file {
    path => "/path/to/myfile.json"
    codec =>"json"
}

xml filter
将XML解析为字段。以下配置解析存储在消息字段中的整个XML文档:

filter {
  xml {
    source => "message"
  }
}

dissect filter
使用分隔符将非结构化事件数据提取到字段中。 解剖过滤器不使用正则表达式,速度非常快。 但是,如果数据的结构因行而异,grok过滤器更合适。例如,假设日志中包含以下消息:

Apr 26 12:20:02 localhost systemd[1]: Starting system activity accounting tool...

以下配置解析消息:

filter {
  dissect {
    mapping => { "message" => "%{ts} %{+ts} %{+ts} %{src} %{prog}[%{pid}]: %{msg}" }
  }
}

解剖过滤器应用后,事件将被解剖到以下领域:

{
  "msg"        => "Starting system activity accounting tool...",
  "@timestamp" => 2017-04-26T19:33:39.257Z,
  "src"        => "localhost",
  "@version"   => "1",
  "host"       => "localhost.localdomain",
  "pid"        => "1",
  "message"    => "Apr 26 12:20:02 localhost systemd[1]: Starting system activity accounting tool...",
  "type"       => "stdin",
  "prog"       => "systemd",
  "ts"         => "Apr 26 12:20:02"
}

kv filter
解析键值对。例如,假设有一条包含以下键值对的日志消息:

ip=1.2.3.4 error=REFUSED

以下配置将键值对解析为字段:

filter {
  kv { }
}

应用过滤器后,示例中的事件将具有以下字段:

ip: 1.2.3.4
error: REFUSED

grok filter
将非结构化事件数据分析到字段中。 这个工具非常适用于系统日志,Apache和其他网络服务器日志,MySQL日志,以及通常为人类而不是计算机消耗的任何日志格式。

55.3.244.1 GET /index.html 15824 0.043

以下配置将消息解析为字段:

filter {
  grok {
    match => { "message" => "%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}" }
  }
}

应用过滤器后,示例中的事件将具有以下字段:

client: 55.3.244.1
method: GET
request: /index.html
bytes: 15824
duration: 0.043

dns filter
执行标准或反向DNS查找。以下配置对source_host字段中的地址执行反向查找,并将其替换为域名:

filter {
  dns {
    reverse => [ "source_host" ]
    action => "replace"
  }
}

elasticsearch
将Elasticsearch中以前的日志事件的字段复制到当前事件中。
以下配置显示了如何使用此过滤器的完整示例。 每当Logstash收到一个“end”事件时,它就会使用这个Elasticsearch过滤器来根据某个操作标识符来查找匹配的“start”事件。

if [type] == "end" {
         elasticsearch {
            hosts => ["es-server"]
            query => "type:start AND operation:%{[opid]}"
            fields => { "@timestamp" => "started" }
         }
         date {
            match => ["[started]", "ISO8601"]
            target => "[started]"
         }
         ruby {
            code => 'event.set("duration_hrs", (event.get("@timestamp") - event.get("started")) / 3600) rescue nil'
         }
      }

geoip filter
添加有关IP地址位置的地理信息。 例如:

filter {
  geoip {
    source => "clientip"
  }
}

jdbc_streaming
用数据库数据丰富事件。以下示例执行SQL查询并将结果集存储在名为country_details的字段中:

filter {
  jdbc_streaming {
    jdbc_driver_library => "/path/to/mysql-connector-java-5.1.34-bin.jar"
    jdbc_driver_class => "com.mysql.jdbc.Driver"
    jdbc_connection_string => "jdbc:mysql://localhost:3306/mydatabase"
    jdbc_user => "me"
    jdbc_password => "secret"
    statement => "select * from WORLD.COUNTRY WHERE Code = :code"
    parameters => { "code" => "country_code"}
    target => "country_details"
  }
}

translate filter
根据散列或文件中指定的替换值替换字段内容。 目前支持这些文件类型:YAML,JSON和CSV。以下示例采用response_code字段的值,将其翻译为基于字典中指定的值的描述,然后从事件中删除response_code字段:

filter {
  translate {
    field => "response_code"
    destination => "http_response"
    dictionary => {
      "200" => "OK"
      "403" => "Forbidden"
      "404" => "Not Found"
      "408" => "Request Timeout"
    }
    remove_field => "response_code"
  }
}

参考:

http://www.51niux.com/?id=205
https://www.elastic.co/guide/en/logstash/6.x/index.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值