astro-collectd 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
data/README.rst ADDED
@@ -0,0 +1,83 @@
1
+ collectd Data Model
2
+ -------------------
3
+
4
+ Collectd groups data by **six categories:**
5
+
6
+ * *hostname* is grabbed from `hostname -f`
7
+ * *plugin* is the application's name
8
+ * *plugin-instance* is passed from the programs' side with the
9
+ programs instance identifier, useful if you're running the same
10
+ script twice (PIDs are quite too random)
11
+ * *type* is the kind of data you are measuring and must be defined in
12
+ types.db_ for collectd to understand
13
+ * *type-instance* provides further distinction and have no relation to
14
+ other type-instances. Multiple type-instances are only rendered into
15
+ one graph by collection3 if defined with module GenericStacked.
16
+ * *values* are one or more field names and types belonging
17
+ together. The exact amount of fields and their corresponding names
18
+ (useful to collection3) are specified in collectd's types.db_.
19
+
20
+ A value can be either of **two types:**
21
+
22
+ * *COUNTER* is for increasing counters where you want to plot the
23
+ delta. Network interface traffic counters are a good example.
24
+ * *GAUGE* is values that go up and down to be plotted as-is, like a
25
+ temperature graph.
26
+
27
+
28
+ Usage
29
+ -----
30
+
31
+ ::
32
+
33
+ gem 'astro-collectd'
34
+ require 'collectd'
35
+
36
+ First of all, specify a server to send data to:
37
+
38
+ ::
39
+
40
+ Collectd.add_server(interval, addr='ff18::efc0:4a42', port=25826)
41
+
42
+ Each server definition you add will receive all the data you push to
43
+ later. An interval of 10 is quite reasonable. Because of UDP and some
44
+ buffering in collectd, an interval of 1 seconds shouldn't hurt either.
45
+
46
+ All the identifiers from above can be given free form with some
47
+ method_missing stuff. Like this:
48
+
49
+ ::
50
+
51
+ # Set gauge absolutely
52
+ Collectd.plugin(:plugin_instance).type(:type_instance).gauge = 23
53
+
54
+ # Increase counter relatively (collectd caches counters)
55
+ Collectd.plugin(:plugin_instance).type(:type_instance).count! 5
56
+
57
+ # Set counter absolutely
58
+ Collectd.plugin(:plugin_instance).type(:type_instance).counter = 42
59
+
60
+ For convenience, define yourself a global *shortcut*, like:
61
+
62
+ ::
63
+
64
+ Stats = Collectd.my_zombie(RAILS_ENV)
65
+
66
+ To automatically collect *memory and CPU statistics* of your Ruby
67
+ process, do:
68
+
69
+ ::
70
+
71
+ Stats.with_full_proc_stats
72
+
73
+ You can also have the library *poll* for your data, if you feel
74
+ comfortable with that, eg:
75
+
76
+ ::
77
+
78
+ Stats.counter(:seconds_elapsed).polled_counter do
79
+ Time.now.to_i
80
+ end
81
+
82
+
83
+ .. _types.db: http://collectd.org/documentation/manpages/types.db.5.shtml
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ begin
2
+ require 'jeweler'
3
+ rescue LoadError
4
+ raise "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
5
+ end
6
+
7
+ Jeweler::Tasks.new do |s|
8
+ s.name = "collectd"
9
+ s.summary = "Send collectd statistics from Ruby"
10
+ s.email = "astro@spaceboyz.net"
11
+ s.homepage = "http://github.com/astro/ruby-collectd"
12
+ s.authors = ["Stephan Maka"]
13
+ s.files = FileList["[A-Z]*", "{lib,spec,examples}/**/*"]
14
+ #s.add_dependency 'eventmachine'
15
+ end
16
+
17
+ begin
18
+ require 'spec/rake/spectask'
19
+ desc "Run all Spec"
20
+ Spec::Rake::SpecTask.new('spec') do |spec|
21
+ spec.spec_files = FileList['spec/*.rb']
22
+ spec.verbose = true
23
+ spec.warning = true
24
+ spec.rcov = true
25
+ spec.rcov_opts = []
26
+ spec.rcov_opts = ['--exclude', 'spec']
27
+ end
28
+ rescue LoadError
29
+ task :spec do
30
+ abort "Rspec is not available. In order to run rspec, you must: sudo gem install rspec"
31
+ end
32
+ end
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :minor: 0
3
+ :patch: 8
4
+ :major: 0
@@ -0,0 +1,17 @@
1
+ require 'eventmachine'
2
+ require 'collectd'
3
+
4
+ EM.run do
5
+ Collectd::use_eventmachine = true
6
+ Collectd::add_server 1
7
+
8
+ c = 0
9
+ EM.add_periodic_timer(0.01) do
10
+ Collectd.ruby_collectd(:test).ping(:fun).gauge = 42 + Math.sin(Time.now.to_f / 600) * 23.5
11
+ Collectd.ruby_collectd(:test).cpu(:time).counter = c
12
+
13
+ c += 1
14
+ print '.'
15
+ STDOUT.flush
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ require 'collectd'
2
+
3
+ Collectd::add_server 1
4
+
5
+ c = 0
6
+ loop do
7
+ Collectd.ruby_collectd(:test).ping(:fun).gauge = 42 + Math.sin(Time.now.to_f / 600) * 23.5
8
+ Collectd.ruby_collectd(:test).cpu(:time).counter = c
9
+ c += 1
10
+ sleep 0.01
11
+ print '.'
12
+ STDOUT.flush
13
+ end
@@ -2,42 +2,39 @@ module Collectd
2
2
  ##
