naplug 1.6.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.
- data/LICENSE +31 -0
- data/README.md +471 -0
- data/examples/almostalwaysok +38 -0
- data/examples/alwaysok +30 -0
- data/examples/alwaysunknown +30 -0
- data/examples/dupplugin +25 -0
- data/examples/exception +32 -0
- data/examples/exception+ +48 -0
- data/examples/markerfile +27 -0
- data/examples/markerfile++ +40 -0
- data/examples/multiplug +34 -0
- data/examples/multiplugin +42 -0
- data/examples/multiplugins +44 -0
- data/examples/status +33 -0
- data/lib/naplug/about.rb +5 -0
- data/lib/naplug/helpers.rb +55 -0
- data/lib/naplug/output.rb +31 -0
- data/lib/naplug/performancedata.rb +52 -0
- data/lib/naplug/plugin.rb +155 -0
- data/lib/naplug/status.rb +62 -0
- data/lib/naplug/version.rb +3 -0
- data/lib/naplug.rb +163 -0
- metadata +67 -0
data/LICENSE
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2013 by Evernote Corporation, All rights reserved.
|
3
|
+
*
|
4
|
+
* Use of the source code and binary libraries included in this package
|
5
|
+
* is permitted under the following terms:
|
6
|
+
*
|
7
|
+
* Redistribution and use in source and binary forms, with or without
|
8
|
+
* modification, are permitted provided that the following conditions
|
9
|
+
* are met:
|
10
|
+
*
|
11
|
+
* 1. Redistributions of source code must retain the above copyright
|
12
|
+
* notice, this list of conditions and the following disclaimer.
|
13
|
+
* 2. Redistributions in binary form must reproduce the above copyright
|
14
|
+
* notice, this list of conditions and the following disclaimer in the
|
15
|
+
* documentation and/or other materials provided with the distribution.
|
16
|
+
*
|
17
|
+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
18
|
+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
19
|
+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
20
|
+
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
21
|
+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
22
|
+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
23
|
+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
24
|
+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
26
|
+
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27
|
+
*
|
28
|
+
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
29
|
+
* not use this file except in compliance with the License. You may obtain a
|
30
|
+
* copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
31
|
+
*/
|
data/README.md
ADDED
@@ -0,0 +1,471 @@
|
|
1
|
+
# Naplug
|
2
|
+
|
3
|
+
*Naplug* is a [Nagios plugin](http://nagiosplug.sourceforge.net/developer-guidelines.html) library for Ruby focused on plugin internals: organization, status, performance data, output and exit code handling. It does not implement any functionality related to option and argument parsing, as there are fine tools already available for this purpose. It aims to ease the task of writing Nagios plugins in Ruby and _handling the paperwork_, allowing the plugin developer to concentrate on the test logic of the plugin. Its internal design is largely modeled after the very excellent [Worlkflow](https://github.com/geekq/workflow) library.
|
4
|
+
|
5
|
+
*Naplug* allows plugins to contain other plugins (referred to as *plugs*), which are a useful abstraction to break up significant tasks that the plugin as a whole must perform in order to determine the state of a service or host. The status and output of these plugs is thus used to determine the overall status of the plugin and build the output depending on said status.
|
6
|
+
|
7
|
+
While *Naplug* handles the nitty-gritty of Nagios plugins, it is important to have familiarity with the [Nagios Plugin Developer Guidelines](http://nagiosplug.sourceforge.net/developer-guidelines.html).
|
8
|
+
|
9
|
+
#### Note
|
10
|
+
|
11
|
+
* *Naplug* `1.x` is incompatible with *Naplug* `0.x` (`0.x` was never released as a Gem)
|
12
|
+
* *Naplug* `1.x` is only supported on Ruby 1.9 and above; it will not be backported to 1.8
|
13
|
+
|
14
|
+
## Overview
|
15
|
+
|
16
|
+
Naplug approaches Nagios plugins as Ruby classes (note that `plugin` is a reserved keyword at both the class and instance levels). To use *Naplug*, install the gem and:
|
17
|
+
|
18
|
+
#!/usr/bin/end ruby -rubygems
|
19
|
+
require 'naplug'
|
20
|
+
|
21
|
+
class MyPlugin
|
22
|
+
include Naplug
|
23
|
+
plugin do |p|
|
24
|
+
...
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
MyPlugin.new.exec!
|
29
|
+
|
30
|
+
|
31
|
+
All examples will omit the `require`s for readability.
|
32
|
+
|
33
|
+
A very simple plugin that always returns an OK status:
|
34
|
+
|
35
|
+
class AlwaysOkPlugin
|
36
|
+
|
37
|
+
include Naplug
|
38
|
+
|
39
|
+
plugin do |p|
|
40
|
+
p.status.ok!
|
41
|
+
p.output! "Optimism level: 100%"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
AlwaysOkPlugin.new.exec!
|
46
|
+
|
47
|
+
In the above example, a new class `AlwaysOkPlugin` is defined (the class name is arbitrary), and within this class, a plugin is created, which performs some work to set the status and output of the plugin. Once the class is defined, a new instance of the plugin is created and executed. The `exec!` method executes the plugin, evaluates status, produces correctly formatted output, and exits with the appropriate exit code:
|
48
|
+
|
49
|
+
naplug@plugin:~: alwaysok
|
50
|
+
OK: Optimism level: 100%
|
51
|
+
naplug@plugin:~: echo $?
|
52
|
+
0
|
53
|
+
|
54
|
+
A less optimistic example, this time with arguments:
|
55
|
+
|
56
|
+
class AlmostAlwaysOkPlugin
|
57
|
+
|
58
|
+
include Naplug
|
59
|
+
|
60
|
+
plugin do |p|
|
61
|
+
|
62
|
+
p.output! "Optimism level: #{p[:optimism]}%"
|
63
|
+
|
64
|
+
case p[:optimism]
|
65
|
+
when 23..100 then p.status.ok!
|
66
|
+
when 6..22 then p.status.warning!
|
67
|
+
when 0..5 then p.status.critical!
|
68
|
+
else
|
69
|
+
p.output! "utterly confused"
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
plugin = AlmostAlwaysOkPlugin.new :optimism => Random.rand(100)
|
76
|
+
plugin.exec!
|
77
|
+
|
78
|
+
Which yields:
|
79
|
+
|
80
|
+
naplug@plugin:~: almostalwaysok
|
81
|
+
OK: Optimism level: 96%
|
82
|
+
naplug@plugin:~: echo $?
|
83
|
+
0
|
84
|
+
|
85
|
+
And
|
86
|
+
|
87
|
+
naplug@plugin:~: almostalwaysok
|
88
|
+
WARNING: Optimism level: 9%
|
89
|
+
naplug@plugin:~: echo $?
|
90
|
+
1
|
91
|
+
|
92
|
+
## Plugins
|
93
|
+
|
94
|
+
*Plugins* are defined inside a new class with the `plugin` keyword. Plugins are always initialized in an `UNKNOWN` state and with their output set to `uninitialized plugin`, since at that point, the status of the plugin has not been determined. This ensures that misbehaved plugins correctly notify Nagios that they are failing in some way (for instance, if there's an unhandled exception, at which point the output will be set to useful information about the exception).
|
95
|
+
|
96
|
+
### Tags
|
97
|
+
|
98
|
+
Plugins can be tagged, and tags *must* be unique within a class. Tags are used to identify a plugin, which is useful when multiple plugins are defined in a single class, which may be necessary in cases where several implementations of tests are required. A plugin's tag defaults to `main` when not specified.
|
99
|
+
|
100
|
+
Plugins can be accessed through _tag_ methods, and executed through _tag!_ methods.
|
101
|
+
|
102
|
+
class MultiPlugin
|
103
|
+
|
104
|
+
include Naplug
|
105
|
+
|
106
|
+
plugin :foo do |p|
|
107
|
+
...
|
108
|
+
end
|
109
|
+
|
110
|
+
plugin :bar do |p|
|
111
|
+
...
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
plugin = MultiPlugin.new
|
117
|
+
case condition
|
118
|
+
when true then plugin.foo!
|
119
|
+
else plugin.bar!
|
120
|
+
end
|
121
|
+
|
122
|
+
When defining multiple plugins, invoking `exec!` will execute the `main` plugin (if defined; otherwise, `exec!` is unable to decide which one to execute). When defining a single plugin, `exec!` will execute it regardess of tag.
|
123
|
+
|
124
|
+
|
125
|
+
### Arguments
|
126
|
+
|
127
|
+
A plugin can accept [mostly] arbitrary arguments, which are entirely optional and are available through the *[]* notation. *Naplug* (again, mostly) attaches no special meaning to them, i.e., they can be used in any way they need to be used.
|
128
|
+
|
129
|
+
A more realistic example that checks the staleness of a marker file:
|
130
|
+
|
131
|
+
class MarkerFilePlugin
|
132
|
+
|
133
|
+
include Naplug
|
134
|
+
|
135
|
+
plugin do |p|
|
136
|
+
if Time.now - File.mtime(p[:marker_file]) > p[:critical]
|
137
|
+
p.status.critical!
|
138
|
+
p.output! "marker file #{p[:marker_file]} mtime greater than #{p[:critical]} seconds"
|
139
|
+
else
|
140
|
+
p.status.ok!
|
141
|
+
p.output! "marker #{p[:marker_file]} is up to date"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
plugin = MarkerFilePlugin.new :marker_file => '/tmp/my_marker', :critical => 120
|
147
|
+
plugin.exec!
|
148
|
+
|
149
|
+
There are some worthwhile observations about the above example. A missing marker file prevents determining the stalesness of said file (infinite staleness?), implicitly resulting in an `UNKNOWN` status and output corresponding to the message of the exception. For finer control of this behavior, exceptions can be raised inside the plugin, which will be handled internally:
|
150
|
+
|
151
|
+
plugin do |p|
|
152
|
+
raise Errno::ENOENT, p[:marker_file] unless File.exists? p[:marker_file]
|
153
|
+
...
|
154
|
+
end
|
155
|
+
|
156
|
+
The exception object is available through the `payload`. This only applies to exceptions raised *inside* the `plugin` block.
|
157
|
+
|
158
|
+
Arguments can also be specified via the `args!` method:
|
159
|
+
|
160
|
+
class ArgumentsPlugin
|
161
|
+
|
162
|
+
include Naplug
|
163
|
+
|
164
|
+
plugin do |p|
|
165
|
+
...
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
plugin = ArgumentsPlugin.new :foo => 'old argument'
|
171
|
+
plugin.args! :foo => 'new argument'
|
172
|
+
|
173
|
+
The above code will override the `:foo` argument with a value of `new argument`.
|
174
|
+
|
175
|
+
### Exceptions and `eject!`
|
176
|
+
|
177
|
+
Plugins operate in restricted runtime environments: Nagios expects the proper exit code and output. Naplug makes every effort to properly handle unexpected exceptions when executing plugins, and where it can't, it propagates them bundled in the `Naplug::Error` exception, which is about the only exception (from Naplug's point of view) that needs to be handled:
|
178
|
+
|
179
|
+
class ExceptionPlugin
|
180
|
+
|
181
|
+
include Naplug
|
182
|
+
|
183
|
+
plugin do |p|
|
184
|
+
raise p[:exception], "raised exception: #{p[:exception]}"
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
|
189
|
+
begin
|
190
|
+
plugin = ExceptionPlugin.new :exception => StandardError
|
191
|
+
plugin.exec!
|
192
|
+
rescue Naplug::Error => e
|
193
|
+
plugin.eject! e
|
194
|
+
end
|
195
|
+
|
196
|
+
Which produces:
|
197
|
+
|
198
|
+
naplug@plugin:~: examples/exception
|
199
|
+
UNKNOWN: exception:18: raised exception: StandardError
|
200
|
+
naplug@plugin:~: echo $?
|
201
|
+
3
|
202
|
+
|
203
|
+
The `eject!` method, which accepts a message string or an exception object as an argument, provides a last-ditch effort, out-of-band, escape hatch to bail out of executing a plugin, producing an `UNKNOWN` status and output from the message string or exception object.
|
204
|
+
|
205
|
+
While Naplug will internally handle exceptions within a plugin, it may be desirable to handle them especifically:
|
206
|
+
|
207
|
+
class ExceptionPlusPlugin
|
208
|
+
|
209
|
+
include Naplug
|
210
|
+
|
211
|
+
EXCEPTIONS = [ ArgumentError, ZeroDivisionError, TypeError ]
|
212
|
+
|
213
|
+
plugin do |p|
|
214
|
+
|
215
|
+
exception = EXCEPTIONS[p[:exception]]
|
216
|
+
|
217
|
+
begin
|
218
|
+
raise exception, "raising exception: #{exception}"
|
219
|
+
rescue ArgumentError => e
|
220
|
+
raise
|
221
|
+
rescue ZeroDivisionError => e
|
222
|
+
p.status.ok!
|
223
|
+
p.output! "divided by zero is infinity"
|
224
|
+
rescue => e
|
225
|
+
p.status.critical!
|
226
|
+
p.output! "got exception #{e.class}"
|
227
|
+
end
|
228
|
+
|
229
|
+
end
|
230
|
+
|
231
|
+
end
|
232
|
+
|
233
|
+
begin
|
234
|
+
plugin = ExceptionPluginPlus.new :exception => Random.rand(3)
|
235
|
+
plugin.exec!
|
236
|
+
rescue Naplug::Error => e
|
237
|
+
plugin.eject! e
|
238
|
+
end
|
239
|
+
|
240
|
+
Which produces:
|
241
|
+
|
242
|
+
naplug@plugin:~: examples/exception+
|
243
|
+
UNKNOWN: exception+:24: raising exception: ArgumentError
|
244
|
+
naplug@plugin:~: examples/exception+
|
245
|
+
CRITICAL: got exception TypeError
|
246
|
+
naplug@plugin:~: examples/exception+
|
247
|
+
OK: divided by zero is infinity
|
248
|
+
|
249
|
+
### Plugs: Plugins within Plugins
|
250
|
+
|
251
|
+
Up until now, *Naplug* has essentially provided *syntactic sugar* to define and use what amounts to single-purpose plugins, along with some convenience methods to represent status and produce output. But plugins sometimes need to perform a number of possibly independent tasks to reach a final, _aggregated_ status.
|
252
|
+
|
253
|
+
In *Naplug*, these tasks are _nested plugins_ or _subplugins_, and are referred to as *plugs* scoped to a _parent_ plugin. When a plugin is created, we can define *plugs* inside the plugin through the `plugin` instance method. Again, these can be tagged, and plug tags must be unique, this time within a plugin.
|
254
|
+
|
255
|
+
class PlugPlugin
|
256
|
+
|
257
|
+
include Naplug
|
258
|
+
|
259
|
+
plugin do |p|
|
260
|
+
|
261
|
+
plugin :plug1 do |p1|
|
262
|
+
...
|
263
|
+
end
|
264
|
+
|
265
|
+
plugin :plug2 do |p2|
|
266
|
+
...
|
267
|
+
end
|
268
|
+
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
Defining plugs imposes one important limitation: no other code besides plug definitions is allowed (in reality, it is allowed, just never really during executed).
|
273
|
+
|
274
|
+
class PluggedPlugin
|
275
|
+
|
276
|
+
include Naplug
|
277
|
+
|
278
|
+
plugin do |p|
|
279
|
+
|
280
|
+
<do something here> # will not be executed
|
281
|
+
|
282
|
+
plugin :plug1 do |p1|
|
283
|
+
...
|
284
|
+
end
|
285
|
+
|
286
|
+
plugin :plug2 do |p2|
|
287
|
+
...
|
288
|
+
end
|
289
|
+
|
290
|
+
<do somthing else here> # will not be executed
|
291
|
+
end
|
292
|
+
|
293
|
+
end
|
294
|
+
|
295
|
+
#### Order of Execution
|
296
|
+
|
297
|
+
When `exec!` is invoked on a plugin, plugs are executed in the order in which they are defined, which is a side-effect of the fact that plugs are inserted into a Hash to keep track of them: [Hashes enumerate their values in the order that the corresponding keys were inserted](http://www.ruby-doc.org/core-1.9.3/Hash.html). Execution order can only be controlled manually:
|
298
|
+
|
299
|
+
plugin.exec :plug2
|
300
|
+
plugin.exex :plug1
|
301
|
+
|
302
|
+
#### Arguments
|
303
|
+
|
304
|
+
With the introduction of *plugs*, arguments do become more structured, as arguments keys are matched to plugin and plug tags to route them appropriately.
|
305
|
+
|
306
|
+
plugin = PlugPlugin.new(:plug1 => { :critical => 120, :warning => 60 },
|
307
|
+
:plug2 => { :ok => 0, :warning => 5, :critical => 10 })
|
308
|
+
|
309
|
+
Any keys not matching plug tags are considered to be shared among all plugs:
|
310
|
+
|
311
|
+
plugin = PlugPlugin.new(:file => '/tmp/file',
|
312
|
+
:plug1 => { :critical => 120, :warning => 60 },
|
313
|
+
:plug2 => { :ok => 0, :warning => 5, :critical => 10 })
|
314
|
+
|
315
|
+
Tagged arguments have priority over shared ones.
|
316
|
+
|
317
|
+
plugin = PlugPlugin.new(:file => '/tmp/file',
|
318
|
+
:plug1 => { :file => '/var/tmp/file', :critical => 120 },
|
319
|
+
:plug2 => { :ok => 0, :warning => 5, :critical => 10 })
|
320
|
+
|
321
|
+
#### A Plugged Plugin Example
|
322
|
+
|
323
|
+
Take a service for which we wish to monitor three conditions:
|
324
|
+
|
325
|
+
* that the service is running one and only one process
|
326
|
+
* that the log file has seen activity within the last 60 seconds
|
327
|
+
* that some metric related to the service (number of files in a queue) is within acceptable thresholds
|
328
|
+
|
329
|
+
Each of these tasks can be a plug, and Naplug will take care of aggregating the statuses to yield a plugin status (worst always wins).
|
330
|
+
|
331
|
+
require 'sys/proctable'
|
332
|
+
require 'naplug'
|
333
|
+
|
334
|
+
class MultiPlugServicePlugin
|
335
|
+
|
336
|
+
include Naplug
|
337
|
+
|
338
|
+
plugin do |p|
|
339
|
+
|
340
|
+
plug :proc_count do |p1|
|
341
|
+
pids = Sys::ProcTable.ps.each do |ps|...
|
342
|
+
case pids.size
|
343
|
+
when 1
|
344
|
+
p1.status.ok
|
345
|
+
p1.output "process #{p1[:name]} running with pid #{pids[0]}"
|
346
|
+
when 0
|
347
|
+
p1.status.critical
|
348
|
+
p1.output "process #{p1[:name]} not running"
|
349
|
+
else
|
350
|
+
p1.status.critical
|
351
|
+
p1.output "multiple #{p1[:name]} processes found, pids #{pids.join(',')}"
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
plug :log_mtime do |p2|
|
356
|
+
delta = Time.now - File.mtime(p2[:log_file])
|
357
|
+
if delta > p2[:critical]
|
358
|
+
p2.status.critical
|
359
|
+
p2.output "p2[:name] log file #{p2[:log_file]} mtime greater than #{p2[:critical]} seconds"
|
360
|
+
else
|
361
|
+
p2.status.ok
|
362
|
+
p2.output "marker #{p2[:log_file]} is up to date"
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
plug :queue_depth do |p3|
|
367
|
+
num_files = Dir.entries(p3[:dir]).length - 2
|
368
|
+
p3.output "queue depth: #{num_files} items"
|
369
|
+
|
370
|
+
case num_files
|
371
|
+
when 0..100 then p3.status.ok
|
372
|
+
when 101..1000 then p3.status.warning
|
373
|
+
else p3.status.critical
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
plugin = MultiPlugServicePlugin.new :name => 'foobard'
|
381
|
+
plugin[:log_mtime] = { :log_file => '/var/log/foobard.log' }
|
382
|
+
plugin[:queue_depth] = { :dir => '/var/spool/foobard' }
|
383
|
+
plugin.exec!
|
384
|
+
|
385
|
+
## Naplug Methods
|
386
|
+
|
387
|
+
### Class Methods
|
388
|
+
|
389
|
+
Whenever Naplug in included in a class, the following class methods are available:
|
390
|
+
|
391
|
+
* `plugin`, which is used to create plugins
|
392
|
+
* `tags`, which returns an array of defined plugin tags
|
393
|
+
|
394
|
+
### Instance Methods
|
395
|
+
|
396
|
+
In addition to the above class methods, the followingh instance methods are available:
|
397
|
+
|
398
|
+
* `args` and `args!` to retrieve and set arguments
|
399
|
+
* `exec!`, `exec` and `eval` to exec-to-exit, exec and evaluate plugins, respectively
|
400
|
+
* `has_plugins?`, which evaluates to true if a plugin has plugs
|
401
|
+
* `[]` and `[]=` to get and set specific arguments
|
402
|
+
* `to_str` to produce formatted plugin output
|
403
|
+
* `eject!`, to quickly bail out
|
404
|
+
* `enable!` and `enabled?`, `disable!` and `disabled?`, for enable and disabled plugs
|
405
|
+
|
406
|
+
Overriding these will likely cause *Naplug* to misbehave, to say the least.
|
407
|
+
|
408
|
+
Other methods can be defined in the class as necessary, and they can be used in the defined plugins or plugs, generally to provide helpers services. These should be defined as `private` or `protected` as necessary.
|
409
|
+
|
410
|
+
### Status
|
411
|
+
|
412
|
+
Status is a special object that represent the status of a plugin for each of the defined states in the [Nagios Plugin Guidelines](http://nagiosplug.sourceforge.net/developer-guidelines.html): `OK`, `WARNING`, `CRITICAL` and `UNKNOWN`. Each of these states is itself an instance method which sets the state, and you can obtain the string and numeric representation through the usual methods `to_s` and `to_i`. The initial (and default) status of a `Status` object is `UNKNOWN`. Statuses are comparable in that larger statuses represent worse states, a feature that will come handy shortly.
|
413
|
+
|
414
|
+
require 'naplug/status'
|
415
|
+
|
416
|
+
puts "All statuses:"
|
417
|
+
Naplug::Status.states.each do |state|
|
418
|
+
status = Naplug::Status.new state
|
419
|
+
puts " status #{status} has exit code #{status.to_i}"
|
420
|
+
end
|
421
|
+
|
422
|
+
puts "Working with a status:"
|
423
|
+
status = Naplug::Status.new
|
424
|
+
puts " status #{status} has exit code #{status.to_i}"
|
425
|
+
status.ok!
|
426
|
+
puts " status #{status} has exit code #{status.to_i}"
|
427
|
+
|
428
|
+
puts "Comparing statuses:"
|
429
|
+
status1 = Naplug::Status.new :warning
|
430
|
+
if status < status1
|
431
|
+
puts " status [#{status}] < status1 [#{status1}] is true"
|
432
|
+
end
|
433
|
+
|
434
|
+
which produces
|
435
|
+
|
436
|
+
naplug@plugin:~: status
|
437
|
+
All statuses:
|
438
|
+
status OK has exit code 0
|
439
|
+
status WARNING has exit code 1
|
440
|
+
status CRITICAL has exit code 2
|
441
|
+
status UNKNOWN has exit code 3
|
442
|
+
Working with a status:
|
443
|
+
status UNKNOWN has exit code 3 after initialization
|
444
|
+
status OK has exit code 0 after status.ok
|
445
|
+
Comparing statuses:
|
446
|
+
status [OK] < status1 [WARNING] is true
|
447
|
+
|
448
|
+
# Futures
|
449
|
+
|
450
|
+
There following are some ideas on future Naplug features.
|
451
|
+
|
452
|
+
### Order of Execution
|
453
|
+
|
454
|
+
A future release will allow the execution order to be changed through an `order!` instance method, which will accept a list of tags in the desired order of execution.
|
455
|
+
|
456
|
+
plugin.order! :plug2, :plug1
|
457
|
+
|
458
|
+
If tags are omitted from the list, the missing plugs are pushed to the end of the line in the last order set.
|
459
|
+
|
460
|
+
#### Enabling and Disabling Plugs
|
461
|
+
|
462
|
+
Currently, when plugs are defined, they are assumed to be enabled and will be executed when `exec!` is invoked. There may be cases when it may be desirable or necessary to disable specific plugins, which will be accomplished through the `disable!` instance method. A disabled plug can be re-enabled via the `enable!` plugin method:
|
463
|
+
|
464
|
+
plugin.disable! :plug2
|
465
|
+
|
466
|
+
Disabled plugs will not be executed and will not be taken into account when evaluating status. The active state of a plugin can be queried via the `enabled?` and `disabled?` methods.
|
467
|
+
|
468
|
+
plugin.enabled? :plug2 => false
|
469
|
+
plugin.disabled? :plug2 => true
|
470
|
+
|
471
|
+
Aditionally, `is_<tag>_enabled?` and `is_<tag>_disabled?` methods will be available for each plug.
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
|
4
|
+
$LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
|
+
require 'naplug'
|
8
|
+
|
9
|
+
module Naplug
|
10
|
+
|
11
|
+
module Examples
|
12
|
+
|
13
|
+
class AlmostAlwaysOkPlugin
|
14
|
+
|
15
|
+
include Naplug
|
16
|
+
|
17
|
+
plugin do |p|
|
18
|
+
|
19
|
+
p.output! "Optimism level: #{p[:optimism]}%"
|
20
|
+
|
21
|
+
case p[:optimism]
|
22
|
+
when 23..100 then p.status.ok!
|
23
|
+
when 6..22 then p.status.warning!
|
24
|
+
when 0..5 then p.status.critical!
|
25
|
+
else
|
26
|
+
p.output! 'utterly confused'
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
plugin = Naplug::Examples::AlmostAlwaysOkPlugin.new :optimism => Random.rand(100)
|
38
|
+
plugin.exec!
|
data/examples/alwaysok
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
|
4
|
+
$LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
|
+
require 'naplug'
|
8
|
+
|
9
|
+
module Naplug
|
10
|
+
|
11
|
+
module Examples
|
12
|
+
|
13
|
+
class AlwaysOkPlugin
|
14
|
+
|
15
|
+
include Naplug
|
16
|
+
|
17
|
+
plugin do |p|
|
18
|
+
|
19
|
+
p.status.ok!
|
20
|
+
p.output! 'Optimism level: 100%'
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
Naplug::Examples::AlwaysOkPlugin.new.exec!
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
|
4
|
+
$LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
|
+
require 'naplug'
|
8
|
+
|
9
|
+
module Naplug
|
10
|
+
|
11
|
+
module Examples
|
12
|
+
|
13
|
+
class AlwaysUnknownPlugin
|
14
|
+
|
15
|
+
include Naplug
|
16
|
+
|
17
|
+
plugin do |p|
|
18
|
+
|
19
|
+
p2.status.ok!
|
20
|
+
p.output! 'Optimism level: 100%'
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
Naplug::Examples::AlwaysUnknownPlugin.new.exec!
|
data/examples/dupplugin
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
|
4
|
+
$LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
|
+
require 'naplug'
|
8
|
+
|
9
|
+
class DupPlugin
|
10
|
+
|
11
|
+
include Naplug
|
12
|
+
|
13
|
+
plugin do |p|
|
14
|
+
p.status.ok!
|
15
|
+
p.output! 'not really; will fail'
|
16
|
+
end
|
17
|
+
|
18
|
+
plugin do |p|
|
19
|
+
p.status.ok!
|
20
|
+
p.output! 'not really; will fail'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
plugin = DupPlugin.new
|
25
|
+
plugin.exec!
|
data/examples/exception
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
|
4
|
+
$LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
|
+
require 'naplug'
|
8
|
+
|
9
|
+
module Naplug
|
10
|
+
|
11
|
+
module Examples
|
12
|
+
|
13
|
+
class ExceptionPlugin
|
14
|
+
|
15
|
+
include Naplug
|
16
|
+
|
17
|
+
plugin do |p|
|
18
|
+
raise p[:exception], "raised exception: #{p[:exception]}"
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
begin
|
28
|
+
plugin = Naplug::Examples::ExceptionPlugin.new :exception => StandardError
|
29
|
+
plugin.exec!
|
30
|
+
rescue Naplug::Error => e
|
31
|
+
plugin.eject! e
|
32
|
+
end
|