drone_collectd 1.0.2 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011-2011 Julien Ammous
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,24 @@
1
+ ## What is this
2
+
3
+ It is an output interface to collectd for Drone.<br/>
4
+ You can find more about Drone [here](https://github.com/schmurfy/drone)
5
+
6
+ # Supported Runtimes
7
+
8
+ - MRI 1.8.7+
9
+ - Rubinius 1.2.2+
10
+
11
+
12
+ # How to use
13
+
14
+ First you obviously need a collectd server (or any server able to receive collectd network packets),
15
+ after that you need to add those lines to your types.db config file if you use collectd:
16
+
17
+ meter mean:GAUGE:U:U, rate1:GAUGE:U:U, rate5:GAUGE:U:U, rate15:GAUGE:U:U
18
+ timer min:GAUGE:0:U, max:GAUGE:0:U, mean:GAUGE:0:U, stddev:GAUGE:U:U, median:GAUGE:0:U, p75:GAUGE:0:U, p95:GAUGE:0:U
19
+
20
+ They are required to be able to understand timers and meters sent from Drone, you can update the timer
21
+ as you wish to add/remove pecentiles (check examples/collectd to see how to configure the interface for that).
22
+
23
+
24
+
@@ -0,0 +1,97 @@
1
+ require File.expand_path('../parser', __FILE__)
2
+
3
+ module Drone
4
+ module Interfaces
5
+
6
+ ##
7
+ # Send data to collectd periodically, this interface except
8
+ # a specific format for the metric names which is:
9
+ #
10
+ # plugin[:plugin_instance]/type[:type_instance]
11
+ # the simplest form being:
12
+ # plugin/type
13
+ #
14
+ class Collectd < Base
15
+
16
+ # 1.9 only ...
17
+ # NAME_FORMAT = %r{(?<plugin>\w+)(:(?<plugin_instance>\w+))?/(?<type>\w+)(:(?<type_instance>\w+))?}
18
+
19
+ NAME_FORMAT = %r{(\w+)(?::(\w+))?/(\w+)(?::(\w+))?}
20
+
21
+ ##
22
+ # Instantiate a collectd interface
23
+ #
24
+ # @param [Numeric] period the period passed to the Base class
25
+ # @param [String] hostname the hostname to use for collectd
26
+ # @param [String] address the address where the collectd daemon is listening
27
+ # @param [Numeric] port The collectd daemon port
28
+ #
29
+ def initialize(period, args = {})
30
+ super(period)
31
+ @hostname = args.delete(:hostname)
32
+ @address = args.delete(:address) || '127.0.0.1'
33
+ @port = args.delete(:port) || 25826
34
+ @reported_percentiles = args.delete(:percentiles)
35
+ @socket = EM::open_datagram_socket('0.0.0.0', nil)
36
+
37
+ unless args.empty?
38
+ raise ArgumentError, "unknown keys: #{args.keys}"
39
+ end
40
+ end
41
+
42
+ def output
43
+
44
+ Drone::each_metric do |m|
45
+ # parse the name
46
+ if NAME_FORMAT.match(m.name)
47
+ # build the packet
48
+ data = DroneCollectd::CollectdPacket.new
49
+ data.host = @hostname
50
+ data.time = Time.now.to_i
51
+ data.interval = @period
52
+ data.plugin = $1.to_s
53
+ data.plugin_instance = $2.to_s
54
+ data.type = $3.to_s
55
+ data.type_instance = $4.to_s
56
+
57
+ case m
58
+ when Metrics::Counter
59
+ data.add_value(:counter, m.value )
60
+
61
+ when Metrics::Gauge
62
+ data.add_value(:gauge, m.value )
63
+
64
+ when Metrics::Meter
65
+ # mean:GAUGE:U:U, rate1:GAUGE:U:U, rate5:GAUGE:U:U, rate15:GAUGE:U:U
66
+ data.add_value(:gauge, m.mean_rate )
67
+ data.add_value(:gauge, m.one_minute_rate )
68
+ data.add_value(:gauge, m.five_minutes_rate )
69
+ data.add_value(:gauge, m.fifteen_minutes_rate )
70
+
71
+ when Metrics::Timer
72
+ # min:GAUGE:0:U, max:GAUGE:0:U, mean:GAUGE:0:U, stddev:GAUGE:U:U, median:GAUGE:0:U, p75:GAUGE:0:U, p95:GAUGE:0:U
73
+ data.add_value(:gauge, m.min )
74
+ data.add_value(:gauge, m.max )
75
+ data.add_value(:gauge, m.mean )
76
+ data.add_value(:gauge, m.stdDev )
77
+
78
+ percs = m.percentiles( *@reported_percentiles )
79
+ percs.each do |p|
80
+ data.add_value(:gauge, p )
81
+ end
82
+
83
+ end
84
+
85
+ # and send it
86
+ @socket.send_datagram(data.build_packet, @address, @port)
87
+ else
88
+ puts "Metric with incorrect name ignored: #{m.name}"
89
+ end
90
+ end
91
+
92
+ end
93
+
94
+ end
95
+
96
+ end
97
+ end