logstash filter 过滤器详解

一、grok 正则捕获插件

grok是一个十分强大的logstash filter插件,他可以通过正则解析任意文本,将非结构化日志数据解析成结构化和方便查询的结构。是目前logstash 中解析非结构化日志数据最好的方式。

grok语法规则:

%{匹配模式类型:自定义标签名}

grok内置字段模式类型:

USERNAME [a-zA-Z0-9._-]+
USER %{USERNAME}
EMAILLOCALPART [a-zA-Z][a-zA-Z0-9_.+-=:]+
EMAILADDRESS %{EMAILLOCALPART}@%{HOSTNAME}
INT (?:[+-]?(?:[0-9]+))
BASE10NUM (?<![0-9.+-])(?>[+-]?(?:(?:[0-9]+(?:\.[0-9]+)?)|(?:\.[0-9]+)))
NUMBER (?:%{BASE10NUM})
BASE16NUM (?<![0-9A-Fa-f])(?:[+-]?(?:0x)?(?:[0-9A-Fa-f]+))
BASE16FLOAT \b(?<![0-9A-Fa-f.])(?:[+-]?(?:0x)?(?:(?:[0-9A-Fa-f]+(?:\.[0-9A-Fa-f]*)?)|(?:\.[0-9A-Fa-f]+)))\b

