munin-plugin 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ *~
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in munin-plugin.gemspec
4
+ gemspec
data/README.rdoc ADDED
@@ -0,0 +1,72 @@
1
+ = munin
2
+
3
+ * http://github.com/albanpeignier/munin/
4
+
5
+ == DESCRIPTION:
6
+
7
+ The munin gem provides a base class to create munin plugins in ruby.
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * create munin plugin config output from class attributes
12
+ * format munin plugin output from a map of values
13
+ * support configuration based on filename
14
+
15
+ == SYNOPSIS:
16
+
17
+ require 'rubygems'
18
+ require 'munin'
19
+
20
+ class FetchmailMailVolume < Munin::Plugin
21
+
22
+ graph_attributes "Fetchmail bytes throughput",
23
+ :category => 'Mail',
24
+ :info => 'This graph shows the volume of mails retrieved by fetchmail'
25
+
26
+ declare_field :volume,
27
+ :label => 'throughput', :type => :derive, :min => 0
28
+
29
+ def retrieve_values
30
+ volume = 0
31
+ File.open('/var/log/mail.log','r') do |f|
32
+ while line = f.gets
33
+ if line.match(/fetchmail\[[0-9]+\]: reading message .*\(([0-9]+) octets\)/)
34
+ volume = volume + $1.to_i
35
+ end
36
+ end
37
+ end
38
+ { :volume => volume }
39
+ end
40
+
41
+ end
42
+
43
+ FetchmailMailVolume.new.run
44
+
45
+ == INSTALL:
46
+
47
+ * sudo gem install munin
48
+
49
+ == LICENSE:
50
+
51
+ (The MIT License)
52
+
53
+ Copyright (c) 2008 Alban Peignier
54
+
55
+ Permission is hereby granted, free of charge, to any person obtaining
56
+ a copy of this software and associated documentation files (the
57
+ 'Software'), to deal in the Software without restriction, including
58
+ without limitation the rights to use, copy, modify, merge, publish,
59
+ distribute, sublicense, and/or sell copies of the Software, and to
60
+ permit persons to whom the Software is furnished to do so, subject to
61
+ the following conditions:
62
+
63
+ The above copyright notice and this permission notice shall be
64
+ included in all copies or substantial portions of the Software.
65
+
66
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
67
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
68
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
69
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
70
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
71
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
72
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,3 @@
1
+ module Munin
2
+ VERSION = '0.0.2'
3
+ end
data/lib/munin.rb ADDED
@@ -0,0 +1,282 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ include 'munin/version'
5
+
6
+ module Munin
7
+
8
+ # Base class to create Munin plugin
9
+ #
10
+ # class ActiveRecordSessionPlugin << Munin::Plugin
11
+ # graph_attributes "Rails Sessions",
12
+ # :category => 'Application',
13
+ # :info => 'This graph shows the rails application session count'
14
+ #
15
+ # declare_field :count, :label => 'session count', :min => 0
16
+ #
17
+ # def retrieve_values
18
+ # count = ...
19
+ # { :count => count }
20
+ # end
21
+ # end
22
+ #
23
+ # ActiveRecordSessionPlugin.run
24
+ class Plugin
25
+
26
+ class << self
27
+
28
+ @@fields = []
29
+
30
+ # Sets the graph attributes of the plugin
31
+ #
32
+ # ==== Attributes
33
+ # * +title+: - The title of the graph, defaults to the plugin's name (munin global attribute graph_title)
34
+ # * +options+: - Other graph attributes for the plugin (munin global attribute graph_*)
35
+ #
36
+ # ==== Examples
37
+ #
38
+ # # Set classic graph attributes
39
+ # graph_attributes "Fetchmail bytes throughput",
40
+ # :category => 'Mail',
41
+ # :info => 'This graph shows the volume of mails retrieved by fetchmail'
42
+ def graph_attributes(title, options = {})
43
+ @@graph_options = { :title => title, :args => '--base 1000' }.merge(options)
44
+ end
45
+
46
+ # Declare a data source / field of the plugin
47
+ #
48
+ # ==== Attributes
49
+ # * +name+: - The field name
50
+ # * +options+: - The field attributes
51
+ #
52
+ # ==== Examples
53
+ #
54
+ # # Set a derive field
55
+ # declare_field :volume, :label => 'throughput', :type => :derive, :min => 0
56
+ def declare_field(name, options = {})
57
+ @@fields << Field.new(name, options)
58
+ end
59
+
60
+ # An elegant way to share common options
61
+ #
62
+ # ==== Attributes
63
+ # * +options+: - The common options
64
+ #
65
+ # ==== Examples
66
+ #
67
+ # # Share field attributes
68
+ # with :type => :derive, :min => 0 do
69
+ # declare_field :input, :label => "download"
70
+ # declare_field :output, :label => "upload"
71
+ # end
72
+ def with_options(options)
73
+ yield OptionMerger.new(self, options)
74
+ end
75
+
76
+ end
77
+
78
+ attr_reader :fields
79
+
80
+ def initialize(config = {})
81
+ @config = config.symbolize_keys
82
+
83
+ if self.class.respond_to?(:config_from_filename)
84
+ @config.merge!(self.class.config_from_filename.symbolize_keys)
85
+ end
86
+
87
+ @fields = @@fields.dup
88
+
89
+ after_initialize if respond_to?(:after_initialize)
90
+ end
91
+
92
+ # Prints plugin configuration by using the munin format
93
+ def print_config
94
+ output 'host_name', hostname unless hostname.nil?
95
+
96
+ GRAPH_ATTRIBUTES.each do |graph_attribute|
97
+ graph_option = @@graph_options[graph_attribute.to_sym]
98
+ output "graph_#{graph_attribute}", graph_option unless graph_option.nil?
99
+ end
100
+
101
+ fields.each do |field|
102
+ field.config.each_pair { |key, value| output key, value }
103
+ end
104
+ end
105
+
106
+ # Prints plugin values by using the munin format
107
+ def print_values
108
+ retrieve_values.each_pair do |name, value|
109
+ output "#{name}.value", value
110
+ end
111
+ end
112
+
113
+ # Create and executes the plugin
114
+ def self.run
115
+ self.new.run
116
+ end
117
+
118
+ # Executes the plugin
119
+ def run
120
+ case ARGV.first
121
+ when "config"
122
+ print_config
123
+ else
124
+ print_values
125
+ end
126
+ end
127
+
128
+ def declare_field(name, options = {})
129
+ @fields << Field.new(name, options)
130
+ end
131
+
132
+ protected
133
+
134
+ attr_accessor :hostname
135
+
136
+ def output(key, value)
137
+ puts "#{key} #{value}"
138
+ end
139
+
140
+ def config_value(key)
141
+ @config[key]
142
+ end
143
+
144
+ GRAPH_ATTRIBUTES = %w{ title args category info order vlabel total scale period vtitle width height printf }
145
+
146
+ private
147
+
148
+ def method_missing(method, *arguments, &block)
149
+ case method.id2name
150
+ when /^graph_([_a-z]+)$/
151
+ @@graph_options[$1.to_sym]
152
+ when /^graph_([_a-z]+)=$/
153
+ @@graph_options[$1.to_sym] = arguments
154
+ else super
155
+ end
156
+ end
157
+
158
+ end
159
+
160
+ class Field
161
+
162
+ attr_reader :name, :options
163
+
164
+ def initialize(name, options = {})
165
+ @name, @options = name.to_s, options
166
+
167
+ @options[:label] ||= default_label(name)
168
+ end
169
+
170
+ def default_label(name)
171
+ name.to_s.gsub('_',' ')
172
+ end
173
+
174
+ def option(key)
175
+ @options[key]
176
+ end
177
+
178
+ DATA_SOURCE_ATTRIBUTES = %w{ label cdef draw graph extinfo max min negative type warning critical colour skipdraw sum stack line }
179
+
180
+ def config
181
+ DATA_SOURCE_ATTRIBUTES.inject({}) do |config, attribute|
182
+ attribute = attribute.to_sym
183
+ attribute_value = @options[attribute]
184
+
185
+ unless attribute_value.nil?
186
+ case attribute
187
+ when :type
188
+ attribute_value = attribute_value.to_s.upcase
189
+ end
190
+ config["#{name}.#{attribute}"] = attribute_value
191
+ end
192
+
193
+ config
194
+ end
195
+ end
196
+
197
+ def ==(other)
198
+ other and name == other.name and options == other.options
199
+ end
200
+
201
+ end
202
+
203
+ class OptionMerger # from ActiveSupport
204
+ instance_methods.each do |method|
205
+ undef_method(method) if method !~ /^(__|instance_eval|class|object_id)/
206
+ end
207
+
208
+ def initialize(context, options)
209
+ @context, @options = context, options
210
+ end
211
+
212
+ private
213
+ def method_missing(method, *arguments, &block)
214
+ merge_argument_options! arguments
215
+ @context.send(method, *arguments, &block)
216
+ end
217
+
218
+ def merge_argument_options!(arguments)
219
+ arguments << if arguments.last.respond_to? :to_hash
220
+ @options.merge(arguments.pop)
221
+ else
222
+ @options.dup
223
+ end
224
+ end
225
+ end
226
+
227
+ module Hash
228
+ module Keys
229
+ # Return a new hash with all keys converted to strings.
230
+ def stringify_keys
231
+ inject({}) do |options, (key, value)|
232
+ options[key.to_s] = value
233
+ options
234
+ end
235
+ end
236
+
237
+ # Destructively convert all keys to strings.
238
+ def stringify_keys!
239
+ keys.each do |key|
240
+ unless key.class.to_s == "String" # weird hack to make the tests run when string_ext_test.rb is also running
241
+ self[key.to_s] = self[key]
242
+ delete(key)
243
+ end
244
+ end
245
+ self
246
+ end
247
+
248
+ # Return a new hash with all keys converted to symbols.
249
+ def symbolize_keys
250
+ inject({}) do |options, (key, value)|
251
+ options[key.to_sym || key] = value
252
+ options
253
+ end
254
+ end
255
+
256
+ # Destructively convert all keys to symbols.
257
+ def symbolize_keys!
258
+ self.replace(self.symbolize_keys)
259
+ end
260
+
261
+ alias_method :to_options, :symbolize_keys
262
+ alias_method :to_options!, :symbolize_keys!
263
+
264
+ # Validate all keys in a hash match *valid keys, raising ArgumentError on a mismatch.
265
+ # Note that keys are NOT treated indifferently, meaning if you use strings for keys but assert symbol
266
+ # as keys, this will fail.
267
+ # examples:
268
+ # { :name => "Rob", :years => "28" }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key(s): years"
269
+ # { :name => "Rob", :age => "28" }.assert_valid_keys("name", "age") # => raises "ArgumentError: Unknown key(s): years, name"
270
+ # { :name => "Rob", :age => "28" }.assert_valid_keys(:name, :age) # => passes, raises nothing
271
+ def assert_valid_keys(*valid_keys)
272
+ unknown_keys = keys - [valid_keys].flatten
273
+ raise(ArgumentError, "Unknown key(s): #{unknown_keys.join(", ")}") unless unknown_keys.empty?
274
+ end
275
+ end
276
+ end
277
+
278
+ end
279
+
280
+ class Hash #:nodoc:
281
+ include Munin::Hash::Keys
282
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "munin/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "munin-plugin"
7
+ s.version = Munin::VERSION
8
+ s.authors = ["Alban Peignier"]
9
+ s.email = ["alban@tryphon.eu"]
10
+ s.homepage = "http://github.com/albanpeignier/munin/"
11
+ s.summary = %q{Create munin plugins in ruby}
12
+ s.description = %q{The munin gem provides a base class to create munin plugins in ruby}
13
+
14
+ s.rubyforge_project = "munin-plugin"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ s.add_development_dependency "rake"
23
+ # s.add_runtime_dependency "rest-client"
24
+ end
data/script/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/munin.rb'}"
9
+ puts "Loading munin gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
data/script/destroy ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
data/script/generate ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,20 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ class TestPlugin < Munin::Plugin
4
+
5
+ end
6
+
7
+ describe Munin::Plugin do
8
+
9
+ before(:each) do
10
+ @plugin = TestPlugin.new
11
+ end
12
+
13
+ it "should have a new field with declare_field" do
14
+ class TestPlugin
15
+ declare_field :test
16
+ end
17
+ @plugin.fields.should == [ Munin::Field.new(:test) ]
18
+ end
19
+
20
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,11 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ gem 'rspec'
6
+ require 'spec'
7
+ end
8
+
9
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
10
+ require 'munin'
11
+
data/tasks/rspec.rake ADDED
@@ -0,0 +1,21 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ require 'spec'
6
+ end
7
+ begin
8
+ require 'spec/rake/spectask'
9
+ rescue LoadError
10
+ puts <<-EOS
11
+ To use rspec for testing you must install rspec gem:
12
+ gem install rspec
13
+ EOS
14
+ exit(0)
15
+ end
16
+
17
+ desc "Run the specs under spec/models"
18
+ Spec::Rake::SpecTask.new do |t|
19
+ t.spec_opts = ['--options', "spec/spec.opts"]
20
+ t.spec_files = FileList['spec/**/*_spec.rb']
21
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: munin-plugin
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 2
10
+ version: 0.0.2
11
+ platform: ruby
12
+ authors:
13
+ - Alban Peignier
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-06-03 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ prerelease: false
22
+ type: :development
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ name: rake
33
+ version_requirements: *id001
34
+ description: The munin gem provides a base class to create munin plugins in ruby
35
+ email:
36
+ - alban@tryphon.eu
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files: []
42
+
43
+ files:
44
+ - .gitignore
45
+ - Gemfile
46
+ - README.rdoc
47
+ - Rakefile
48
+ - lib/munin.rb
49
+ - lib/munin/version.rb
50
+ - munin-plugin.gemspec
51
+ - script/console
52
+ - script/destroy
53
+ - script/generate
54
+ - spec/munin_spec.rb
55
+ - spec/spec.opts
56
+ - spec/spec_helper.rb
57
+ - tasks/rspec.rake
58
+ homepage: http://github.com/albanpeignier/munin/
59
+ licenses: []
60
+
61
+ post_install_message:
62
+ rdoc_options: []
63
+
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ hash: 3
81
+ segments:
82
+ - 0
83
+ version: "0"
84
+ requirements: []
85
+
86
+ rubyforge_project: munin-plugin
87
+ rubygems_version: 1.8.15
88
+ signing_key:
89
+ specification_version: 3
90
+ summary: Create munin plugins in ruby
91
+ test_files:
92
+ - spec/munin_spec.rb
93
+ - spec/spec.opts
94
+ - spec/spec_helper.rb