naplug 1.6.1 → 1.7.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/README.md +94 -2
- data/examples/multiplugins +0 -1
- data/examples/{alwaysok → o_alwaysok} +0 -0
- data/examples/perfdata_multiplug +48 -0
- data/examples/perfdata_uniplug +24 -0
- data/examples/status +1 -1
- data/examples/{alwaysunknown → u_alwaysunknown} +0 -0
- data/lib/naplug.rb +72 -20
- data/lib/naplug/helpers.rb +61 -0
- data/lib/naplug/performancedata.rb +80 -21
- data/lib/naplug/plugin.rb +14 -11
- data/lib/naplug/version.rb +2 -2
- metadata +7 -4
    
        data/README.md
    CHANGED
    
    | @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            # Naplug
         | 
| 1 | 
            +
            # Naplug [](http://badge.fury.io/rb/naplug)
         | 
| 2 2 |  | 
| 3 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 4 |  | 
| @@ -246,6 +246,33 @@ Which produces: | |
| 246 246 | 
             
                naplug@plugin:~: examples/exception+
         | 
| 247 247 | 
             
                OK: divided by zero is infinity
         | 
| 248 248 |  | 
| 249 | 
            +
            ### Performance Data
         | 
| 250 | 
            +
             | 
| 251 | 
            +
            Naplug supports plugin performance data, which is only available after a plugin has been `exec`ed. Within plugins, two methods are relevant: `perfdata!` and `perfdata`, which set and get performance data metrics, respectively:
         | 
| 252 | 
            +
             | 
| 253 | 
            +
                class PerfDataPlugin
         | 
| 254 | 
            +
             | 
| 255 | 
            +
                  include Naplug
         | 
| 256 | 
            +
             | 
| 257 | 
            +
                  plugin :p do |p|
         | 
| 258 | 
            +
                    p.status.ok!
         | 
| 259 | 
            +
                    p.output! "#{p.tag}:#{p[:instance]} with argument metric #{p[:metric]}"
         | 
| 260 | 
            +
                    p.perfdata! :metric, p[:metric]
         | 
| 261 | 
            +
                    p.perfdata! '"_met ric!', 30, :max => 70
         | 
| 262 | 
            +
                  end
         | 
| 263 | 
            +
             | 
| 264 | 
            +
                end
         | 
| 265 | 
            +
             | 
| 266 | 
            +
                pd = PerfDataPlugin.new :instance => :x1, :p => { :metric => 10 }
         | 
| 267 | 
            +
                pd.exec!
         | 
| 268 | 
            +
             | 
| 269 | 
            +
            This yields:
         | 
| 270 | 
            +
             | 
| 271 | 
            +
                naplug@plugin:~: perfdata_uniplug 
         | 
| 272 | 
            +
                OK: p:x1 with argument metric 10 | metric=10;;;; '"_met ric!'=30;;;;70
         | 
| 273 | 
            +
                
         | 
| 274 | 
            +
            It is also possible to access performance data from within the user-defined plugin class through the `perfdata` method, which returns an array of [`PerformanceData`](http://rubydoc.info/gems/naplug/Naplug/PerformanceData) objects.
         | 
| 275 | 
            +
             | 
| 249 276 | 
             
            ### Plugs: Plugins within Plugins 
         | 
| 250 277 |  | 
| 251 278 | 
             
            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.
         | 
| @@ -318,6 +345,71 @@ Tagged arguments have priority over shared ones. | |
| 318 345 | 
             
                                        :plug1 => { :file => '/var/tmp/file', :critical => 120 },
         | 
| 319 346 | 
             
                                        :plug2 => { :ok => 0, :warning => 5, :critical => 10 })
         | 
| 320 347 |  | 
| 348 | 
            +
            #### Performance Data
         | 
| 349 | 
            +
             | 
| 350 | 
            +
            As mentioned earlier, Naplug supports plugin performance data, through two methods of `Plugin`, `perfdata!` and `perfdata`:
         | 
| 351 | 
            +
             | 
| 352 | 
            +
                class PerfDataPlugPlugin
         | 
| 353 | 
            +
             | 
| 354 | 
            +
                  include Naplug
         | 
| 355 | 
            +
             | 
| 356 | 
            +
                  plugin :p do |p|
         | 
| 357 | 
            +
             | 
| 358 | 
            +
                    plugin :p1 do |p1|
         | 
| 359 | 
            +
                      p1.status.ok!
         | 
| 360 | 
            +
                      p1.output! "#{p.tag}:#{p1.tag} #{p[:instance]}"
         | 
| 361 | 
            +
                      p1.perfdata! :metric, p1[:metric], :max => 70
         | 
| 362 | 
            +
                      p1.perfdata! '"_met ric!', 30, :max => 70
         | 
| 363 | 
            +
                    end
         | 
| 364 | 
            +
             | 
| 365 | 
            +
                    plugin :p2 do |p2|
         | 
| 366 | 
            +
                      p2.status.ok!
         | 
| 367 | 
            +
                      p2.output! "#{p.tag}:#{p2.tag} #{p[:instance]}"
         | 
