Class: LogStash::Codecs::Multiline
- Inherits:
-
Base
- Object
- Base
- LogStash::Codecs::Multiline
- Defined in:
- lib/logstash/codecs/multiline.rb
Overview
The multiline codec will collapse multiline messages and merge them into a single event.
The original goal of this codec was to allow joining of multiline messages from files into a single event. For example, joining Java exception and stacktrace messages into a single event.
The config looks like this:
- source,ruby
-
input {
stdin { codec => multiline { pattern => "pattern, a regexp" negate => "true" or "false" what => "previous" or "next" } }}
The pattern should match what you believe to be an indicator that the field is part of a multi-line event.
The what must be previous or next and indicates the relation to the multi-line event.
The negate can be true or false (defaults to false). If true, a message not matching the pattern will constitute a match of the multiline filter and the what will be applied. (vice-versa is also true)
For example, Java stack traces are multiline and usually have the message starting at the far-left, with each subsequent line indented. Do this:
- source,ruby
-
input {
stdin { codec => multiline { pattern => "^\s" what => "previous" } }}
This says that any line starting with whitespace belongs to the previous line.
Another example is to merge lines not starting with a date up to the previous line..
- source,ruby
-
input
file { path => "/var/log/someapp.log" codec => multiline { # Grok pattern names are valid! :) pattern => "^%{TIMESTAMP_ISO8601 " negate => true what => previous } }}
This says that any line not starting with a timestamp should be merged with the previous line.
One more common example is C line continuations (backslash). Here’s how to do that:
- source,ruby
-
filter {
multiline { type => "somefiletype" pattern => "\\$" what => "next" }}
This says that any line ending with a backslash should be combined with the following line.
Instance Method Summary collapse
-
#buffer(text) ⇒ Object
def decode.
- #decode(text, &block) ⇒ Object
- #do_next(text, matched, &block) ⇒ Object
- #do_previous(text, matched, &block) ⇒ Object
- #encode(event) ⇒ Object
- #flush(&block) ⇒ Object
- #register ⇒ Object
Instance Method Details
#buffer(text) ⇒ Object
def decode
163 164 165 166 |
# File 'lib/logstash/codecs/multiline.rb', line 163 def buffer(text) @time = LogStash::Timestamp.now if @buffer.empty? @buffer << text end |
#decode(text, &block) ⇒ Object
151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/logstash/codecs/multiline.rb', line 151 def decode(text, &block) text = @converter.convert(text) match = @grok.match(text) @logger.debug("Multiline", :pattern => @pattern, :text => text, :match => !match.nil?, :negate => @negate) # Add negate option match = (match and !@negate) || (!match and @negate) @handler.call(text, match, &block) end |
#do_next(text, matched, &block) ⇒ Object
179 180 181 182 |
# File 'lib/logstash/codecs/multiline.rb', line 179 def do_next(text, matched, &block) buffer(text) flush(&block) if !matched end |
#do_previous(text, matched, &block) ⇒ Object
184 185 186 187 |
# File 'lib/logstash/codecs/multiline.rb', line 184 def do_previous(text, matched, &block) flush(&block) if !matched buffer(text) end |
#encode(event) ⇒ Object
190 191 192 193 |
# File 'lib/logstash/codecs/multiline.rb', line 190 def encode(event) # Nothing to do. @on_event.call(event) end |
#flush(&block) ⇒ Object
168 169 170 171 172 173 174 175 176 177 |
# File 'lib/logstash/codecs/multiline.rb', line 168 def flush(&block) if @buffer.any? event = LogStash::Event.new(LogStash::Event::TIMESTAMP => @time, "message" => @buffer.join(NL)) # Tag multiline events event.tag @multiline_tag if @multiline_tag && @buffer.size > 1 yield event @buffer = [] end end |
#register ⇒ Object
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/logstash/codecs/multiline.rb', line 119 def register require "grok-pure" # rubygem 'jls-grok' require 'logstash/patterns/core' # Detect if we are running from a jarfile, pick the right path. patterns_path = [] patterns_path += [LogStash::Patterns::Core.path] @grok = Grok.new @patterns_dir = patterns_path.to_a + @patterns_dir @patterns_dir.each do |path| if File.directory?(path) path = File.join(path, "*") end Dir.glob(path).each do |file| @logger.info("Grok loading patterns from file", :path => file) @grok.add_patterns_from_file(file) end end @grok.compile(@pattern) @logger.debug("Registered multiline plugin", :type => @type, :config => @config) @buffer = [] @handler = method("do_#{@what}".to_sym) @converter = LogStash::Util::Charset.new(@charset) @converter.logger = @logger end |