astro-collectd 0.0.4

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.
@@ -0,0 +1,20 @@
1
+ require 'eventmachine'
2
+
3
+ module Collectd
4
+ class EmServer < Values
5
+
6
+ def initialize(interval, host, port)
7
+ super(interval)
8
+ @sock = UDPSocket.new(host.index(':') ? Socket::AF_INET6 : Socket::AF_INET)
9
+ @sock.connect(host, port)
10
+
11
+ EM.add_periodic_timer(interval) do
12
+ Thread.critical = true
13
+ pkt = make_pkt
14
+ Thread.critical = false
15
+ @sock.send(pkt, 0)
16
+ end
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,147 @@
1
+ require 'collectd/pkt'
2
+
3
+
4
+ module Collectd
5
+ class << self
6
+
7
+ def hostname
8
+ @@hostname ||= `hostname -f`.strip
9
+ @@hostname
10
+ end
11
+ def hostname=(h)
12
+ @@hostname = h
13
+ end
14
+
15
+ @@servers = []
16
+
17
+ def add_server(interval, addr='ff18::efc0:4a42', port=25826)
18
+ @@servers << Server.new(interval, addr, port)
19
+ end
20
+
21
+ def each_server(&block)
22
+ @@servers.each(&block)
23
+ end
24
+
25
+ def method_missing(plugin, plugin_instance)
26
+ Plugin.new(plugin, plugin_instance)
27
+ end
28
+
29
+ end
30
+
31
+ ##
32
+ # Interface helper
33
+ class Plugin
34
+ def initialize(plugin, plugin_instance)
35
+ @plugin, @plugin_instance = plugin, plugin_instance
36
+ end
37
+ def method_missing(type, type_instance)
38
+ Type.new(@plugin, @plugin_instance, type, type_instance)
39
+ end
40
+ end
41
+
42
+ ##
43
+ # Interface helper
44
+ class Type
45
+ def initialize(plugin, plugin_instance, type, type_instance)
46
+ @plugin, @plugin_instance = plugin, plugin_instance
47
+ @type, @type_instance = type, type_instance
48
+ end
49
+ def gauge=(values)
50
+ values = [values] unless values.kind_of? Array
51
+ Collectd.each_server do |server|
52
+ server.set_gauge(plugin_type, values)
53
+ end
54
+ end
55
+ def counter=(values)
56
+ values = [values] unless values.kind_of? Array
57
+ Collectd.each_server do |server|
58
+ server.set_counter(plugin_type, values)
59
+ end
60
+ end
61
+ def count!(*values)
62
+ Collectd.each_server do |server|
63
+ server.inc_counter(plugin_type, values)
64
+ end
65
+ end
66
+ def plugin_type
67
+ [@plugin, @plugin_instance, @type, @type_instance]
68
+ end
69
+ end
70
+
71
+ ##
72
+ # Value-holder, baseclass for servers
73
+ class Values
74
+ attr_reader :interval
75
+ def initialize(interval)
76
+ @interval = interval
77
+ @counters = {}
78
+ @gauges = {}
79
+ end
80
+ def set_counter(plugin_type, values)
81
+ @counters[plugin_type] = values
82
+ end
83
+ def inc_counter(plugin_type, values)
84
+ old_values = @counters[plugin_type] || []
85
+ values.map! { |value|
86
+ value + (old_values.shift || 0)
87
+ }
88
+ @counters[plugin_type] = values
89
+ end
90
+ def set_gauge(plugin_type, values)
91
+ # Use count & sums for average
92
+ if @gauges.has_key?(plugin_type)
93
+ old_values = @gauges[plugin_type]
94
+ count = old_values.shift
95
+ values.map! { |value| value + (old_values.shift || value) }
96
+ @gauges[plugin_type] = [count + 1] + values
97
+ else
98
+ @gauges[plugin_type] = [1] + values
99
+ end
100
+ end
101
+
102
+ def make_pkt
103
+ plugin_type_values = {}
104
+ @counters.each do |plugin_types,values|
105
+ plugin, plugin_instance, type, type_instance = plugin_types
106
+ plugin_type_values[plugin] ||= {}
107
+ plugin_type_values[plugin][plugin_instance] ||= {}
108
+ plugin_type_values[plugin][plugin_instance][type] ||= {}
109
+ plugin_type_values[plugin][plugin_instance][type][type_instance] =
110
+ Packet::Values.new(values.map { |value| Packet::Values::Counter.new(value) })
111
+ end
112
+ @gauges.each do |plugin_types,values|
113
+ plugin, plugin_instance, type, type_instance = plugin_types
114
+ plugin_type_values[plugin] ||= {}
115
+ plugin_type_values[plugin][plugin_instance] ||= {}
116
+ plugin_type_values[plugin][plugin_instance][type] ||= {}
117
+ count = values.shift
118
+ values.map! { |value| value.to_f / count }
119
+ plugin_type_values[plugin][plugin_instance][type][type_instance] =
120
+ Packet::Values.new(values.map { |value| Packet::Values::Gauge.new(value) })
121
+ end
122
+ pkt = [Packet::Host.new(Collectd.hostname),
123
+ Packet::Time.new(Time.now.to_i),
124
+ Packet::Interval.new(10)]
125
+ plugin_type_values.each do |plugin,plugin_instances|
126
+ pkt << Packet::Plugin.new(plugin)
127
+ plugin_instances.each do |plugin_instance,types|
128
+ pkt << Packet::PluginInstance.new(plugin_instance)
129
+ types.each do |type,type_instances|
130
+ pkt << Packet::Type.new(type)
131
+ type_instances.each do |type_instance,values|
132
+ pkt << Packet::TypeInstance.new(type_instance)
133
+ pkt << values
134
+ end
135
+ end
136
+ end
137
+ end
138
+
139
+ # Reset only gauges. Counters are persistent for incrementing.
140
+ @gauges = {}
141
+
142
+ # And return serialized packet of parts
143
+ pkt.to_s
144
+ end
145
+ end
146
+
147
+ end
@@ -0,0 +1,107 @@
1
+ module Collectd
2
+ module Packet
3
+
4
+ class Part
5
+ def to_s(content)
6
+ [type, content.length + 4].pack("nn") + content
7
+ end
8
+
9
+ ##
10
+ # Makes subclasses more declarative
11
+ def self.type(number)
12
+ define_method(:type) { number }
13
+ end
14
+ end
15
+
16
+ class String < Part
17
+ def initialize(s)
18
+ @s = s
19
+ end
20
+ def to_s
21
+ super "#{@s}\000"
22
+ end
23
+ end
24
+
25
+ class Number < Part
26
+ def initialize(n)
27
+ @n = n
28
+ end
29
+ def to_s
30
+ super [@n >> 32, @n & 0xffffffff].pack("NN")
31
+ end
32
+ end
33
+
34
+ class Host < String
35
+ type 0
36
+ end
37
+
38
+ class Time < Number
39
+ type 1
40
+ end
41
+
42
+ class Plugin < String
43
+ type 2
44
+ end
45
+
46
+ class PluginInstance < String
47
+ type 3
48
+ end
49
+
50
+ class Type < String
51
+ type 4
52
+ end
53
+
54
+ class TypeInstance < String
55
+ type 5
56
+ end
57
+
58
+ class Values < Part
59
+ type 6
60
+ def initialize(v)
61
+ @v = v
62
+ end
63
+ def to_s
64
+ types, values = [], []
65
+ @v.each { |v1|
66
+ types << [v1.type].pack("C")
67
+ values << v1.to_s
68
+ }
69
+ super [@v.length].pack("n") + types.join + values.join
70
+ end
71
+
72
+ class Counter < Part
73
+ type 0
74
+ def initialize(c)
75
+ @c = c
76
+ end
77
+ def to_s
78
+ [@c >> 32, @c & 0xffffffff].pack("NN")
79
+ end
80
+ end
81
+
82
+ class Gauge < Part
83
+ type 1
84
+ def initialize(f)
85
+ @f = f
86
+ end
87
+ def to_s
88
+ [@f].pack("d")
89
+ end
90
+ end
91
+ end
92
+
93
+ class Interval < Number
94
+ type 7
95
+ end
96
+
97
+
98
+ class Message < String
99
+ type 0x100
100
+ end
101
+
102
+ class Severity < Number
103
+ type 0x101
104
+ end
105
+
106
+ end
107
+ end
@@ -0,0 +1,25 @@
1
+ require 'socket'
2
+ require 'thread'
3
+
4
+ module Collectd
5
+ class Server < Values
6
+
7
+ def initialize(interval, host, port)
8
+ super(interval)
9
+ @sock = UDPSocket.new(Socket::AF_INET6)
10
+ @sock.connect(host, port)
11
+
12
+ Thread.new do
13
+ loop do
14
+ sleep interval
15
+
16
+ Thread.critical = true
17
+ pkt = make_pkt
18
+ Thread.critical = false
19
+ @sock.send(pkt, 0)
20
+ end
21
+ end.abort_on_exception = true
22
+ end
23
+
24
+ end
25
+ end
data/lib/collectd.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'collectd/interface'
2
+ require 'collectd/server'
3
+ begin
4
+ require 'collectd/em_server'
5
+ rescue LoadError
6
+ # EM is optional
7
+ end
8
+
9
+
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: astro-collectd
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Stephan Maka
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-04-25 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: stephan@spaceboyz.net
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - lib/collectd/interface.rb
26
+ - lib/collectd/pkt.rb
27
+ - lib/collectd/server.rb
28
+ - lib/collectd/em_server.rb
29
+ - lib/collectd.rb
30
+ has_rdoc: false
31
+ homepage: http://github.com/astro/ruby-collectd
32
+ post_install_message:
33
+ rdoc_options: []
34
+
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: "0"
42
+ version:
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ version:
49
+ requirements: []
50
+
51
+ rubyforge_project:
52
+ rubygems_version: 1.2.0
53
+ signing_key:
54
+ specification_version: 2
55
+ summary: Send collectd statistics from Ruby
56
+ test_files: []
57
+