Class: LogStash::Outputs::Gelf

Inherits:
Base show all
Defined in:
lib/logstash/outputs/gelf.rb

Overview

GELF output. This is most useful if you want to use logstash to output events to graylog2.

More information at <graylog2.org/gelf#specs>

Constant Summary

Constants included from Config::Mixin

Config::Mixin::CONFIGSORT

Instance Attribute Summary

Attributes included from Config::Mixin

#config, #original_params

Attributes inherited from Plugin

#logger, #params

Instance Method Summary collapse

Methods inherited from Base

#handle, #handle_worker, #initialize, #worker_setup, #workers_not_supported

Methods included from Config::Mixin

#config_init, included

Methods inherited from Plugin

#eql?, #finished, #finished?, #hash, #initialize, #inspect, lookup, #reload, #running?, #shutdown, #teardown, #terminating?, #to_s

Constructor Details

This class inherits a constructor from LogStash::Outputs::Base

Instance Method Details

#receive(event) ⇒ Object



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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/logstash/outputs/gelf.rb', line 124

def receive(event)
  return unless output?(event)

  # We have to make our own hash here because GELF expects a hash
  # with a specific format.
  m = Hash.new

  m["short_message"] = event["message"]
  if event[@short_message]
    v = event[@short_message]
    short_message = (v.is_a?(Array) && v.length == 1) ? v.first : v
    short_message = short_message.to_s
    if !short_message.empty?
      m["short_message"] = short_message
    end
  end

  m["full_message"] = event.sprintf(@full_message)

  m["host"] = event.sprintf(@sender)

  # deprecated fields
  m["facility"] = event.sprintf(@facility) if @facility
  m["file"] = event.sprintf(@file) if @file
  m["line"] = event.sprintf(@line) if @line
  m["line"] = m["line"].to_i if m["line"].is_a?(String) and m["line"] === /^[\d]+$/

  if @ship_metadata
    event.to_hash.each do |name, value|
      next if value == nil
      next if name == "message"

      # Trim leading '_' in the event
      name = name[1..-1] if name.start_with?('_')
      name = "_id" if name == "id"  # "_id" is reserved, so use "__id"
      if !value.nil? and !@ignore_metadata.include?(name)
        if value.is_a?(Array)
          m["_#{name}"] = value.join(', ')
        elsif value.is_a?(Hash)
          value.each do |hash_name, hash_value|
            m["_#{name}_#{hash_name}"] = hash_value
          end
        else
          # Non array values should be presented as-is
          # https://logstash.jira.com/browse/LOGSTASH-113
          m["_#{name}"] = value
        end
      end
    end
  end

  if @ship_tags
    m["_tags"] = event["tags"].join(', ') if event["tags"]
  end

  if @custom_fields
    @custom_fields.each do |field_name, field_value|
      m["_#{field_name}"] = field_value unless field_name == 'id'
    end
  end

  # Probe severity array levels
  level = nil
  if @level.is_a?(Array)
    @level.each do |value|
      parsed_value = event.sprintf(value)
      next if value.count('%{') > 0 and parsed_value == value

      level = parsed_value
      break
    end
  else
    level = event.sprintf(@level.to_s)
  end
  m["level"] = (@level_map[level.downcase] || level).to_i

  @logger.debug(["Sending GELF event", m])
  begin
    @gelf.notify!(m, :timestamp => event["@timestamp"].to_f)
  rescue
    @logger.warn("Trouble sending GELF event", :gelf_event => m,
                 :event => event, :error => $!)
  end
end

#registerObject



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/logstash/outputs/gelf.rb', line 82

def register
  require "gelf" # rubygem 'gelf'
  option_hash = Hash.new

  #@gelf = GELF::Notifier.new(@host, @port, @chunksize, option_hash)
  @gelf = GELF::Notifier.new(@host, @port, @chunksize)

  # This sets the 'log level' of gelf; since we're forwarding messages, we'll
  # want to forward *all* messages, so set level to 0 so all messages get
  # shipped
  @gelf.level = 0

  # Since we use gelf-rb which assumes the severity level integer
  # is coming from a ruby logging subsystem, we need to instruct it
  # that the levels we provide should be mapped directly since they're
  # already RFC 5424 compliant
  # this requires gelf-rb commit bb1f4a9 which added the level_mapping def
  level_mapping = Hash.new
  (0..7).step(1) { |l| level_mapping[l]=l }
  @gelf.level_mapping = level_mapping

  # If we leave that set, the gelf gem will extract the file and line number
  # of the source file that logged the message (i.e. logstash/gelf.rb:138).
  # With that set to false, it can use the actual event's filename (i.e.
  # /var/log/syslog), which is much more useful
  @gelf.collect_file_and_line = false

  # these are syslog words and abbreviations mapped to RFC 5424 integers
  # and logstash's syslog_pri filter
  @level_map = {
    "debug" => 7, "d" => 7,
    "info" => 6, "i" => 6, "informational" => 6,
    "notice" => 5, "n" => 5,
    "warn" => 4, "w" => 4, "warning" => 4,
    "error" => 3, "e" => 3,
    "critical" => 2, "c" => 2,
    "alert" => 1, "a" => 1,
    "emergency" => 0, "e" => 0,
   }
end