从部分日期时间字段创建新字段
Create new fields from parts of datetime field
我有一个 logstash 管道,它从 apache 日志条目中提取日期并将其保存在新字段中:
date {
match => [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ]
target => "@apache_timestamp"
}
对于某些特定的报告,我还希望能够将此日期的部分内容提取到单独的字段中。
我尝试在日志中的新日期字段上使用 date
插件:
date {
match => ["@apache_timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ]
add_field => {"[hourOfDay]" => "%{+HH}"}
add_field => {"[dayOfWeek]" => "%{+EEE}"}
add_field => {"[weekOfYear]" => "%{+ww}"}
add_field => {"[monthName]" => "%{+MMMM}"}
add_field => {"[year]" => "%{+yyyy}"}
}
但它似乎没有添加任何新字段。
我也试过直接在消息上使用 grok 插件:
grok {
match => { "message" => ["%{HTTPDATE}"] }
add_field => {"[hourOfDay]" => "%{HOUR}"}
add_field => {"[monthName]" => "%{MONTH}"}
add_field => {"[year]" => "%{YEAR}"}
}
这会添加字段,但它们具有文字值 %{HOUR}
、%{MONTH}
等...
如何从 Apache 时间戳中提取 "Day of week" 和 "week of year" 等字段?
(我能够使用 Kibana 的脚本字段提取我需要的值,但它们看起来相当慢,而且 Kibana 无法查询脚本字段,因此这不是一个很好的解决方案。)
使用 Logstash 6.0
我不知道你的具体时间格式,所以我用 google 搜索了一个 apache 时间戳,发现了这个:
[Wed Oct 11 14:32:52 2000]
我去过这个地方:
http://grokconstructor.appspot.com/do/match#result
并使用了这个 grok 模式:
%{DAY:day} %{MONTH:month} %{NUMBER:year} %{NUMBER:hour}:%{NUMBER:minute}:%{NUMBER:second} %{NUMBER:millisecond}
使用 grok 匹配字段应该会在您的记录中生成新字段,因此不需要 add_field。请记住,grok 模式匹配在特殊字符周围可能会很棘手,这就是我试图将括号排除在外的原因,它对我有用。
也不要忘记,测试站点特别要求不要使用引号,但您仍然需要在配置文件中使用引号。
对于我得到的线条,我需要使用这个 grok 表达式:
grok {
match => { "message" => ["^.*%{MONTHDAY:dayOfMonth}\/%{MONTH:monthName}\/%{YEAR:year}:(?!<[0-9])%{HOUR:hourOfDay}:%{MINUTE}(?::%{SECOND})(?![0-9]) %{INT:utcOffset}.*$"] }
}
使用此日志行:
192.168.0.1 - - [01/Jan/2017:00:00:00 -0500] "GET /some-image-file.png HTTP/1.1" 200 13281 "-" "MobileSafari/602.0 CFNetwork/808.2.13 Darwin/16.3.0" "-" "-"
我可以像这样提取字段:
monthName Jan
year 2017
hourOfDay 00
dayOfMonth 1
utcOffset -0500
我仍然无法获得 DayOfWeek 字段(星期日、星期一、星期二等...),但现在这可能已经足够了。
编辑
我能够获得星期几和一年中的星期几,但我需要在 Ruby 中完成:
ruby {
code => 'event.set("dayOfWeek", Time.parse(event.get("@apache_timestamp").to_s).strftime("%A"))'
}
ruby {
code => 'event.set("weekOfYear", Time.parse(event.get("@apache_timestamp").to_s).strftime("%W"))'
}
仅供参考:
语法如下:
add_field => {"[dayOfWeek]" => "%{+EEE}"}
似乎只能在@timestamp
上工作。我不认为有任何其他方法可以在其他日期时间字段(例如我的 @apache_timestamp
)上使用该语法,因此丑陋的 Ruby 解决方案。
我有一个 logstash 管道,它从 apache 日志条目中提取日期并将其保存在新字段中:
date {
match => [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ]
target => "@apache_timestamp"
}
对于某些特定的报告,我还希望能够将此日期的部分内容提取到单独的字段中。
我尝试在日志中的新日期字段上使用 date
插件:
date {
match => ["@apache_timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ]
add_field => {"[hourOfDay]" => "%{+HH}"}
add_field => {"[dayOfWeek]" => "%{+EEE}"}
add_field => {"[weekOfYear]" => "%{+ww}"}
add_field => {"[monthName]" => "%{+MMMM}"}
add_field => {"[year]" => "%{+yyyy}"}
}
但它似乎没有添加任何新字段。
我也试过直接在消息上使用 grok 插件:
grok {
match => { "message" => ["%{HTTPDATE}"] }
add_field => {"[hourOfDay]" => "%{HOUR}"}
add_field => {"[monthName]" => "%{MONTH}"}
add_field => {"[year]" => "%{YEAR}"}
}
这会添加字段,但它们具有文字值 %{HOUR}
、%{MONTH}
等...
如何从 Apache 时间戳中提取 "Day of week" 和 "week of year" 等字段?
(我能够使用 Kibana 的脚本字段提取我需要的值,但它们看起来相当慢,而且 Kibana 无法查询脚本字段,因此这不是一个很好的解决方案。)
使用 Logstash 6.0
我不知道你的具体时间格式,所以我用 google 搜索了一个 apache 时间戳,发现了这个:
[Wed Oct 11 14:32:52 2000]
我去过这个地方:
http://grokconstructor.appspot.com/do/match#result
并使用了这个 grok 模式:
%{DAY:day} %{MONTH:month} %{NUMBER:year} %{NUMBER:hour}:%{NUMBER:minute}:%{NUMBER:second} %{NUMBER:millisecond}
使用 grok 匹配字段应该会在您的记录中生成新字段,因此不需要 add_field。请记住,grok 模式匹配在特殊字符周围可能会很棘手,这就是我试图将括号排除在外的原因,它对我有用。
也不要忘记,测试站点特别要求不要使用引号,但您仍然需要在配置文件中使用引号。
对于我得到的线条,我需要使用这个 grok 表达式:
grok {
match => { "message" => ["^.*%{MONTHDAY:dayOfMonth}\/%{MONTH:monthName}\/%{YEAR:year}:(?!<[0-9])%{HOUR:hourOfDay}:%{MINUTE}(?::%{SECOND})(?![0-9]) %{INT:utcOffset}.*$"] }
}
使用此日志行:
192.168.0.1 - - [01/Jan/2017:00:00:00 -0500] "GET /some-image-file.png HTTP/1.1" 200 13281 "-" "MobileSafari/602.0 CFNetwork/808.2.13 Darwin/16.3.0" "-" "-"
我可以像这样提取字段:
monthName Jan year 2017 hourOfDay 00 dayOfMonth 1 utcOffset -0500
我仍然无法获得 DayOfWeek 字段(星期日、星期一、星期二等...),但现在这可能已经足够了。
编辑
我能够获得星期几和一年中的星期几,但我需要在 Ruby 中完成:
ruby {
code => 'event.set("dayOfWeek", Time.parse(event.get("@apache_timestamp").to_s).strftime("%A"))'
}
ruby {
code => 'event.set("weekOfYear", Time.parse(event.get("@apache_timestamp").to_s).strftime("%W"))'
}
仅供参考:
语法如下:
add_field => {"[dayOfWeek]" => "%{+EEE}"}
似乎只能在@timestamp
上工作。我不认为有任何其他方法可以在其他日期时间字段(例如我的 @apache_timestamp
)上使用该语法,因此丑陋的 Ruby 解决方案。