fluent-plugin-snmp 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fluent-plugin-snmp.gemspec
4
+ gemspec
5
+ gem 'mocha'
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2012, Internet Initiative Japan Inc.
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
@@ -0,0 +1,56 @@
1
+ # Fluent::Plugin::Snmp
2
+
3
+ Fluent plugin from snmp
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'fluent-plugin-snmp'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install fluent-plugin-snmp
18
+
19
+ ## Usage
20
+
21
+ <source>
22
+ type snmp
23
+ tag snmp.server1
24
+ nodes name, value
25
+ host server1
26
+ community private
27
+ version 2c
28
+ mib hrStorageIndex, hrStorageDescr, hrStorageSize, hrStorageUsed
29
+ mib_modules HOST-RESOURCES-MIB
30
+ retries 0
31
+ timeout 3s
32
+ polling_time 0,10,20,30,40,50
33
+ </source>
34
+
35
+ <source>
36
+ type snmp
37
+ tag snmp.server2
38
+ host server2
39
+ community private
40
+ version 2c
41
+ mib hrStorageIndex, hrStorageDescr,
42
+ hrStorageSize, hrStorageUsed
43
+ mib_modules HOST-RESOURCES-MIB
44
+ retries 0
45
+ timeout 3s
46
+ polling_time 5,15,25,35,45,55
47
+ </source>
48
+
49
+
50
+ 2012-11-08 16:07:40 +0900 snmp.server1: {"name":"HOST-RESOURCES-MIB::hrStorageUsed.31","value":"2352425"}
51
+ 2012-11-08 16:07:40 +0900 snmp.server2: {"value":"[name=HOST-RESOURCES-MIB::hrStorageIndex.7, value=7 (INTEGER)]"}
52
+
53
+
54
+ ## Copyright
55
+ Copyright (c) 2012 Internet Initiative Inc.
56
+ Apache Licence, Version 2.0
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require 'rake/testtask'
4
+ Rake::TestTask.new(:test) do |test|
5
+ test.libs << 'lib' << 'test'
6
+ test.pattern = 'test/**/test_*.rb'
7
+ test.verbose = true
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = "fluent-plugin-snmp"
6
+ gem.version = "0.0.3"
7
+ gem.authors = ["Hiroshi Sugimoto"]
8
+ gem.email = ["h-sugimoto@iij.ad.jp"]
9
+ gem.description = %q{Input plugin to walk snmp}
10
+ gem.summary = %q{Input plugin to walk snmp}
11
+
12
+ gem.files = `git ls-files`.split($\)
13
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
14
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
15
+ gem.require_paths = ["lib"]
16
+
17
+ gem.add_development_dependency "fluentd"
18
+ gem.add_development_dependency "snmp"
19
+ gem.add_development_dependency "polling"
20
+ gem.add_runtime_dependency "fluentd"
21
+ gem.add_runtime_dependency "snmp"
22
+ gem.add_runtime_dependency "polling"
23
+ end
@@ -0,0 +1,163 @@
1
+ require 'snmp' # http://snmplib.rubyforge.org/doc/index.html
2
+ require 'polling' # https://github.com/iij/polling.git
3
+
4
+ module Fluent
5
+ class SnmpInput < Input
6
+ Plugin.register_input('snmp', self)
7
+
8
+ # Fluent Params
9
+ # require param: tag, mib
10
+ config_param :tag, :string
11
+ config_param :mib, :string
12
+ config_param :nodes, :string, :default => nil
13
+ config_param :polling_time, :string, :default => nil
14
+ config_param :host_name, :string, :default => nil
15
+
16
+ # SNMP Lib Params
17
+ # require param: host, community
18
+ #
19
+ # Option Default Value
20
+ # --------------------------------------
21
+ # :host 'localhost'
22
+ # :port 161
23
+ # :trap_port 162
24
+ # :community 'public'
25
+ # :write_community Same as :community
26
+ # :version :SNMPv2c
27
+ # :timeout 1 (timeout units are seconds)
28
+ # :retries 5
29
+ # :transport UDPTransport
30
+ # :max_recv_bytes 8000 bytes
31
+ # :mib_dir MIB::DEFAULT_MIB_PATH
32
+ # :mib_modules SNMPv2-SMI, SNMPv2-MIB, IF-MIB, IP-MIB, TCP-MIB, UDP-MIB
33
+ # :use_IPv6 false, unless :host is formatted like an IPv6 address
34
+ config_param :host, :string
35
+ config_param :port, :integer, :default => nil
36
+ config_param :trap_port, :integer, :default => nil
37
+ config_param :community, :string
38
+ config_param :write_community, :string, :default => nil
39
+ config_param :version, :string, :default => nil # Use :SNMPv1 or :SNMPv2c
40
+ config_param :timeout, :time, :default => nil
41
+ config_param :retries, :integer, :default => nil
42
+ config_param :transport, :string, :default => nil
43
+ config_param :max_recv_bytes, :string, :default => nil
44
+ config_param :mib_dir, :string, :default => nil
45
+ config_param :mib_modules, :string, :default => nil
46
+ config_param :use_IPv6, :string, :default => nil
47
+
48
+ def initialize
49
+ super
50
+ end
51
+
52
+ def configure(conf)
53
+ super
54
+
55
+ raise ConfigError, "tag is required param" if @tag.empty?
56
+
57
+ # @mib, @mib_modules, @nodesを配列に変換
58
+ @mib = @mib.split(',').map{|str| str.strip}
59
+ raise ConfigError, "snmp: 'mib' parameter is required on snmp input" if @mib.empty?
60
+
61
+ @mib_modules = @mib_modules.split(',').map{|str| str.strip} unless @mib_modules.nil?
62
+ raise ConfigError, "snmp: 'mib_modules' parameter is required on snmp input" if !@mib_modules.nil? && @mib_modules.empty?
63
+
64
+ @nodes = @nodes.split(',').map{|str| str.strip} unless @nodes.nil?
65
+ raise ConfigError, "snmp: 'nodes' parameter is required on snmp input" if !@nodes.nil? && @nodes.empty?
66
+
67
+ @polling_time = @polling_time.split(',').map{|str| str.strip.to_i} unless @polling_time.nil?
68
+ raise ConfigError, "snmp: 'polling_time' parameter is required on snmp input" if !@polling_time.nil? && @polling_time.empty?
69
+
70
+ # snmp version
71
+ @version = @version == "1" ? :SNMPv1 : :SNMPv2c
72
+
73
+ # SNMP Libraryの初期値を設定
74
+ @snmp_init_params = {
75
+ :host => @host, #or conf["host"]
76
+ :port => @port,
77
+ :trap_port => @trap_port,
78
+ :community => @community,
79
+ :write_community => @write_community,
80
+ :version => @version,
81
+ :timeout => @timeout,
82
+ :retries => @retries,
83
+ :transport => @transport,
84
+ :max_recv_bytes => @max_recv_bytes,
85
+ :mib_dir => @mib_dir,
86
+ :mib_modules => @mib_modules,
87
+ :use_IPv6 => @use_IPv6
88
+ }
89
+
90
+ @retry_conut = 0
91
+ end
92
+
93
+ def starter
94
+ @starter = Thread.new do
95
+ yield
96
+ end
97
+ end
98
+
99
+ def start
100
+ starter do
101
+ @manager = SNMP::Manager.new(@snmp_init_params)
102
+ @thread = Thread.new(&method(:run))
103
+ @end_flag = false
104
+ end
105
+ end
106
+
107
+ def run
108
+ Polling::run(@polling_time) do
109
+ snmpwalk(@manager, @mib, @nodes)
110
+ break if @end_flag
111
+ end
112
+ rescue TypeError => ex
113
+ $log.error "run TypeError", :error=>ex.message
114
+ exit
115
+ rescue => ex
116
+ $log.error "run failed", :error=>ex.message
117
+ sleep(10)
118
+ @retry_conut += 1
119
+ retry if @retry_conut < 30
120
+ end
121
+
122
+ #Ctrl-cで処理を停止時に呼ばれる
123
+ def shutdown
124
+ @end_flag = true
125
+ @thread.run
126
+ @thread.join
127
+ @starter.join
128
+ @manager.close
129
+ end
130
+
131
+ private
132
+
133
+ def snmpwalk(manager, mib, nodes = nil, test = false)
134
+ manager.walk(mib) do |row|
135
+ time = Engine.now
136
+ time = time - time % 5
137
+ record = Hash.new
138
+ row.each do |vb|
139
+ if nodes.nil?
140
+ record["value"] = vb
141
+ else
142
+ nodes.each{|param| record[param] = check_type(vb.__send__(param))}
143
+ end
144
+ Engine.emit(@tag, time, record)
145
+ return {:time => time, :record => record} if test
146
+ end
147
+ end
148
+ end
149
+
150
+ # SNMPで取得したデータの型チェック
151
+ def check_type(value)
152
+ if value =~ /^\d+(\.\d+)?$/
153
+ return value.to_f
154
+ else
155
+ return value.to_s
156
+ end
157
+ rescue => ex
158
+ $Log.error "snmp failed to check_type", :error=>ex.message
159
+ $log.warn_backtrace ex.backtrace
160
+ end
161
+
162
+ end
163
+ end
@@ -0,0 +1,31 @@
1
+ <source>
2
+ type snmp
3
+ tag snmp.server1
4
+ nodes name, value
5
+ host localhost
6
+ community private
7
+ version 2c
8
+ mib hrStorageIndex, hrStorageDescr, hrStorageSize, hrStorageUsed
9
+ mib_modules HOST-RESOURCES-MIB
10
+ retries 0
11
+ timeout 3s
12
+ polling_time 0,10,20,30,40,50
13
+ </source>
14
+
15
+ <source>
16
+ type snmp
17
+ tag snmp.server2
18
+ nodes name, value
19
+ host localhost
20
+ community private
21
+ version 2c
22
+ mib hrStorageIndex, hrStorageDescr, hrStorageSize, hrStorageUsed
23
+ mib_modules HOST-RESOURCES-MIB
24
+ retries 0
25
+ timeout 3s
26
+ polling_time 5,15,25,35,45,55
27
+ </source>
28
+
29
+ <match snmp.server*>
30
+ type stdout
31
+ </match>
@@ -0,0 +1,22 @@
1
+ require 'test/unit'
2
+
3
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+
6
+ require 'fluent/test'
7
+
8
+ unless ENV.has_key?('VERBOSE')
9
+ nulllogger = Object.new
10
+ nulllogger.instance_eval {|obj|
11
+ def method_missing(method, *args)
12
+ # pass
13
+ end
14
+ }
15
+ $log = nulllogger
16
+ end
17
+
18
+ require 'fluent/plugin/in_snmp'
19
+
20
+ class Test::Unit::TestCase
21
+ end
22
+
@@ -0,0 +1,88 @@
1
+ require 'helper'
2
+ require 'mocha'
3
+ require 'time'
4
+
5
+ class SnmpInputTest < Test::Unit::TestCase
6
+
7
+ def setup
8
+ Fluent::Test.setup
9
+ @obj = Fluent::SnmpInput.new
10
+ end
11
+
12
+ CONFIG = %[
13
+ tag snmp.server1
14
+ mib hrStorageIndex, hrStorageDescr, hrStorageSize, hrStorageUsed
15
+ nodes name, value
16
+ polling_time 0,10,20,30,40,50
17
+ host localhost
18
+ community private
19
+ mib_modules HOST-RESOURCES-MIB, IF-MIB
20
+ retries 0
21
+ timeout 3s
22
+ ]
23
+
24
+ def create_driver(conf=CONFIG)
25
+ Fluent::Test::InputTestDriver.new(Fluent::SnmpInput).configure(conf)
26
+ end
27
+
28
+ def test_configure
29
+ d = create_driver
30
+
31
+ # Fluent Params
32
+ assert_equal "snmp.server1", d.instance.tag
33
+ assert_equal ["hrStorageIndex","hrStorageDescr","hrStorageSize","hrStorageUsed"], d.instance.mib
34
+ assert_equal ["name","value"], d.instance.nodes
35
+ assert_equal [0,10,20,30,40,50], d.instance.polling_time
36
+
37
+ # SNMP Lib Params
38
+ assert_equal "localhost", d.instance.host
39
+ assert_nil d.instance.port
40
+ assert_nil d.instance.trap_port
41
+ assert_equal "private", d.instance.community
42
+ assert_nil d.instance.write_community
43
+ assert_equal :SNMPv2c, d.instance.version
44
+ assert_equal 3, d.instance.timeout
45
+ assert_equal 0, d.instance.retries
46
+ assert_nil d.instance.transport
47
+ assert_nil d.instance.max_recv_bytes
48
+ assert_nil d.instance.mib_dir
49
+ assert_equal ["HOST-RESOURCES-MIB","IF-MIB"], d.instance.mib_modules
50
+ assert_nil d.instance.use_IPv6
51
+ end
52
+
53
+ def test_check_type
54
+ assert_equal "test", @obj.__send__(:check_type,"test")
55
+ assert_equal "utrh0", @obj.__send__(:check_type,"utrh0")
56
+ assert_equal "sensorValue_degC", @obj.__send__(:check_type,"sensorValue_degC")
57
+ assert_equal "sensorValue_%RH", @obj.__send__(:check_type,"sensorValue_%RH")
58
+ assert_equal 12.00, @obj.__send__(:check_type,"12")
59
+ assert_equal 12.34, @obj.__send__(:check_type,"12.34")
60
+ end
61
+
62
+ def test_snmpwalk
63
+ d = create_driver
64
+ nodes = d.instance.nodes
65
+ mib = d.instance.mib
66
+
67
+ snmp_init_params = {
68
+ :host => d.instance.host,
69
+ :community => d.instance.community,
70
+ :timeout => d.instance.timeout,
71
+ :retries => d.instance.retries,
72
+ :mib_dir => d.instance.mib_dir,
73
+ :mib_modules => d.instance.mib_modules,
74
+ }
75
+
76
+ # unixtime 1356965990
77
+ Time.stubs(:now).returns(Time.parse "2012/12/31 23:59:50")
78
+ manager = SNMP::Manager.new(snmp_init_params)
79
+
80
+ data = @obj.__send__(:snmpwalk, manager, mib, nodes, true)
81
+ record = data[:record]
82
+
83
+ assert_equal 1356965990, data[:time]
84
+ assert_equal "HOST-RESOURCES-MIB::hrStorageIndex.1", record["name"]
85
+ assert_equal "1", record["value"]
86
+ end
87
+
88
+ end
metadata ADDED
@@ -0,0 +1,153 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-snmp
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Hiroshi Sugimoto
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-10 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: fluentd
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: snmp
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: polling
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: fluentd
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: snmp
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: polling
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ description: Input plugin to walk snmp
111
+ email:
112
+ - h-sugimoto@iij.ad.jp
113
+ executables: []
114
+ extensions: []
115
+ extra_rdoc_files: []
116
+ files:
117
+ - .gitignore
118
+ - Gemfile
119
+ - LICENSE.txt
120
+ - README.md
121
+ - Rakefile
122
+ - fluent-plugin-snmp.gemspec
123
+ - lib/fluent/plugin/in_snmp.rb
124
+ - snmp.conf.sample
125
+ - test/helper.rb
126
+ - test/plugin/test_in_snmp.rb
127
+ homepage:
128
+ licenses: []
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ none: false
135
+ requirements:
136
+ - - ! '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ required_rubygems_version: !ruby/object:Gem::Requirement
140
+ none: false
141
+ requirements:
142
+ - - ! '>='
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ requirements: []
146
+ rubyforge_project:
147
+ rubygems_version: 1.8.24
148
+ signing_key:
149
+ specification_version: 3
150
+ summary: Input plugin to walk snmp
151
+ test_files:
152
+ - test/helper.rb
153
+ - test/plugin/test_in_snmp.rb