lib/logstash/inputs/snmp.rb in logstash-input-snmp-1.2.8 vs lib/logstash/inputs/snmp.rb in logstash-input-snmp-1.3.0

- old
+ new

@@ -5,15 +5,28 @@ require "socket" # for Socket.gethostname require_relative "snmp/client" require_relative "snmp/clientv3" require_relative "snmp/mib" +require 'logstash/plugin_mixins/ecs_compatibility_support' +require 'logstash/plugin_mixins/ecs_compatibility_support/target_check' +require 'logstash/plugin_mixins/event_support/event_factory_adapter' +require 'logstash/plugin_mixins/validator_support/field_reference_validation_adapter' + # Generate a repeating message. # # This plugin is intented only as an example. class LogStash::Inputs::Snmp < LogStash::Inputs::Base + + include LogStash::PluginMixins::ECSCompatibilitySupport(:disabled, :v1, :v8 => :v1) + include LogStash::PluginMixins::ECSCompatibilitySupport::TargetCheck + + include LogStash::PluginMixins::EventSupport::EventFactoryAdapter + + extend LogStash::PluginMixins::ValidatorSupport::FieldReferenceValidationAdapter + config_name "snmp" # List of OIDs for which we want to retrieve the scalar value config :get,:validate => :array # ["1.3.6.1.2.1.1.1.0"] @@ -65,13 +78,10 @@ # Set polling interval in seconds # # The default, `30`, means poll each host every 30 seconds. config :interval, :validate => :number, :default => 30 - # Add the default "host" field to the event. - config :add_field, :validate => :hash, :default => { "host" => "%{[@metadata][host_address]}" } - # SNMPv3 Credentials # # A single user can be configured and will be used for all defined SNMPv3 hosts. # Multiple snmp input declarations will be needed if multiple SNMPv3 users are required. # If not using SNMPv3 simply leave options empty. @@ -92,13 +102,33 @@ config :priv_pass, :validate => :password # The SNMPv3 security level can be Authentication, No Privacy; Authentication, Privacy; or no Authentication, no Privacy config :security_level, :validate => ["noAuthNoPriv", "authNoPriv", "authPriv"] + # Defines a target field for placing fields. + # If this setting is omitted, data gets stored at the root (top level) of the event. + # The target is only relevant while decoding data into a new event. + config :target, :validate => :field_reference + BASE_MIB_PATH = ::File.join(__FILE__, "..", "..", "..", "mibs") PROVIDED_MIB_PATHS = [::File.join(BASE_MIB_PATH, "logstash"), ::File.join(BASE_MIB_PATH, "ietf")].map { |path| ::File.expand_path(path) } + def initialize(params={}) + super(params) + + @host_protocol_field = ecs_select[disabled: '[@metadata][host_protocol]', v1: '[@metadata][input][snmp][host][protocol]'] + @host_address_field = ecs_select[disabled: '[@metadata][host_address]', v1: '[@metadata][input][snmp][host][address]'] + @host_port_field = ecs_select[disabled: '[@metadata][host_port]', v1: '[@metadata][input][snmp][host][port]'] + @host_community_field = ecs_select[disabled: '[@metadata][host_community]', v1: '[@metadata][input][snmp][host][community]'] + + # Add the default "host" field to the event, for backwards compatibility, or host.ip in ecs mode + unless params.key?('add_field') + host_ip_field = ecs_select[disabled: "host", v1: "[host][ip]"] + @add_field = { host_ip_field => "%{#{@host_address_field}}" } + end + end + def register validate_oids! validate_hosts! validate_tables! validate_strip! @@ -163,50 +193,53 @@ def run(queue) # for now a naive single threaded poller which sleeps off the remaining interval between # each run. each run polls all the defined hosts for the get and walk options. stoppable_interval_runner.every(@interval, "polling hosts") do @client_definitions.each do |definition| + client = definition[:client] result = {} if !definition[:get].empty? + oids = definition[:get] begin - result = result.merge(definition[:client].get(definition[:get], @oid_root_skip, @oid_path_length)) + result = result.merge(client.get(oids, @oid_root_skip, @oid_path_length)) rescue => e - logger.error("error invoking get operation on #{definition[:host_address]} for OIDs: #{definition[:get]}, ignoring", :exception => e, :backtrace => e.backtrace) + logger.error("error invoking get operation for OIDs: #{oids}, ignoring", + host: definition[:host_address], exception: e, backtrace: e.backtrace) end end - if !definition[:walk].empty? + if !definition[:walk].empty? definition[:walk].each do |oid| begin - result = result.merge(definition[:client].walk(oid, @oid_root_skip, @oid_path_length)) + result = result.merge(client.walk(oid, @oid_root_skip, @oid_path_length)) rescue => e - logger.error("error invoking walk operation on OID: #{oid}, ignoring", :exception => e, :backtrace => e.backtrace) + logger.error("error invoking walk operation on OID: #{oid}, ignoring", + host: definition[:host_address], exception: e, backtrace: e.backtrace) end end end - if !Array(@tables).empty? + if !Array(@tables).empty? @tables.each do |table_entry| begin - result = result.merge(definition[:client].table(table_entry, @oid_root_skip, @oid_path_length)) + result = result.merge(client.table(table_entry, @oid_root_skip, @oid_path_length)) rescue => e - logger.error("error invoking table operation on OID: #{table_entry['name']}, ignoring", :exception => e, :backtrace => e.backtrace) + logger.error("error invoking table operation on OID: #{table_entry['name']}, ignoring", + host: definition[:host_address], exception: e, backtrace: e.backtrace) end end end unless result.empty? - metadata = { - "host_protocol" => definition[:host_protocol], - "host_address" => definition[:host_address], - "host_port" => definition[:host_port], - "host_community" => definition[:host_community], - } - result["@metadata"] = metadata - - event = LogStash::Event.new(result) + event = targeted_event_factory.new_event(result) + event.set(@host_protocol_field, definition[:host_protocol]) + event.set(@host_address_field, definition[:host_address]) + event.set(@host_port_field, definition[:host_port]) + event.set(@host_community_field, definition[:host_community]) decorate(event) queue << event + else + logger.debug? && logger.debug("no snmp data retrieved", host: definition[:host_address]) end end end end @@ -228,10 +261,10 @@ end private OID_REGEX = /^\.?([0-9\.]+)$/ - HOST_REGEX = /^(?<host_protocol>udp|tcp):(?<host_address>.+)\/(?<host_port>\d+)$/i + HOST_REGEX = /^(?<host_protocol>\w+):(?<host_address>.+)\/(?<host_port>\d+)$/i VERSION_REGEX =/^1|2c|3$/ def validate_oids! @get = Array(@get).map do |oid| # verify oids for valid pattern and get rid or any leading dot if present