POSINT \b(?:[1-9][0-9]*)\b
NONNEGINT \b(?:[0-9]+)\b
WORD \b\w+\b
NOTSPACE \S+
SPACE \s*
DATA .*?
GREEDYDATA .*
QUOTEDSTRING (?>(?<!\\)(?>"(?>\\.|[^\\"]+)+"|""|(?>'(?>\\.|[^\\']+)+')|''|(?>`(?>\\.|[^\\`]+)+`)|``))
UUID [A-Fa-f0-9]{8}-(?:[A-Fa-f0-9]{4}-){3}[A-Fa-f0-9]{12}
# URN, allowing use of RFC 2141 section 2.3 reserved characters
URN urn:[0-9A-Za-z][0-9A-Za-z-]{0,31}:(?:%[0-9a-fA-F]{2}|[0-9A-Za-z()+,.:=@;$_!*'/?#-])+

# Networking
MAC (?:%{CISCOMAC}|%{WINDOWSMAC}|%{COMMONMAC})
CISCOMAC (?:(?:[A-Fa-f0-9]{4}\.){2}[A-Fa-f0-9]{4})
WINDOWSMAC (?:(?:[A-Fa-f0-9]{2}-){5}[A-Fa-f0-9]{2})
COMMONMAC (?:(?:[A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2})
IPV6 ((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?
IPV4 (?<![0-9])(?:(?:[0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])[.](?:[0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])[.](?:[0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])[.](?:[0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5]))(?![0-9])
IP (?:%{IPV6}|%{IPV4})
HOSTNAME \b(?:[0-9A-Za-z][0-9A-Za-z-]{0,62})(?:\.(?:[0-9A-Za-z][0-9A-Za-z-]{0,62}))*(\.?|\b)
IPORHOST (?:%{IP}|%{HOSTNAME})
HOSTPORT %{IPORHOST}:%{POSINT}

# paths
PATH (?:%{UNIXPATH}|%{WINPATH})
UNIXPATH (/([\w_%!$@:.,+~-]+|\\.)*)+
TTY (?:/dev/(pts|tty([pq])?)(\w+)?/?(?:[0-9]+))
WINPATH (?>[A-Za-z]+:|\\)(?:\\[^\\?*]*)+
URIPROTO [A-Za-z]([A-Za-z0-9+\-.]+)+
URIHOST %{IPORHOST}(?::%{POSINT:port})?
# uripath comes loosely from RFC1738, but mostly from what Firefox
# doesn't turn into %XX
URIPATH (?:/[A-Za-z0-9$.+!*'(){},~:;=@#%&_\-]*)+
#URIPARAM \?(?:[A-Za-z0-9]+(?:=(?:[^&]*))?(?:&(?:[A-Za-z0-9]+(?:=(?:[^&]*))?)?)*)?
URIPARAM \?[A-Za-z0-9$.+!*'|(){},~@#%&/=:;_?\-\[\]<>]*
URIPATHPARAM %{URIPATH}(?:%{URIPARAM})?
URI %{URIPROTO}://(?:%{USER}(?::[^@]*)?@)?(?:%{URIHOST})?(?:%{URIPATHPARAM})?

# Months: January, Feb, 3, 03, 12, December
MONTH \b(?:[Jj]an(?:uary|uar)?|[Ff]eb(?:ruary|ruar)?|[Mm](?:a|ä)?r(?:ch|z)?|[Aa]pr(?:il)?|[Mm]a(?:y|i)?|[Jj]un(?:e|i)?|[Jj]ul(?:y)?|[Aa]ug(?:ust)?|[Ss]ep(?:tember)?|[Oo](?:c|k)?t(?:ober)?|[Nn]ov(?:ember)?|[Dd]e(?:c|z)(?:ember)?)\b
MONTHNUM (?:0?[1-9]|1[0-2])
MONTHNUM2 (?:0[1-9]|1[0-2])
MONTHDAY (?:(?:0[1-9])|(?:[12][0-9])|(?:3[01])|[1-9])

# Days: Monday, Tue, Thu, etc...
DAY (?:Mon(?:day)?|Tue(?:sday)?|Wed(?:nesday)?|Thu(?:rsday)?|Fri(?:day)?|Sat(?:urday)?|Sun(?:day)?)

# Years?
YEAR (?>\d\d){1,2}
HOUR (?:2[0123]|[01]?[0-9])
MINUTE (?:[0-5][0-9])
# '60' is a leap second in most time standards and thus is valid.
SECOND (?:(?:[0-5]?[0-9]|60)(?:[:.,][0-9]+)?)
TIME (?!<[0-9])%{HOUR}:%{MINUTE}(?::%{SECOND})(?![0-9])
# datestamp is YYYY/MM/DD-HH:MM:SS.UUUU (or something like it)
DATE_US %{MONTHNUM}[/-]%{MONTHDAY}[/-]%{YEAR}
DATE_EU %{MONTHDAY}[./-]%{MONTHNUM}[./-]%{YEAR}
ISO8601_TIMEZONE (?:Z|[+-]%{HOUR}(?::?%{MINUTE}))
ISO8601_SECOND (?:%{SECOND}|60)
TIMESTAMP_ISO8601 %{YEAR}-%{MONTHNUM}-%{MONTHDAY}[T ]%{HOUR}:?%{MINUTE}(?::?%{SECOND})?%{ISO8601_TIMEZONE}?
DATE %{DATE_US}|%{DATE_EU}
DATESTAMP %{DATE}[- ]%{TIME}
TZ (?:[APMCE][SD]T|UTC)
DATESTAMP_RFC822 %{DAY} %{MONTH} %{MONTHDAY} %{YEAR} %{TIME} %{TZ}
DATESTAMP_RFC2822 %{DAY}, %{MONTHDAY} %{MONTH} %{YEAR} %{TIME} %{ISO8601_TIMEZONE}
DATESTAMP_OTHER %{DAY} %{MONTH} %{MONTHDAY} %{TIME} %{TZ} %{YEAR}
DATESTAMP_EVENTLOG %{YEAR}%{MONTHNUM2}%{MONTHDAY}%{HOUR}%{MINUTE}%{SECOND}

# Syslog Dates: Month Day HH:MM:SS
SYSLOGTIMESTAMP %{MONTH} +%{MONTHDAY} %{TIME}
PROG [\x21-\x5a\x5c\x5e-\x7e]+
SYSLOGPROG %{PROG:program}(?:\[%{POSINT:pid}\])?
SYSLOGHOST %{IPORHOST}
SYSLOGFACILITY <%{NONNEGINT:facility}.%{NONNEGINT:priority}>
HTTPDATE %{MONTHDAY}/%{MONTH}/%{YEAR}:%{TIME} %{INT}

# Shortcuts
QS %{QUOTEDSTRING}

# Log formats
SYSLOGBASE %{SYSLOGTIMESTAMP:timestamp} (?:%{SYSLOGFACILITY} )?%{SYSLOGHOST:logsource} %{SYSLOGPROG}:

# Log Levels
LOGLEVEL ([Aa]lert|ALERT|[Tt]race|TRACE|[Dd]ebug|DEBUG|[Nn]otice|NOTICE|[Ii]nfo|INFO|[Ww]arn?(?:ing)?|WARN?(?:ING)?|[Ee]rr?(?:or)?|ERR?(?:OR)?|[Cc]rit?(?:ical)?|CRIT?(?:ICAL)?|[Ff]atal|FATAL|[Ss]evere|SEVERE|EMERG(?:ENCY)?|[Ee]merg(?:ency)?)

内置的字段模式,可见 logstash 中的 grok-patterns

{logstash to path}/vendor/bundle/jruby/2.5.0/gems/logstash-patterns-core-4.1.2/patterns/grok-patterns

也可以使用自定义正则:

修改 logstash 中的 grok-patterns 文件,在文件末尾添加自定义规则(注意名字不能和已存在的重复),然后重启服务生效。

如:

# 自定义正则
URL (http(s)?:\/\/)?%{URIHOST:domain_name}%{URIPATH}

二、grok 实战

2.1、过滤IP

创建 t1.conf

input {
    stdin {
    }
}
filter{
    grok{
        match => {"message" => "%{IPV4:ip}"}
    }
}
output {
    stdout {
    }
}

启动脚本

/opt/logstash-6.8.23/bin/logstash -f /opt/logstash/config/t1.conf --path.data=/data/logstash/data/t1

启动完成,输入数据:

172.16.213.132 [07/Feb/2018:16:24:19 +0800] "GET /HTTP/1.1" 403 5039

 2.2、过滤时间戳

创建 t1.conf

input {
    stdin {
    }
}
filter{
    grok{
        match => {"message" => "%{IPV4:ip}\ \[%{HTTPDATE:timestamp}\]"}
    }
}
output {
    stdout {
    }
}

注意:

日志中的空格、双引号、单引号、中括号等,需要用 \ 进行转义

启动脚本

/opt/logstash-6.8.23/bin/logstash -f /opt/logstash/config/t1.conf --path.data=/data/logstash/data/t1

启动完成,输入数据:

172.16.213.132 [07/Feb/2018:16:24:19 +0800] "GET /HTTP/1.1" 403 5039

 2.3、过滤报文头信息

创建 t1.conf

input {
    stdin {
    }
}
filter{
    grok{
        match => {"message" => "\ %{QS:referrer}\ "}
    }
}
output {
    stdout {
    }
}

启动脚本

/opt/logstash-6.8.23/bin/logstash -f /opt/logstash/config/t1.conf --path.data=/data/logstash/data/t1

启动完成,输入数据:

172.16.213.132 [07/Feb/2018:16:24:19 +0800] "GET /HTTP/1.1" 403 5039

 三、date 插件

date过滤器用于解析字段中的日期,然后使用该日期或时间戳作为事件的logstash时间戳。

例如,syslog事件通常有这样的时间戳:

"Apr 17 09:32:01"

你应该使用 MMM dd HH:mm:ss 的日期格式来解析这个。

日期过滤器对于事件的排序和对旧数据的回填特别重要,如果在你的事件中没有得到正确的日期,那么以后搜索它们可能会出现顺序不对。

如果没有这个过滤器,logstash将根据第一次得到事件(在输入时)的时间(如果时间戳还没有在事件中设置)选择一个时间戳,例如,对于文件输入,时间戳被设置为每次读取的时间。

日期格式说明

date 过滤器配置选项

设置输入类型要求
localestringNo
matcharrayNo
tag_on_failurearrayNo
targetstringNo
timezonestringNo

四、date 实战

在上面我们有个例子是讲解timestamp字段,表示取出日志中的时间。但是在显示的时候除了显示你指定的timestamp外,还有一行是@timestamp信息,这两个时间是不一样的,@timestamp表示系统当前时间。两个时间并不是一回事,在ELK的日志处理系统中,@timestamp字段会被elasticsearch用到,用来标注日志的生产时间,如此一来,日志生成时间就会发生混乱,要解决这个问题,需要用到另一个插件,即date插件,这个时间插件用来转换日志记录中的时间字符串,变成Logstash::Timestamp对象,然后转存到@timestamp字段里面。

创建 t1.conf

input {
    stdin {
    }
}
filter{
     grok{
          match => {"message" => "\ \[%{HTTPDATE:timestamp}\]"}
     }
     date{
          match => ["timestamp","dd/MMM/yyyy:HH:mm:ss Z"]
     }
}
output {
    stdout {
    }
}

启动脚本

/opt/logstash-6.8.23/bin/logstash -f /opt/logstash/config/t1.conf --path.data=/data/logstash/data/t1

启动完成,输入数据:

172.16.213.132 [07/Feb/2018:16:24:19 +0800] "GET /HTTP/1.1" 403 5039

 五、数据修改 mutate 插件

mutate插件是logstash另一个非常重要的插件,它提供了丰富的基础类型数据处理能力,包括重命名、删除、替换、修改日志事件中的字段。我们这里举几个常用的mutate插件:字段类型转换功能covert、正则表达式替换字段功能gsub、分隔符分隔字符串为数值功能split、重命名字段功能rename、删除字段功能remove_field 等

  • add_field 增加字段
  • remove_field 删除字段
  • rename_field 重命名字段
  • replace 修改字段的值(可以调用其他字段)
  • update 修改字段的值(不可以调用其他字段)
  • convert 字段类型转换
  • copy 复制一个字段
  • lowercase 值转小写
  • uppercase 值转大写
  • split 字段分割
  • strip 去掉末尾空格
  • gsub 正则替换,只对字符串类型有效

六、geoip 地址查询

geoip是常见的免费的IP地址归类查询库,geoip可以根据IP地址提供对应的地域信息,包括国别,省市,经纬度等等,此插件对于可视化地图和区域统计非常有用。

七、geoip 实战

创建 t1.conf

input {
    stdin {
    }
}
filter{
    grok {
        match => ["message","%{IP:ip}"]
        remove_field => ["message"]
    }
    geoip {
        source => ["ip"]
    }
}
output {
    stdout {
    }
}

启动脚本

/opt/logstash-6.8.23/bin/logstash -f /opt/logstash/config/t1.conf --path.data=/data/logstash/data/t1

启动完成,输入数据:

112.156.245.15 [07/Feb/2018:16:24:19 +0800] "GET /HTTP/1.1" 403 5039

上面的结果输出了很多信息,我们对结果进行选择性的输出

创建 t1.conf

input {
    stdin {
    }
}
filter{
    grok {
        match => ["message","%{IP:ip}"]
        remove_field => ["message"]
    }
    geoip {
        source => ["ip"]
    }
}
output {
    stdout {
    }
}

启动脚本

/opt/logstash-6.8.23/bin/logstash -f /opt/logstash/config/t1.conf --path.data=/data/logstash/data/t1

启动完成,输入数据:

112.156.245.15 [07/Feb/2018:16:24:19 +0800] "GET /HTTP/1.1" 403 5039

 八、filter 插件综合应用

创建 t1.conf

input {
    stdin {
    }
}
filter{
    grok {
        match => ["message","%{IPORHOST:client_ip}\ \[%{HTTPDATE:timestamp}\]\ %{QS:referrer}\ %{NUMBER:status}\ %{NUMBER:bytes}\ \"-\"\ \"%{DATA:browser_info}\ %{GREEDYDATA:extra_info}\"\ \"-\""]
    }
    geoip {
        source => ["client_ip"]
        target => ["geoip"]
        fields => ["city_name","region_name","country_name","ip"]
    }
    date {
        match => ["timestamp","dd/MMM/yyyy:HH:mm:ss Z"]
    }
    mutate {
        remove_field => ["message","timestamp"]
    }
}
output {
    stdout {
    }
}

启动脚本

/opt/logstash-6.8.23/bin/logstash -f /opt/logstash/config/t1.conf --path.data=/data/logstash/data/t1

启动完成,输入数据:

112.156.245.15 [20/Feb/2018:12:12:14 +0800] "GET / HTTP/1.1" 200 190 "-" "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Mobile Safari/537.36" "-"

 注意:

在匹配信息的时候,GREEDYDATA 与 DATA 匹配的机制是不一样的,GREEDYDATA 是贪婪模式,而 DATA 则是能少匹配一点就少匹配一点。

  • 8
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Grok过滤器Logstash中一种用于解析和匹配日志消息的工具。它使用正则表达式来匹配文本模式,并将匹配的值存储在新字段中。然而,当模式不匹配时,Grok过滤器可能会遇到性能问题。为了解决这个问题,可以考虑改用基于分隔符的Dissect过滤器,它比基于正则表达式的过滤器更容易编写和使用。不幸的是,目前还没有针对此的应用程序。要使用Grok过滤器,可以在配置文件中指定字段名称和匹配模式,如: ``` filter { grok { match => [ "message", "%{USERNAME:user}" ] } } ``` 这将从"message"字段中提取匹配的用户名,并将其存储在新的"user"字段中。另一方面,如果想在Logstash中改变应用程序的日志记录模式,可能会增加直接日志读取的困难。在这种情况下,可以考虑使用Logstash的Dissect过滤器,并进行相应的配置。一个可能的配置示例如下: ``` filter { dissect { mapping => { "message" => ... } } mutate { strip => [ "log", "class" ] } } ``` 这个配置将使用Dissect过滤器根据指定的映射将日志消息拆分成多个字段,并通过mutate过滤器删除不需要的字段,例如"log"和"class"。综上所述,Grok过滤器Logstash中用于解析和匹配日志消息的一种工具,而Dissect过滤器则是一种更简单易用的基于分隔符的过滤器。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Logstash:如何使用 Logstash Grok 过滤器提取模式](https://blog.csdn.net/UbuntuTouch/article/details/107512971)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

magic_kid_2010

你的支持将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值