3
3
  # Included by Interface
4
4
  module ProcStats
5
- def with_polled_memory
6
- def process_status(field)
7
- fields = {}
5
+ def process_status(field)
6
+ fields = {}
7
+ begin
8
8
  IO.readlines("/proc/#{$$}/status").each { |line|
9
9
  line.strip!
10
10
  if line =~ /^(.+?):\s+(.+)$/
11
11
  fields[$1] = $2
12
12
  end
13
13
  }
14
+ rescue Errno::ENOENT
15
+ nil
16
+ else
14
17
  fields[field]
15
18
  end
19
+ end
16
20
 
21
+ def with_polled_memory
17
22
  memory('VmRSS').polled_gauge do
18
- process_status('VmRSS').to_i * 1024
23
+ v = process_status('VmRSS') ? v.to_i * 1024 : nil
19
24
  end
20
25
  memory('VmSize').polled_gauge do
21
- process_status('VmSize').to_i * 1024
26
+ v = process_status('VmSize') ? v.to_i * 1024 : nil
22
27
  end
23
28
 
24
29
  self
25
30
  end
26
31
 
27
32
  def with_polled_cpu
28
- def schedstats
29
- if IO.readlines("/proc/#{$$}/schedstat").to_s =~ /^(\d+) (\d+) (\d+)/
30
- [$1.to_i, $2.to_i, $3.to_i]
31
- else
32
- []
33
- end
34
- end
35
-
36
33
  cpu('user').polled_counter do
37
- schedstats[0]
34
+ (Process::times.utime * 100).to_i
38
35
  end
39
- cpu('wait').polled_counter do
40
- schedstats[1]
36
+ cpu('sys').polled_counter do
37
+ (Process::times.stime * 100).to_i
41
38
  end
42
39
  end
43
40
 
