写在前面:logstash的插件有很多,即使filter的插件也有很多,因为生产马上要实践了,这边做一个归类总结
学习来源:官方文档
基本说明
官方的文档里面,主要讲了以下几个filter的作用。
首先,filter的定义是为了即时解析和转换您的数据
当数据从源传输到存储时,Logstash过滤器会解析每个事件,识别命名字段以构建结构,并将它们转换为汇聚在通用格式上,以便更轻松,更快速地进行分析和业务价值。
这边把他总结成下面四点
- 1.使用grok从非结构化数据中导出结构
- 2.从IP地址解密地理坐标
- 3.匿名化PII数据,完全排除敏感字段
- 4.简化整体处理,独立于数据源,格式或模式。
这边讲一下GROK,GEO IP,FINGERPRINT,DATE
这四个插件。
备注:以下说明大部分都为翻译,如有出错,敬请见谅
一、GROK
1.描述
Grok是一种很好的解析文本并构造它方法,它可以将非结构化日志数据解析为结构化和可查询的内容。
此工具非常适用于syslog日志,apache和其他Web服务器日志,mysql日志,以及通常为人类而非计算机使用而编写的任何日志格式。
Logstash默认提供约120种模式(解析日志的规则)。你可以在这里找到它们:https://github.com/logstash-plugins/logstash-patterns-core/tree/master/patterns。你可以轻松添加自己的。(见patterns_dir设定)
重要辅助工具: debug
2.基础知识
语法
grok模式的语法是 %{SYNTAX:SEMANTIC}
这SYNTAX是与您的文本匹配的模式的名称。例如,3.44将与NUMBER模式匹配,55.3.244.1将与IP模式匹配。
这SEMANTIC是您为匹配的文本提供的标识符。例如,3.44可能是事件的持续时间,因此您可以简单地调用它duration。此外,字符串55.3.244.1可以标识client 发出请求。
对于上面的示例,您的grok过滤器看起来像这样:
%{NUMBER:duration}%{IP:client}
默认情况下,所有语义都保存为字符串。如果您希望转换语义的数据类型,例如将字符串更改为整数,则使用目标数据类型将其后缀。例如%{NUMBER:num:int}
,它将num语义从字符串转换为整数。目前唯一支持的转化是int
和float
。
示例
通过语法和语义的概念,我们可以从示例日志中提取有用的字段,如虚构的http请求日志:
55.3.244.1 GET /index.html 15824 0.043
这种模式可能是:
%{IP:client}%{WORD:method}%{URIPATHPARAM:request}%{NUMBER:bytes}%{NUMBER:duration}
详细点的logstash的配置就是
input {
file {
path => "/var/log/http.log"
}
}
filter {
grok {
match => { "message" => "%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}" }
}
}
在grok过滤器之后,该事件将包含一些额外的字段:
- client: 55.3.244.1
- method: GET
- request: /index.html
- bytes: 15824
- duration: 0.043
3.正则表达式
首先,Grok位于正则表达式之上,因此任何正则表达式在grok中也是有效的。
正则表达式库是Oniguruma,您可以在Oniguruma站点上看到完整支持的regexp语法。
自定义模式
有时logstash没有您需要的模式。为此,您有几个选择。
1.首先,您可以使用Oniguruma语法进行命名捕获,它可以匹配一段文本并将其保存为字段:
(?<field_name>the pattern here)
例如,后缀日志具有queue id10或11个字符的十六进制值。我可以像这样轻松捕获:
(?<queue_id>[0-9A-F]{10,11})
2.或者,您可以创建自定义模式文件
- 创建一个名为patterns其中调用文件的目录extra (文件名无关紧要,但为自己命名有意义)
- 在该文件中,将您需要的模式写为模式名称,空格,然后是该模式的正则表达式。
例如:执行上面的postfix queue id示例
# contents of ./patterns/postfix:
POSTFIX_QUEUEID [0-9A-F]{10,11}
然后使用patterns_dir此插件中的设置告诉logstash您的自定义模式目录所在的位置。这是一个包含示例日志的完整示例:
Jan 1 06:25:43 mailserver14 postfix/cleanup[21403]: BEF25A72965: message-id=<20130101142543.5828399CCAF@mailserver14.example.com>
filter {
grok {
patterns_dir => ["./patterns"]
match => { "message" => "%{SYSLOGBASE} %{POSTFIX_QUEUEID:queue_id}: %{GREEDYDATA:syslog_message}" }
}
}
以上将匹配并导致以下字段:
- timestamp: Jan 1 06:25:43
- logsource: mailserver14
- program: postfix/cleanup
- pid: 21403
- queue_id: BEF25A72965
- syslog_message: message-id=<[email protected]>
timestamp,logsource,program
,和pid
字段来自 SYSLOGBASE其本身由其它模式确定定的模式。
另一种选择是使用过滤器定义内联模式pattern_definitions
。这主要是为了方便起见,并允许用户定义一个可以在该过滤器中使用的模式。这个新定义的模式pattern_definitions
将不会在该特定grok过滤器之外可用。
4.GROK配置选项
break_on_match
- 值类型是boolean
- 默认值是 true
打破第一次的匹配。grok的第一次成功匹配将导致过滤器完成。如果你想让grok尝试所有模式(也许你正在解析不同的东西),那么将其设置为false。
keep_empty_captures
- 值类型是boolean
- 默认值是 false
如果true,将empty捕获保留为事件字段。
match
- 值类型是hash
- 默认值是 {}
字段⇒值的匹配hash
例如:
filter {
grok { match => { "message" => "Duration: %{NUMBER:duration}" } }
}
如果需要将多个模式与单个字段匹配,则该值可以是模式数组
filter {
grok { match => { "message" => [ "Duration: %{NUMBER:duration}", "Speed: %{NUMBER:speed}" ] } }
}
named_captures_only
- 值类型是boolean
- 默认值是 true
如果true,只存储来自grok的名为capture的存储。
overwrite
- 值类型是array
- 默认值是 []
要覆盖的字段。
这允许您覆盖已存在的字段中的值。
例如,如果syslog行在message域内,则可以使用部分匹配覆盖message字段,如下所示:
filter {
grok {
match => {“message”=>“%{SYSLOGBASE}%{DATA:message}”}
overwrite => [“message”]
}
}
在这种情况下,类似的May 29 16:37:11 sadness logger: hello world
行将被解析hello world
并将覆盖原始消息。
pattern_definitions
- 值类型是hash
- 默认值是 {}
模式名称和模式元组的hash,用于定义当前过滤器使用的自定义模式。匹配现有名称的模式将覆盖预先存在的定义。可以将此视为可用于grok定义的内联模式。
patterns_dir
- 值类型是array
- 默认值是 []
Logstash默认带有一堆模式,因此除非您要添加其他模式,否则您不一定需要自己定义。
您可以使用此设置指向多个模式目录。请注意,Grok将读取与patterns_files_glob
匹配的目录中的所有文件,并假设它是一个模式文件(包括任何代字号备份文件)。
patterns_dir => ["/opt/logstash/patterns", "/opt/logstash/extra_patterns"]
模式文件是纯文本格式:
NAME PATTERN
例如:NUMBER \d+
创建管道(pipeline)时会加载模式。
patterns_files_glob
- 值类型是string
- 默认值是 “*”
Glob模式,用于选择patterns_dir指定的目录中的模式文件
tag_on_failure
- 值类型是array
- 默认值是 [“_grokparsefailure”]
tags没有成功匹配时,将值附加到字段
tag_on_timeout
- 值类型是字符串
- 默认值是 “_groktimeout”
如果grok regexp超时,则应用标记。
timeout_millis
- 值类型是number
- 默认值是 30000
在这段时间后尝试终止正则表达式。如果应用了多个模式,这适用于每个模式。
这将永远不会提前超时,但可能需要更长时间才能超时。实际超时是基于250ms量化的近似值。
设置为0可禁用超时
logstash grok 自测实例+常用正则(grok-patterns)
二、GEO IP
1.描述
GeoIP过滤器根据Maxmind GeoLite2数据库中的数据添加有关IP地址的地理位置的信息。
此插件与GeoLite2 City数据库捆绑在一起。从Maxmind的描述 —— “GeoLite2数据库是免费的IP地理定位数据库,与MaxMind的GeoIP2数据库相当,但不太准确”。有关详细信息,请参阅GeoIP Lite2许可证。
如果您需要使用捆绑的GeoLite2 City以外的数据库,可以直接从Maxmind的网站下载它们并使用该database选项指定它们的位置。GeoLite2数据库可以从这里下载。
如果您想获得自治系统编号(ASN)信息,可以使用GeoLite2-ASN数据库。
细节
[geoip][location]
如果GeoIP查找返回纬度和经度,则会创建一个字段。该字段以GeoJSON格式存储 。此外,随elasticsearch输出提供的默认Elasticsearch模板 将该[geoip][location]
字段映射到Elasticsearch geo_point
。
由于此字段是一个geo_point 并且它仍然是有效的GeoJSON,因此您可以获得Elasticsearch的地理空间查询,构面和过滤器函数以及将GeoJSON用于所有其他应用程序(如Kibana的地图可视化)的灵活性。
2.Geoip过滤器配置选项
cache_size
- 值类型是number
- 默认值是 1000
GeoIP查找非常昂贵。此过滤器使用缓存来利用IP代理经常在日志文件中彼此相邻并且很少具有随机分布的事实。设置得越高,项目在缓存中的可能性就越大,此过滤器的运行速度就越快。但是,如果将此设置得太高,则可以使用比预期更多的内存。由于Geoip API升级到v2,到目前为止还没有任何驱逐策略,如果缓存已满,则不能再添加记录。尝试使用此选项的不同值来查找数据集的最佳性能。
这必须设置为> 0的值。没有理由不想要这种行为,开销很小,速度增益很大。
值得注意的是,此配置值对于geoip_type是全局的。也就是说,相同geoip_type的geoip过滤器的所有实例共享相同的高速缓存。最后声明的缓存大小将获胜。这样做的原因是,在管道中的不同点处为不同实例提供多个高速缓存没有任何好处,这只会增加高速缓存未命中数和浪费内存。
database
- 值类型是 path
- 此设置没有默认值。
Logstash应该使用的Maxmind数据库文件的路径。默认数据库GeoLite2-City. GeoLite2-City, GeoLite2-Country, GeoLite2-ASN
,这些是受免费的数据库Maxmind支持。GeoIP2-City,GeoIP2-ISP,GeoIP2-Country
是Maxmind支持的商业数据库。
如果未指定,则默认为Logstash附带的GeoLite2 City数据库。
default_database_type
该插件现在包括GeoLite2-City和GeoLite2-ASN数据库。如果database和default_database_type未设置,将选择GeoLite2-City数据库。要使用包含的GeoLite2-ASN数据库,请设置default_database_type
为ASN。
- 值类型是string
- 默认值为 City
- 唯一可接受的值是City和ASN
fields
- 值类型是array
- 此设置没有默认值。
要包含在事件中的一组geoip字段。
可能的字段取决于数据库类型。默认情况下,所有geoip字段都包含在事件中。
对于内置GeoLite2市数据库,以下是可供选择:city_name,continent_code,country_code2,country_code3,country_name, dma_code,ip,latitude,longitude,postal_code,region_name和timezone
。
source
- 这是必需的设置。
- 值类型是string
- 此设置没有默认值。
包含要通过geoip映射的IP地址或主机名的字段。如果此字段是数组,则仅使用第一个值。
tag_on_failure
- 值类型是array
- 默认值是 [“_geoip_lookup_failure”]
在未能查找地理信息时标记事件。这可以在以后的分析中使用。
target
- 值类型是string
- 默认值是 “geoip”
指定Logstash应存储geoip数据的字段。这可能很有用,例如,如果您有src_ip
和dst_ip
字段并且想要两个IP的GeoIP信息。
如果将数据保存到Elasticsearch 以外的目标字段geoip并希望使用 geo_point相关函数,则需要更改Elasticsearch输出提供的模板并配置输出以使用新模板。
即使您不使用geo_point
映射,该[target][location]
字段仍然是有效的GeoJSON。
三、FINGERPRINT
1.描述
创建一个或多个字段的一致hash(fingerprints)并将结果存储在新字段中。
这可以用于在将事件插入Elasticsearch时创建一致的文档ID,允许Logstash中的事件导致更新现有文档而不是创建新文档。
1.当使用除了UUID, PUNCTUATION or MURMUR3 以外的方法时,必须设置key,否则插件将引发异常
2.当该target选项设置为UUID结果时,将不是一致的hash,而是随机的 UUID。要生成UUID,请选择uuid过滤器(filter)。
2.FINGERPRINT配置选项
base64encode
- 值类型是boolean
- 默认值是 false
当设置为true中,SHA1,SHA256,SHA384,SHA512和MD5 fingerprint 方法将产生base64编码字符串,而不是十六进制编码。
concatenate_sources
- 值类型是boolean
- 默认值是 false
当设置为true,并且方法不是UUID或者PUNCTUATION时,插件会在执行fingerprint 计算之前将选项中给出的所有字段的名称和值连接 成一个字符串(如旧的校验和过滤器)。
如果false给定多个源字段,则目标字段将是具有给定源字段的fingerprint 的数组。
key
- 值类型是string
- 此设置没有默认值。
与IPV4_NETWORK方法一起使用时,请填写子网前缀长度。key是需要与除MURMUR3,PUNCTUATION或UUID以外的所有方法 。使用其他方法填写HMAC密钥。
method
- 这是必需的设置。
- 值可以是任何的:
SHA1,SHA256,SHA384,SHA512,MD5,MURMUR3,IPV4_NETWORK,UUID,PUNCTUATION
- 默认值是
"SHA1"
要使用的fingerprint 方法。
如果设置为SHA1,SHA256,SHA384,SHA512,或MD5
具有相同名称的加密keyed-hash函数将被用来生成fingerprint 。如果设置MURMUR3
为非加密MurmurHash函数将被使用。
如果设置为IPV4_NETWORK
,输入数据需要是IPv4地址,hash值将使用key选项中指定的位数作为屏蔽输出地址。例如,如果输入“1.2.3.4”并key设置为16,则hash变为“1.2.0.0”。
如果设置为PUNCTUATION
,则将从输入字符串中删除所有非标点字符。
如果设置为UUID
, 则将生成UUID
。结果将是随机的,因此不是一致的hash。
source
- 值类型是array
- 默认值是 “message”
源字段的名称,其内容将用于创建fingerprint 。如果给出了数组,请参阅concatenate_sources
选项。
target
- 值类型是string
- 默认值是 “fingerprint”
将存储生成的fingerprint的字段的名称。该字段的任何当前内容都将被覆盖。
四、DATE
1.描述
日期筛选器用于解析字段中的日期,然后使用该日期或时间戳作为事件的logstash时间戳。
例如,syslog事件通常有这样的时间戳:"Apr 17 09:32:01"
您可以使用日期格式MMM dd HH:mm:ss
来解析它。
日期过滤器对于排序事件和回填旧数据尤其重要。如果您未在事件中获得正确的日期,那么稍后搜索它们可能会排序不正常。
如果没有此过滤器,logstash将根据第一次看到事件(在输入时),如果事件中尚未设置时间戳,则选择时间戳。例如,对于文件输入,时间戳设置为每次读取的时间。
2.date过滤器配置选项
locale
- 值类型是string
- 此设置没有默认值。
使用IETF-BCP47
或POSIX
语言标记指定用于日期解析的语言环境。简单的例子是BCP47
的en,en-US
,POSIX
的en_US
。
区域设置主要用于解析月份名称(带有模式MMM)和工作日名称(带有模式EEE)。
如果未指定,将使用平台默认值,但对于非英语平台默认,英语解析器也将用作回退机制。
match
- 值类型是array
- 默认值是 []
首先是字段名称的数组,然后是格式模式, [ field, formats… ]
如果您的时间字段有多种可能的格式,您可以这样做:
match => [ "logdate", "MMM dd yyyy HH:mm:ss",
"MMM d yyyy HH:mm:ss", "ISO8601" ]
以上将匹配syslog(rfc3164)
或iso8601
时间戳。
有一些特殊例外。以下存在的格式帮助您节省时间并确保日期解析的正确性。
- ISO8601 - 应解析任何有效的ISO8601时间戳,例如 2011-04-19T03:44:01.103Z
- UNIX- 将解析浮点数或int值表示unix时间,以秒为单位,如1326149001.132以及1326149001
- UNIX_MS- 将解析表示unix时间的int值,以及自1337125117000之后的纪元以毫秒为单位
- TAI64N - 将解析tai64n时间值
例如,如果您有一个logdate具有类似值的字段,则 Aug 13 2010 00:03:44
可以使用此配置:
filter {
date {
match => [ "logdate", "MMM dd yyyy HH:mm:ss" ]
}
}
有关语法的更多详细信息(待补充)
tag_on_failure
- 值类型是array
- 默认值是 [“_dateparsefailure”]
没有成功匹配时,将值附加到tags
target
- 值类型是string
- 默认值是 “@timestamp”
将匹配的时间戳存储到给定的目标字段中。如果未提供,则默认更新@timestamp事件的字段
timezone
- 值类型是string
- 此设置没有默认值。
指定时区规范ID用于日期解析。有效的ID罗列在Joda.org可用时区页面上。如果无法从值中提取时区,并且不是平台默认值,则此选项非常有用。如果未指定,则将使用平台默认值。
Canonical ID很好,因为它可以为您节省夏令时。例如,America/Los_Angeles
或者Europe/Paris
是有效的ID。该字段可以是动态的,并包含使用%{field}
的事件的一部分
五、常用选项
包括以上所讲的,所有过滤器插件都支持以下配置选项(以下配置以date为例子)。
add_field
- 值类型是hash
- 默认值是 {}
如果此过滤器成功,请向此事件添加任意字段。字段名称可以是动态的,并包含使用%{field}事件的部分。
例子:
filter {
date {
add_field => { "foo_%{somefield}" => "Hello world, from %{host}" }
}
}
你还可以一次添加多个字段:
filter {
date {
add_field => {
"foo_%{somefield}" => "Hello world, from %{host}"
"new_field" => "new_static_value"
}
}
}
如果事件有字段,则"somefield" == "hello"
此过滤器成功时,foo_hello
如果存在,则添加字段,上面的值和%{host}
该事件中的值替换。第二个例子还会添加一个硬编码字段。
add_tag
- 值类型是array
- 默认值是 []
如果此过滤器成功,则向事件添加任意标记。标签可以是动态的,并包含使用%{field}
语法事件的部分。
例子:
filter {
date {
add_tag => [ "foo_%{somefield}" ]
}
}
你还可以一次添加多个字段:
filter {
date {
add_tag => [ "foo_%{somefield}", "taggedy_tag"]
}
}
如果事件有字段,则"somefield" == "hello"
此过滤器成功时将添加标记foo_hello
(第二个示例当然会添加taggedy_tag
标记)。
enable_metric
- 值类型是boolean
- 默认值是 true
默认情况下,禁用或启用此特定插件实例的度量标准记录我们会记录所有可用的度量标准,但你可以禁用特定插件的度量标准收集。
id
- 值类型是string
- 此设置没有默认值。
为插件添加唯一配置ID。如果未指定ID,则Logstash将生成一个ID。强烈建议在配置中设置此ID。当您有两个或更多相同类型的插件时,这尤其有用,
例如,如果您有2个日期过滤器。在这种情况下添加命名ID将有助于在使用监视API时监视Logstash。
filter {
date {
id => "ABC"
}
}
periodic_flush
- 值类型是boolean
- 默认值是 false
定期调用过滤器刷新方法。可选的。
remove_field
- 值类型是array
- 默认值是 []
如果此过滤器成功,请从此事件中删除任意字段。例:
filter {
date {
remove_field => [ "foo_%{somefield}" ]
}
}
你还可以一次添加多个字段:
filter {
date {
remove_field => [ "foo_%{somefield}", "my_extraneous_field" ]
}
}
如果事件具有字段,则”somefield” == “hello”此过滤器成功时将删除具有名称的字段(foo_hello如果存在)。第二个示例将删除另一个非动态字段。
remove_tag
- 值类型是array
- 默认值是 []
如果此过滤器成功,则从事件中删除任意标记。标签可以是动态的,并包含使用%{field} 语法事件的一部分。
例:
filter {
date {
remove_tag => [ "foo_%{somefield}" ]
}
}
你还可以一次添加多个字段:
filter {
date {
remove_tag => [ "foo_%{somefield}", "sad_unwanted_tag"]
}
}
如果事件具有字段,则”somefield” == “hello”此过滤器成功时将删除标记(foo_hello如果存在)。第二个例子也会删除一个悲伤的,不需要的标签。