diff --git a/etc/logstash-nagios.yaml b/etc/logstash-nagios.yaml new file mode 100644 index 000000000..204eda57d --- /dev/null +++ b/etc/logstash-nagios.yaml @@ -0,0 +1,19 @@ +--- +configname: nagios +# Example config that filters already-parsed logs (grok filter at least) for +# certain patterns and sends the results to Nagios. +inputs: + all: + - amqp:///topic/parsedlogs +filters: +- grep: + java: + - match: + JAVASTACKTRACEPART: .* + add_fields: + nagios_host: localhost + nagios_service: Java Exceptions + nagios_annotation: "Java exception" +outputs: +- stdout:/// +- nagios:///var/lib/nagios3/rw/nagios.cmd diff --git a/lib/logstash/outputs/nagios.rb b/lib/logstash/outputs/nagios.rb new file mode 100644 index 000000000..fca66cfa9 --- /dev/null +++ b/lib/logstash/outputs/nagios.rb @@ -0,0 +1,72 @@ +require "logstash/outputs/base" + +class LogStash::Outputs::Nagios < LogStash::Outputs::Base + NAGIOS_CRITICAL = 2 + NAGIOS_WARN = 1 + + def initialize(url, config={}, &block) + super + + if @url.path == "" or @url.path == "/" + @cmdfile = "/var/lib/nagios3/rw/nagios.cmd" + else + @cmdfile = @url.path + end + end + + def register + # nothing to do + end # def register + + def receive(event) + if !File.exists?(@cmdfile) + @logger.warn(["Skipping nagios output; command file is missing", + {"cmdfile" => @cmdfile, "missed_event" => event}]) + return + end + + # TODO(petef): if nagios_host/nagios_service both have more than one + # value, send multiple alerts. They will have to match up together by + # array indexes (host/service combos) and the arrays must be the same + # length. + + host = event.fields["nagios_host"] + if !host + @logger.warn(["Skipping nagios output; nagios_host field is missing", + {"missed_event" => event}]) + return + end + + service = event.fields["nagios_service"] + if !service + @logger.warn(["Skipping nagios output; nagios_service field is missing", + {"missed_event" => event}]) + return + end + + annotation = event.fields["nagios_annotation"] + level = NAGIOS_CRITICAL + if event.fields["nagios_level"] and event.fields["nagios_level"][0].downcase == "warn" + level = NAGIOS_WARN + end + + cmd = "[#{Time.now.to_i}] PROCESS_SERVICE_CHECK_RESULT;#{host[0]};#{service[0]};#{level};" + if annotation + cmd += "#{annotation[0]}: " + end + cmd += "#{event.source}: " + # In the multi-line case, escape the newlines for the nagios command file + cmd += event.message.gsub("\n", "\\n") + + @logger.debug({"cmdfile" => @cmdfile, "nagios_command" => cmd}) + begin + File.open(@cmdfile, "a") do |f| + f.puts cmd + end + rescue + @logger.warn(["Skipping nagios output; error writing to command file", + {"error" => $!, "cmdfile" => @cmdfile, + "missed_event" => event}]) + end + end # def event +end # class LogStash::Outputs::Nagios