1 # Ruby class to access collectd daemon through the UNIX socket
2 # plugin.
3 #
4 # Requires collectd to be configured with the unixsock plugin, like so:
5 #
6 # LoadPlugin unixsock
7 # <Plugin unixsock>
8 # SocketFile "/var/run/collectd-unixsock"
9 # SocketPerms "0775"
10 # </Plugin>
11 #
12 # Copyright (C) 2009 Novell Inc.
13 # Author: Duncan Mac-Vicar P. <dmacvicar@suse.de>
14 #
15 # Inspired in python version:
16 # Copyright (C) 2008 Clay Loveless <clay@killersoft.com>
17 #
18 # This software is provided 'as-is', without any express or implied
19 # warranty. In no event will the author be held liable for any damages
20 # arising from the use of this software.
21 #
22 # Permission is granted to anyone to use this software for any purpose,
23 # including commercial applications, and to alter it and redistribute it
24 # freely, subject to the following restrictions:
25 #
26 # 1. The origin of this software must not be misrepresented; you must not
27 # claim that you wrote the original software. If you use this software
28 # in a product, an acknowledgment in the product documentation would be
29 # appreciated but is not required.
30 # 2. Altered source versions must be plainly marked as such, and must not be
31 # misrepresented as being the original software.
32 # 3. This notice may not be removed or altered from any source distribution.
33 #
34 require 'socket'
36 # Access to collectd data using the unix socket
37 # interface
38 #
39 # see http://collectd.org/wiki/index.php/Plugin:UnixSock
40 #
41 class CollectdUnixSock
42 include Socket::Constants
44 # initializes the collectd interface
45 # path is the location of the collectd
46 # unix socket
47 #
48 # collectd = CollectdUnixSock.new
49 #
50 def initialize(path='/var/run/collectd-unixsock')
51 @socket = UNIXSocket.open(path)
52 # @socket = Socket.new(AF_UNIX, SOCK_STREAM, 0)
53 # @socket.connect(path)
54 @path = path
55 end
57 # iterates over available values, passing the
58 # identifier to the block and the time
59 # the data for this identifier was last
60 # updated
61 #
62 # collectd.each_value do |time, identifier|
63 # ...
64 # end
65 def each_value
66 n_lines = cmd("LISTVAL")
67 n_lines.times do
68 line = @socket.readline
69 time_s, identifier = line.split(' ', 2)
70 time = Time.at(time_s.to_i)
71 yield time, identifier
72 end
73 end
75 # iterates over each value current data
76 #
77 # collectd.each_value_data('myhost/swap/swap-free') { |col, val| }
78 #
79 # each iteration gives the column name and the value for it.
80 #
81 # You can also disable flushing by specifying it as an option:
82 #
83 # client.each_value_data('tarro/swap/swap-free',
84 # :flush => false ) do |col, val|
85 # # .. do something with col and val
86 # end
87 #
88 # :flush option is by default true
89 #
90 def each_value_data(identifier, opts={})
91 n_lines = cmd("GETVAL \"#{identifier}\"")
92 n_lines.times do
93 line = @socket.readline
94 col, val = line.split('=', 2)
95 yield col, val
96 end
98 # unless the user explicitly disabled
99 # flush...
100 unless opts[:flush] == false
101 cmd("FLUSH identifier=\"#{identifier}\"")
102 end
104 end
106 private
108 # internal command execution
109 def cmd(c)
110 @socket.write("#{c}\n")
111 line = @socket.readline
112 status_string, message = line.split(' ', 2)
113 status = status_string.to_i
114 raise message if status < 0
115 status
116 end
118 end
120 if __FILE__ == $0
122 client = CollectdUnixSock.new
123 client.each_value do |time, id|
124 puts "#{time.to_i} - #{id}"
125 end
127 client.each_value_data("tarro/cpu-0/cpu-user") do |col, val|
128 puts "#{col} -> #{val}"
129 end
131 client.each_value_data("tarro/interface/if_packets-eth0") do |col, val|
132 puts "#{col} -> #{val}"
133 end
135 end