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.
@@ -0,0 +1,48 @@
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 ExceptionPlusPlugin
14
+
15
+ include Naplug
16
+
17
+ EXCEPTIONS = [ ArgumentError, ZeroDivisionError, TypeError ]
18
+
19
+ plugin do |p|
20
+
21
+ exception = EXCEPTIONS[p[:exception]]
22
+
23
+ begin
24
+ raise exception, "raising exception: #{exception}"
25
+ rescue ArgumentError => e
26
+ raise
27
+ rescue ZeroDivisionError => e
28
+ p.status.ok!
29
+ p.output! "divided by zero is infinity"
30
+ rescue => e
31
+ p.status.critical!
32
+ p.output! "got exception #{e.class}"
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+
43
+ begin
44
+ plugin = Naplug::Examples::ExceptionPlusPlugin.new :exception => Random.rand(3)
45
+ plugin.exec!
46
+ rescue Naplug::Error => e
47
+ plugin.eject! e
48
+ end
@@ -0,0 +1,27 @@
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 MarkerFilePlugin
10
+
11
+ include Naplug
12
+
13
+ plugin do |p|
14
+
15
+ if Time.now - File.mtime(p[:marker_file]) > p[:critical]
16
+ p.status.critical!
17
+ p.output! "marker file #{p[:marker_file]} mtime greater than #{p[:critical]} seconds"
18
+ else
19
+ p.status.ok!
20
+ p.output! "marker #{p[:marker_file]} is up to date"
21
+ end
22
+
23
+ end
24
+ end
25
+
26
+ plugin = MarkerFilePlugin.new :marker_file => '/tmp/my_marker', :critical => 120
27
+ plugin.exec!
@@ -0,0 +1,40 @@
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 MarkerFilePlusPlusPlugin
10
+
11
+ include Naplug
12
+
13
+ plugin :mkf do |p|
14
+ delta, size = file_mtime_and_size p[:marker_file]
15
+ case
16
+ when (delta < p[:w_seconds] and size > p[:c_size])
17
+ p.status.ok!
18
+ p.output! "marker file %s is up to date and not empty" % [p[:marker_file]]
19
+ when (p[:w_seconds]..p[:c_seconds]).include?(delta), size > p[:c_size]
20
+ p.status.warning!
21
+ p.output! "marker file is %d seconds out of date" % [delta]
22
+ when delta >= p[:c_seconds], size == p[:c_size]
23
+ p.status.critical!
24
+ p.output! "marker file is %d seconds out of date or empty" % [delta]
25
+ else
26
+ p.outout! "marker file is in an inconsistent state"
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def file_mtime_and_size(file)
33
+ fs = File.stat file
34
+ return Time.now - fs.mtime,fs.size
35
+ end
36
+
37
+ end
38
+
39
+ plugin = MarkerFilePlusPlusPlugin.new :marker_file => '/tmp/my_marker', :c_seconds => 120, :w_seconds => 60, :c_size => 0
40
+ plugin.exec!
@@ -0,0 +1,34 @@
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 MultiPlugPlugin
10
+
11
+ include Naplug
12
+
13
+ plugin do |p|
14
+
15
+ plugin :p1 do |p1|
16
+ p1.status.critical!
17
+ p1.output! "argument 'c' is #{p1[:c]}"
18
+ end
19
+
20
+ plugin :p2 do |p2|
21
+ p2.status.critical!
22
+ p2.output! "tis critical!"
23
+ end
24
+
25
+ plugin :p3 do |p3|
26
+ p3.status.warning!
27
+ p3.output! "tis warning!"
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ plugin = MultiPlugPlugin.new :shared1 => 'shared arg2', :shared2 => 'shared arg 2', :p1 => { :c => 0 }
34
+ plugin.exec!
@@ -0,0 +1,42 @@
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 MultiPluginPlugin
10
+
11
+ include Naplug
12
+
13
+ plugin :one do |p|
14
+
15
+ plugin :p1 do |p1|
16
+ p1.status.ok!
17
+ p1.output! "#{p1.tag} args: #{p.args}"
18
+ end
19
+
20
+ plugin :p2 do |p2|
21
+ p2.status.critical!
22
+ p2.output! "tis critical!"
23
+ end
24
+
25
+ plugin :p3 do |p3|
26
+ p3.status.unknown!
27
+ p3.output! "tis unknown! #{p3.args}"
28
+ end
29
+
30
+ end
31
+
32
+ plugin :two do |p|
33
+
34
+ p.status.ok!
35
+ p.output! "plugin #{p.tag}"
36
+
37
+ end
38
+
39
+ end
40
+
41
+ plugin = MultiPluginPlugin.new
42
+ plugin.one!
@@ -0,0 +1,44 @@
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 MultiPluginPlugin
10
+
11
+ include Naplug
12
+
13
+ plugin :one do |p|
14
+
15
+ plugin :p1 do |p1|
16
+ p1.status.ok!
17
+ p1.output! "#{p.tag}:#{p1.tag} #{p[:instance]}"
18
+ end
19
+
20
+ plugin :p2 do |p2|
21
+ p2.status.ok!
22
+ p2.output! "#{p.tag}:#{p2.tag} #{p[:instance]}"
23
+ end
24
+
25
+ plugin :p3 do |p3|
26
+ p3.status.ok!
27
+ p3.output! "#{p.tag}:#{p3.tag} #{p[:instance]}"
28
+ end
29
+
30
+ end
31
+
32
+ plugin :two do |p|
33
+
34
+ p.status.ok!
35
+ p.output! "plugin #{p.tag}"
36
+
37
+ end
38
+
39
+ end
40
+
41
+
42
+ x1 = MultiPluginPlugin.new :instance => :x1, :one => { :p1 => { :instance => :x1 }}
43
+ x2 = MultiPluginPlugin.new :instance => :x2, :one => { :p1 => { :instance => :x2 }}
44
+ x1.one!
data/examples/status ADDED
@@ -0,0 +1,33 @@
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/status'
8
+
9
+ module Naplug
10
+
11
+ module Examples
12
+
13
+ puts "All statuses:"
14
+ Naplug::Status.states.each do |state|
15
+ status = Naplug::Status.new state
16
+ puts " status #{status} has exit code #{status.to_i}"
17
+ end
18
+
19
+ puts "Working with a status:"
20
+ status = Naplug::Status.new
21
+ puts " status #{status} has exit code #{status.to_i} after initialization"
22
+ status.ok
23
+ puts " status #{status} has exit code #{status.to_i} after status.ok"
24
+
25
+ puts "Comparing statuses:"
26
+ status1 = Naplug::Status.new :warning
27
+ if status < status1
28
+ puts " status [#{status}] < status1 [#{status1}] is true"
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,5 @@
1
+ require 'naplug/version'
2
+ module Naplug
3
+ ME = :naplug
4
+ ABOUT = "#{ME} v#{VERSION}\nhttps://github.com/gerirgaudi/#{ME}\nCopyright (c) 2014 by Evernote Corporation\nLicensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)"
5
+ end
@@ -0,0 +1,55 @@
1
+ require 'json'
2
+ require 'naplug/status'
3
+
4
+ module Naplug
5
+
6
+ module Helpers
7
+
8
+ module Thresholds
9
+
10
+ def hashify_json_thresholds(tag,thres_json=nil)
11
+ thresholds = { tag => {} }
12
+ plug = nil
13
+ thres_proc = Proc.new do |json_element|
14
+ case
15
+ when (json_element.is_a? String and json_element.match(/\d*:\d*:\d*:\d*/))
16
+ thresholds[:main][plug] = Hash[Status.states.zip json_element.split(':',-1).map { |v| v.nil? ? nil : v.to_i } ]
17
+ when Symbol
18
+ plug = json_element
19
+ else
20
+ nil
21
+ end
22
+ end
23
+ JSON.recurse_proc(JSON.parse(thres_json, :symbolize_names => true),&thres_proc) if thres_json
24
+ thresholds
25
+ end
26
+
27
+ end
28
+
29
+ module Hashes
30
+
31
+ # Thx Avdi Grimm! http://devblog.avdi.org/2009/11/20/hash-transforms-in-ruby/
32
+ def transform_hash(original, options={}, &block)
33
+ original.inject({}){|result, (key,value)|
34
+ value = if options[:deep] && Hash === value
35
+ transform_hash(value, options, &block)
36
+ else
37
+ value
38
+ end
39
+ block.call(result,key,value)
40
+ result
41
+ }
42
+ end
43
+
44
+ def symbolify_keys(hash)
45
+ transform_hash(hash) {|h, key, value|
46
+ h[key.to_sym] = value
47
+ }
48
+ end
49
+
50
+
51
+ end
52
+
53
+ end
54
+
55
+ end
@@ -0,0 +1,31 @@
1
+ module Naplug
2
+
3
+ class Output
4
+ # Implements Text Output and Long Text elements from the Nagios Plugin API
5
+ # * Nagios v3: http://nagios.sourceforge.net/docs/nagioscore/3/en/pluginapi.html
6
+ # * Nagios v4: http://nagios.sourceforge.net/docs/nagioscore/4/en/pluginapi.html
7
+
8
+ attr_accessor :text_output
9
+ attr_reader :long_text
10
+
11
+ def initialize(text_output = 'uninitialized plugin')
12
+ @text_output = text_output
13
+ @long_text = []
14
+ end
15
+
16
+ # Pushes the given long text strings on the end of long text. Returns the long_text
17
+ # @return [Array<String>] array of long text strings
18
+ def push(*long_text)
19
+ @long_text.push long_text
20
+ end
21
+
22
+ def to_s(output = :text_output)
23
+ case output
24
+ when :text_output then @text_output
25
+ when :long_text then @long_text.joing "\n"
26
+ else nil
27
+ end
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,52 @@
1
+ module Naplug
2
+
3
+ class PerformanceData
4
+
5
+ attr_reader :tag, :data
6
+
7
+ class MissingLabel < StandardError; end
8
+ class InvalidField < StandardError; end
9
+ class ThatIsNoHash < StandardError; end
10
+
11
+ FIELDS = [:label, :value, :uom, :warn, :crit, :min, :max] # label=value[UOM];[warn];[crit];[min];[max]
12
+
13
+ def initialize(tag)
14
+ @tag = tag
15
+ @data = Hash.new
16
+ end
17
+
18
+ def to_s(label = nil)
19
+ label_ary = label.nil? ? @data.keys : [label]
20
+ label_ary.map do |l|
21
+ '%s=%s%s;%s;%s;%s;%s' % FIELDS.map { |k| @data[l][k] }
22
+ end.join(' ').strip
23
+ end
24
+
25
+ def []=(label,value,args = {})
26
+ raise ThatIsNoHash, 'hash of fields is not a hash' unless args.is_a? Hash
27
+ args.keys.each { |field| raise InvalidField unless FIELDS.include? field }
28
+ raise MissingLabel, 'missing label' unless label
29
+ @data[label] = { :label => label, :value => value }.merge args
30
+ end
31
+ alias_method :store, :[]=
32
+
33
+ def [](label)
34
+ @data[label]
35
+ end
36
+ alias_method :fetch, :[]
37
+
38
+ def delete(label)
39
+ @data.delete(label)
40
+ end
41
+
42
+ def has_label?(label)
43
+ @data.has_key? label
44
+ end
45
+ alias_method :include?, :has_label?
46
+
47
+ def fields
48
+ FIELDS
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,155 @@
1
+ require 'ostruct'
2
+
3
+ require 'naplug/status'
4
+ require 'naplug/output'
5
+ require 'naplug/performancedata'
6
+
7
+ module Naplug
8
+
9
+ class Plugin
10
+
11
+ attr_reader :block, :plugins, :tag
12
+
13
+ class DuplicatePlugin < StandardError; end
14
+
15
+ def initialize(tag, meta = false, block)
16
+ @tag = tag
17
+ @block = block
18
+ @plugins = Hash.new
19
+
20
+ @_args = Hash.new
21
+ @_data = OpenStruct.new :status => Status.new, :output => Output.new, :payload => nil, :perfdata => nil
22
+ @_meta = OpenStruct.new :status => meta, :enabled => true, :debug => true
23
+
24
+ begin; instance_eval &block ; rescue => e; nil ; end
25
+
26
+ end
27
+
28
+ # @param format [Symbol] the format type, `:text` or `:html`
29
+ # @return [True, False<String>, nil] the object or objects to
30
+ # find in the database. Can be nil.@return [String] the object converted into the expected format.
31
+ # # true if this plugin is a metaplugin, false otherwise
32
+ def is_meta?
33
+ @_meta.status
34
+ end
35
+
36
+ # enable execution of the plugin; metaplugins are always enabled
37
+ def enable!
38
+ is_meta? ? nil : @_meta.enabled = true
39
+ end
40
+
41
+ # disable execution of the plugin; metaplugins cannot be disabled
42
+ def disable!
43
+ is_meta? ? nil : @_meta.enabled = false
44
+ end
45
+
46
+ # true when plugin is enabled; false otherwise
47
+ def is_enabled?
48
+ @_meta.enabled
49
+ end
50
+
51
+ # true when the plugin is disabled; false otherwise
52
+ def is_disabled?
53
+ not @_meta.enabled
54
+ end
55
+
56
+ # true when a plugin contains plugs
57
+ def has_plugins?
58
+ @plugins.empty? ? false : true
59
+ end
60
+ alias_method :has_plugs?, :has_plugins?
61
+
62
+ # @return [Status] plugin status
63
+ def status
64
+ @_data.status
65
+ end
66
+
67
+ # Gets plugin text output
68
+ # @return [String] plugin text output
69
+ def output
70
+ @_data.output
71
+ end
72
+
73
+ # Sets plugin text output
74
+ # @param text_output [String] plugin text output
75
+ # @return [String] new plugin text output
76
+ def output!(text_output)
77
+ @_data.output.text_output = text_output
78
+ end
79
+
80
+ def long_output
81
+ @_data.output.long_output
82
+ end
83
+
84
+ def long_output!(long_output)
85
+ @_data.output.push long_output
86
+ end
87
+
88
+ # returns the performance data of the plugin as a PerformanceData object
89
+ def perfdata
90
+ @_data.perfdata
91
+ end
92
+
93
+ def perfdata!(label,value,f = {})
94
+ @_data.perfdata ||= PerformanceData.new @tag
95
+ @_data.perfdata.store label, value, f
96
+ end
97
+
98
+ def payload
99
+ @_data.payload
100
+ end
101
+
102
+ def payload!(p)
103
+ @_data.payload = p
104
+ end
105
+
106
+ def args
107
+ @_args
108
+ end
109
+
110
+ def args!(args)
111
+ @_args.merge! args
112
+ @plugins.each do |tag,plug|
113
+ plug_args = args.key?(tag) ? args[tag] : {}
114
+ shared_args = args.select { |t,a| not @plugins.keys.include? t }
115
+ plug.args! shared_args.merge! plug_args
116
+ end
117
+ end
118
+
119
+ def [](k)
120
+ @_args[k]
121
+ end
122
+
123
+ def []=(k,v)
124
+ @_args[k] = v
125
+ end
126
+
127
+ def to_s
128
+ '%s: %s' % [status,output]
129
+ end
130
+
131
+ def eval
132
+ unless @plugins.empty?
133
+ wcu_plugins = @plugins.values.select { |plug| plug.status.not_ok? }
134
+ plugins = wcu_plugins.empty? ? @plugins.values : wcu_plugins
135
+ output! plugins.map { |plug| "[#{plug.status.to_y}#{plug.tag} #{plug.output}]" }.join(' ')
136
+ @_data.status = plugins.map { |plug| plug.status }.max
137
+ end
138
+ end
139
+
140
+ private
141
+
142
+ def plugin(tag, &block)
143
+ raise DuplicatePlugin, "duplicate definition of #{tag}" if @plugins.key? tag
144
+ @plugins[tag] = Plugin.new tag, block
145
+ self.define_singleton_method tag do
146
+ @plugins[tag]
147
+ end
148
+ end
149
+
150
+ def debug?
151
+ @_meta.debug
152
+ end
153
+
154
+ end
155
+ end
@@ -0,0 +1,62 @@
1
+ require 'ostruct'
2
+
3
+ module Naplug
4
+
5
+ class Status
6
+
7
+ include Comparable
8
+
9
+ class InvalidStatus < StandardError; end
10
+
11
+ STATUS = {
12
+ :ok => OpenStruct.new({ :i => 0, :s => 'OK', :y => '+' }),
13
+ :warning => OpenStruct.new({ :i => 1, :s => 'WARNING', :y => '-' }),
14
+ :critical => OpenStruct.new({ :i => 2, :s => 'CRITICAL', :y => '!' }),
15
+ :unknown => OpenStruct.new({ :i => 3, :s => 'UNKNOWN', :y => '*' })
16
+ }
17
+
18
+ def self.states
19
+ STATUS.keys
20
+ end
21
+
22
+ def initialize(state = :unknown)
23
+ @status = state
24
+ end
25
+
26
+ STATUS.keys.each do |state|
27
+ define_method "#{state}!".to_sym do
28
+ @status = state
29
+ end
30
+ end
31
+
32
+ STATUS.keys.each do |state|
33
+ define_method "#{state}?".to_sym do
34
+ @status == state ? true : false
35
+ end
36
+ define_method "not_#{state}?".to_sym do
37
+ @status == state ? false : true
38
+ end
39
+ end
40
+
41
+ def to_s
42
+ STATUS[@status].s
43
+ end
44
+
45
+ def to_i
46
+ STATUS[@status].i
47
+ end
48
+
49
+ def to_y
50
+ STATUS[@status].y
51
+ end
52
+
53
+ def <=>(other)
54
+ case
55
+ when self.to_i < other.to_i then -1
56
+ when self.to_i > other.to_i then 1
57
+ else 0
58
+ end
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,3 @@
1
+ module Naplug
2
+ VERSION = '1.6.1'
3
+ end