| 368 | 
            +
                      p2.perfdata! 'p2/metric', p2[:metric], :crit => 70
         | 
| 369 | 
            +
                    end
         | 
| 370 | 
            +
             | 
| 371 | 
            +
                    plugin :p3 do |p3|
         | 
| 372 | 
            +
                      p3.status.ok!
         | 
| 373 | 
            +
                     p3.output! "#{p.tag}:#{p3.tag} #{p[:instance]}"
         | 
| 374 | 
            +
                    end
         | 
| 375 | 
            +
                  end
         | 
| 376 | 
            +
                end
         | 
| 377 | 
            +
             | 
| 378 | 
            +
                # Note: the following code is meant to show some of the behavior related to Performance Data:
         | 
| 379 | 
            +
                plugin = PerfDataPlugPlugin.new :instance => :x1, :p1 => { :metric => 10 }, :p2 => { :metric => 50 }
         | 
| 380 | 
            +
                plugin.exec
         | 
| 381 | 
            +
                
         | 
| 382 | 
            +
                # Plugin Perfdata Ancestors
         | 
| 383 | 
            +
            	plugin.perfdata.each do |pd|
         | 
| 384 | 
            +
            	  puts "#{pd.tag} has #{pd.to_a.size} labels and its tree is #{pd.ancestors :mode => :tags}"
         | 
| 385 | 
            +
            	end
         | 
| 386 | 
            +
             | 
| 387 | 
            +
            	plugin.perfdata.each do |pd|
         | 
| 388 | 
            +
                  puts "plugin #{pd.tag} has #{pd.labels}"
         | 
| 389 | 
            +
            	end
         | 
| 390 | 
            +
            	
         | 
| 391 | 
            +
            which produces:
         | 
| 392 | 
            +
             | 
| 393 | 
            +
                plugin@naplug:~: perfdata_multiplug
         | 
| 394 | 
            +
                perfdata p1 has 2 labels and its tree is p/p1
         | 
| 395 | 
            +
                perfdata p2 has 1 labels and its tree is p/p2
         | 
| 396 | 
            +
                plugin p1 has ["metric", "'\"_met ric!'"]
         | 
| 397 | 
            +
                plugin p2 has ["p2/metric"]
         | 
| 398 | 
            +
             | 
| 399 | 
            +
            Some of this functionality is intended to ease integration with, for instance, Graphite:
         | 
| 400 | 
            +
             | 
| 401 | 
            +
                g = Graphite.new :hostname => 'graphite', :port => 2013
         | 
| 402 | 
            +
                h = `hostname`.gsub(/\./,'_')
         | 
| 403 | 
            +
                
         | 
| 404 | 
            +
                plugin.perfdata.each do |pd|
         | 
| 405 | 
            +
                  pd.to_a.each do |l|
         | 
| 406 | 
            +
                    g.push "#{h}_app_#{l}
         | 
| 407 | 
            +
                  end
         | 
| 408 | 
            +
                end
         | 
| 409 | 
            +
                g.flush!
         | 
| 410 | 
            +
             | 
| 411 | 
            +
            This would push the collected performance data metrics to Graphite with an invented API. Note that Nagios performance data labels are not always legal graphite metric names (`"\"_met ric!'` above). Naplug makes no attempt to address this.
         | 
| 412 | 
            +
                                                                        
         | 
| 321 413 | 
             
            #### A Plugged Plugin Example
         | 
| 322 414 |  | 
| 323 415 | 
             
            Take a service for which we wish to monitor three conditions:
         | 
