Class: LogStash::Outputs::OpenNMS

Inherits:
Base
  • Object
show all
Defined in:
lib/logstash/outputs/opennms.rb

Overview

The OpenNMS output is used to send an event (xml document) to an OpenNMS server. The event ‘@timestamp` will automatically be associated with the OpenNMS item data.

NOTE: This plugin will log a warning if a necessary field is missing. It will not attempt to resend if OpenNMS is down, but will log an error message.

Instance Method Summary collapse

Instance Method Details

#field_check(event, fieldname) ⇒ Object



98
99
100
101
102
103
104
105
# File 'lib/logstash/outputs/opennms.rb', line 98

def field_check(event, fieldname)
  if !event.get(fieldname)
    @logger.warn("Field referenced by #{fieldname} is missing")
    false
  else
    true
  end
end

#format_request(message) ⇒ Object



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
# File 'lib/logstash/outputs/opennms.rb', line 154

def format_request(message)
  event_doc  = "<log>"
  event_doc += "<events>"
  event_doc += "<event>"
  event_doc += "<uei>" + message['uei'] + "</uei>"
  event_doc += "<source>" + message['source'] + "</source>"
  event_doc += "<nodeid>" + message['nodeid'] + "</nodeid>" if !message['nodeid'].empty?
  event_doc += "<time>" + Time.now.strftime("%A, %d %B %Y %H:%M:%S o'clock GMT") + "</time>"
  event_doc += "<host>" + message['origin'] + "</host>"
  event_doc += "<interface>" + message['interface'] + "</interface>" if !message['interface'].empty?
  event_doc += "<service>" + message ['service'] + "</service>" if !message['service'].empty?
  event_doc += "<parms>"
  #message['parms'].each do |parm_name, parm_value|
  message['parms_order'].each do |parm_name|
     parm_value = message['parms'][parm_name]
     next if parm_name == 'severity'
     event_doc += "<parm>"
     event_doc += "<parmName><![CDATA[" + parm_name + "]]></parmName>"
     event_doc += "<value type=\"string\" encoding=\"text\"><![CDATA[" + parm_value + "]]></value>"
     event_doc += "</parm>"
  end
  event_doc += "</parms>"
  #event_doc += "<descr>"    + message['description'] + "</descr>" if !message['description'].empty?
  event_doc += "<logmsg>"   + message['logmsg'] + "</logmsg>" if !message['logmsg'].empty?
  event_doc += "<severity>" + message['severity'] + "</severity>"
  event_doc += "</event>"
  event_doc += "</events>"
  event_doc += "</log>"
  xml_event = REXML::Document.new(event_doc)
end

#kv_check(event, key_field, value_field) ⇒ Object



108
109
110
111
112
113
114
# File 'lib/logstash/outputs/opennms.rb', line 108

def kv_check(event, key_field, value_field)
  errors = 0
  for field in [key_field, value_field]
    errors += 1 unless field_check(event, field)
  end
  errors < 1 ? true : false
end

#receive(event) ⇒ Object



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/logstash/outputs/opennms.rb', line 218

def receive(event)
  #parms = validate_props(event,@opennms_event_parms)
  
  @logger.warn("======> BREAK-1")
  
  message_map = { 'host'        => @opennms_server_host.to_s,
                  'port'        => @opennms_server_port.to_s,
                  'timezone'    => @opennms_event_timezone.to_s,
                  'service'     => @opennms_event_service.to_s,
                  'nodeid'      => @opennms_event_nodeid.to_s,
                  'interface'   => @opennms_event_interface.to_s,
                  'uei'         => @opennms_event_uei.to_s,
                  'origin'      => @opennms_event_origin.to_s,
                  'severity'    => @opennms_event_severity.to_s,
                  'source'      => @opennms_event_source.to_s,
                  'description' => @opennms_event_description.to_s,
                  'logmsg'      => @opennms_event_logmsg.to_s,
                  'parms'       => @opennms_event_parms,
                  'parms_order' => @opennms_event_parms_order
  }
  
  @logger.warn("======> BREAK-2")  
 
  message = validate_props(event,message_map,{})
  
  @logger.warn("======> BREAK-3")  
               
  #message['parms'].each do |k,v| 
  #   @logger.debug("Hash: " + k + " => " + v) 
  #end

  #return unless field_check(event, @opennms_host)

  send_to_opennms(message)
  
end

#registerObject



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/logstash/outputs/opennms.rb', line 76

def register
  if !@opennms_key.nil? && !@multi_value.nil?
    @logger.warn("Cannot use multi_value in conjunction with opennms_key/opennms_value.  Ignoring opennms_key.")
  end
  
  if @opennms_event_parms.nil?
    @opennms_event_parms = { 'a' => '1', 'b' => '2', 'c' => '3' }
  end

  # We're only going to use @multi_value in the end, so let's build it from
  # @opennms_key and @opennms_value if it is empty (single value configuration).
  if @multi_value.nil?
    @multi_value = [ @opennms_key, @opennms_value ]
  end
  if @multi_value.length % 2 == 1
    raise LogStash::ConfigurationError, I18n.t("logstash.agent.configuration.invalid_plugin_register",
      :plugin => "output", :type => "opennms",
      :error => "Invalid opennms configuration #{@multi_value}. multi_value requires an even number of elements as ['opennms_key1', 'opennms_value1', 'opennms_key2', 'opennms_value2']")
  end
end

#send_to_opennms(event) ⇒ Object

def tcp_send



202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/logstash/outputs/opennms.rb', line 202

def send_to_opennms(event)
  begin
    Timeout::timeout(@opennms_server_timeout) do
      tcp_send(event)
    end
  rescue Timeout::Error
    @logger.warn("Connection attempt to OpenNMS server timed out.",
      :server => @opennms_server_host,
      :port => @opennms_server_port.to_s,
      :timeout => @opennms_server_timeout.to_s
    )
    false
  end
end

#tcp_send(message) ⇒ Object

def format_request



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/logstash/outputs/opennms.rb', line 185

def tcp_send(message)
  begin
    @opennms_server_hosts.each do |server,port|
      TCPSocket.open(server,port) do |sock|
         xml_event = format_request(message).to_s
         logger.debug("XML Event: " + xml_event)
         sock.print xml_event
      end
    end
  rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ECONNRESET
    @logger.error("Connection error.  Unable to connect to OpenNMS server",
       :server => @opennms_server_hosts,
    )
    false
  end
end

#validate_fields(event) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
# File 'lib/logstash/outputs/opennms.rb', line 117

def validate_fields(event)
  found = []
  (0..@multi_value.length-1).step(2) do |idx|
    @logger.warn("---> " + @multi_value[idx].to_s)
    if kv_check(event, @multi_value[idx], @multi_value[idx+1])
      found << @multi_value[idx]
      found << @multi_value[idx+1]
    end
  end
  found
end

#validate_props(event, props, found) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/logstash/outputs/opennms.rb', line 130

def validate_props(event,props,found)
  props.each do |props_key,props_value|
    @logger.warn("props_key: " + props_key.to_s)
    if props_value.is_a?(::Hash)
       found[props_key] = validate_props(event,props_value,{})
    elsif props_value.is_a?(::Array)
       found[props_key]=props_value
   elsif !props_value.nil? and props_value.to_s.length > 0
    @logger.warn("props_value: " + props_value.to_s)
    if !event.get(props_value)
       @logger.warn("Field referenced by #{props_value} is missing")
       found[props_key] = props_value.empty? ? "n/a" : props_value
     else
       found[props_key]=event.get(props_value)
     end
    else
       found[props_key]="n/a"
    end
  end
  found
end