高级配置
本节描述了如何为 Logstash 设置高级配置选项,例如引用字段值和条件语句。
引用字段值
要访问字段,请使用 - field
语法。您也可以用方括号 - [field]
括住字段名,这使得您更明确地表示正在引用一个字段。
例如,如果您有以下事件
{
"request": "/products/view/123",
"verb": "GET",
"response": 200,
"headers": {
"request_path" => "/"
}
}
要访问 request
字段,请使用 - request
或 - [request]
。
如果您想引用嵌套字段,请使用方括号语法并指定字段的路径。每个级别都用方括号括起来:- [headers][request_path]
。
您可以使用 sprintf
格式引用字段。这也被称为字符串扩展。您需要添加一个 % 符号,然后将字段引用括在花括号中。
在使用条件语句时,您需要引用字段值。
例如,您可以使文件名动态化,并包含已处理事件的类型 - access
或 error
。 type
选项主要用于根据正在处理的事件类型有条件地应用过滤器插件。
让我们添加一个 type
选项并指定值为 access
。
input {
file {
path => ""
start_position => "beginning"
type => "access"
}
http {
type => "access"
}
}
filter {
mutate {
remove_field => {"host"}
}
}
output {
stdout {
codec => rubydebug
}
file {
path => "%{[type]}.log"
}
}
启动 Logstash 并发送一个 HTTP 请求。处理后的事件在终端中输出。该事件现在包含一个名为 type
的字段。
您会看到在 Logstash 目录中创建了 access.log
文件。
条件语句
您可以使用条件语句来根据某些条件控制代码执行的流程。
语法
if EXPR {
...
} else if EXPR {
...
} else {
...
}
EXPR
是任何有效的 Logstash 语法,其计算结果为布尔值。例如,您可以检查事件类型是否设置为 access
或 error
,并根据此执行一些操作
if [type] == "access" {
...
} else if [type] == "error" {
file { .. }
} else {
...
}
您可以将字段值与某个任意值进行比较
if [headers][content_length] >= 1000 {
...
}
您可以使用正则表达式
if [some_field =~ /[0-9]+/ {
//some field only contains digits
}
您可以使用数组
if [some_field] in ["one", "two", "three"] {
some field is either "one", "two", or "three"
}
您可以使用布尔运算符
if [type] == "access" or [type] == "error" {
...
}
格式化日期
您可以使用 sprintf
格式或字符串扩展来格式化日期。例如,您可能希望当前日期成为文件名的一部分。
要格式化日期,请在花括号中添加一个加号,后跟日期格式 - %{+yyyy-MM-dd}
。
file {
path => "%{[type]}_%{+yyyy_MM_dd}.log"
}
这是存储在 @timestamp 字段中的日期,它是事件的时间和日期。向管道发送请求并验证是否输出了包含事件日期的文件名。
您也可以将日期嵌入到其他输出中,例如 OpenSearch 中的索引名称。
发送时间信息
您可以设置事件的时间。
Logstash 已经将事件被输入插件接收时的时间设置在 @timestamp 字段中。在某些情况下,您可能需要使用不同的时间戳。例如,如果您有一个电商商店,并且您每天午夜处理订单。当 Logstash 在午夜接收到事件时,它将时间戳设置为当前时间。但您希望它是订单下达的时间,而不是 Logstash 接收事件的时间。
让我们将事件时间戳更改为 Web 服务器接收请求的日期。您可以使用名为 dates
的过滤器插件来完成此操作。dates
过滤器会从一个字段中传递一个 date
或 datetime
值,并将其结果用作事件时间戳。
在 filter
块的底部添加 date
插件
date {
match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
}
timestamp
是 grok
模式创建的字段。Z
是时区,即 UTC 偏移量。
启动 Logstash 并发送 HTTP 请求。
您可以看到文件名包含请求的日期而不是当前日期。
如果日期传递失败,filter
插件会在文本字段中添加一个名为 _datepassfailure
的标签。
在您将 @timestamp 字段设置为新值后,您就不再需要其他 timestamp
字段了。您可以使用 remove_field
选项将其删除。
date {
match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
remove_field => [ "timestamp" ]
}
解析用户代理
用户代理是日志条目的最后一部分,由浏览器名称、浏览器版本和设备的操作系统组成。
用户可能使用各种浏览器、设备和操作系统。手动完成这项工作很困难。
您不能使用 grok
模式,因为 grok
模式只匹配字符串中的整体用法,而无法识别访问者使用了哪种浏览器等。
Logstash 附带了一个文件,其中包含用于此目的的正则表达式。这使得提取用户代理信息变得非常容易,您可以将其发送到 OpenSearch 并运行聚合。
为此,添加一个包含字段名称的 source
选项。在这种情况下,它是 agent
字段。默认情况下,用户代理插件在事件的顶层添加许多字段。由于这可能会变得非常混乱,我们可以添加一个名为 target
的选项,其值为 ua
,即 user agent 的缩写。这样做是将字段嵌套在一个名为 ua
的对象中,使事情更有条理。
useragent {
source => "agent"
target => "ua"
}
启动 Logstash 并发送 HTTP 请求。
您可以看到一个名为 ua
的字段,其中包含许多键,包括浏览器名称和版本、操作系统和设备。
您可以使用 OpenSearch Dashboards 创建饼图,显示有多少访问者使用移动设备,有多少是桌面用户。或者,您可以获得关于哪些浏览器版本受欢迎的统计数据。
丰富地理数据
您可以使用 geoip
过滤器获取 IP 地址并执行地理查找,以解析用户的地理位置。
geoip
过滤器插件附带一个名为 geolite 2
的数据库,由 MaxMind 公司提供。geolite 2
是一个流行的地理数据源,并且免费可用。在 else
块的底部添加 geoip
插件。
source
选项的值是包含 IP 地址的字段名称,在这种情况下是 clientip
。您可以使用 grok
模式使此字段可用。
geoip {
source => "clientip"
}
启动 Logstash 并发送 HTTP 请求。
在终端中,您会看到一个名为 geoip
的新字段,其中包含时区、国家、大陆、城市、邮政编码以及纬度/经度对等信息。
例如,如果您只需要国家名称,请包含一个名为 fields
的选项,其中包含您希望 geoip
插件返回的字段名称数组。
某些字段(例如城市名称和区域)并非总是可用,因为将 IP 地址转换为地理位置通常不太准确。如果 geoip
插件无法查找地理位置,它会添加一个名为 geoip_lookup_failure
的标签。
您可以将 geoip
插件与 OpenSearch 输出一起使用,因为 geoip
对象中的 location
对象是 JSON 中表示地理空间数据的标准格式。这与 OpenSearch 用于其 geo_point
数据类型的格式相同。
您可以使用 OpenSearch 强大的地理空间查询来处理地理数据。