fluent-plugin-nsca 0.0.1

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,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fluent-plugin-nsca.gemspec
4
+ gemspec
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2015- MIYAKAWA Taku
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,240 @@
1
+ # fluent-plugin-nsca
2
+
3
+ [Fluentd](http://fluentd.org) output plugin to send service checks to an
4
+ [NSCA](http://exchange.nagios.org/directory/Addons/Passive-Checks/NSCA--2D-Nagios-Service-Check-Acceptor/details)
5
+ / [Nagios](http://www.nagios.org/) monitoring server.
6
+
7
+ The plugin sends a service check to the NSCA server for each record.
8
+
9
+ ## Configuration
10
+
11
+ ### Examples
12
+
13
+ ```apache
14
+ <match ddos>
15
+ type nsca
16
+
17
+ # Connection settings
18
+ server monitor.example.com
19
+ port 5667
20
+ password aoxomoxoa
21
+
22
+ # Payload settings
23
+
24
+ ## The monitored host name is "web.example.com"
25
+ host_name web.example.com
26
+
27
+ ## The service is "ddos_detection"
28
+ service_description ddos_detection
29
+
30
+ ## The return code is read from the field "severity"
31
+ return_code_field severity
32
+
33
+ ## The plugin output is not specified;
34
+ ## hence the plugin sends the JSON notation of the record.
35
+
36
+ </match>
37
+ ```
38
+
39
+ ### Plugin type
40
+
41
+ The type of this plugin is `nsca`.
42
+ Specify `type nsca` in the `match` section.
43
+
44
+ ### Connection
45
+
46
+ * `server` (default is "localhost")
47
+ * The IP address or the hostname of the host running the NSCA daemon.
48
+ * `port` (default i 5667)
49
+ * The port on which the NSCA daemon is running.
50
+ * `password` (default is empty string)
51
+ * The password for authentication and encryption.
52
+
53
+ ### Payload
54
+
55
+ A service check for the NSCA server
56
+ comprises the following four fields.
57
+
58
+ * Host name
59
+ * The name of the monitored host.
60
+ * The corresponding property in the Nagios configuration is
61
+ `host_name` property in a `host` definition.
62
+ * Service description
63
+ * The name of the monitored service.
64
+ * The corresponding property in the Nagios configuration is
65
+ `service_description` property in a `service` definition.
66
+ * Return code
67
+ * The severity of the service status.
68
+ * 0 (OK), 1 (WARNING), 2 (CRITICAL) or 3 (UNKNOWN).
69
+ * Plugin output
70
+ * A description of the service status.
71
+
72
+ The destination of checks
73
+ are identified by the pair of the host name and the service description.
74
+
75
+ #### Host name
76
+
77
+ The host name is determined as below.
78
+
79
+ 1. The host name of the fluentd server (lowest priority)
80
+ 2. `host_name` option
81
+ 3. The field specified by `host_name_field` option (highest priority)
82
+
83
+ For example,
84
+ let the fluentd server have the host name "fluent",
85
+ and the configuration file contain the section below:
86
+
87
+ ```apache
88
+ <match ddos>
89
+ type nsca
90
+ ...snip...
91
+ host_name_field monitee
92
+ </match>
93
+ ```
94
+
95
+ When the record `{"num" => 42, "monitee" => "web.example.org"}`
96
+ is input to the tag `ddos`,
97
+ the plugin sends a service check with the host name "web.example.org".
98
+
99
+ When the record `{"num" => 42}` is input to the tag `ddos`,
100
+ the plugin sends a service check with the host name "fluent"
101
+ (the host name of the fluentd server).
102
+
103
+ Be aware that if the host name exceeds 64 bytes, it will be truncated.
104
+
105
+ #### Service description
106
+
107
+ The service description is determined as below.
108
+
109
+ 1. The tag name (lowest priority)
110
+ 2. `service_description` option
111
+ 3. The field specified by `service_description_field` option (highest priority)
112
+
113
+ For example,
114
+ let the configuration file contain the section below:
115
+
116
+ ```apache
117
+ <match ddos>
118
+ type nsca
119
+ ...snip...
120
+ service_description_field monitee_service
121
+ </match>
122
+ ```
123
+
124
+ When the record
125
+ `{"num" => 42, "monitee_service" => "ddos_detection"}`
126
+ is input to the tag `ddos`,
127
+ the plugin sends a service check with the service description
128
+ "ddos\_detection".
129
+
130
+ When the record
131
+ `{"num" => 42}` is input to the tag `ddos`,
132
+ the plugin sends a service check with the service description
133
+ "ddos" (the tag name).
134
+
135
+ Be aware that if the service description exceeds 128 bytes,
136
+ it will be truncated.
137
+
138
+ #### Return code
139
+
140
+ The return code is determined as below.
141
+
142
+ 1. 3 or UNKNOWN (lowest priority)
143
+ 2. `return_code` option
144
+ * The permitted values are `0`, `1`, `2`, `3`,
145
+ and `OK`, `WARNING`, `CRITICAL`, `UNKNOWN`.
146
+ 3. The field specified by `return_code_field` option (highest priority)
147
+ * The values permitted for the field are integers `0`, `1`, `2`, `3`
148
+ and strings `"0"`, `"1"`, `"2"`, `"3"`,
149
+ `"OK"`, `"WARNING"`, `"CRITICAL"`, `"UNKNOWN"`.
150
+ * If the field contains a value not permitted,
151
+ the plugin falls back to `return_code` if present, or to 3 (UNKNOWN).
152
+
153
+ For example,
154
+ let the configuration file contain the section below:
155
+
156
+ ```apache
157
+ <match ddos>
158
+ type nsca
159
+ ...snip...
160
+ return_code_field retcode
161
+ </match>
162
+ ```
163
+
164
+ When the record
165
+ `{"num" => 42, "retcode" => "WARNING"}` is input to the tag `ddos`,
166
+ the plugin sends a service check with the return code `1`,
167
+ which means WARNING.
168
+
169
+ When the record
170
+ `{"num" => 42}` is input to the tag `ddos`,
171
+ the plugin sends a service check with the default return code `3`.
172
+
173
+ #### Plugin output
174
+
175
+ The plugin output is determined as below.
176
+
177
+ 1. JSON notation of the record (lowest priority)
178
+ 2. `plugin_output` option
179
+ 3. The field specified by `plugin_output_field` option (highest priority)
180
+
181
+ For example,
182
+ let the configuration file contain the section below:
183
+
184
+ ```apache
185
+ <match ddos>
186
+ type nsca
187
+ ...snip...
188
+ plugin_output_field status
189
+ </match>
190
+ ```
191
+
192
+ When the record
193
+ `{"num" => 42, "status" => "DDOS detected"}` is input to the tag `ddos`,
194
+ the plugin sends a service check with the plugin output "DDOS detected".
195
+
196
+ When the record
197
+ `{"num" => 42}` is input to the tag `ddos`,
198
+ the plugin sends a service check with the plugin output '{"num":42}'.
199
+
200
+ Be aware that if the plugin output exceeds 512 bytes,
201
+ it will be truncated.
202
+
203
+ ### Buffering
204
+
205
+ The default value of `flush_interval` option is set to 1 second.
206
+ It means that checks are sent for every 1 second.
207
+
208
+ Except for `flush_interval`,
209
+ the plugin uses default options
210
+ for buffered output plugins (defined in Fluent::BufferedOutput class).
211
+
212
+ You can override buffering options in the configuration.
213
+ For example:
214
+
215
+ ```apache
216
+ <match ddos>
217
+ type nsca
218
+ ...snip...
219
+ buffer_type file
220
+ buffer_path /var/lib/td-agent/buffer/ddos
221
+ flush_interval 0.1
222
+ try_flush_interval 0.1
223
+ </match>
224
+ ```
225
+
226
+ ## Installation
227
+
228
+ If you are using td-agent, execute the command below.
229
+
230
+ $ sudo /usr/lib64/fluent/ruby/bin/fluent-gem fluent-plugin-nsca
231
+
232
+ Then add `match` section to your configuration file.
233
+
234
+ ## Contributing
235
+
236
+ 1. Fork it
237
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
238
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
239
+ 4. Push to the branch (`git push origin my-new-feature`)
240
+ 5. Create new Pull Request
@@ -0,0 +1,13 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # vim: et sw=2 sts=2
3
+
4
+ require "bundler/gem_tasks"
5
+ require 'rake/testtask'
6
+
7
+ Rake::TestTask.new(:test) do |test|
8
+ test.libs << 'lib' << 'test'
9
+ test.pattern = 'test/**/test_*.rb'
10
+ test.verbose = true
11
+ end
12
+
13
+ task :default => :test
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "fluent-plugin-nsca"
8
+ spec.version = '0.0.1'
9
+ spec.authors = ["MIYAKAWA Taku"]
10
+ spec.email = ["miyakawa.taku@gmail.com"]
11
+ spec.description = %q{Fluentd output plugin to send service checks to a Nagios NSCA daemon}
12
+ spec.summary = %q{Fluentd output plugin to send service checks to a Nagios NSCA daemon}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rr"
24
+ spec.add_runtime_dependency "send_nsca", "0.5.0"
25
+ spec.add_runtime_dependency "fluentd"
26
+ end
@@ -0,0 +1,177 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # vim: et sw=2 sts=2
3
+
4
+ module Fluent
5
+ class NscaOutput < Fluent::BufferedOutput
6
+ Fluent::Plugin.register_output('nsca', self)
7
+
8
+ # These max bytes are specified in the pack string in send_nsca library
9
+ MAX_HOST_NAME_BYTES = 64
10
+ MAX_SERVICE_DESCRIPTION_BYTES = 128
11
+ MAX_PLUGIN_OUTPUT_BYTES = 512
12
+
13
+ # The IP address or the hostname of the host running the NSCA daemon.
14
+ config_param :server, :string, :default => 'localhost'
15
+
16
+ # The port on which the NSCA daemon is running.
17
+ config_param :port, :integer, :default => 5667
18
+
19
+ # The password for authentication and encryption.
20
+ config_param :password, :string, :default => ''
21
+
22
+ # Host name options: default = the host name of the fluentd server
23
+ config_param :host_name, :string, :default => nil
24
+ config_param :host_name_field, :string, :default => nil
25
+
26
+ # Service description options: default=tag
27
+ config_param :service_description, :string, :default => nil
28
+ config_param :service_description_field, :string, :default => nil
29
+
30
+ # Return code options: default=3 (UNKNOWN)
31
+ config_param :return_code_field, :string, :default => nil
32
+ config_param(:return_code, :default => 3) { |return_code|
33
+ if not @@valid_return_codes.has_key?(return_code)
34
+ raise Fluent::ConfigError,
35
+ "invalid 'return_code': #{return_code}; 'return_code' must be" +
36
+ " 0, 1, 2, 3, OK, WARNING, CRITICAL, or UNKNOWN"
37
+ end
38
+ @@valid_return_codes[return_code]
39
+ }
40
+ @@valid_return_codes = {
41
+ 0 => 0, 1 => 1, 2 => 2, 3 => 3,
42
+ '0' => 0, '1' => 1, '2' => 2, '3' => 3,
43
+ 'OK' => 0, 'WARNING' => 1, 'CRITICAL' => 2, 'UNKNOWN' => 3
44
+ }
45
+
46
+ # Plugin output options: default = JSON notation of the record
47
+ config_param :plugin_output, :string, :default => nil
48
+ config_param :plugin_output_field, :string, :default => nil
49
+
50
+ # Overrides a buffering option
51
+ config_param :flush_interval, :time, :default => 1
52
+
53
+ private
54
+ def initialize
55
+ super
56
+ require 'send_nsca'
57
+ end
58
+
59
+ public
60
+ def configure(conf)
61
+ super
62
+ @host_name ||= Socket.gethostname
63
+ warn_if_host_name_exceeds_max_bytes(@host_name)
64
+ warn_if_service_description_exceeds_max_bytes(@service_description)
65
+ warn_if_plugin_output_exceeds_max_bytes(@plugin_output)
66
+ end
67
+
68
+ private
69
+ def warn_if_host_name_exceeds_max_bytes(host_name)
70
+ if host_name.bytesize > MAX_HOST_NAME_BYTES
71
+ log.warn("Host name exceeds the max bytes; it will be truncated",
72
+ :max_host_name_bytes => MAX_HOST_NAME_BYTES,
73
+ :host_name => host_name)
74
+ end
75
+ end
76
+
77
+ private
78
+ def warn_if_service_description_exceeds_max_bytes(service_description)
79
+ if service_description and
80
+ service_description.bytesize > MAX_SERVICE_DESCRIPTION_BYTES
81
+ log.warn(
82
+ "Service description exceeds the max bytes; it will be truncated.",
83
+ :max_service_description_bytes => MAX_SERVICE_DESCRIPTION_BYTES,
84
+ :service_description => service_description)
85
+ end
86
+ end
87
+
88
+ private
89
+ def warn_if_plugin_output_exceeds_max_bytes(plugin_output)
90
+ if plugin_output and plugin_output.bytesize > MAX_PLUGIN_OUTPUT_BYTES
91
+ log.warn("Plugin output exceeds the max bytes; it will be truncated.",
92
+ :max_plugin_output_bytes => MAX_PLUGIN_OUTPUT_BYTES,
93
+ :plugin_output => plugin_output)
94
+ end
95
+ end
96
+
97
+ public
98
+ def format(tag, time, record)
99
+ [tag, time, record].to_msgpack
100
+ end
101
+
102
+ public
103
+ def write(chunk)
104
+ results = []
105
+ chunk.msgpack_each { |(tag, time, record)|
106
+ nsca_check = SendNsca::NscaConnection.new({
107
+ :nscahost => @server,
108
+ :port => @port,
109
+ :password => @password,
110
+ :hostname => determine_host_name(record),
111
+ :service => determine_service_description(tag, record),
112
+ :return_code => determine_return_code(record),
113
+ :status => determine_plugin_output(record)
114
+ })
115
+ results.push(nsca_check.send_nsca)
116
+ }
117
+
118
+ # Returns the results of send_nsca for tests
119
+ return results
120
+ end
121
+
122
+ private
123
+ def determine_host_name(record)
124
+ if @host_name_field and record[@host_name_field]
125
+ host_name = record[@host_name_field].to_s
126
+ warn_if_host_name_exceeds_max_bytes(host_name)
127
+ return host_name
128
+ else
129
+ return @host_name
130
+ end
131
+ end
132
+
133
+ private
134
+ def determine_service_description(tag, record)
135
+ if @service_description_field and record[@service_description_field]
136
+ service_description = record[@service_description_field]
137
+ warn_if_service_description_exceeds_max_bytes(service_description)
138
+ return service_description
139
+ elsif @service_description
140
+ return @service_description
141
+ else
142
+ warn_if_service_description_exceeds_max_bytes(tag)
143
+ return tag
144
+ end
145
+ end
146
+
147
+ private
148
+ def determine_return_code(record)
149
+ if @return_code_field and record[@return_code_field]
150
+ return_code = @@valid_return_codes[record[@return_code_field]]
151
+ if return_code
152
+ return return_code
153
+ end
154
+ log.warn('Invalid return code.',
155
+ :return_code_field => @return_code_field,
156
+ :value => record[@return_code_field],
157
+ :fall_back_to => @return_code)
158
+ end
159
+ return @return_code
160
+ end
161
+
162
+ private
163
+ def determine_plugin_output(record)
164
+ if @plugin_output_field and record[@plugin_output_field]
165
+ plugin_output = record[@plugin_output_field]
166
+ warn_if_plugin_output_exceeds_max_bytes(plugin_output)
167
+ return plugin_output
168
+ elsif @plugin_output
169
+ return @plugin_output
170
+ else
171
+ plugin_output = record.to_json
172
+ warn_if_plugin_output_exceeds_max_bytes(plugin_output)
173
+ return plugin_output
174
+ end
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,36 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # vim: et sw=2 sts=2
3
+
4
+ require 'rubygems'
5
+ require 'bundler'
6
+
7
+ begin
8
+ Bundler.setup(:default, :development)
9
+ rescue Bundler::BundlerError => e
10
+ $stderr.puts e.message
11
+ $stderr.puts "Run `bundle install` to install missing gems"
12
+ exit e.status_code
13
+ end
14
+
15
+ require 'test/unit'
16
+ require 'rr'
17
+
18
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
19
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
20
+
21
+ require 'fluent/test'
22
+
23
+ unless ENV.has_key?('VERBOSE')
24
+ nulllogger = Object.new
25
+ nulllogger.instance_eval {|obj|
26
+ def method_missing(method, *args)
27
+ # pass
28
+ end
29
+ }
30
+ $log = nulllogger
31
+ end
32
+
33
+ require 'fluent/plugin/out_nsca'
34
+
35
+ class Test::Unit::TestCase
36
+ end
@@ -0,0 +1,330 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # vim: et sw=2 sts=2
3
+
4
+ require 'helper'
5
+ require 'socket'
6
+ require 'send_nsca'
7
+
8
+ class NscaOutputTest < Test::Unit::TestCase
9
+ def setup
10
+ Fluent::Test.setup
11
+ stub.proxy(SendNsca::NscaConnection).new { |obj|
12
+ stub(obj).send_nsca {
13
+ obj.instance_eval {
14
+ [@nscahost, @port, @password, @hostname, @service, @return_code, @status]
15
+ }
16
+ }
17
+ }
18
+ end
19
+
20
+ CONFIG = %[
21
+ server monitor.example.com
22
+ port 4242
23
+ password aoxomoxoa
24
+ ]
25
+
26
+ def create_driver(conf = CONFIG, tag='test')
27
+ Fluent::Test::BufferedOutputTestDriver.new(Fluent::NscaOutput, tag).configure(conf)
28
+ end
29
+
30
+ # Connection settings are read
31
+ def test_connection_settings
32
+ driver = create_driver(CONFIG)
33
+ assert_equal 'monitor.example.com', driver.instance.instance_eval{ @server }
34
+ assert_equal 4242, driver.instance.instance_eval{ @port }
35
+ assert_equal 'aoxomoxoa', driver.instance.instance_eval{ @password }
36
+ end
37
+
38
+ # Default values are set to connection values
39
+ def test_default_connection_settings
40
+ driver = create_driver('')
41
+ assert_equal 'localhost', driver.instance.instance_eval{ @server }
42
+ assert_equal 5667, driver.instance.instance_eval{ @port }
43
+ assert_equal '', driver.instance.instance_eval{ @password }
44
+ end
45
+
46
+ # Rejects invalid return codes
47
+ def test_reject_invalid_return_codes
48
+ config = %[
49
+ #{CONFIG}
50
+ return_code invalid_return_code
51
+ ]
52
+ message = "invalid 'return_code': invalid_return_code;" +
53
+ " 'return_code' must be 0, 1, 2, 3," +
54
+ " OK, WARNING, CRITICAL, or UNKNOWN"
55
+ assert_raise(Fluent::ConfigError, message) {
56
+ create_driver(config)
57
+ }
58
+ end
59
+
60
+ # flush_interval is set to 1
61
+ def test_flush_interval
62
+ driver = create_driver('')
63
+ assert_equal 1, driver.instance.instance_eval { @flush_interval }
64
+ end
65
+
66
+ # Format to MessagePack(tag, time, record)
67
+ def test_format
68
+ driver = create_driver('', 'ddos')
69
+ time = Time.parse('2015-01-03 12:34:56 UTC').to_i
70
+ driver.emit({"name" => "Stephen"}, time)
71
+ driver.emit({"name" => "Aggi"}, time)
72
+ driver.expect_format(['ddos', time, {"name" => "Stephen"}].to_msgpack)
73
+ driver.expect_format(['ddos', time, {"name" => "Aggi"}].to_msgpack)
74
+ driver.run
75
+ end
76
+
77
+ # Sends a service check with constant values
78
+ def test_write_constant_values
79
+ config = %[
80
+ #{CONFIG}
81
+ host_name web.example.org
82
+ service_description ddos_monitor
83
+ return_code 2
84
+ plugin_output possible attacks
85
+ ]
86
+ driver = create_driver(config, 'ddos')
87
+ time = Time.parse('2015-01-03 12:34:56 UTC').to_i
88
+ driver.emit({"name" => "Stephen"}, time)
89
+ output = driver.run
90
+ assert_equal [['monitor.example.com', 4242, 'aoxomoxoa', 'web.example.org', 'ddos_monitor', 2, 'possible attacks']], output
91
+ end
92
+
93
+ # Sends a service check with host_name and host_name_field
94
+ def test_write_check_with_host_name_and_host_name_field
95
+ config = %[
96
+ #{CONFIG}
97
+ host_name_field host
98
+ host_name fallback.example.org
99
+
100
+ service_description ddos_monitor
101
+ return_code 2
102
+ plugin_output possible attacks
103
+ ]
104
+ driver = create_driver(config, 'ddos')
105
+ time = Time.parse('2015-01-03 12:34:56 UTC').to_i
106
+ driver.emit({"name" => "Stephen", "host" => "app.example.org"}, time)
107
+ driver.emit({"name" => "Aggi"}, time)
108
+ output = driver.run
109
+ expected_first = [
110
+ 'monitor.example.com', 4242, 'aoxomoxoa', 'app.example.org', 'ddos_monitor', 2, 'possible attacks'
111
+ ]
112
+ expected_second = [
113
+ 'monitor.example.com', 4242, 'aoxomoxoa', 'fallback.example.org', 'ddos_monitor', 2, 'possible attacks'
114
+ ]
115
+ assert_equal [expected_first, expected_second], output
116
+ end
117
+
118
+ # Sends a service check with host_name_field
119
+ def test_write_check_with_host_name_field
120
+ config = %[
121
+ #{CONFIG}
122
+ host_name_field host
123
+
124
+ service_description ddos_monitor
125
+ return_code 2
126
+ plugin_output possible attacks
127
+ ]
128
+ driver = create_driver(config, 'ddos')
129
+ time = Time.parse('2015-01-03 12:34:56 UTC').to_i
130
+ driver.emit({"name" => "Stephen", "host" => "app.example.org"}, time)
131
+ driver.emit({"name" => "Aggi"}, time)
132
+ output = driver.run
133
+ expected_first = [
134
+ 'monitor.example.com', 4242, 'aoxomoxoa', 'app.example.org', 'ddos_monitor', 2, 'possible attacks'
135
+ ]
136
+ expected_second = [
137
+ 'monitor.example.com', 4242, 'aoxomoxoa', Socket.gethostname, 'ddos_monitor', 2, 'possible attacks'
138
+ ]
139
+ assert_equal [expected_first, expected_second], output
140
+ end
141
+
142
+ # Sends a service check with service_description and service_description_field
143
+ def test_write_check_with_service_description_and_service_description_field
144
+ config = %[
145
+ #{CONFIG}
146
+ service_description ddos_detection
147
+ service_description_field service
148
+
149
+ host_name web.example.org
150
+ return_code 2
151
+ plugin_output possible attacks
152
+ ]
153
+ driver = create_driver(config, 'ddos')
154
+ time = Time.parse('2015-01-03 12:34:56 UTC').to_i
155
+ driver.emit({"name" => "Stephen", "service" => "possible_ddos"})
156
+ driver.emit({"name" => "Aggi"})
157
+ output = driver.run
158
+ expected_first = [
159
+ 'monitor.example.com', 4242, 'aoxomoxoa',
160
+ 'web.example.org', 'possible_ddos', 2, 'possible attacks'
161
+ ]
162
+ expected_second = [
163
+ 'monitor.example.com', 4242, 'aoxomoxoa',
164
+ 'web.example.org', 'ddos_detection', 2, 'possible attacks'
165
+ ]
166
+ assert_equal [expected_first, expected_second], output
167
+ end
168
+
169
+ # Sends a service check with service_description_field
170
+ def test_write_check_with_service_description_field
171
+ config = %[
172
+ #{CONFIG}
173
+ service_description_field service
174
+
175
+ host_name web.example.org
176
+ return_code 2
177
+ plugin_output possible attacks
178
+ ]
179
+ driver = create_driver(config, 'ddos')
180
+ time = Time.parse('2015-01-03 12:34:56 UTC').to_i
181
+ driver.emit({"name" => "Stephen", "service" => "possible_ddos"})
182
+ driver.emit({"name" => "Aggi"})
183
+ output = driver.run
184
+ expected_first = [
185
+ 'monitor.example.com', 4242, 'aoxomoxoa',
186
+ 'web.example.org', 'possible_ddos', 2, 'possible attacks'
187
+ ]
188
+ expected_second = [
189
+ 'monitor.example.com', 4242, 'aoxomoxoa',
190
+ 'web.example.org', 'ddos', 2, 'possible attacks'
191
+ ]
192
+ assert_equal [expected_first, expected_second], output
193
+ end
194
+
195
+ # Sends a service check with return_code and return_code_field
196
+ def test_write_check_with_return_code_and_return_code_field
197
+ config = %[
198
+ #{CONFIG}
199
+ return_code OK
200
+ return_code_field retcode
201
+
202
+ host_name web.example.org
203
+ service_description ddos_monitor
204
+ plugin_output possible attacks
205
+ ]
206
+ driver = create_driver(config, 'ddos')
207
+ time = Time.parse('2015-01-03 12:34:56 UTC').to_i
208
+ driver.emit({"name" => "Stephen", "retcode" => "UNKNOWN"})
209
+ driver.emit({"name" => "Aggi", "retcode" => "2"})
210
+ driver.emit({"name" => "Katrina", "retcode" => 1})
211
+ driver.emit({"name" => "Brian", "retcode" => "invalid-value"})
212
+ driver.emit({"name" => "Martin"})
213
+ output = driver.run
214
+ expected1 = [
215
+ 'monitor.example.com', 4242, 'aoxomoxoa',
216
+ 'web.example.org', 'ddos_monitor', 3, 'possible attacks'
217
+ ]
218
+ expected2 = [
219
+ 'monitor.example.com', 4242, 'aoxomoxoa',
220
+ 'web.example.org', 'ddos_monitor', 2, 'possible attacks'
221
+ ]
222
+ expected3 = [
223
+ 'monitor.example.com', 4242, 'aoxomoxoa',
224
+ 'web.example.org', 'ddos_monitor', 1, 'possible attacks'
225
+ ]
226
+ expected4 = [
227
+ 'monitor.example.com', 4242, 'aoxomoxoa',
228
+ 'web.example.org', 'ddos_monitor', 0, 'possible attacks'
229
+ ]
230
+ expected5 = [
231
+ 'monitor.example.com', 4242, 'aoxomoxoa',
232
+ 'web.example.org', 'ddos_monitor', 0, 'possible attacks'
233
+ ]
234
+ assert_equal [expected1, expected2, expected3, expected4, expected5], output
235
+ end
236
+
237
+ # Sends a service check with return_code_field
238
+ def test_write_check_with_return_code_field
239
+ config = %[
240
+ #{CONFIG}
241
+ return_code_field retcode
242
+
243
+ host_name web.example.org
244
+ service_description ddos_monitor
245
+ plugin_output possible attacks
246
+ ]
247
+ driver = create_driver(config, 'ddos')
248
+ time = Time.parse('2015-01-03 12:34:56 UTC').to_i
249
+ driver.emit({"name" => "Stephen", "retcode" => "OK"})
250
+ driver.emit({"name" => "Aggi", "retcode" => "1"})
251
+ driver.emit({"name" => "Katrina", "retcode" => 2})
252
+ driver.emit({"name" => "Brian", "retcode" => "invalid-value"})
253
+ driver.emit({"name" => "Martin"})
254
+ output = driver.run
255
+ expected1 = [
256
+ 'monitor.example.com', 4242, 'aoxomoxoa',
257
+ 'web.example.org', 'ddos_monitor', 0, 'possible attacks'
258
+ ]
259
+ expected2 = [
260
+ 'monitor.example.com', 4242, 'aoxomoxoa',
261
+ 'web.example.org', 'ddos_monitor', 1, 'possible attacks'
262
+ ]
263
+ expected3 = [
264
+ 'monitor.example.com', 4242, 'aoxomoxoa',
265
+ 'web.example.org', 'ddos_monitor', 2, 'possible attacks'
266
+ ]
267
+ expected4 = [
268
+ 'monitor.example.com', 4242, 'aoxomoxoa',
269
+ 'web.example.org', 'ddos_monitor', 3, 'possible attacks'
270
+ ]
271
+ expected5 = [
272
+ 'monitor.example.com', 4242, 'aoxomoxoa',
273
+ 'web.example.org', 'ddos_monitor', 3, 'possible attacks'
274
+ ]
275
+ assert_equal [expected1, expected2, expected3, expected4, expected5], output
276
+ end
277
+
278
+ # Sends a service check with plugin_output and plugin_output_field
279
+ def test_write_check_with_plugin_output_and_plugin_output_field
280
+ config = %[
281
+ #{CONFIG}
282
+ plugin_output DDOS detected
283
+ plugin_output_field status
284
+
285
+ host_name web.example.org
286
+ service_description ddos_monitor
287
+ return_code 2
288
+ ]
289
+ driver = create_driver(config, 'ddos')
290
+ time = Time.parse('2015-01-03 12:34:56 UTC').to_i
291
+ driver.emit({"name" => "Stephen", "status" => "Possible DDOS detected"})
292
+ driver.emit({"name" => "Aggi"})
293
+ output = driver.run
294
+ expected1 = [
295
+ 'monitor.example.com', 4242, 'aoxomoxoa',
296
+ 'web.example.org', 'ddos_monitor', 2, 'Possible DDOS detected'
297
+ ]
298
+ expected2 = [
299
+ 'monitor.example.com', 4242, 'aoxomoxoa',
300
+ 'web.example.org', 'ddos_monitor', 2, 'DDOS detected'
301
+ ]
302
+ assert_equal [expected1, expected2], output
303
+ end
304
+
305
+ # Sends a service check with plugin_output_field
306
+ def test_write_check_with_plugin_output_field
307
+ config = %[
308
+ #{CONFIG}
309
+ plugin_output_field status
310
+
311
+ host_name web.example.org
312
+ service_description ddos_monitor
313
+ return_code 2
314
+ ]
315
+ driver = create_driver(config, 'ddos')
316
+ time = Time.parse('2015-01-03 12:34:56 UTC').to_i
317
+ driver.emit({"name" => "Stephen", "status" => "Possible DDOS detected"})
318
+ driver.emit({"name" => "Aggi"})
319
+ output = driver.run
320
+ expected1 = [
321
+ 'monitor.example.com', 4242, 'aoxomoxoa',
322
+ 'web.example.org', 'ddos_monitor', 2, 'Possible DDOS detected'
323
+ ]
324
+ expected2 = [
325
+ 'monitor.example.com', 4242, 'aoxomoxoa',
326
+ 'web.example.org', 'ddos_monitor', 2, '{"name":"Aggi"}'
327
+ ]
328
+ assert_equal [expected1, expected2], output
329
+ end
330
+ end
metadata ADDED
@@ -0,0 +1,143 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-nsca
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - MIYAKAWA Taku
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-02-15 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
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: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
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: rr
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: send_nsca
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - '='
68
+ - !ruby/object:Gem::Version
69
+ version: 0.5.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.5.0
78
+ - !ruby/object:Gem::Dependency
79
+ name: fluentd
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
+ description: Fluentd output plugin to send service checks to a Nagios NSCA daemon
95
+ email:
96
+ - miyakawa.taku@gmail.com
97
+ executables: []
98
+ extensions: []
99
+ extra_rdoc_files: []
100
+ files:
101
+ - .gitignore
102
+ - Gemfile
103
+ - LICENSE.txt
104
+ - README.md
105
+ - Rakefile
106
+ - fluent-plugin-nsca.gemspec
107
+ - lib/fluent/plugin/out_nsca.rb
108
+ - test/helper.rb
109
+ - test/plugin/test_out_nsca.rb
110
+ homepage: ''
111
+ licenses:
112
+ - MIT
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ none: false
119
+ requirements:
120
+ - - ! '>='
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ segments:
124
+ - 0
125
+ hash: -559361203854015159
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ segments:
133
+ - 0
134
+ hash: -559361203854015159
135
+ requirements: []
136
+ rubyforge_project:
137
+ rubygems_version: 1.8.23
138
+ signing_key:
139
+ specification_version: 3
140
+ summary: Fluentd output plugin to send service checks to a Nagios NSCA daemon
141
+ test_files:
142
+ - test/helper.rb
143
+ - test/plugin/test_out_nsca.rb