astro-collectd 0.0.7 → 0.0.8

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.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