forked from logstash-plugins/logstash-output-gelf
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This came from elasticsearch/logstash at cf2242170011fbf2d264ae876601…
…92754697671a
- Loading branch information
Richard Pijnenburg
committed
Oct 20, 2014
0 parents
commit 6171e75
Showing
7 changed files
with
431 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
*.gem | ||
Gemfile.lock | ||
.bundle | ||
vendor |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
source 'https://rubygems.org' | ||
gem 'rake' | ||
gem 'gem_publisher' | ||
gem 'archive-tar-minitar' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
@files=[] | ||
|
||
task :default do | ||
system("rake -T") | ||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
# encoding: utf-8 | ||
require "logstash/namespace" | ||
require "logstash/outputs/base" | ||
|
||
# This output generates messages in GELF format. This is most useful if you | ||
# want to use Logstash to output events to Graylog2. | ||
# | ||
# More information at <http://graylog2.org/gelf#specs> | ||
class LogStash::Outputs::Gelf < LogStash::Outputs::Base | ||
|
||
config_name "gelf" | ||
milestone 2 | ||
|
||
# Graylog2 server IP address or hostname. | ||
config :host, :validate => :string, :required => true | ||
|
||
# Graylog2 server port number. | ||
config :port, :validate => :number, :default => 12201 | ||
|
||
# The GELF chunksize. You usually don't need to change this. | ||
config :chunksize, :validate => :number, :default => 1420 | ||
|
||
# Allow overriding of the GELF `sender` field. This is useful if you | ||
# want to use something other than the event's source host as the | ||
# "sender" of an event. A common case for this is using the application name | ||
# instead of the hostname. | ||
config :sender, :validate => :string, :default => "%{host}" | ||
|
||
# The GELF message level. Dynamic values like %{level} are permitted here; | ||
# useful if you want to parse the 'log level' from an event and use that | ||
# as the GELF level/severity. | ||
# | ||
# Values here can be integers [0..7] inclusive or any of | ||
# "debug", "info", "warn", "error", "fatal" (case insensitive). | ||
# Single-character versions of these are also valid, "d", "i", "w", "e", "f", | ||
# "u" | ||
# The following additional severity\_labels from Logstash's syslog\_pri filter | ||
# are accepted: "emergency", "alert", "critical", "warning", "notice", and | ||
# "informational". | ||
config :level, :validate => :array, :default => [ "%{severity}", "INFO" ] | ||
|
||
# The GELF facility. Dynamic values like %{foo} are permitted here; this | ||
# is useful if you need to use a value from the event as the facility name. | ||
# Should now be sent as an underscored "additional field" (e.g. `\_facility`) | ||
config :facility, :validate => :string, :deprecated => true | ||
|
||
# The GELF line number; this is usually the line number in your program where | ||
# the log event originated. Dynamic values like %{foo} are permitted here, but the | ||
# value should be a number. | ||
# Should now be sent as an underscored "additional field" (e.g. `\_line`). | ||
config :line, :validate => :string, :deprecated => true | ||
|
||
# The GELF file; this is usually the source code file in your program where | ||
# the log event originated. Dynamic values like %{foo} are permitted here. | ||
# Should now be sent as an underscored "additional field" (e.g. `\_file`). | ||
config :file, :validate => :string, :deprecated => true | ||
|
||
# Should Logstash ship metadata within event object? This will cause Logstash | ||
# to ship any fields in the event (such as those created by grok) in the GELF | ||
# messages. These will be sent as underscored "additional fields". | ||
config :ship_metadata, :validate => :boolean, :default => true | ||
|
||
# Ship tags within events. This will cause Logstash to ship the tags of an | ||
# event as the field `\_tags`. | ||
config :ship_tags, :validate => :boolean, :default => true | ||
|
||
# Ignore these fields when `ship_metadata` is set. Typically this lists the | ||
# fields used in dynamic values for GELF fields. | ||
config :ignore_metadata, :validate => :array, :default => [ "@timestamp", "@version", "severity", "host", "source_host", "source_path", "short_message" ] | ||
|
||
# The GELF custom field mappings. GELF supports arbitrary attributes as custom | ||
# fields. This exposes that. Exclude the `_` portion of the field name | ||
# e.g. `custom_fields => ['foo_field', 'some_value'] | ||
# sets `_foo_field` = `some_value`. | ||
config :custom_fields, :validate => :hash, :default => {} | ||
|
||
# The GELF full message. Dynamic values like %{foo} are permitted here. | ||
config :full_message, :validate => :string, :default => "%{message}" | ||
|
||
# The GELF short message field name. If the field does not exist or is empty, | ||
# the event message is taken instead. | ||
config :short_message, :validate => :string, :default => "short_message" | ||
|
||
public | ||
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 # def register | ||
|
||
public | ||
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 # def receive | ||
end # class LogStash::Outputs::Gelf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
Gem::Specification.new do |s| | ||
|
||
s.name = 'logstash-output-gelf' | ||
s.version = '0.1.0' | ||
s.licenses = ['Apache License (2.0)'] | ||
s.summary = "This output generates messages in GELF format." | ||
s.description = "This output generates messages in GELF format. This is most useful if you want to use Logstash to output events to Graylog2." | ||
s.authors = ["Elasticsearch"] | ||
s.email = '[email protected]' | ||
s.homepage = "http://logstash.net/" | ||
s.require_paths = ["lib"] | ||
|
||
# Files | ||
s.files = `git ls-files`.split($\)+::Dir.glob('vendor/*') | ||
|
||
# Tests | ||
s.test_files = s.files.grep(%r{^(test|spec|features)/}) | ||
|
||
# Special flag to let us know this is actually a logstash plugin | ||
s.metadata = { "logstash_plugin" => "true", "group" => "output" } | ||
|
||
# Gem dependencies | ||
s.add_runtime_dependency 'logstash', '>= 1.4.0', '< 2.0.0' | ||
|
||
s.add_runtime_dependency 'gelf', ['1.3.2'] | ||
|
||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
require "gem_publisher" | ||
|
||
desc "Publish gem to RubyGems.org" | ||
task :publish_gem do |t| | ||
gem_file = Dir.glob(File.expand_path('../*.gemspec',File.dirname(__FILE__))).first | ||
gem = GemPublisher.publish_if_updated(gem_file, :rubygems) | ||
puts "Published #{gem}" if gem | ||
end | ||
|
Oops, something went wrong.