drone_collectd 1.0.2 → 1.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.
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