问题描述
我目前正在使用日志,其某些内容如下所示:
I am currently working with logs with some of its content looking like this:
00:19:59.771 (07120/evtThread ) TRC> Cem< [Core1] CALL_STATE...
00:20:00.199 (05768/BCMApplicationThread) INF>
#S#|Call stats, ongoing calls: 8, handled_calls: 7304
#S#+----------------------------+----------+----------+----------+----------+----------+
#S#|Peer | From| To| MinTime| MaxTime| AvgTime|
#S#+----------------------------+----------+----------+----------+----------+----------+
#S#| CallDispatcher:Core2| 0| 0| 0| 0| 0|
#S#| CallDispatcher:Core3| 0| 0| 0| 0| 0|
#S#| Cem:Core1| 1632| 6207| 0| 5996522| 311685|
我这样解析包含时间的行:
I parsed the line containing the time like this:
grok {
match => [ "message", "%{TIME:time} (?<bcm_comp>\(\d{5}\/\w{4,}\:*\ *\w*\)) (?<loglevel>\w{3}>{1}) %{GREEDYDATA:message}" ]
overwrite => [ "message" ]
add_field => [ "BCM_System", "PROD" ]
}
像这样解析前面包含#S#的行.忽略包含--------的行以及包含表标题和调用统计信息行的行.
The lines containing the #S# at the front was parsed like this. Disregard the lines containing -------- and the lines containing the title of the table and the call stats line.
grok {
match => [ "message", "(?<start>\#\S\#\|)\s* (?<peer>\w*\:\w*)(?<div2>\|)\s* %{NUMBER:From}(?<div3>\|)\s* %{NUMBER:To}(?<div4>\|)\s* %{NUMBER:MinTime}(?<div5>\|)\s* %{NUMBER:MaxTime}(?<div6>\|)\s* %{NUMBER:AvgTime}(?<div7>\|)" ]
remove_field => [ "start", "div2", "div3", "div4", "div5", "div6", "div7" ]
overwrite => [ "message"]
add_field => [ "reference_time", "%{@time}"]
}
我想做的是花些时间从上一行开始,并将其添加为我在#s#行中摸索的字段.如图所示,我尝试使用logstash中的add_field语法,但是它不起作用...它只是打印出%{@ time}.
What I am trying to do is take the time from the previous line and add it as a field for where I groked the #s# lines. I try using the add_field syntax from logstash as shown but it doesn't work...it just literally prints out %{@time}.
我可以通过某种方式从上一行中提取时间并将其放入另一个事件的字段中吗?
Is there any way I can somehow extract that time from the previous line and put it in a field for another event?
推荐答案
据我所知,您必须编写一个过滤器插件才能执行此类操作.这是我放在一起做的一个简单的插件,它可以执行类似的操作-看到它会记住一个字段,然后使用它看到的最后一个值(如果不存在).
You'd have to write a filter plugin to do something like this as far as I know. Here's a simple plugin I threw together to do something like that -- it memorizes a field when it sees it and then uses the last value it saw if it's not present.
# encoding: utf-8
require "logstash/filters/base"
require "logstash/namespace"
require "set"
#
# This filter will look for a field from an event and record the last value
# of it. If it's not present, it will add the last value to the event
#
# The config looks like this:
#
# filter {
# memorize {
# field => "time"
# default => "00:00:00.000"
# }
# }
#
# The `field` is the name of the field that you want to memorize
# The `default` is the value to use for the field if you haven't seen it yet
# in the file (this is optional)
class LogStash::Filters::Memorize < LogStash::Filters::Base
config_name "memorize"
milestone 1
# The field to memorize
config :field, :validate => :string, :required => true
# the default value to use for the field if it's not seen before we need it
config :default, :validate => :string, :required => false
# The stream identity is how the multiline filter determines which stream an
# event belongs to. See the multiline plugin if you want more details on how
# this might work
config :stream_identity , :validate => :string, :default => "%{host}.%{path}.%{type}"
public
def initialize(config = {})
super
@threadsafe = false
# This filter needs to keep state.
@memorized = Hash.new
end # def initialize
public
def register
# nothing needed
end # def register
public
def filter(event)
return unless filter?(event)
if event[@field].nil?
val = @memorized[@stream_identity]
if val.nil?
val = @default
end
event[@field] = val
filter_matched(event)
else
@memorized[@stream_identity] = event[@field]
end
end
end
这篇关于如何在Logstash中引用一个事件到另一个事件的字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!