@@ -0,0 +1,145 @@
1
+ $: << File.dirname(__FILE__) + '/../lib'
2
+ require 'collectd'
3
+
4
+ describe Collectd do
5
+ before(:each) do
6
+ Collectd.reset!
7
+ @server = mock('Server')
8
+ Collectd << @server
9
+ end
10
+
11
+ it 'should set_counter' do
12
+ @server.should_receive(:set_counter).
13
+ with([:plugin1, :plugin_instance1,
14
+ :type1, :type_instance1], [23])
15
+ Collectd.plugin1(:plugin_instance1).type1(:type_instance1).counter = 23
16
+ end
17
+ it 'should inc_counter' do
18
+ @server.should_receive(:inc_counter).
19
+ with([:plugin1, :plugin_instance1,
20
+ :type1, :type_instance1], [23, 42])
21
+ Collectd.plugin1(:plugin_instance1).type1(:type_instance1).count! 23, 42
22
+ end
23
+ it 'should set_gauge' do
24
+ @server.should_receive(:set_gauge).
25
+ with([:plugin1, :plugin_instance1,
26
+ :type1, :type_instance1], [23, 42, 5])
27
+ Collectd.plugin1(:plugin_instance1).type1(:type_instance1).gauge = [23, 42, 5]
28
+ end
29
+
30
+ it 'should poll a pollable' do
31
+ pollable = mock('Pollable')
32
+ Collectd.add_pollable { |*a|
33
+ pollable.call *a
34
+ }
35
+ pollable.should_receive(:call).with(@server).and_return(nil)
36
+ Collectd.run_pollables_for @server
37
+ end
38
+ it 'should poll a polled_count' do
39
+ Collectd.plugin1(:plugin_instance1).type1(:type_instance1).polled_count do
40
+ [23, 42, 5, 7]
41
+ end
42
+ @server.should_receive(:inc_counter).
43
+ with([:plugin1, :plugin_instance1,
44
+ :type1, :type_instance1], [23, 42, 5, 7])
45
+ Collectd.run_pollables_for @server
46
+ end
47
+ it 'should poll a polled_counter' do
48
+ Collectd.plugin1(:plugin_instance1).type1(:type_instance1).polled_counter do
49
+ [23, 42, 5, 7]
50
+ end
51
+ @server.should_receive(:set_counter).
52
+ with([:plugin1, :plugin_instance1,
53
+ :type1, :type_instance1], [23, 42, 5, 7])
54
+ Collectd.run_pollables_for @server
55
+ end
56
+ it 'should poll a polled_gauge' do
57
+ Collectd.plugin1(:plugin_instance1).type1(:type_instance1).polled_gauge do
58
+ [23, 42, 5, 7]
59
+ end
60
+ @server.should_receive(:set_gauge).
61
+ with([:plugin1, :plugin_instance1,
62
+ :type1, :type_instance1], [23, 42, 5, 7])
63
+ Collectd.run_pollables_for @server
64
+ end
65
+ end
66
+
67
+ class StubServer < Collectd::Values
68
+ attr_reader :counters
69
+ attr_reader :gauges
70
+ def initialize
71
+ super(1000)
72
+ end
73
+ end
74
+
75
+ describe Collectd::ProcStats do
76
+ before(:each) do
77
+ Collectd.reset!
78
+ @server = StubServer.new
79
+ Collectd << @server
80
+ Collectd.plugin1(:plugin_instance1).with_full_proc_stats
81
+ Collectd.run_pollables_for @server
82
+ end
83
+
84
+ context 'when polling memory' do
85
+ it 'should report VmRSS' do
86
+ g = @server.gauges[[:plugin1, :plugin_instance1, :memory, "VmRSS"]]
87
+ g[0].should be_kind_of(Fixnum)
88
+ end
89
+ it 'should report VmSize' do
90
+ g = @server.gauges[[:plugin1, :plugin_instance1, :memory, "VmSize"]]
91
+ g[0].should be_kind_of(Fixnum)
92
+ end
93
+ end
94
+ context 'when polling cpu' do
95
+ it 'should report user time' do
96
+ c = @server.counters[[:plugin1, :plugin_instance1, :cpu, "user"]]
97
+ c[0].should be_kind_of(Fixnum)
98
+ end
99
+ it 'should report system time' do
100
+ c = @server.counters[[:plugin1, :plugin_instance1, :cpu, "sys"]]
101
+ c[0].should be_kind_of(Fixnum)
102
+ end
103
+ end
104
+ end
105
+
106
+ describe Collectd::EmPlugin do
107
+ before(:each) do
108
+ Collectd.reset!
109
+ @server = StubServer.new
110
+ Collectd << @server
111
+ @df = EM::DefaultDeferrable.new
112
+ Collectd.plugin1(:plugin_instance1).track_deferrable('df', @df)
113
+ end
114
+
115
+ context 'when succeeding' do
116
+ it 'should callback' do
117
+ @df.succeed
118
+ end
119
+ it 'should report latency' do
120
+ @df.succeed
121
+ g = @server.gauges[[:plugin1, :plugin_instance1, :latency, 'df success']]
122
+ g[0].should be_kind_of(Numeric)
123
+ end
124
+ it 'should increase a counter' do
125
+ @df.succeed
126
+ c = @server.counters[[:plugin1, :plugin_instance1, :counter, 'df success']]
127
+ c[0].should be_kind_of(Numeric)
128
+ end
129
+ end
130
+ context 'when failing' do
131
+ it 'should callback' do
132
+ @df.fail
133
+ end
134
+ it 'should report latency' do
135
+ @df.fail
136
+ g = @server.gauges[[:plugin1, :plugin_instance1, :latency, 'df error']]
137
+ g[0].should be_kind_of(Numeric)
138
+ end
139
+ it 'should increase a counter' do
140
+ @df.fail
141
+ c = @server.counters[[:plugin1, :plugin_instance1, :counter, 'df error']]
142
+ c[0].should be_kind_of(Numeric)
143
+ end
144
+ end
145
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: astro-collectd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephan Maka
@@ -9,31 +9,37 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-05-27 00:00:00 -07:00
12
+ date: 2009-05-29 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
16
16
  description:
17
- email: stephan@spaceboyz.net
17
+ email: astro@spaceboyz.net
18
18
  executables: []
19
19
 
20
20
  extensions: []
21
21
 
22
- extra_rdoc_files: []
23
-
22
+ extra_rdoc_files:
23
+ - README.rst
24
24
  files:
25
- - lib/collectd/pkt.rb
25
+ - README.rst
26
+ - Rakefile
27
+ - VERSION.yml
28
+ - examples/em_sender.rb
29
+ - examples/sender.rb
30
+ - lib/collectd.rb
26
31
  - lib/collectd/em_server.rb
32
+ - lib/collectd/em_support.rb
27
33
  - lib/collectd/interface.rb
34
+ - lib/collectd/pkt.rb
28
35
  - lib/collectd/proc_stats.rb
29
36
  - lib/collectd/server.rb
30
- - lib/collectd/em_support.rb
31
- - lib/collectd.rb
37
+ - spec/interface_spec.rb
32
38
  has_rdoc: false
33
39
  homepage: http://github.com/astro/ruby-collectd
34
40
  post_install_message:
35
- rdoc_options: []
36
-
41
+ rdoc_options:
42
+ - --charset=UTF-8
37
43
  require_paths:
38
44
  - lib
39
45
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -53,7 +59,9 @@ requirements: []
53
59
  rubyforge_project:
54
60
  rubygems_version: 1.2.0
55
61
  signing_key:
56
- specification_version: 2
62
+ specification_version: 3
57
63
  summary: Send collectd statistics from Ruby
58
- test_files: []
59
-
64
+ test_files:
65
+ - spec/interface_spec.rb
66
+ - examples/sender.rb
67
+ - examples/em_sender.rb