ubc-monitor 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,16 @@
1
+ 1.1.0 - 2008-11-07 Christian Johansen <christian@cjohansen.no>w
2
+ * Packaged project as gem
3
+ * Switched from Subversion to Git
4
+
5
+ 1.0.2 - 2008-04-25 Christian Johansen <christian@cjohansen.no>
6
+
7
+ * Added Changelog to project :)
8
+ * Added a boolean updated flag to Ubc::Report
9
+ * Changed check on failcounts to make sure failcounts higher than 0, but no higher than previous
10
+ failcount still gets written back to the log file
11
+
12
+ 1.0.1 - 2008-04-21 Christian Johansen <christian@cjohansen.no>
13
+
14
+ * Changed shebang to /usr/bin/env ruby
15
+ * Changed cat /proc/user_beancounters command (removed grep part which rendered it useless)
16
+ * Removed -t option for mail which didn't work under Debian
@@ -0,0 +1,16 @@
1
+ History.txt
2
+ Manifest.txt
3
+ PostInstall.txt
4
+ README.txt
5
+ Rakefile
6
+ bin/ubc_monitor
7
+ lib/ubc_monitor.rb
8
+ lib/ubc_monitor/cli.rb
9
+ lib/ubc_monitor/monitor.rb
10
+ lib/ubc_monitor/report.rb
11
+ script/console
12
+ script/destroy
13
+ script/generate
14
+ test/test_helper.rb
15
+ test/test_ubc_monitor.rb
16
+ test/test_ubc_report.rb
@@ -0,0 +1,2 @@
1
+
2
+ For more information on ubc_monitor, see http://www.cjohansen.no/projects/ubc_monitor
@@ -0,0 +1,56 @@
1
+ = ubc_monitor
2
+
3
+ * http://www.cjohansen.no/projects/ubc_monitor
4
+
5
+ == DESCRIPTION:
6
+
7
+ ubc_monitor monitors resource usage in virtual servers run by
8
+ OpenVz.
9
+
10
+ Monitor /proc/user_beancounters and send an email to the systems
11
+ administrator if failcnt has increased since last time ubc_monitor
12
+ was run.
13
+
14
+ ubc_monitor uses a file (by default ~/.ubc_monitor) to keep track of
15
+ user_beancounter fail counts. When running without this file (such
16
+ as the first run) any fail count except 0 will be reported.
17
+
18
+ == SYNOPSIS:
19
+
20
+ ubc_monitor [options]
21
+
22
+ Options:
23
+
24
+ -f --file Log failcounts to this file, default is ~/.ubc_monitor
25
+ -n --no-log Don't log fail counts (only print results to STDOUT)
26
+ -t --email-recipient [EMAIL] The recipient of report emails. If this is not set, no email is sent
27
+ -s --email-subject [SUBJECT] Email subject. Default value is 'VPS has increased failcounts'
28
+
29
+ == INSTALL:
30
+
31
+ sudo gem install ubc_monitor
32
+
33
+ == LICENSE:
34
+
35
+ (The MIT License)
36
+
37
+ Copyright (c) 2008 Christian Johansen
38
+
39
+ Permission is hereby granted, free of charge, to any person obtaining
40
+ a copy of this software and associated documentation files (the
41
+ 'Software'), to deal in the Software without restriction, including
42
+ without limitation the rights to use, copy, modify, merge, publish,
43
+ distribute, sublicense, and/or sell copies of the Software, and to
44
+ permit persons to whom the Software is furnished to do so, subject to
45
+ the following conditions:
46
+
47
+ The above copyright notice and this permission notice shall be
48
+ included in all copies or substantial portions of the Software.
49
+
50
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
51
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
52
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
53
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
54
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
55
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
56
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,28 @@
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
+ require File.dirname(__FILE__) + '/lib/ubc_monitor'
3
+
4
+ # Generate all the Rake tasks
5
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
6
+ $hoe = Hoe.new('ubc-monitor', UbcMonitor::VERSION) do |p|
7
+ p.developer('Christian Johansen', 'christian@cjohansen.no')
8
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
9
+ p.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
10
+ p.rubyforge_name = p.name # TODO this is default value
11
+ # p.extra_deps = [
12
+ # ['activesupport','>= 2.0.2'],
13
+ # ]
14
+ p.extra_dev_deps = [
15
+ ['newgem', ">= #{::Newgem::VERSION}"]
16
+ ]
17
+
18
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
19
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
20
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
21
+ p.rsync_args = '-av --delete --ignore-errors'
22
+ end
23
+
24
+ require 'newgem/tasks' # load /tasks/*.rake
25
+ Dir['tasks/**/*.rake'].each { |t| load t }
26
+
27
+ # TODO - want other tests/tasks run by default? Add them to the list
28
+ # task :default => [:spec, :features]
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Created by Christian Johansen on 2008-11-3.
4
+ # Copyright (c) 2008. All rights reserved.
5
+
6
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/ubc_monitor")
7
+ require "ubc_monitor/cli"
8
+
9
+ Ubc::CLI.execute(ARGV)
@@ -0,0 +1,18 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'ubc_monitor/report'
5
+ require 'ubc_monitor/monitor'
6
+
7
+ #
8
+ # Monitor /proc/user_beancounters and send an email to the systems
9
+ # administrator if failcnt has increased since last time ubc_monitor
10
+ # was run.
11
+ #
12
+ # ubc_monitor uses a file (by default ~/.ubc_monitor) to keep track of
13
+ # user_beancounter fail counts. When running without this file (such
14
+ # as the first run) any fail count except 0 will be reported.
15
+ #
16
+ module UbcMonitor
17
+ VERSION = '1.1.0'
18
+ end
@@ -0,0 +1,46 @@
1
+ require 'optparse'
2
+
3
+ module UbcMonitor
4
+ #
5
+ # Run the monitor
6
+ #
7
+ class CLI
8
+ def self.execute(arguments=[])
9
+ options = { :file => File.expand_path('~/.ubc_monitor'),
10
+ :email_recipient => nil,
11
+ :email_subject => 'User beancounters has new errors' }
12
+
13
+ OptionParser.new do |opts|
14
+ opts.banner = <<-BANNER.gsub(/^ /,'')
15
+ Monitor /proc/user_beancounters and send an email to the systems
16
+ administrator if failcnt has increased since last time ubc_monitor
17
+ was run.
18
+
19
+ ubc_monitor uses a file (by default ~/.ubc_monitor) to keep track of
20
+ user_beancounter fail counts. When running without this file (such
21
+ as the first run) any fail count except 0 will be reported.
22
+
23
+ Usage: #{File.basename(__FILE__)} [options]
24
+ BANNER
25
+ opts.on("-f", "--file [FILE]", "Log failcounts to this file, default\n" +
26
+ " is #{options[:file]}") { |f| options[:file] = File.expand_path f }
27
+ opts.on("-n", "--no-log", "Don't log fail counts") { |r| options[:file] = nil }
28
+ opts.on("-t", "--email-recipient [EMAIL]", "The recipient of report emails.\n" +
29
+ " If this is not set, no email is sent") { |r| options[:email_recipient] = r }
30
+ opts.on("-s", "--email-subject [SUBJECT]", "Email subject. Default\n" +
31
+ " 'value is #{options[:email_subject]}'") { |s| options[:email_subject] = s }
32
+ end.parse!
33
+
34
+ monitor = UbcMonitor::Monitor.new(options)
35
+ report = monitor.run
36
+
37
+ if report.updated && !options[:email_recipient].nil?
38
+ `echo '"#{report.to_s}"' | mail -s "#{options[:email_subject]}" "#{options[:email_recipient]}"`
39
+ elsif report.updated
40
+ puts report.to_s
41
+ else
42
+ puts "All's swell!"
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,77 @@
1
+ require 'net/smtp'
2
+ require 'ostruct'
3
+
4
+ # Namespace for the UbcMonitor script
5
+ module UbcMonitor
6
+
7
+ # The Monitor provides an interface for inspecting /proc/user_beancounters as well
8
+ # as a number of ways to report numbers that exceed given limits
9
+ class Monitor
10
+
11
+ def initialize(options = {})
12
+ @options = ({ :file => nil }).merge(options)
13
+ end
14
+
15
+ # Run the monitor. Uses a UbcMonitor::Report object to track runs so as to not
16
+ # report back errors that have already been reported
17
+ def run
18
+ filename = @options[:file]
19
+
20
+ # Fetch data from the previous run, this will be the baseline
21
+ report = filename.nil? ? Report.new : Report.load(filename)
22
+
23
+ # Update the report by scanning /proc/user_beancounters
24
+ report = scan(report)
25
+
26
+ # Log report back to file and return report
27
+ report.dump!(filename) unless filename.nil? || report.length == 0
28
+
29
+ report
30
+ end
31
+
32
+ # Generate the /proc/user_beancounters report by running cat on it.
33
+ # The method takes a UbcMonitor::Report object and returns a fresh report containing
34
+ # only VPS's that have increased failcounts
35
+ def scan(report = Report.new)
36
+ vps = nil
37
+ nrep = Report.new
38
+
39
+ proc_user_beancounters.split("\n").each do |line|
40
+ if line =~ /^\s+(\d+):/
41
+ vps = $1.to_sym
42
+ end
43
+
44
+ # If the VPS is set, and the line (that is, the failcount) does not end with
45
+ # a 0, set the resource/failcount pair
46
+ unless vps.nil? || line =~ /\s0$/
47
+ pieces = line.gsub(/^\s*(\d+:)?\s*/, '').split(/\s+/)
48
+ resource = pieces[0].to_sym
49
+
50
+ if report[vps, resource].nil? || report[vps, resource][:failcnt].nil? ||
51
+ pieces[5].to_i > report[vps, resource][:failcnt]
52
+ nrep[vps, resource] = { :held => pieces[1].to_i, :maxheld => pieces[2].to_i,
53
+ :barrier => pieces[3].to_i, :limit => pieces[4].to_i,
54
+ :failcnt => pieces[5].to_i }
55
+
56
+ # Mark report as updated if failcount has increased
57
+ nrep.updated = true if report[vps, resource].nil? || pieces[5].to_i > report[vps, resource][:failcnt]
58
+ end
59
+ end
60
+ end
61
+
62
+ nrep
63
+ end
64
+
65
+ private
66
+
67
+ # Reading /proc/user_beancounters itself is separated to allow for better testability
68
+ def proc_user_beancounters
69
+ unless File.readable? '/proc/user_beancounters'
70
+ puts "Unable to \'cat /proc/user_beancounters\'. Are you root?"
71
+ exit
72
+ end
73
+
74
+ `cat /proc/user_beancounters`
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,128 @@
1
+ # Namespace for the UbcMonitor script
2
+ module UbcMonitor
3
+
4
+ # The UbcMonitor::Report object holds information on the current state of failcounts in the
5
+ # /proc/user_beancounts table
6
+ #
7
+ # The Report is able to generate different views of the data it represents. It can use a
8
+ # file to log reports between uses in order to only report on failcounts that have increased
9
+ # since its last run.
10
+ #
11
+ # The log file contains sections for each VPS currently having failcounts. The VPS id introduces
12
+ # the section, followed by a newline and then resource: <failcount> pairs, one on each line.
13
+ # The VPS block is terminated by a double newline.
14
+ #
15
+ # Example file:
16
+ #
17
+ # 101
18
+ # privvmpages: 2
19
+ # kmemsize: 4
20
+ #
21
+ # 102
22
+ # privvmpages: 3
23
+ #
24
+ class Report
25
+ attr_accessor :updated
26
+
27
+ # Setup a new Report
28
+ def initialize
29
+ @resource_counts = {}
30
+ @updated = false
31
+ end
32
+
33
+ # Parse the ubc_monitor logfile and return a UbcMonitor::Report object
34
+ def self.load(file)
35
+ report = Report.new
36
+ vps = nil
37
+
38
+ return report if file.nil? || !File.exist?(file)
39
+
40
+ IO.read(file).each do |line|
41
+ if line =~ /^\s*$/
42
+ # This is a blank line separating VPS instances. Reset vps
43
+ vps = nil
44
+ elsif vps.nil?
45
+ # If the VPS has been reset, this line is expected to contain a new VPS id
46
+ vps = line.strip.to_sym
47
+ else
48
+ # Otherwise, this is a resource: <value> line belonging to the current VPS
49
+ resource, failcnt = line.split(':')
50
+ report[vps, resource.to_sym] = { :failcnt => failcnt.to_i }
51
+ end
52
+ end
53
+
54
+ return report
55
+ end
56
+
57
+ # Dump the report back to file
58
+ def dump!(file)
59
+ File.open(file, 'w+') do |f|
60
+ @resource_counts.each_pair do |vps, content|
61
+ # Each VPS in its own section, starting with the VPS id and followed by all the
62
+ # resources currently keeping a failcount, then terminated by a blank line.
63
+ # Resources whose failcounts are 0 are not dumped
64
+ str = ''
65
+ content.each_pair { |resource, numbers| str += "#{resource}: #{numbers[:failcnt]}\n" unless numbers[:failcnt] == 0 }
66
+ f.puts vps, str, '' unless str == ''
67
+ end
68
+ end
69
+ end
70
+
71
+ # Add a resource failcount. If resource and failcnt are nil, only allocate room for
72
+ # the VPS. Returns the VPS symbol
73
+ #
74
+ # +vps+ and +resource+ are both symbols while +limits+ should be a hash (unless
75
+ # +resource+ and +limits+ are both +nil+ in which case no resource/limits pair
76
+ # is actually appended). The hash can contain the following values:
77
+ # :held, :maxheld, :barrier, :limit, :failcnt
78
+ def []=(vps, resource, limits)
79
+ @resource_counts[vps] = {} if @resource_counts[vps].nil?
80
+ @resource_counts[vps][resource] = limits
81
+ vps
82
+ end
83
+
84
+ # Fetch the ubc numbers array for a given VPS
85
+ def [](vps, resource = nil)
86
+ has_vps = @resource_counts.key? vps
87
+ has_resource = has_vps && @resource_counts[vps].key?(resource)
88
+
89
+ return resource.nil? ?
90
+ (has_vps ? @resource_counts[vps] : nil) :
91
+ (has_resource ? @resource_counts[vps][resource] : nil)
92
+ end
93
+
94
+ # Returns true if no VPS's has any reported failcounts
95
+ def empty?
96
+ return length == 0
97
+ end
98
+
99
+ # Returns the number of VPSs in the report
100
+ def length
101
+ return @resource_counts.length
102
+ end
103
+
104
+ # Alias of +UbcMonitor::Monitor#length+
105
+ alias size length
106
+
107
+ # Return a nicely formatted report
108
+ def to_s
109
+ str = ''
110
+
111
+ @resource_counts.dup.each do |vps, content|
112
+ str += "VPS #{vps} has increased fail counts:\n"
113
+ str += "#{'resource'.rjust(20)}#{'held'.rjust(15)}#{'maxheld'.rjust(15)}" +
114
+ "#{'barrier'.rjust(15)}#{'limit'.rjust(15)}#{'failcount'.rjust(15)}\n"
115
+
116
+ content.each_pair do |resource, report|
117
+ str += resource.to_s.rjust(20)
118
+ [:held, :maxheld, :barrier, :limit, :failcnt].each { |sym| str += report[sym].to_s.rjust(15) }
119
+ str += "\n"
120
+ end
121
+
122
+ str += "\n"
123
+ end
124
+
125
+ str
126
+ end
127
+ end
128
+ end
@@ -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/ubc_monitor.rb'}"
9
+ puts "Loading ubc_monitor gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
@@ -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)
@@ -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,2 @@
1
+ require 'test/unit'
2
+ require File.dirname(__FILE__) + '/../lib/ubc_monitor'
@@ -0,0 +1,117 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ # Mock cat /proc/user_beancounters
4
+ module UbcMonitor
5
+ class Monitor
6
+ def proc_user_beancounters
7
+ <<-EOF
8
+ Version: 2.5
9
+ uid resource held maxheld barrier limit failcnt
10
+ 101: kmemsize 1477444 2608200 8192000 9011200 3
11
+ lockedpages 0 0 2048 2048 4
12
+ numtcpsock 4 6 250 250 0
13
+ numflock 5 6 200 220 0
14
+ numpty 0 0 32 32 13
15
+ numsiginfo 0 2 256 256 0
16
+ tcpsndbuf 69504 90168 2682880 5242880 0
17
+ tcprcvbuf 65536 0 2682880 5242880 0
18
+ 102: kmemsize 5749546 6930244 18000000 48000000 0
19
+ lockedpages 0 0 2048 2048 0
20
+ tcprcvbuf 81920 0 2682880 5242880 0
21
+ othersockbuf 4592 11200 751616 20311616 0
22
+ dgramrcvbuf 0 8440 131072 131072 345
23
+ numothersock 3 10 250 250 0
24
+ dcachesize 0 0 2097152 2158592 0
25
+ 103: kmemsize 5749546 6930244 18000000 48000000 0
26
+ lockedpages 0 0 2048 2048 0
27
+ tcprcvbuf 81920 0 2682880 5242880 0
28
+ EOF
29
+ end
30
+ end
31
+ end
32
+
33
+ class TestUbcMonitor < Test::Unit::TestCase
34
+
35
+ def test_init_monitor
36
+ monitor = UbcMonitor::Monitor.new
37
+ assert_not_nil monitor
38
+ end
39
+
40
+ def test_monitor_scan
41
+ monitor = UbcMonitor::Monitor.new
42
+ report = monitor.scan
43
+
44
+ assert_equal 2, report.length
45
+ assert_equal 3, report[:'101'].length
46
+ assert_equal 1, report[:'102'].length
47
+
48
+ report[:'101', :kmemsize] = { :failcnt => 0 }
49
+ report[:'101', :numpty] = { :failcnt => 4 }
50
+ nrep = monitor.scan report
51
+
52
+ assert_equal 1, nrep.length
53
+ assert_equal 2, nrep[:'101'].length
54
+ assert_equal 13, nrep[:'101', :numpty][:failcnt]
55
+ assert_equal 3, nrep[:'101', :kmemsize][:failcnt]
56
+ end
57
+
58
+ def test_run
59
+ monitor = UbcMonitor::Monitor.new
60
+ report = monitor.run
61
+
62
+ assert_equal 2, report.length
63
+ assert_equal 3, report[:'101'].length
64
+ assert_equal 1, report[:'102'].length
65
+
66
+ filename = '.ubc_test_file'
67
+ monitor = UbcMonitor::Monitor.new :file => filename
68
+ report = monitor.run
69
+
70
+ assert_equal 2, report.length
71
+ assert_equal 3, report[:'101'].length
72
+ assert_equal 1, report[:'102'].length
73
+
74
+ contents = <<-EOF
75
+ 101
76
+ kmemsize: 3
77
+ lockedpages: 4
78
+ numpty: 13
79
+
80
+ 102
81
+ dgramrcvbuf: 345
82
+
83
+ EOF
84
+
85
+ assert_equal contents.split("\n").sort, IO.read(filename).split("\n").sort
86
+
87
+ # Again, this time the report should be empty, and the file unchanged
88
+ atime = File.new(filename).atime
89
+ monitor = UbcMonitor::Monitor.new :file => filename
90
+ report = monitor.run
91
+
92
+ assert_equal 0, report.length
93
+ assert_equal atime, File.new(filename).atime
94
+
95
+ File.delete filename
96
+ end
97
+
98
+ def test_to_s
99
+ monitor = UbcMonitor::Monitor.new
100
+ report = monitor.run
101
+
102
+ content = <<-EOF
103
+ VPS 101 has increased fail counts:
104
+ resource held maxheld barrier limit failcount
105
+ kmemsize 1477444 2608200 8192000 9011200 3
106
+ lockedpages 0 0 2048 2048 4
107
+ numpty 0 0 32 32 13
108
+
109
+ VPS 102 has increased fail counts:
110
+ resource held maxheld barrier limit failcount
111
+ dgramrcvbuf 0 8440 131072 131072 345
112
+
113
+ EOF
114
+
115
+ assert_equal content.split("\n").sort, report.to_s.split("\n").sort
116
+ end
117
+ end
@@ -0,0 +1,67 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestUbcReport < Test::Unit::TestCase
4
+
5
+ def test_init_report
6
+ report = UbcMonitor::Report.new
7
+ assert_not_nil report
8
+ assert report.empty?
9
+ end
10
+
11
+ def test_append
12
+ report = UbcMonitor::Report.new
13
+ assert report.empty?
14
+
15
+ assert :'196', report[:'196', :privvmpages] = { :failcnt => 4 }
16
+ assert !report.empty?
17
+ end
18
+
19
+ def test_getter
20
+ report = UbcMonitor::Report.new
21
+ numbers = { :failcnt => 4 }
22
+ vps = :'196'
23
+ report[vps, :privvmpages] = numbers
24
+ assert_equal numbers, report[:'196', :privvmpages]
25
+
26
+ # More complex hash
27
+ numbers = { :held => 1000, :maxheld => 1012, :barrier => 4000, :limit => 4050, :failcnt => 4 }
28
+ report[vps, :privvmpages] = numbers
29
+ assert_equal numbers, report[vps, :privvmpages]
30
+
31
+ assert !report.empty?
32
+ end
33
+
34
+ def test_load_dump
35
+ filename = '.ubc_test_file'
36
+ contents = <<-EOF
37
+ 196
38
+ privvmpages: 4
39
+
40
+ 197
41
+ kmemsize: 6
42
+ privvmpages: 5
43
+
44
+ EOF
45
+
46
+ File.open(filename, 'w') { |f| f.puts contents }
47
+
48
+ report = UbcMonitor::Report.load filename
49
+ assert_equal 1, report[:'196'].length, report[:'196'].inspect
50
+ assert_equal 1, report[:'196'][:privvmpages].length
51
+ assert_equal 2, report[:'197'].length
52
+
53
+ assert_equal 4, report[:'196'][:privvmpages][:failcnt]
54
+ assert_equal 5, report[:'197'][:privvmpages][:failcnt]
55
+ assert_equal 6, report[:'197'][:kmemsize][:failcnt]
56
+
57
+ assert_equal 2, report.length
58
+ assert_equal 2, report.size
59
+
60
+ report[:'197', :kmemsize] = { :held => 1000, :maxheld => 1050, :barrier => 4000, :limit => 4000, :failcnt => 8 }
61
+ assert_equal 8, report[:'197'][:kmemsize][:failcnt]
62
+
63
+ report.dump! filename
64
+ assert_equal "197\nprivvmpages: 5\nkmemsize: 8\n\n196\nprivvmpages: 4\n\n", IO.read(filename)
65
+ File.delete filename
66
+ end
67
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ubc-monitor
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Christian Johansen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-12-09 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: newgem
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.0.6
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: hoe
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.8.0
34
+ version:
35
+ description: ubc_monitor monitors resource usage in virtual servers run by OpenVz. Monitor /proc/user_beancounters and send an email to the systems administrator if failcnt has increased since last time ubc_monitor was run. ubc_monitor uses a file (by default ~/.ubc_monitor) to keep track of user_beancounter fail counts. When running without this file (such as the first run) any fail count except 0 will be reported.
36
+ email:
37
+ - christian@cjohansen.no
38
+ executables:
39
+ - ubc_monitor
40
+ extensions: []
41
+
42
+ extra_rdoc_files:
43
+ - History.txt
44
+ - Manifest.txt
45
+ - PostInstall.txt
46
+ - README.txt
47
+ files:
48
+ - History.txt
49
+ - Manifest.txt
50
+ - PostInstall.txt
51
+ - README.txt
52
+ - Rakefile
53
+ - bin/ubc_monitor
54
+ - lib/ubc_monitor.rb
55
+ - lib/ubc_monitor/cli.rb
56
+ - lib/ubc_monitor/monitor.rb
57
+ - lib/ubc_monitor/report.rb
58
+ - script/console
59
+ - script/destroy
60
+ - script/generate
61
+ - test/test_helper.rb
62
+ - test/test_ubc_monitor.rb
63
+ - test/test_ubc_report.rb
64
+ has_rdoc: true
65
+ homepage: http://www.cjohansen.no/projects/ubc_monitor
66
+ post_install_message: PostInstall.txt
67
+ rdoc_options:
68
+ - --main
69
+ - README.txt
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: "0"
77
+ version:
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: "0"
83
+ version:
84
+ requirements: []
85
+
86
+ rubyforge_project: ubc-monitor
87
+ rubygems_version: 1.2.0
88
+ signing_key:
89
+ specification_version: 2
90
+ summary: ubc_monitor monitors resource usage in virtual servers run by OpenVz
91
+ test_files:
92
+ - test/test_helper.rb
93
+ - test/test_ubc_monitor.rb
94
+ - test/test_ubc_report.rb