| @@ -457,7 +549,7 @@ A future release will allow the execution order to be changed through an `order! | |
| 457 549 |  | 
| 458 550 | 
             
            If tags are omitted from the list, the missing plugs are pushed to the end of the line in the last order set.
         | 
| 459 551 |  | 
| 460 | 
            -
             | 
| 552 | 
            +
            ### Enabling and Disabling Plugs
         | 
| 461 553 |  | 
| 462 554 | 
             
            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 555 |  | 
    
        data/examples/multiplugins
    CHANGED
    
    
| 
            File without changes
         | 
| @@ -0,0 +1,48 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby -rubygems
         | 
| 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 'naplug'
         | 
| 7 | 
            +
            require 'awesome_print'
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            class PerfDataPlugPlugin
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              include Naplug
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              plugin :p do |p|
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                plugin :p1 do |p1|
         | 
| 16 | 
            +
                  p1.status.ok!
         | 
| 17 | 
            +
                  p1.output! "#{p.tag}:#{p1.tag} #{p[:instance]}"
         | 
| 18 | 
            +
                  p1.perfdata! :metric, p1[:metric], :max => 70
         | 
| 19 | 
            +
                  p1.perfdata! '"_met ric!', 30, :max => 70
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                plugin :p2 do |p2|
         | 
| 23 | 
            +
                  p2.status.ok!
         | 
| 24 | 
            +
                  p2.output! "#{p.tag}:#{p2.tag} #{p[:instance]}"
         | 
| 25 | 
            +
                  p2.perfdata! 'p2/metric', p2[:metric], :crit => 70
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                plugin :p3 do |p3|
         | 
| 29 | 
            +
                  p3.status.ok!
         | 
| 30 | 
            +
                  p3.output! "#{p.tag}:#{p3.tag} #{p[:instance]}"
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
            end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            plugin = PerfDataPlugPlugin.new :instance => :x1, :p1 => { :metric => 10 }, :p2 => { :metric => 50 }
         | 
| 38 | 
            +
            plugin.exec
         | 
| 39 | 
            +
             | 
| 40 | 
            +
            # Plugin Perfdata Ancestors
         | 
| 41 | 
            +
            plugin.perfdata.each do |pd|
         | 
| 42 | 
            +
                puts "perfdata #{pd.tag} has #{pd.to_a.size} labels and its tree is #{pd.ancestors :mode => :tags}"
         | 
| 43 | 
            +
            end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
            plugin.perfdata.each do |pd|
         | 
| 46 | 
            +
                puts "plugin #{pd.tag} has labels #{pd.labels}"
         | 
| 47 | 
            +
            end
         | 
| 48 | 
            +
             | 
| @@ -0,0 +1,24 @@ | |
| 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 | 
            +
            #require 'awesome_print'
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            class PerfDataPlugin
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              include Naplug
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              plugin :p do |p|
         | 
| 15 | 
            +
                p.status.ok!
         | 
| 16 | 
            +
                p.output! "#{p.tag}:#{p[:instance]} with argument metric #{p[:metric]}"
         | 
| 17 | 
            +
                p.perfdata! :metric, p[:metric]
         | 
| 18 | 
            +
                p.perfdata! '"_met ric!', 30, :max => 70
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            pd = PerfDataPlugin.new :instance => :x1, :p => { :metric => 10 }
         | 
| 24 | 
            +
            pd.exec!
         | 
    
        data/examples/status
    CHANGED
    
    | @@ -19,7 +19,7 @@ module Naplug | |
| 19 19 | 
             
                puts "Working with a status:"
         | 
| 20 20 | 
             
                status = Naplug::Status.new
         | 
| 21 21 | 
             
                puts "  status #{status} has exit code #{status.to_i} after initialization"
         | 
| 22 | 
            -
                status.ok
         | 
| 22 | 
            +
                status.ok!
         | 
| 23 23 | 
             
                puts "  status #{status} has exit code #{status.to_i} after status.ok"
         | 
| 24 24 |  | 
| 25 25 | 
             
                puts "Comparing statuses:"
         | 
| 
            File without changes
         | 
    
        data/lib/naplug.rb
    CHANGED
    
    | @@ -1,3 +1,17 @@ | |
| 1 | 
            +
            #--
         | 
| 2 | 
            +
            #
         | 
| 3 | 
            +
            # Author:: Gerir Lopez-Fernandez
         | 
| 4 | 
            +
            # Homepage::  https://github.com/gerirgaudi/naplug/
         | 
| 5 | 
            +
            # Date:: 25 Feb 2014
         | 
| 6 | 
            +
            #
         | 
| 7 | 
            +
            # See the file LICENSE for licensing information.
         | 
| 8 | 
            +
            #
         | 
| 9 | 
            +
            #---------------------------------------------------------------------------
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            #--
         | 
| 12 | 
            +
            # Naplug::ClassMethods and Naplug::InstanceMethods
         | 
| 13 | 
            +
             | 
| 14 | 
            +
             | 
| 1 15 | 
             
            require 'rubygems'
         | 
| 2 16 | 
             
            require 'naplug/plugin'
         | 
| 3 17 |  | 
| @@ -7,31 +21,43 @@ module Naplug | |
| 7 21 |  | 
| 8 22 | 
             
              module ClassMethods
         | 
| 9 23 |  | 
| 24 | 
            +
                # @!scope class
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                # @!attribute [r] plugins
         | 
| 27 | 
            +
                #   @return [Hash<Symbol, Plugin>] metaplugins
         | 
| 10 28 | 
             
                attr_reader :plugins
         | 
| 11 29 |  | 
| 30 | 
            +
                # Create a metaplugin (which basically contains a tag and a block)
         | 
| 31 | 
            +
                # @param tag [Symbol] the plugin tag
         | 
| 32 | 
            +
                # @return [Plugin] a metaplugin
         | 
| 12 33 | 
             
                def plugin(tag = :main, &block)
         | 
| 13 34 | 
             
                  @plugins = Hash.new unless @plugins
         | 
| 14 35 | 
             
                  @plugins[tag] = create_metaplugin tag, block
         | 
| 15 36 | 
             
                end
         | 
| 16 37 |  | 
| 38 | 
            +
                # A list of plugin tags
         | 
| 39 | 
            +
                # @return [Array<Symbol>] the list of plugin tags
         | 
| 17 40 | 
             
                def tags
         | 
| 18 41 | 
             
                  self.plugins.keys
         | 
| 19 42 | 
             
                end
         | 
| 20 43 |  | 
| 21 44 | 
             
                private
         | 
| 22 45 |  | 
| 46 | 
            +
                # Create a metaplugin (helper)
         | 
| 23 47 | 
             
                def create_metaplugin(tag,block)
         | 
| 24 48 | 
             
                  module_eval do
         | 
| 25 | 
            -
                    define_method "#{tag}".to_sym  do;  | 
| 49 | 
            +
                    define_method "#{tag}".to_sym  do; @plugins[tag];  end    # <tag> methods for quick access to plugins
         | 
| 26 50 | 
             
                    define_method "#{tag}!".to_sym do; self.exec! tag; end    # <tag>! methods to involke exec! on a given plugin
         | 
| 27 51 | 
             
                  end
         | 
| 28 | 
            -
                  Plugin.new tag, :meta,  | 
| 52 | 
            +
                  Plugin.new tag, block, :meta => true, :parent => self
         | 
| 29 53 | 
             
                end
         | 
| 30 54 |  | 
| 31 55 | 
             
              end
         | 
| 32 56 |  | 
| 33 57 | 
             
              module InstanceMethods
         | 
| 34 58 |  | 
| 59 | 
            +
                # @!scope instancce
         | 
| 60 | 
            +
             | 
| 35 61 | 
             
                attr_reader :plugins
         | 
| 36 62 |  | 
| 37 63 | 
             
                def initialize(args = {})
         | 
| @@ -42,10 +68,14 @@ module Naplug | |
| 42 68 | 
             
                  args! args
         | 
| 43 69 | 
             
                end
         | 
| 44 70 |  | 
| 71 | 
            +
                # Returns the arguments of the plugin
         | 
| 72 | 
            +
                # @return [Hash] a hash by argument key of argument values
         | 
| 45 73 | 
             
                def args
         | 
| 46 74 | 
             
                  @_args
         | 
| 47 75 | 
             
                end
         | 
| 48 76 |  | 
| 77 | 
            +
                # Sets and propagates plugin arguments
         | 
| 78 | 
            +
                # @param [Hash <Symbol, Object>] args
         | 
| 49 79 | 
             
                def args!(args)
         | 
| 50 80 | 
             
                  @_args.merge! args
         | 
| 51 81 | 
             
                  @plugins.each do |tag,plugin|
         | 
| @@ -56,25 +86,45 @@ module Naplug | |
| 56 86 | 
             
                end
         | 
| 57 87 |  | 
| 58 88 | 
             
                def to_str(tag = default_plugin.tag)
         | 
| 59 | 
            -
                   | 
| 60 | 
            -
                   | 
| 89 | 
            +
                  pd = perfdata(tag)
         | 
| 90 | 
            +
                  if pd.empty?
         | 
| 91 | 
            +
                    s_format = '%s: %s'
         | 
| 92 | 
            +
                    s_array = [@plugins[tag].status,@plugins[tag].output]
         | 
| 93 | 
            +
                  else
         | 
| 94 | 
            +
                    s_format = '%s: %s | %s'
         | 
| 95 | 
            +
                    s_array = [@plugins[tag].status,@plugins[tag].output,pd.join(' ').strip]
         | 
| 96 | 
            +
                  end
         | 
| 61 97 | 
             
                  s_format % s_array
         | 
| 62 98 | 
             
                end
         | 
| 63 99 |  | 
| 100 | 
            +
                # Execute, evaluate and exit the plugin according to the plugin status, outputting the plugin's text output (and performance data, if applicable)
         | 
| 101 | 
            +
                # @param tag [Symbol] a plugin tag
         | 
| 64 102 | 
             
                def exec!(tag = default_plugin.tag)
         | 
| 65 103 | 
             
                  exec tag
         | 
| 66 104 | 
             
                  eval tag
         | 
| 67 105 | 
             
                  exit tag
         | 
| 68 106 | 
             
                end
         | 
| 69 107 |  | 
| 70 | 
            -
                 | 
| 71 | 
            -
             | 
| 108 | 
            +
                # Execute the plugin
         | 
| 109 | 
            +
                # @param tag [Symbol] a plugin tag
         | 
| 110 | 
            +
                def exec(t = default_plugin.tag)
         | 
| 111 | 
            +
                  plugin = target_plugin t
         | 
| 112 | 
            +
                  if plugin.has_plugins?
         | 
| 113 | 
            +
                    plugin.plugins.each_value { |p| exec p }
         | 
| 114 | 
            +
                  else
         | 
| 115 | 
            +
                    plexec plugin
         | 
| 116 | 
            +
                  end
         | 
| 72 117 | 
             
                end
         | 
| 73 118 |  | 
| 74 119 | 
             
                def eval(tag = default_plugin.tag)
         | 
| 75 120 | 
             
                  @plugins[tag].eval
         | 
| 76 121 | 
             
                end
         | 
| 77 122 |  | 
| 123 | 
            +
                def eval!(tag = default_plugin.tag)
         | 
| 124 | 
            +
                  @plugins[tag].eval
         | 
| 125 | 
            +
                  exit tag
         | 
| 126 | 
            +
                end
         | 
| 127 | 
            +
             | 
| 78 128 | 
             
                def eject!(payload = nil)
         | 
| 79 129 | 
             
                  o = case payload
         | 
| 80 130 | 
             
                        when String then payload
         | 
| @@ -86,24 +136,27 @@ module Naplug | |
| 86 136 | 
             
                  Kernel::exit 3
         | 
| 87 137 | 
             
                end
         | 
| 88 138 |  | 
| 89 | 
            -
                 | 
| 90 | 
            -
             | 
| 91 | 
            -
             | 
| 92 | 
            -
                  if  | 
| 93 | 
            -
                     | 
| 139 | 
            +
                # @return [Array<PerformanceData>] a list of performance data objects
         | 
| 140 | 
            +
                def perfdata(tag = default_plugin.tag)
         | 
| 141 | 
            +
                  plugin = @plugins[tag]
         | 
| 142 | 
            +
                  if plugin.has_plugins?
         | 
| 143 | 
            +
                    plugin.plugins.values.select { |plug| plug.perfdata }.map { |plug| plug.perfdata }
         | 
| 94 144 | 
             
                  else
         | 
| 95 | 
            -
                     | 
| 145 | 
            +
                    plugin.perfdata ? [plugin.perfdata] : []
         | 
| 96 146 | 
             
                  end
         | 
| 97 147 | 
             
                end
         | 
| 98 148 |  | 
| 149 | 
            +
                private
         | 
| 150 | 
            +
             | 
| 99 151 | 
             
                def plexec(p)
         | 
| 100 152 | 
             
                  begin
         | 
| 101 153 | 
             
                    @_running = p.tag
         | 
| 102 154 | 
             
                    instance_exec p, &p.block
         | 
| 103 155 | 
             
                    @_running = nil
         | 
| 104 156 | 
             
                  rescue Naplug::Error => e
         | 
| 105 | 
            -
             | 
| 106 | 
            -
             | 
| 157 | 
            +
                    p.status.unknown!
         | 
| 158 | 
            +
                    p.output! "#{e.backtrace[1][/[^\/]+:\d+/]}: #{e.message}"
         | 
| 159 | 
            +
                    p.payload! e
         | 
| 107 160 | 
             
                  rescue => e
         | 
| 108 161 | 
             
                    p.status.unknown!
         | 
| 109 162 | 
             
                    p.output!  "#{e.backtrace[0][/[^\/]+:\d+/]}: #{e.message}"
         | 
| @@ -125,12 +178,11 @@ module Naplug | |
| 125 178 | 
             
                  raise Naplug::Error, 'unable to determine default plugin'
         | 
| 126 179 | 
             
                end
         | 
| 127 180 |  | 
| 128 | 
            -
                def  | 
| 129 | 
            -
                   | 
| 130 | 
            -
             | 
| 131 | 
            -
                     | 
| 132 | 
            -
             | 
| 133 | 
            -
                    plugin.perfdata
         | 
| 181 | 
            +
                def target_plugin(target)
         | 
| 182 | 
            +
                  case target
         | 
| 183 | 
            +
                    when Symbol then @plugins[target]
         | 
| 184 | 
            +
                    when Plugin then target
         | 
| 185 | 
            +
                    else raise Naplug::Error, "unable to determine target plugin"
         | 
| 134 186 | 
             
                  end
         | 
| 135 187 | 
             
                end
         | 
| 136 188 |  | 
    
        data/lib/naplug/helpers.rb
    CHANGED
    
    | @@ -1,4 +1,6 @@ | |
| 1 1 | 
             
            require 'json'
         | 
| 2 | 
            +
            require 'socket'
         | 
| 3 | 
            +
            require 'timeout'
         | 
| 2 4 | 
             
            require 'naplug/status'
         | 
| 3 5 |  | 
| 4 6 | 
             
            module Naplug
         | 
| @@ -47,6 +49,65 @@ module Naplug | |
| 47 49 | 
             
                    }
         | 
| 48 50 | 
             
                  end
         | 
| 49 51 |  | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                module ENGraphite
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  class Client
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                    attr_reader :metrics
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                    def initialize(options)
         | 
| 61 | 
            +
                      raise ArgumentError, 'missing graphite server address' if options[:graphite].nil?
         | 
| 62 | 
            +
                      @graphite = options[:graphite]
         | 
| 63 | 
            +
                      @port = options[:port].nil? ? 2003 : options[:port].to_i
         | 
| 64 | 
            +
                      @prefix = options[:prefix].nil? ? '' : options[:prefix]
         | 
| 65 | 
            +
                      @metrics = []
         | 
| 66 | 
            +
                    end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                    def metric path, value, time = Time.now
         | 
| 69 | 
            +
                      @metrics.push(Metric.new(path,value,time))
         | 
| 70 | 
            +
                    end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                    def metrics!
         | 
| 73 | 
            +
                      @metrics.each do |metric|
         | 
| 74 | 
            +
                        metric = "#{@prefix}.#{metric.to_s}\n"
         | 
| 75 | 
            +
                        print metric
         | 
| 76 | 
            +
                      end
         | 
| 77 | 
            +
                    end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                    def flush!(options = { :timeout => 3})
         | 
| 80 | 
            +
                      begin
         | 
| 81 | 
            +
                        Timeout.timeout(options[:timeout]) do
         | 
| 82 | 
            +
                          s = TCPSocket.open(@graphite,@port)
         | 
| 83 | 
            +
                          @metrics.each do |metric|
         | 
| 84 | 
            +
                            metric = "#{@prefix}.#{metric.to_s}\n"
         | 
| 85 | 
            +
                            s.write metric
         | 
| 86 | 
            +
                          end
         | 
| 87 | 
            +
                          s.close
         | 
| 88 | 
            +
                        end
         | 
| 89 | 
            +
                      rescue Timeout::Error => e
         | 
| 90 | 
            +
                        raise Naplug::Error, "graphite timeout (#{options[:timeout]}s)"
         | 
| 91 | 
            +
                      rescue Errno::ECONNREFUSED, SocketError => e
         | 
| 92 | 
            +
                        raise Naplug::Error, 'graphite socket error'
         | 
| 93 | 
            +
                      end
         | 
| 94 | 
            +
                    end
         | 
| 95 | 
            +
                  end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                  class Metric
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                    attr_reader :path, :value, :time
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                    def initialize(path,value,time = Time.now)
         | 
| 102 | 
            +
                      @path = path
         | 
| 103 | 
            +
                      @value = value
         | 
| 104 | 
            +
                      @time = time
         | 
| 105 | 
            +
                    end
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                    def to_s
         | 
| 108 | 
            +
                      '%s %d %d' % [@path,@value,@time.to_i]
         | 
| 109 | 
            +
                    end
         | 
| 110 | 
            +
                  end
         | 
| 50 111 |  | 
| 51 112 | 
             
                end
         | 
| 52 113 |  | 
| @@ -1,52 +1,111 @@ | |
| 1 | 
            +
            require 'ostruct'
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            module Naplug
         | 
| 2 4 |  | 
| 3 5 | 
             
              class PerformanceData
         | 
| 4 6 |  | 
| 5 | 
            -
                 | 
| 7 | 
            +
                include Enumerable
         | 
| 6 8 |  | 
| 7 | 
            -
                 | 
| 8 | 
            -
                class InvalidField < StandardError; end
         | 
| 9 | 
            -
                class ThatIsNoHash < StandardError; end
         | 
| 9 | 
            +
                attr_reader :tag, :data, :meta
         | 
| 10 10 |  | 
| 11 | 
            -
                FIELDS = [:label, :value, :uom, :warn, :crit, :min, :max] | 
| 11 | 
            +
                FIELDS = [:label, :value, :uom, :warn, :crit, :min, :max]
         | 
| 12 12 |  | 
| 13 | 
            -
                def initialize( | 
| 14 | 
            -
                  @tag = tag
         | 
| 13 | 
            +
                def initialize(plugin)
         | 
| 14 | 
            +
                  @tag = plugin.tag
         | 
| 15 15 | 
             
                  @data = Hash.new
         | 
| 16 | 
            +
                  @meta = OpenStruct.new :plugin => plugin, :ancestors => traverse_to_root(plugin)
         | 
| 16 17 | 
             
                end
         | 
| 17 18 |  | 
| 18 | 
            -
                 | 
| 19 | 
            -
             | 
| 19 | 
            +
                # performance data format: 'label=value[UOM];[warn];[crit];[min];[max]'
         | 
| 20 | 
            +
                def to_str(label = nil)
         | 
| 21 | 
            +
                  label_ary = label.nil? ? labels : [curate_label(label)]
         | 
| 20 22 | 
             
                  label_ary.map do |l|
         | 
| 21 23 | 
             
                    '%s=%s%s;%s;%s;%s;%s' % FIELDS.map { |k| @data[l][k] }
         | 
| 22 24 | 
             
                  end.join(' ').strip
         | 
| 23 25 | 
             
                end
         | 
| 24 26 |  | 
| 25 | 
            -
                 | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
                   | 
| 29 | 
            -
             | 
| 27 | 
            +
                # List of performance data label entries
         | 
| 28 | 
            +
                # @return [Array<Hash<label,field_data>>] an array of hashes keyed by field
         | 
| 29 | 
            +
                def to_a
         | 
| 30 | 
            +
                  @data.values
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                # @raise Naplug::Error if the label contains invalid characters, the value is not a number, or specify invalid fields
         | 
| 34 | 
            +
                def []=(label,valuefields)
         | 
| 35 | 
            +
                  value, fields = valuefields
         | 
| 36 | 
            +
                  if validate_label label and validate_value value and validate_fields fields
         | 
| 37 | 
            +
                    @data[curate_label(label)] = { :label => curate_label(label), :value => value }.merge fields
         | 
| 38 | 
            +
                  else
         | 
| 39 | 
            +
                    raise Naplug::Error, "invalid performance data label (#{label}), value (#{value}), field representation (#{fields.class}) or field (#{fields.keys.join(',')})"
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                def each(&block)
         | 
| 44 | 
            +
                  @data.values.each(&block)
         | 
| 30 45 | 
             
                end
         | 
| 31 | 
            -
                alias_method :store, :[]=
         | 
| 32 46 |  | 
| 33 47 | 
             
                def [](label)
         | 
| 34 | 
            -
                  @data[label]
         | 
| 48 | 
            +
                  @data[curate_label(label)]
         | 
| 35 49 | 
             
                end
         | 
| 36 | 
            -
                alias_method :fetch, :[]
         | 
| 37 50 |  | 
| 38 51 | 
             
                def delete(label)
         | 
| 39 | 
            -
                  @data.delete(label)
         | 
| 52 | 
            +
                  @data.delete(curate_label(label))
         | 
| 40 53 | 
             
                end
         | 
| 41 54 |  | 
| 42 | 
            -
                def  | 
| 43 | 
            -
                  @data.has_key? label
         | 
| 55 | 
            +
                def include?(label)
         | 
| 56 | 
            +
                  @data.has_key? curate_label(label)
         | 
| 44 57 | 
             
                end
         | 
| 45 | 
            -
                alias_method : | 
| 58 | 
            +
                alias_method :has_label?, :include?
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                def keys
         | 
| 61 | 
            +
                  @data.keys
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
                alias_method :labels, :keys
         | 
| 46 64 |  | 
| 47 65 | 
             
                def fields
         | 
| 48 66 | 
             
                  FIELDS
         | 
| 49 67 | 
             
                end
         | 
| 50 68 |  | 
| 69 | 
            +
                # @return [Plugin] plugin performance data belongs to
         | 
| 70 | 
            +
                def plugin
         | 
| 71 | 
            +
                  @meta.plugin
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                # @return [Array<Plugin>] of parent plugins
         | 
| 75 | 
            +
                def ancestors(options = { :mode => :tags, :separator => :/ })
         | 
| 76 | 
            +
                  options[:separator] = :/ if options[:separator].nil?
         | 
| 77 | 
            +
                  options[:mode].nil? ? @meta.ancestors : @meta.ancestors.map { |a| a.tag }.join(options[:separator].to_s)
         | 
| 78 | 
            +
                end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                private
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                # can contain any characters except the equals sign or single quote (')
         | 
| 83 | 
            +
                def validate_label(l)
         | 
| 84 | 
            +
                  l.nil? or l.to_s.index(/['=]/) ? false : true
         | 
| 85 | 
            +
                end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                def validate_value(v)
         | 
| 88 | 
            +
                  true #      v =~ /^[0-9.-]+$/ ? true : false
         | 
| 89 | 
            +
                end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                def validate_fields(fields)
         | 
| 92 | 
            +
                  fields.is_a? Hash and fields.keys.select { |field| not FIELDS.include? field }.empty? ? true : false
         | 
| 93 | 
            +
                end
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                # single quotes for the label are optional; required if spaces are in the label
         | 
| 96 | 
            +
                def curate_label(l)
         | 
| 97 | 
            +
                  l.to_s.index(/\s+/) ? "'#{l}'" : l.to_s
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                def traverse_to_root(plugin)
         | 
| 101 | 
            +
                  lineage = []
         | 
| 102 | 
            +
                  loop do
         | 
| 103 | 
            +
                    break unless plugin.is_a? Plugin
         | 
| 104 | 
            +
                    lineage.push plugin
         | 
| 105 | 
            +
                    plugin = plugin.parent
         | 
| 106 | 
            +
                  end
         | 
| 107 | 
            +
                  lineage.reverse
         | 
| 108 | 
            +
                end
         | 
| 109 | 
            +
             | 
| 51 110 | 
             
              end
         | 
| 52 111 | 
             
            end
         | 
    
        data/lib/naplug/plugin.rb
    CHANGED
    
    | @@ -8,27 +8,26 @@ module Naplug | |
| 8 8 |  | 
| 9 9 | 
             
              class Plugin
         | 
| 10 10 |  | 
| 11 | 
            -
                attr_reader :block, :plugins, :tag
         | 
| 11 | 
            +
                attr_reader :block, :plugins, :tag, :meta
         | 
| 12 12 |  | 
| 13 13 | 
             
                class DuplicatePlugin < StandardError; end
         | 
| 14 14 |  | 
| 15 | 
            -
                 | 
| 15 | 
            +
                DEFAULT_META = { :debug => false, :enabled => true }
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def initialize(tag, block, meta = {})
         | 
| 16 18 | 
             
                  @tag = tag
         | 
| 17 19 | 
             
                  @block = block
         | 
| 18 20 | 
             
                  @plugins = Hash.new
         | 
| 19 21 |  | 
| 20 22 | 
             
                  @_args = Hash.new
         | 
| 21 23 | 
             
                  @_data = OpenStruct.new :status => Status.new, :output => Output.new, :payload => nil, :perfdata => nil
         | 
| 22 | 
            -
                  @_meta = OpenStruct.new  | 
| 24 | 
            +
                  @_meta = OpenStruct.new DEFAULT_META.merge meta
         | 
| 23 25 |  | 
| 24 26 | 
             
                  begin; instance_eval &block ; rescue => e; nil ; end
         | 
| 25 27 |  | 
| 26 28 | 
             
                end
         | 
| 27 29 |  | 
| 28 | 
            -
                # @ | 
| 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
         | 
| 30 | 
            +
                # @return [True, False] true if this plugin is a metaplugin, false otherwise
         | 
| 32 31 | 
             
                def is_meta?
         | 
| 33 32 | 
             
                  @_meta.status
         | 
| 34 33 | 
             
                end
         | 
| @@ -53,6 +52,10 @@ module Naplug | |
| 53 52 | 
             
                  not @_meta.enabled
         | 
| 54 53 | 
             
                end
         | 
| 55 54 |  | 
| 55 | 
            +
                def parent
         | 
| 56 | 
            +
                  @_meta.parent
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
             | 
| 56 59 | 
             
                # true when a plugin contains plugs
         | 
| 57 60 | 
             
                def has_plugins?
         | 
| 58 61 | 
             
                  @plugins.empty? ? false : true
         | 
| @@ -91,8 +94,8 @@ module Naplug | |
| 91 94 | 
             
                end
         | 
| 92 95 |  | 
| 93 96 | 
             
                def perfdata!(label,value,f = {})
         | 
| 94 | 
            -
                  @_data.perfdata ||= PerformanceData.new  | 
| 95 | 
            -
                  @_data.perfdata | 
| 97 | 
            +
                  @_data.perfdata ||= PerformanceData.new self
         | 
| 98 | 
            +
                  @_data.perfdata[label] = value, f
         | 
| 96 99 | 
             
                end
         | 
| 97 100 |  | 
| 98 101 | 
             
                def payload
         | 
| @@ -124,7 +127,7 @@ module Naplug | |
| 124 127 | 
             
                  @_args[k] = v
         | 
| 125 128 | 
             
                end
         | 
| 126 129 |  | 
| 127 | 
            -
                def  | 
| 130 | 
            +
                def to_str
         | 
| 128 131 | 
             
                  '%s: %s' % [status,output]
         | 
| 129 132 | 
             
                end
         | 
| 130 133 |  | 
| @@ -141,7 +144,7 @@ module Naplug | |
| 141 144 |  | 
| 142 145 | 
             
                def plugin(tag, &block)
         | 
| 143 146 | 
             
                  raise DuplicatePlugin, "duplicate definition of #{tag}" if @plugins.key? tag
         | 
| 144 | 
            -
                  @plugins[tag] = Plugin.new tag, block
         | 
| 147 | 
            +
                  @plugins[tag] = Plugin.new tag, block, :parent => self
         | 
| 145 148 | 
             
                  self.define_singleton_method tag do
         | 
| 146 149 | 
             
                    @plugins[tag]
         | 
| 147 150 | 
             
                  end
         | 
    
        data/lib/naplug/version.rb
    CHANGED
    
    | @@ -1,3 +1,3 @@ | |
| 1 1 | 
             
            module Naplug
         | 
| 2 | 
            -
              VERSION = '1. | 
| 3 | 
            -
            end
         | 
| 2 | 
            +
              VERSION = '1.7.1'
         | 
| 3 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: naplug
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1. | 
| 4 | 
            +
              version: 1.7.1
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors:
         | 
| @@ -9,7 +9,7 @@ authors: | |
| 9 9 | 
             
            autorequire: 
         | 
| 10 10 | 
             
            bindir: bin
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date: 2014-02- | 
| 12 | 
            +
            date: 2014-02-26 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies: []
         | 
| 14 14 | 
             
            description: ! 'A Ruby library for Nagios plugins '
         | 
| 15 15 | 
             
            email: gerir@evernote.com
         | 
| @@ -26,8 +26,6 @@ files: | |
| 26 26 | 
             
            - lib/naplug/version.rb
         | 
| 27 27 | 
             
            - lib/naplug.rb
         | 
| 28 28 | 
             
            - examples/almostalwaysok
         | 
| 29 | 
            -
            - examples/alwaysok
         | 
| 30 | 
            -
            - examples/alwaysunknown
         | 
| 31 29 | 
             
            - examples/dupplugin
         | 
| 32 30 | 
             
            - examples/exception
         | 
| 33 31 | 
             
            - examples/exception+
         | 
| @@ -36,7 +34,11 @@ files: | |
| 36 34 | 
             
            - examples/multiplug
         | 
| 37 35 | 
             
            - examples/multiplugin
         | 
| 38 36 | 
             
            - examples/multiplugins
         | 
| 37 | 
            +
            - examples/o_alwaysok
         | 
| 38 | 
            +
            - examples/perfdata_multiplug
         | 
| 39 | 
            +
            - examples/perfdata_uniplug
         | 
| 39 40 | 
             
            - examples/status
         | 
| 41 | 
            +
            - examples/u_alwaysunknown
         | 
| 40 42 | 
             
            - LICENSE
         | 
| 41 43 | 
             
            - README.md
         | 
| 42 44 | 
             
            homepage: https://github.com/gerirgaudi/naplug
         | 
| @@ -65,3 +67,4 @@ signing_key: | |
| 65 67 | 
             
            specification_version: 3
         | 
| 66 68 | 
             
            summary: A Ruby library for Nagios plugins
         | 
| 67 69 | 
             
            test_files: []
         | 
| 70 | 
            +
            has_rdoc: 
         |