Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 158 lines (133 sloc) 5.082 kb
4654755 @jordansissel - Style cleanup. Tests still pass, so I probably didn't break anything ;...
jordansissel authored
1 require "logstash/namespace"
9fdbe25 @jordansissel - Add GELF output for graylog2: see http://www.graylog2.org/about/gelf
jordansissel authored
2 require "logstash/outputs/base"
3
fcce185 @jordansissel - More config doc and related cleanup
jordansissel authored
4 # GELF output. This is most useful if you want to use logstash
5 # to output events to graylog2.
6 #
b01595a @jordansissel - more docs!
jordansissel authored
7 # More information at <http://www.graylog2.org/about/gelf>
9fdbe25 @jordansissel - Add GELF output for graylog2: see http://www.graylog2.org/about/gelf
jordansissel authored
8 class LogStash::Outputs::Gelf < LogStash::Outputs::Base
33d6619 @jordansissel - Config parsing works again; bug was causing '\' in a string to
jordansissel authored
9
10 config_name "gelf"
e017087 @jordansissel - rename plugin status "unstable" to "beta" so as to imply less in the
jordansissel authored
11 plugin_status "beta"
347831d @lusis setting plugin_status on all plugins
lusis authored
12
fcce185 @jordansissel - More config doc and related cleanup
jordansissel authored
13 # graylog2 server address
3b0f84b @lusis making all gelf params tunable
lusis authored
14 config :host, :validate => :string, :required => true
15
fcce185 @jordansissel - More config doc and related cleanup
jordansissel authored
16 # graylog2 server port
17 config :port, :validate => :number, :default => 12201
18
f56c639 @jordansissel - add docs for gelf
jordansissel authored
19 # The GELF chunksize. You usually don't need to change this.
fcce185 @jordansissel - More config doc and related cleanup
jordansissel authored
20 config :chunksize, :validate => :number, :default => 1420
3b0f84b @lusis making all gelf params tunable
lusis authored
21
f56c639 @jordansissel - add docs for gelf
jordansissel authored
22 # Allow overriding of the gelf 'sender' field. This is useful if you
23 # want to use something other than the event's source host as the
24 # "sender" of an event. A common case for this is using the application name
25 # instead of the hostname.
d38842a @lusis Because i'm tired of hearing Rick Astley
lusis authored
26 config :sender, :validate => :string, :default => "%{@source_host}"
52e1059 @lusis addding support to override sender in GELF message
lusis authored
27
a345bb9 @jordansissel - Allow dynamic strings for facility and level.
jordansissel authored
28 # The GELF message level. Dynamic values like %{level} are permitted here;
29 # useful if you want to parse the 'log level' from an event and use that
30 # as the gelf level/severity.
31 #
32 # Values here can be integers [0..7] inclusive or any of
33 # "debug", "info", "warn", "error", "fatal", "unknown" (case insensitive).
34 # Single-character versions of these are also valid, "d", "i", "w", "e", "f",
35 # "u"
494cc77 @fetep Added GELF output to support multiple (frist-value-match) level and faci...
fetep authored
36 config :level, :validate => :array, :default => [ "%{severity}", "INFO" ]
3b0f84b @lusis making all gelf params tunable
lusis authored
37
a345bb9 @jordansissel - Allow dynamic strings for facility and level.
jordansissel authored
38 # The GELF facility. Dynamic values like %{foo} are permitted here; this
39 # is useful if you need to use a value from the event as the facility name.
494cc77 @fetep Added GELF output to support multiple (frist-value-match) level and faci...
fetep authored
40 config :facility, :validate => :array, :default => [ "%{facility}" , "logstash-gelf" ]
41
42 # Ship metadata within event object?
43 config :ship_metadata, :validate => :boolean, :default => true
33d6619 @jordansissel - Config parsing works again; bug was causing '\' in a string to
jordansissel authored
44
56b3202 @lusis adding custom fields to gelf output. fixing DateTime conversion on gelf ...
lusis authored
45 # The GELF custom field mappings. GELF supports arbitrary attributes as custom
46 # fields. This exposes that. Exclude the `_` portion of the field name
47 # e.g. `custom_fields => ['foo_field', 'some_value']
48 # sets `_foo_field` = `some_value`
49 config :custom_fields, :validate => :hash, :default => {}
50
4654755 @jordansissel - Style cleanup. Tests still pass, so I probably didn't break anything ;...
jordansissel authored
51 public
9fdbe25 @jordansissel - Add GELF output for graylog2: see http://www.graylog2.org/about/gelf
jordansissel authored
52 def register
438aedc @jordansissel - move more requires to register method
jordansissel authored
53 require "gelf" # rubygem 'gelf'
3b0f84b @lusis making all gelf params tunable
lusis authored
54 option_hash = Hash.new
a345bb9 @jordansissel - Allow dynamic strings for facility and level.
jordansissel authored
55 #option_hash['level'] = @level
56 #option_hash['facility'] = @facility
3b0f84b @lusis making all gelf params tunable
lusis authored
57
a345bb9 @jordansissel - Allow dynamic strings for facility and level.
jordansissel authored
58 #@gelf = GELF::Notifier.new(@host, @port, @chunksize, option_hash)
59 @gelf = GELF::Notifier.new(@host, @port, @chunksize)
60
61 # This sets the 'log level' of gelf; since we're forwarding messages, we'll
62 # want to forward *all* messages, so set level to 0 so all messages get
63 # shipped
64 @gelf.level = 0
65
66 @level_map = {
67 "debug" => 7, "d" => 7,
68 "info" => 6, "i" => 6,
69 "warn" => 5, "w" => 5,
70 "error" => 4, "e" => 4,
71 "fatal" => 3, "f" => 3,
72 "unknown" => 1, "u" => 1,
73 }
9fdbe25 @jordansissel - Add GELF output for graylog2: see http://www.graylog2.org/about/gelf
jordansissel authored
74 end # def register
75
4654755 @jordansissel - Style cleanup. Tests still pass, so I probably didn't break anything ;...
jordansissel authored
76 public
9fdbe25 @jordansissel - Add GELF output for graylog2: see http://www.graylog2.org/about/gelf
jordansissel authored
77 def receive(event)
600ba54 @fetep support tag & type filtering for all outputs
fetep authored
78 return unless output?(event)
79
0726603 @jordansissel - add note about why we're making a hash
jordansissel authored
80 # We have to make our own hash here because GELF expects a hash
81 # with a specific format.
39377a4 @lusis fixing gelf output for deprecated usage
lusis authored
82 m = Hash.new
db50c70 @jordansissel - use first element if fields['message'] is an array
jordansissel authored
83 if event.fields["message"]
84 v = event.fields["message"]
0e6b6ef @fetep s/array/Array/
fetep authored
85 m["short_message"] = (v.is_a?(Array) && v.length == 1) ? v.first : v
db50c70 @jordansissel - use first element if fields['message'] is an array
jordansissel authored
86 else
87 m["short_message"] = event.message
88 end
89
39377a4 @lusis fixing gelf output for deprecated usage
lusis authored
90 m["full_message"] = (event.message)
dfd2a9b @lusis allowing override of gelf sender
lusis authored
91
d38842a @lusis Because i'm tired of hearing Rick Astley
lusis authored
92 m["host"] = event.sprintf(@sender)
39377a4 @lusis fixing gelf output for deprecated usage
lusis authored
93 m["file"] = event["@source_path"]
9decdf7 @jordansissel - Add fields and timestamp from to gelf
jordansissel authored
94
494cc77 @fetep Added GELF output to support multiple (frist-value-match) level and faci...
fetep authored
95 if @ship_metadata
96 event.fields.each do |name, value|
97 next if value == nil
98 name = "_id" if name == "id" # "_id" is reserved, so use "__id"
99 if !value.nil?
100 if value.is_a?(Array)
101 # collapse single-element arrays, otherwise leave as array
102 m["_#{name}"] = (value.length == 1) ? value.first : value
103 else
104 # Non array values should be presented as-is
105 # https://logstash.jira.com/browse/LOGSTASH-113
106 m["_#{name}"] = value
107 end
108 end
3dfa25f @jordansissel - Allow fields which are not arrays (syslog input generates them)
jordansissel authored
109 end
9decdf7 @jordansissel - Add fields and timestamp from to gelf
jordansissel authored
110 end
a345bb9 @jordansissel - Allow dynamic strings for facility and level.
jordansissel authored
111
56b3202 @lusis adding custom fields to gelf output. fixing DateTime conversion on gelf ...
lusis authored
112 if @custom_fields
113 @custom_fields.each do |field_name, field_value|
114 m["_#{field_name}"] = field_value unless field_name == 'id'
115 end
116 end
117
a345bb9 @jordansissel - Allow dynamic strings for facility and level.
jordansissel authored
118 # Allow 'INFO' 'I' or number. for 'level'
594576a @fetep fix GELF output: support extra fields properly (_ prefix) and pass times...
fetep authored
119 m["timestamp"] = event.unix_timestamp.to_i
a345bb9 @jordansissel - Allow dynamic strings for facility and level.
jordansissel authored
120
494cc77 @fetep Added GELF output to support multiple (frist-value-match) level and faci...
fetep authored
121 # Probe facility array levels
122 if @facility.is_a?(Array)
77c3c89 @fetep style/whitespace cleanup
fetep authored
123 @facility.each do |value|
124 parsed_value = event.sprintf(value)
125 if parsed_value
126 m["facility"] = parsed_value
127 break
494cc77 @fetep Added GELF output to support multiple (frist-value-match) level and faci...
fetep authored
128 end
77c3c89 @fetep style/whitespace cleanup
fetep authored
129 end
494cc77 @fetep Added GELF output to support multiple (frist-value-match) level and faci...
fetep authored
130 else
77c3c89 @fetep style/whitespace cleanup
fetep authored
131 m["facility"] = event.sprintf(@facility)
494cc77 @fetep Added GELF output to support multiple (frist-value-match) level and faci...
fetep authored
132 end
77c3c89 @fetep style/whitespace cleanup
fetep authored
133
494cc77 @fetep Added GELF output to support multiple (frist-value-match) level and faci...
fetep authored
134 # Probe severity array levels
e2db33c @jseidl Fixed some mistakes on the severity probe routine
jseidl authored
135 level = nil
494cc77 @fetep Added GELF output to support multiple (frist-value-match) level and faci...
fetep authored
136 if @level.is_a?(Array)
77c3c89 @fetep style/whitespace cleanup
fetep authored
137 @level.each do |value|
138 parsed_value = event.sprintf(value)
139 if parsed_value
140 level = parsed_value
141 break
494cc77 @fetep Added GELF output to support multiple (frist-value-match) level and faci...
fetep authored
142 end
77c3c89 @fetep style/whitespace cleanup
fetep authored
143 end
494cc77 @fetep Added GELF output to support multiple (frist-value-match) level and faci...
fetep authored
144 else
77c3c89 @fetep style/whitespace cleanup
fetep authored
145 level = event.sprintf(@level.to_s)
494cc77 @fetep Added GELF output to support multiple (frist-value-match) level and faci...
fetep authored
146 end
e2db33c @jseidl Fixed some mistakes on the severity probe routine
jseidl authored
147 m["level"] = (@level_map[level.downcase] || level).to_i
148
494cc77 @fetep Added GELF output to support multiple (frist-value-match) level and faci...
fetep authored
149 @logger.debug(["Sending GELF event", m])
d1acd13 @fetep LOGSTASH-173: catch exceptions generated by gelf.notify
fetep authored
150 begin
151 @gelf.notify!(m)
152 rescue
153 @logger.warn("Trouble sending GELF event", :gelf_event => m,
154 :event => event, :error => $!)
155 end
4654755 @jordansissel - Style cleanup. Tests still pass, so I probably didn't break anything ;...
jordansissel authored
156 end # def receive
f22e259 @jordansissel - fix comment
jordansissel authored
157 end # class LogStash::Outputs::Gelf
Something went wrong with that request. Please try again.