one2influx 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2538b53b0ce8cac2ffbb31b297dfe015f3d49e42
4
+ data.tar.gz: f8bae0a57a94d99818f79f529d7ddd38b421dee5
5
+ SHA512:
6
+ metadata.gz: 492ab445d56b866b7bd99df28c22afc5e4f8a1ee4288f794b0d8bd89dc9ddad7951c2fed6607a3c19c590b9bdab548ae589874e65d44269a3389049041c5aaf8
7
+ data.tar.gz: bc944a9a54efb341f871a071da6fc0ce965fdf5f521efbcf8a0c12d2702202277637611b1a41522cc64943bedf055315adbe35a14889aee26bbe66c03376345f
data/bin/one2influx ADDED
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ require 'rubygems'
5
+ rescue Exception
6
+ $stderr.puts 'Failed to load rubygems!'
7
+ end
8
+
9
+ # add local dirs to load path if necessary
10
+ lib = File.expand_path(File.join('..', '..', 'lib'), __FILE__)
11
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
12
+
13
+ require 'one2influx'
14
+
15
+ # Load configuration
16
+ begin
17
+ $CFG = ::One2Influx::Config.new
18
+ rescue Exception => e
19
+ if $LOG.nil?
20
+ $stderr.puts e.message
21
+ else
22
+ $LOG.error e.message
23
+ $stderr.puts 'Failure, exiting. Check the log file.'
24
+ end
25
+ exit 1
26
+ end
27
+
28
+ # Register termination signals
29
+ Signal.trap('INT') do
30
+ exit 0
31
+ end
32
+ Signal.trap('TERM') do
33
+ exit 0
34
+ end
35
+
36
+ # Checks connection with ONE using provided credentials
37
+ unless $CFG.is_one_available?
38
+ $stderr.puts 'Failure, exiting. Check the log file.'
39
+ exit 2
40
+ end
41
+
42
+ # Load InfluxDB connection link
43
+ begin
44
+ influx = ::One2Influx::Influx.new
45
+ rescue Exception => e
46
+ $LOG.error e.message
47
+ $stderr.puts 'Failure, exiting. Check the log file.'
48
+ exit 3
49
+ end
50
+
51
+ # Check if InfluxDB database and policy exist
52
+ unless influx.db_exists?
53
+ $stderr.puts 'Failure, exiting. Check the log file.'
54
+ exit 4
55
+ end
56
+
57
+ loop do
58
+ # Timestamp is same for all points in batch
59
+ # Get data from ONE
60
+ retries = 4
61
+ begin
62
+ data = ::One2Influx::Data.new
63
+ $LOG.info 'Successfully fetched data from ONE.'
64
+ rescue Exception => e
65
+ if retries < 0
66
+ $LOG.error 'Unable to fetch ONE data for the 5th time. Error:' +
67
+ "#{e.message}. Stacktrace: #{e.backtrace}"
68
+ sleep($CFG.sec_interval)
69
+ next
70
+ else
71
+ $LOG.warn "Unable to fetch ONE data. Trying #{retries+1} more times. " +
72
+ "Error: #{e.message}"
73
+ retries -= 1
74
+ sleep(0.01)
75
+ retry
76
+ end
77
+
78
+ end
79
+
80
+ # Store data
81
+ begin
82
+ influx.store(data.points)
83
+ $LOG.info "Successfully stored #{data.points.length} data points."
84
+ rescue Exception => e
85
+ $LOG.error e.message
86
+ end
87
+
88
+ sleep($CFG.sec_interval)
89
+ end
@@ -0,0 +1,92 @@
1
+ # Logfile created on 2015-04-29 17:25:53 +0200 by logger.rb/47272
2
+ E, [2015-05-06T13:21:09.497567 #22731] ERROR -- : Unable to find out ONE version with message: Connection refused - connect(2) for "localhost" port 2633
3
+ I, [2015-05-06T13:22:04.402884 #22917] INFO -- : Connection with ONE verified.
4
+ I, [2015-05-06T13:22:04.421713 #22917] INFO -- : Connection to InfluxDB database 'test' with retention policy 'ten_hours' verified.
5
+ I, [2015-05-06T13:22:04.574628 #22917] INFO -- : Stored data for 3 VMs, 2 hosts, 4 datastores and 1 clusters.
6
+ I, [2015-05-06T13:22:04.574757 #22917] INFO -- : Successfully fetched data from ONE.
7
+ E, [2015-05-06T13:22:04.574870 #22917] ERROR -- : exit
8
+ I, [2015-05-06T13:22:34.766527 #22917] INFO -- : Stored data for 3 VMs, 2 hosts, 4 datastores and 1 clusters.
9
+ I, [2015-05-06T13:22:34.766696 #22917] INFO -- : Successfully fetched data from ONE.
10
+ E, [2015-05-06T13:22:34.766805 #22917] ERROR -- : exit
11
+ I, [2015-05-06T13:23:04.887303 #22917] INFO -- : Stored data for 3 VMs, 2 hosts, 4 datastores and 1 clusters.
12
+ I, [2015-05-06T13:23:04.887481 #22917] INFO -- : Successfully fetched data from ONE.
13
+ E, [2015-05-06T13:23:04.887583 #22917] ERROR -- : exit
14
+ I, [2015-05-06T13:23:35.004802 #22917] INFO -- : Stored data for 3 VMs, 2 hosts, 4 datastores and 1 clusters.
15
+ I, [2015-05-06T13:23:35.004945 #22917] INFO -- : Successfully fetched data from ONE.
16
+ E, [2015-05-06T13:23:35.005052 #22917] ERROR -- : exit
17
+ I, [2015-05-06T13:24:05.143408 #22917] INFO -- : Stored data for 3 VMs, 2 hosts, 4 datastores and 1 clusters.
18
+ I, [2015-05-06T13:24:05.143577 #22917] INFO -- : Successfully fetched data from ONE.
19
+ E, [2015-05-06T13:24:05.143682 #22917] ERROR -- : exit
20
+ I, [2015-05-06T13:24:35.314966 #22917] INFO -- : Stored data for 3 VMs, 2 hosts, 4 datastores and 1 clusters.
21
+ I, [2015-05-06T13:24:35.315100 #22917] INFO -- : Successfully fetched data from ONE.
22
+ E, [2015-05-06T13:24:35.315197 #22917] ERROR -- : exit
23
+ I, [2015-05-06T13:24:52.210693 #23035] INFO -- : Connection with ONE verified.
24
+ I, [2015-05-06T13:24:52.226595 #23035] INFO -- : Connection to InfluxDB database 'test' with retention policy 'ten_hours' verified.
25
+ I, [2015-05-06T13:24:52.340054 #23035] INFO -- : Stored data for 3 VMs, 2 hosts, 4 datastores and 1 clusters.
26
+ I, [2015-05-06T13:24:52.340200 #23035] INFO -- : Successfully fetched data from ONE.
27
+ E, [2015-05-06T13:24:52.340320 #23035] ERROR -- : exit
28
+ I, [2015-05-06T13:25:05.424588 #22917] INFO -- : Stored data for 3 VMs, 2 hosts, 4 datastores and 1 clusters.
29
+ I, [2015-05-06T13:25:05.424739 #22917] INFO -- : Successfully fetched data from ONE.
30
+ E, [2015-05-06T13:25:05.424834 #22917] ERROR -- : exit
31
+ I, [2015-05-06T13:25:22.460081 #23035] INFO -- : Stored data for 3 VMs, 2 hosts, 4 datastores and 1 clusters.
32
+ I, [2015-05-06T13:25:22.460184 #23035] INFO -- : Successfully fetched data from ONE.
33
+ E, [2015-05-06T13:25:22.460258 #23035] ERROR -- : exit
34
+ I, [2015-05-06T13:37:58.353992 #23321] INFO -- : Connection with ONE verified.
35
+ I, [2015-05-06T13:37:58.367204 #23321] INFO -- : Connection to InfluxDB database 'test' with retention policy 'ten_hours' verified.
36
+ I, [2015-05-06T13:37:58.524869 #23321] INFO -- : Stored data for 3 VMs, 2 hosts, 4 datastores and 1 clusters.
37
+ I, [2015-05-06T13:37:58.525008 #23321] INFO -- : Successfully fetched data from ONE.
38
+ E, [2015-05-06T13:37:58.525149 #23321] ERROR -- : exit
39
+ I, [2015-05-06T13:38:44.753960 #23354] INFO -- : Connection with ONE verified.
40
+ I, [2015-05-06T13:38:44.769092 #23354] INFO -- : Connection to InfluxDB database 'test' with retention policy 'ten_hours' verified.
41
+ I, [2015-05-06T13:38:44.924625 #23354] INFO -- : Stored data for 3 VMs, 2 hosts, 4 datastores and 1 clusters.
42
+ I, [2015-05-06T13:38:44.924757 #23354] INFO -- : Successfully fetched data from ONE.
43
+ E, [2015-05-06T13:38:44.924866 #23354] ERROR -- : exit
44
+ I, [2015-05-06T13:41:42.382117 #23434] INFO -- : Connection with ONE verified.
45
+ I, [2015-05-06T13:41:42.398424 #23434] INFO -- : Connection to InfluxDB database 'test' with retention policy 'ten_hours' verified.
46
+ I, [2015-05-06T13:41:42.948566 #23434] INFO -- : Stored data for 3 VMs, 2 hosts, 4 datastores and 1 clusters.
47
+ I, [2015-05-06T13:41:42.948689 #23434] INFO -- : Successfully fetched data from ONE.
48
+ E, [2015-05-06T13:41:42.948786 #23434] ERROR -- : exit
49
+ I, [2015-05-06T13:42:00.006974 #23454] INFO -- : Connection with ONE verified.
50
+ I, [2015-05-06T13:42:00.133223 #23454] INFO -- : Connection to InfluxDB database 'test' with retention policy 'ten_hours' verified.
51
+ I, [2015-05-06T13:42:00.239825 #23454] INFO -- : Stored data for 3 VMs, 2 hosts, 4 datastores and 1 clusters.
52
+ I, [2015-05-06T13:42:00.239937 #23454] INFO -- : Successfully fetched data from ONE.
53
+ E, [2015-05-06T13:42:00.240007 #23454] ERROR -- : exit
54
+ I, [2015-05-06T13:42:13.784101 #23470] INFO -- : Connection with ONE verified.
55
+ I, [2015-05-06T13:42:13.798026 #23470] INFO -- : Connection to InfluxDB database 'test' with retention policy 'ten_hours' verified.
56
+ W, [2015-05-06T13:42:13.845268 #23470] WARN -- : Unable to fetch ONE data. Trying 5 more times. Error: no implicit conversion of nil into String
57
+ W, [2015-05-06T13:42:13.915400 #23470] WARN -- : Unable to fetch ONE data. Trying 4 more times. Error: no implicit conversion of nil into String
58
+ W, [2015-05-06T13:42:13.984934 #23470] WARN -- : Unable to fetch ONE data. Trying 3 more times. Error: no implicit conversion of nil into String
59
+ W, [2015-05-06T13:42:14.035001 #23470] WARN -- : Unable to fetch ONE data. Trying 2 more times. Error: no implicit conversion of nil into String
60
+ W, [2015-05-06T13:42:14.085218 #23470] WARN -- : Unable to fetch ONE data. Trying 1 more times. Error: no implicit conversion of nil into String
61
+ E, [2015-05-06T13:42:14.130828 #23470] ERROR -- : Unable to fetch ONE data for the 5th time. Error:no implicit conversion of nil into String. Stacktrace: ["/home/ldoku/RubymineProjects/one2influx/lib/one2influx/one_object/virtual_machine.rb:39:in `+'", "/home/ldoku/RubymineProjects/one2influx/lib/one2influx/one_object/virtual_machine.rb:39:in `get_MEMORY_PERC'", "/home/ldoku/RubymineProjects/one2influx/lib/one2influx/one_object/one_object.rb:72:in `block in init_custom_metrics'", "/home/ldoku/RubymineProjects/one2influx/lib/one2influx/one_object/one_object.rb:71:in `each'", "/home/ldoku/RubymineProjects/one2influx/lib/one2influx/one_object/one_object.rb:71:in `init_custom_metrics'", "/home/ldoku/RubymineProjects/one2influx/lib/one2influx/one_object/one_object.rb:20:in `initialize'", "/home/ldoku/RubymineProjects/one2influx/lib/one2influx/one_object/virtual_machine.rb:18:in `initialize'", "/home/ldoku/RubymineProjects/one2influx/lib/one2influx/data.rb:30:in `new'", "/home/ldoku/RubymineProjects/one2influx/lib/one2influx/data.rb:30:in `block (2 levels) in initialize'", "/home/ldoku/RubymineProjects/one2influx/lib/one2influx/data.rb:25:in `each'", "/home/ldoku/RubymineProjects/one2influx/lib/one2influx/data.rb:25:in `block in initialize'", "/home/ldoku/RubymineProjects/one2influx/vendor/bundle/ruby/2.2.0/gems/opennebula-4.12.0/lib/opennebula/xml_pool.rb:35:in `call'", "/home/ldoku/RubymineProjects/one2influx/vendor/bundle/ruby/2.2.0/gems/opennebula-4.12.0/lib/opennebula/xml_pool.rb:35:in `block in each_element'", "/home/ldoku/RubymineProjects/one2influx/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.6.2/lib/nokogiri/xml/node_set.rb:187:in `block in each'", "/home/ldoku/RubymineProjects/one2influx/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.6.2/lib/nokogiri/xml/node_set.rb:186:in `upto'", "/home/ldoku/RubymineProjects/one2influx/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.6.2/lib/nokogiri/xml/node_set.rb:186:in `each'", "/home/ldoku/RubymineProjects/one2influx/vendor/bundle/ruby/2.2.0/gems/opennebula-4.12.0/lib/opennebula/xml_pool.rb:34:in `each_element'", "/home/ldoku/RubymineProjects/one2influx/vendor/bundle/ruby/2.2.0/gems/opennebula-4.12.0/lib/opennebula/pool.rb:152:in `each'", "/home/ldoku/RubymineProjects/one2influx/lib/one2influx/data.rb:22:in `initialize'", "/home/ldoku/RubymineProjects/one2influx/bin/one2influx:62:in `new'", "/home/ldoku/RubymineProjects/one2influx/bin/one2influx:62:in `block in <top (required)>'", "/home/ldoku/RubymineProjects/one2influx/bin/one2influx:57:in `loop'", "/home/ldoku/RubymineProjects/one2influx/bin/one2influx:57:in `<top (required)>'", "-e:1:in `load'", "-e:1:in `<main>'"]
62
+ I, [2015-05-06T13:42:22.673995 #23494] INFO -- : Connection with ONE verified.
63
+ I, [2015-05-06T13:42:22.688081 #23494] INFO -- : Connection to InfluxDB database 'test' with retention policy 'ten_hours' verified.
64
+ W, [2015-05-06T13:42:22.735880 #23494] WARN -- : Unable to fetch ONE data. Trying 5 more times. Error: no implicit conversion of nil into String
65
+ W, [2015-05-06T13:42:22.794775 #23494] WARN -- : Unable to fetch ONE data. Trying 4 more times. Error: no implicit conversion of nil into String
66
+ W, [2015-05-06T13:42:22.837748 #23494] WARN -- : Unable to fetch ONE data. Trying 3 more times. Error: no implicit conversion of nil into String
67
+ W, [2015-05-06T13:42:22.894808 #23494] WARN -- : Unable to fetch ONE data. Trying 2 more times. Error: no implicit conversion of nil into String
68
+ W, [2015-05-06T13:42:22.954857 #23494] WARN -- : Unable to fetch ONE data. Trying 1 more times. Error: no implicit conversion of nil into String
69
+ E, [2015-05-06T13:42:22.994985 #23494] ERROR -- : Unable to fetch ONE data for the 5th time. Error:no implicit conversion of nil into String. Stacktrace: ["/home/ldoku/RubymineProjects/one2influx/lib/one2influx/one_object/virtual_machine.rb:39:in `+'", "/home/ldoku/RubymineProjects/one2influx/lib/one2influx/one_object/virtual_machine.rb:39:in `get_MEMORY_PERC'", "/home/ldoku/RubymineProjects/one2influx/lib/one2influx/one_object/one_object.rb:72:in `block in init_custom_metrics'", "/home/ldoku/RubymineProjects/one2influx/lib/one2influx/one_object/one_object.rb:71:in `each'", "/home/ldoku/RubymineProjects/one2influx/lib/one2influx/one_object/one_object.rb:71:in `init_custom_metrics'", "/home/ldoku/RubymineProjects/one2influx/lib/one2influx/one_object/one_object.rb:20:in `initialize'", "/home/ldoku/RubymineProjects/one2influx/lib/one2influx/one_object/virtual_machine.rb:18:in `initialize'", "/home/ldoku/RubymineProjects/one2influx/lib/one2influx/data.rb:30:in `new'", "/home/ldoku/RubymineProjects/one2influx/lib/one2influx/data.rb:30:in `block (2 levels) in initialize'", "/home/ldoku/RubymineProjects/one2influx/lib/one2influx/data.rb:25:in `each'", "/home/ldoku/RubymineProjects/one2influx/lib/one2influx/data.rb:25:in `block in initialize'", "/home/ldoku/RubymineProjects/one2influx/vendor/bundle/ruby/2.2.0/gems/opennebula-4.12.0/lib/opennebula/xml_pool.rb:35:in `call'", "/home/ldoku/RubymineProjects/one2influx/vendor/bundle/ruby/2.2.0/gems/opennebula-4.12.0/lib/opennebula/xml_pool.rb:35:in `block in each_element'", "/home/ldoku/RubymineProjects/one2influx/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.6.2/lib/nokogiri/xml/node_set.rb:187:in `block in each'", "/home/ldoku/RubymineProjects/one2influx/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.6.2/lib/nokogiri/xml/node_set.rb:186:in `upto'", "/home/ldoku/RubymineProjects/one2influx/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.6.2/lib/nokogiri/xml/node_set.rb:186:in `each'", "/home/ldoku/RubymineProjects/one2influx/vendor/bundle/ruby/2.2.0/gems/opennebula-4.12.0/lib/opennebula/xml_pool.rb:34:in `each_element'", "/home/ldoku/RubymineProjects/one2influx/vendor/bundle/ruby/2.2.0/gems/opennebula-4.12.0/lib/opennebula/pool.rb:152:in `each'", "/home/ldoku/RubymineProjects/one2influx/lib/one2influx/data.rb:22:in `initialize'", "/home/ldoku/RubymineProjects/one2influx/bin/one2influx:62:in `new'", "/home/ldoku/RubymineProjects/one2influx/bin/one2influx:62:in `block in <top (required)>'", "/home/ldoku/RubymineProjects/one2influx/bin/one2influx:57:in `loop'", "/home/ldoku/RubymineProjects/one2influx/bin/one2influx:57:in `<top (required)>'", "-e:1:in `load'", "-e:1:in `<main>'"]
70
+ I, [2015-05-06T13:42:58.004202 #23537] INFO -- : Connection with ONE verified.
71
+ I, [2015-05-06T13:42:58.017566 #23537] INFO -- : Connection to InfluxDB database 'test' with retention policy 'ten_hours' verified.
72
+ E, [2015-05-06T13:42:58.054988 #23537] ERROR -- : Unable to get metric 'MEMORY_PERC' in One2Influx::VirtualMachine.
73
+ E, [2015-05-06T13:42:58.074978 #23537] ERROR -- : Unable to get metric 'MEMORY_PERC' in One2Influx::VirtualMachine.
74
+ E, [2015-05-06T13:42:58.090473 #23537] ERROR -- : Unable to get metric 'MEMORY_PERC' in One2Influx::VirtualMachine.
75
+ I, [2015-05-06T13:42:58.130001 #23537] INFO -- : Stored data for 3 VMs, 2 hosts, 4 datastores and 1 clusters.
76
+ I, [2015-05-06T13:42:58.130099 #23537] INFO -- : Successfully fetched data from ONE.
77
+ E, [2015-05-06T13:42:58.130189 #23537] ERROR -- : exit
78
+ I, [2015-05-06T13:43:47.863069 #23562] INFO -- : Connection with ONE verified.
79
+ I, [2015-05-06T13:43:47.909290 #23562] INFO -- : Connection to InfluxDB database 'test' with retention policy 'ten_hours' verified.
80
+ E, [2015-05-06T13:43:47.955788 #23562] ERROR -- : Unable to get metric 'MEMORY_PERC' in One2Influx::VirtualMachine.
81
+ E, [2015-05-06T13:43:47.975642 #23562] ERROR -- : Unable to get metric 'MEMORY_PERC' in One2Influx::VirtualMachine.
82
+ E, [2015-05-06T13:43:48.007135 #23562] ERROR -- : Unable to get metric 'MEMORY_PERC' in One2Influx::VirtualMachine.
83
+ I, [2015-05-06T13:43:48.034434 #23562] INFO -- : Stored data for 3 VMs, 2 hosts, 4 datastores and 1 clusters.
84
+ I, [2015-05-06T13:43:48.034562 #23562] INFO -- : Successfully fetched data from ONE.
85
+ E, [2015-05-06T13:43:48.034658 #23562] ERROR -- : exit
86
+ I, [2015-05-06T13:44:10.064663 #23582] INFO -- : Connection with ONE verified.
87
+ I, [2015-05-06T13:44:10.599592 #23582] INFO -- : Connection to InfluxDB database 'test' with retention policy 'ten_hours' verified.
88
+ I, [2015-05-06T13:44:10.750799 #23582] INFO -- : Stored data for 3 VMs, 2 hosts, 4 datastores and 1 clusters.
89
+ I, [2015-05-06T13:44:10.750902 #23582] INFO -- : Successfully fetched data from ONE.
90
+ E, [2015-05-06T13:44:10.751059 #23582] ERROR -- : exit
91
+ E, [2015-05-10T13:21:23.324353 #26300] ERROR -- : Unable to find out ONE version with message: Connection refused - connect(2) for "localhost" port 2633
92
+ E, [2015-05-11T00:16:42.153808 #12763] ERROR -- : Unable to find out ONE version with message: Connection refused - connect(2) for "localhost" port 2633
data/lib/one2influx.rb ADDED
@@ -0,0 +1,20 @@
1
+ module One2Influx; end
2
+
3
+ # Runtime dependencies
4
+ require 'opennebula'
5
+ require 'nokogiri'
6
+ require 'json'
7
+ require 'net/http'
8
+ require 'uri'
9
+ require 'logger'
10
+
11
+
12
+ # one2influx files
13
+ require 'one2influx/config'
14
+ require 'one2influx/data'
15
+ require 'one2influx/influx'
16
+ require 'one2influx/one_object/one_object'
17
+ require 'one2influx/one_object/host'
18
+ require 'one2influx/one_object/datastore'
19
+ require 'one2influx/one_object/virtual_machine'
20
+ require 'one2influx/one_object/cluster'
@@ -0,0 +1,264 @@
1
+ # Class for holding all configuration data, it is accessed by its only instance
2
+ # in global variable $CFG
3
+ class One2Influx::Config
4
+
5
+ ##############################################################################
6
+ ## EDIT THIS PART IF NECESSARY ##
7
+ ##############################################################################
8
+
9
+ # Allowed values are number of seconds, minutes, hours
10
+ # separated by space
11
+ @@fetch_interval = '30 seconds'
12
+
13
+ # OpenNebula connection configuration
14
+ #####################################
15
+ @@one = {
16
+ # Login credentials separated by semicolon
17
+ credentials: 'user:password',
18
+
19
+ # XML_RPC endpoint where OpenNebula is listening
20
+ endpoint: 'http://localhost:2633/RPC2'
21
+ }
22
+
23
+ # InfluxDB connection configuration
24
+ ###################################
25
+ @@influx = {
26
+ # Whether to use basic authentication
27
+ authenticate: false,
28
+
29
+ # Login credentials separated by semicolon
30
+ credentials: 'user:password',
31
+
32
+ # InfluxDB HTTP API endpoint
33
+ endpoint: 'http://localhost:8086',
34
+
35
+ # Database name
36
+ database: 'test',
37
+
38
+ # Retention policy for records with the smallest granularity
39
+ # you have to create retention policy manually if you want to change
40
+ # this one
41
+ policy: 'ten_hours'
42
+ }
43
+
44
+ # Logging configuration
45
+ #######################
46
+ @@log = {
47
+ # Level to use. Logger::INFO, Logger::WARN, Logger::ERROR are supported
48
+ level: Logger::INFO,
49
+
50
+ # Path to log file
51
+ path: ''
52
+ }
53
+
54
+ # Configuration of metrics and tags to be stored to InfluxDB
55
+ # Comment or uncomment metrics, tags or whole object depending on what you
56
+ # want to store.
57
+ ##########################################################################
58
+ @@storage = {
59
+ # Host
60
+ host: {
61
+ tags: {
62
+ HOST_NAME: 'NAME',
63
+ CLUSTER_ID: 'CLUSTER_ID',
64
+ CLUSTER_NAME: 'CLUSTER',
65
+ DSS_IDS: '' # [string] IDs of datastores that this host uses
66
+ # encoded in form ,,ID_1,,ID_2...,,
67
+ },
68
+ metrics: [
69
+ 'MEM_USAGE', # [kB] memory requested by VMs
70
+ 'MAX_MEM', # [kB] total memory available in host
71
+ 'FREE_MEM', # [kB] free memory returned by probes
72
+ 'USED_MEM', # [kB] memory used by all host processes over MAX_MEM
73
+ 'CPU_USAGE', # [%] usage of CPU calculated by ONE as the summatory
74
+ # CPU requested by all VMs running in the host
75
+ 'MAX_CPU', # [%] total CPU in the host (number of cores * 100)
76
+ 'FREE_CPU', # [%] free CPU as returned by the probes
77
+ 'USED_CPU' # [%] CPU used by all host processes over a total
78
+ # of # cores * 100
79
+ ],
80
+ cust_metrics: []
81
+ },
82
+ # Virtual machine
83
+ vm: {
84
+ tags: {
85
+ CLUSTER_ID: 'CLUSTER_ID',
86
+ CLUSTER_NAME: 'CLUSTER_NAME',
87
+ HOST_ID: 'HOST_ID',
88
+ HOST_NAME: 'HOST_NAME',
89
+ VM_NAME: 'NAME',
90
+ UID: 'UID', # [int] user's ID
91
+ GID: 'GID', # [int] group's ID
92
+ UNAME: 'UNAME', # [string] user's name
93
+ GNAME: 'GNAME' # [string] group's name
94
+ },
95
+ metrics: [
96
+ 'MEMORY', # [kB] memory consumption
97
+ 'CPU', # [%] 1 VCPU consumed (two fully consumed cpu is 200)
98
+ #'NET_TX', # [B] sent to the networ
99
+ #'NET_RX' # [B] received from the network
100
+ ],
101
+ cust_metrics: [
102
+ #'MEMORY_PERC' # Computes percentage usage of memory for VM
103
+ ]
104
+
105
+ },
106
+ # Datastore
107
+ ds: {
108
+ tags: {
109
+ DS_NAME: 'NAME',
110
+ CLUSTER_ID: 'CLUSTER_ID',
111
+ CLUSTER_NAME: 'CLUSTER',
112
+ TM_MAD: 'TM_MAD', # [shared|ssh|qcow2|vmfs|ceph|lvm|fs_lvm|dev]
113
+ # transfer manager
114
+ DS_MAD: 'DS_MAD', # [fs|vmfs|lvm|ceph|dev] datastore type
115
+ UID: 'UID', # [int] user's ID
116
+ GID: 'GID', # [int] group's ID
117
+ UNAME: 'UNAME', # [string] user's name
118
+ GNAME: 'GNAME', # [string] group's name
119
+ HOSTS_IDS: '' # [string] IDs of hosts that are using this
120
+ # datastore encoded in form ,,ID_1,,ID_2...,,
121
+ },
122
+ metrics: [
123
+ 'TOTAL_MB', # [MB] total space available in datastore
124
+ 'FREE_MB', # [MB] free space
125
+ 'USED_MB' # [MB] used space
126
+ ],
127
+ cust_metrics: []
128
+ },
129
+ # Cluster
130
+ cluster: {
131
+ tags: {
132
+ CLUSTER_NAME: 'NAME'
133
+ },
134
+ metrics: [
135
+ 'CLUSTER_MEM_USAGE', # [kB] memory requested by all VMs in cluster
136
+ 'CLUSTER_MAX_MEM', # [kB] total memory available in all hosts
137
+ 'CLUSTER_FREE_MEM', # [kB] free memory of all hosts returned
138
+ # by probes
139
+ 'CLUSTER_USED_MEM', # [kB] memory used by all processes of all
140
+ # hosts over MAX_MEM
141
+ 'CLUSTER_CPU_USAGE', # [%] usage of CPU calculated by ONE as the
142
+ # sum of CPU requested by all VMs running
143
+ # in the cluster
144
+ 'CLUSTER_MAX_CPU', # [%] total CPU in the cluster
145
+ # (number of cores * 100)
146
+ 'CLUSTER_FREE_CPU', # [%] free CPU as returned by the probes
147
+ 'CLUSTER_USED_CPU' # [%] CPU used by all processes of all hosts
148
+ # over a total of # cores * 100
149
+ ],
150
+ cust_metrics: []
151
+ }
152
+ }
153
+
154
+ ##############################################################################
155
+ ## DO NOT EDIT BELOW THIS LINE ##
156
+ ##############################################################################
157
+
158
+ attr_reader :sec_interval
159
+ # @@fetch_interval in seconds
160
+ @sec_interval = 0
161
+
162
+ public
163
+ # Group of getter methods for configuration class variables
164
+ def one
165
+ @@one
166
+ end
167
+
168
+ def influx
169
+ @@influx
170
+ end
171
+
172
+ def storage
173
+ @@storage
174
+ end
175
+
176
+ # Initializes logging, converts fetch interval from human readable form,
177
+ # adds tag ID to all metrics and converts VM's tags from human readable form
178
+ def initialize
179
+ log_path = @@log[:path] + 'one2influx.log'
180
+ begin
181
+ $LOG = Logger.new(log_path, 'daily', 30)
182
+ rescue Exception => e
183
+ raise "Unable to create log file. #{e.message}"
184
+ end
185
+ $LOG.level = @@log[:level]
186
+
187
+ convert_to_sec
188
+ prepare_storage_ids
189
+ prepare_vm_config
190
+ end
191
+
192
+ # Checks it is possible to connect to ONE with provided credentials.
193
+ def is_one_available?
194
+ begin
195
+ client = OpenNebula::Client.new(@@one[:credentials], @@one[:endpoint])
196
+ rescue Exception => e
197
+ $LOG.error "Unable to connect to ONE with message: #{e.message}"
198
+ return false
199
+ end
200
+
201
+ version = client.get_version
202
+ # Try to get ONE version just to check if it's possible to connect to ONE
203
+ if version.is_a? OpenNebula::Error
204
+ $LOG.error 'Unable to find out ONE version with message: '+version.message
205
+ return false
206
+ end
207
+ $LOG.info 'Connection with ONE verified.'
208
+
209
+ return true
210
+ end
211
+
212
+ private
213
+
214
+ # Adds obligatory ID tag to all storage objects in form OBJ_ID, where OBJ is
215
+ # object name. Therefore OneObjects will always have at least one tag, ID.
216
+ def prepare_storage_ids
217
+ @@storage.each do |object, values|
218
+ id_name = "#{object.to_s.upcase}_ID"
219
+ values[:tags][id_name.to_sym] = 'ID'
220
+ end
221
+ end
222
+
223
+ # XML with virtual machine monitoring doesn't contain tags CLUSTER_ID,
224
+ # CLUSTER_NAME, HOST_ID and HOST_NAME so it needs to be loaded from the host
225
+ # running that VM.
226
+ # Therefore these tags are handled differently and needs to be separated from
227
+ # the rest into @@storage[:vm][:inh_tags]
228
+ def prepare_vm_config
229
+ inh_tags = %i(CLUSTER_ID CLUSTER_NAME HOST_ID HOST_NAME)
230
+ @@storage[:vm][:inh_tags] = @@storage[:vm][:tags].clone
231
+
232
+ # Get inherited tags into special hash for VMs only
233
+ @@storage[:vm][:inh_tags].keep_if do |key, value|
234
+ inh_tags.include? key
235
+ end
236
+ # Remove them from original hash
237
+ @@storage[:vm][:inh_tags].each do |key, value|
238
+ @@storage[:vm][:tags].delete(key)
239
+ end
240
+ end
241
+
242
+ # Converts local variable human_interval to seconds
243
+ # and stores in sec_interval
244
+ def convert_to_sec
245
+ duration = @@fetch_interval.split(' ')
246
+
247
+ if duration.length != 2
248
+ raise "Invalid @@fetch_interval(=#{@@fetch_interval}) in config.rb."
249
+ end
250
+
251
+ case duration[1]
252
+ when /seconds?/
253
+ multiply = 1
254
+ when /minutes?/
255
+ multiply = 60
256
+ when /hours?/
257
+ multiply = 3600
258
+ else
259
+ raise "Invalid @@fetch_interval(=#{@@fetch_interval}) in config.rb."
260
+ end
261
+
262
+ @sec_interval = duration[0].to_i * multiply
263
+ end
264
+ end
@@ -0,0 +1,84 @@
1
+ # Wrapper for function that loads all data from OpenNebula
2
+ class One2Influx::Data
3
+
4
+ attr_reader :points
5
+
6
+ # Loads all data from ONE according to $CFG and stores it in
7
+ # instance variable @points
8
+ def initialize
9
+ @points = []
10
+ counter = {hosts: 0, vms: 0, dss: 0, clusters: 0}
11
+ # Connect to ONE
12
+ @client = OpenNebula::Client.new($CFG.one[:credentials], $CFG.one[:endpoint])
13
+
14
+ # Load pool of all hosts
15
+ host_pool = OpenNebula::HostPool.new(@client)
16
+ rc = host_pool.info
17
+ raise rc.message if OpenNebula.is_error?(rc)
18
+
19
+ # Get data from all hosts in the pool
20
+ hosts_xml = {} # XML of all hosts, passed to theirs cluster
21
+ oo_hosts = [] # array of all instances of OneObject::Host
22
+ host_pool.each do |one_host|
23
+ host = ::One2Influx::Host.new(one_host.to_xml, @client)
24
+ # Get data from all VMs belonging to current host
25
+ host.vms.each do |vm_id|
26
+ xml_rep = OpenNebula::VirtualMachine.build_xml(vm_id)
27
+ one_vm = OpenNebula::VirtualMachine.new(xml_rep, @client)
28
+ rc = one_vm.info
29
+ raise rc.message if OpenNebula.is_error?(rc)
30
+ vm = ::One2Influx::VirtualMachine.new(one_vm.to_xml, @client, host)
31
+ @points += vm.serialize_as_points
32
+ counter[:vms] += 1
33
+ end
34
+ hosts_xml[host.tags[:HOST_ID]] = one_host.to_xml
35
+ oo_hosts << host
36
+ @points += host.serialize_as_points
37
+ counter[:hosts] += 1
38
+ end
39
+
40
+ # Load pool of all clusters
41
+ cluster_pool = OpenNebula::ClusterPool.new(@client)
42
+ rc = cluster_pool.info
43
+ raise rc.message if OpenNebula.is_error?(rc)
44
+ #
45
+ # Get data from all clusters in the pool
46
+ cluster_pool.each do |one_cluster|
47
+ cluster = ::One2Influx::Cluster.new(one_cluster.to_xml, @client,hosts_xml)
48
+ @points += cluster.serialize_as_points
49
+ counter[:clusters] += 1
50
+ end
51
+
52
+ # Load pool of all datastores
53
+ ds_pool = OpenNebula::DatastorePool.new(@client)
54
+ rc = ds_pool.info
55
+ raise rc.message if OpenNebula.is_error?(rc)
56
+
57
+ # Get hash of all hosts for every datastore if these tags are required
58
+ # It has form {DS_ID_1: [HOST_ID_1, HOST_ID_2, ...], ...}
59
+ ds_has_hosts = {}
60
+ if $CFG.storage[:ds][:tags].has_key? :HOSTS_IDS
61
+ oo_hosts.each do |host|
62
+ host.datastores.each do |ds|
63
+ ds_has_hosts[ds] ||= []
64
+ ds_has_hosts[ds] << host.tags[:HOST_ID]
65
+ end
66
+ end
67
+ end
68
+
69
+ # Get data from all datastores in the pool
70
+ ds_pool.each do |one_ds|
71
+ ds = ::One2Influx::Datastore.new(one_ds.to_xml, @client)
72
+ hosts = ds_has_hosts[ds.tags[:DS_ID]]
73
+ hosts ||= []
74
+ # This doesn't do anything if tag HOSTS_IDS is not enabled
75
+ ds.add_hosts_ids(hosts)
76
+ @points += ds.serialize_as_points
77
+ counter[:dss] += 1
78
+ end
79
+
80
+ $LOG.info "Fetched data for #{counter[:vms]} VMs, #{counter[:hosts]} hosts" +
81
+ ", #{counter[:dss]} datastores and #{counter[:clusters]} " +
82
+ 'clusters.'
83
+ end
84
+ end
@@ -0,0 +1,156 @@
1
+ # Used for storing data to InfluxDB through HTTP API
2
+ class One2Influx::Influx
3
+
4
+ # Initializes class Influx.
5
+ # @raise [Exception] in case of error while getting UUID
6
+ def initialize
7
+ @authenticate = $CFG.influx[:authenticate]
8
+ if @authenticate
9
+ creds = $CFG.influx[:credentials].split(':')
10
+ raise 'InfluxDB credentials have invalid form!' if creds.length != 2
11
+ @user = creds[0]
12
+ @pass = creds[1]
13
+ end
14
+ uri = URI.parse($CFG.influx[:endpoint])
15
+ @host = uri.host
16
+ @port = uri.port
17
+ @db = $CFG.influx[:database]
18
+ @retention_policy = $CFG.influx[:policy]
19
+ end
20
+
21
+
22
+ # @param [hash] points returned by OneObject.serialize_as_points
23
+ # @raise [Exception] in case of unsuccessful storing
24
+ def store(points)
25
+ # Split points by 2500 for better performance
26
+ points.each_slice(2500).to_a.each do |slice|
27
+ # Default InfluxDB payload form
28
+ payload = {
29
+ :database => @db,
30
+ :retentionPolicy => @retention_policy,
31
+ :points => slice
32
+ }
33
+ # puts "Total number of points is #{points.length}"
34
+
35
+ # Create InfluxDB write request
36
+ req = Net::HTTP::Post.new(
37
+ '/write',
38
+ initheader = {
39
+ 'Content-Type' => 'application/json'
40
+ }
41
+ )
42
+
43
+ req.body = payload.to_json
44
+ response = make_request(req)
45
+
46
+ if (not response.nil?) && (response.code != '200')
47
+ raise 'Failed to store data to InfluxDB. Received HTTP code ' +
48
+ "#{response.code}, body: #{response.body}"
49
+ end
50
+ $LOG.info "Successfully stored #{slice.length} data points."
51
+ end
52
+ end
53
+
54
+ # Checks whether InfluxDB connection is possible, database @db exists
55
+ # and @retention_policy exists.
56
+ # @return [boolean]
57
+ def db_exists?
58
+ uri = URI('/query')
59
+ query = {:q => "SHOW RETENTION POLICIES #{@db}"}
60
+ uri.query = URI.encode_www_form(query)
61
+
62
+ req = Net::HTTP::Get.new(uri.to_s)
63
+
64
+ response = make_request(req)
65
+
66
+ # Was request successful?
67
+ if response.nil?
68
+ return false
69
+ end
70
+
71
+ # Check for invalid HTTP response codes
72
+ if response.code.to_i == 401
73
+ $LOG.error "Unauthorized user '#{@user}', unable to verify connection" +
74
+ ' to InfluxDB.'
75
+ return false
76
+ elsif response.code.to_i != 200
77
+ $LOG.error 'Failed to store data to InfluxDB. Received HTTP code ' +
78
+ "#{response.code}, body: #{response.body}"
79
+ return false
80
+ end
81
+
82
+ # Parse response
83
+ begin
84
+ response = JSON.parse(response.body)
85
+ rescue JSON::ParserError => e
86
+ $LOG.error 'Unable to parse InfluxDB response, while verifying ' +
87
+ "connection to database '#{@db}': #{e}. " +
88
+ "Received: #{response.body}"
89
+ return false
90
+ end
91
+
92
+ begin
93
+ if response['results'][0].has_key? 'error'
94
+ $LOG.error "Unable to verify connection to InfluxDB database '#{@db}'" +
95
+ " with message: #{response['results'][0]['error']}"
96
+ return false
97
+ end
98
+
99
+ response['results'][0]['series'][0]['values'].each do |policy|
100
+ if policy[0] == @retention_policy
101
+ $LOG.info "Connection to InfluxDB database '#{@db}' with retention " +
102
+ "policy '#{@retention_policy}' verified."
103
+ return true
104
+ end
105
+ end
106
+ rescue Exception
107
+ # Handle index out of bounds etc. exceptions
108
+ $LOG.error "Unable to verify connection to InfluxDB database '#{@db}'. " +
109
+ 'Invalid InfluxDB response format.'
110
+ return false
111
+ end
112
+ $LOG.error "InfluxDB database '#{@db}' does not contain supplied " +
113
+ "retention policy '#{@retention_policy}'."
114
+
115
+ return false
116
+ end
117
+
118
+ private
119
+
120
+ # @param [Net::HTTP::Post|Net::HTTP::Get] request
121
+ # @raise [Exception] Net::*
122
+ # @return [Net::HTTPResponse]
123
+ def make_request(request)
124
+ if @authenticate
125
+ request.basic_auth @user, @pass
126
+ end
127
+
128
+ retries = 4
129
+ begin
130
+ http = Net::HTTP.new(@host, @port)
131
+ http.read_timeout = 2
132
+ response = http.start do |http|
133
+ http.request(request)
134
+ end
135
+ rescue Exception => e
136
+ if retries < 0 then
137
+ if e.is_a? Net::ReadTimeout
138
+ raise 'Unable to post data to InfluxDB for 5th time! ' +
139
+ 'Timed out, possibly not stored.'
140
+ else
141
+ raise 'Unable to post data to InfluxDB for 5th time! ' +
142
+ "Error: #{e.message}."
143
+ end
144
+ return nil
145
+ else
146
+ $LOG.warn "Unable to post data to InfluxDB! Trying #{retries+1} more " +
147
+ "times. Error: #{e.message}."
148
+ retries -= 1
149
+ sleep(0.01)
150
+ retry
151
+ end
152
+ end
153
+
154
+ return response
155
+ end
156
+ end
@@ -0,0 +1,53 @@
1
+ # Representation of ONE cluster
2
+ class One2Influx::Cluster < ::One2Influx::OneObject
3
+
4
+ #
5
+ # @param [string] xml representation of cluster
6
+ # @param [OpenNebula::Client] client connection link to ONE API
7
+ # @param [hash] hosts_xml xml representations of hosts in this cluster,
8
+ # in hash form {HOST_ID : XML_STRING}
9
+ def initialize(xml, client, hosts_xml)
10
+ # Load configuration
11
+ @tag_names = $CFG.storage[:cluster][:tags]
12
+ @metric_names = $CFG.storage[:cluster][:metrics]
13
+ @custom_metric_names = $CFG.storage[:cluster][:cust_metrics]
14
+ @hosts_xml = hosts_xml
15
+
16
+ super(xml, client)
17
+ end
18
+
19
+ protected
20
+
21
+ # Overrides OneObject init_metrics because cluster itself doesn't
22
+ # have any own metrics, so they are gathered as sum of metrics of
23
+ # hosts that belong to this cluster
24
+ def init_metrics
25
+ @metric_names.each do |metric|
26
+ @metrics[metric.to_s] = 0
27
+ end
28
+
29
+ host_ids = @doc.xpath('//HOSTS/ID').map { |node| node.content }
30
+ host_ids.each do |id|
31
+ host_doc = Nokogiri::XML(@hosts_xml[id])
32
+ @metric_names.each do |metric|
33
+ host_metric = metric.split('CLUSTER_')[1]
34
+ unless host_metric.nil?
35
+ ni_element = host_doc.css(host_metric).first
36
+ if ni_element.nil?
37
+ $LOG.error "Unable to get metric '#{metric}' in #{self.class}."
38
+ else
39
+ @metrics[metric.to_s] += ni_element.content.to_i
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ # Get real percentage for cluster
46
+ hosts_count = host_ids.length == 0 ? 1 : host_ids.length
47
+ @metrics.each do |metric, value|
48
+ if metric.to_s.include? 'CPU'
49
+ @metrics[metric] = value / hosts_count
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,30 @@
1
+ # Representation of ONE datastore
2
+ class One2Influx::Datastore < ::One2Influx::OneObject
3
+
4
+ #
5
+ # @param [string] xml representation of datastore
6
+ # @param [OpenNebula::Client] client connection link to ONE API
7
+ def initialize(xml, client)
8
+ # Load configuration
9
+ @tag_names = $CFG.storage[:ds][:tags]
10
+ @metric_names = $CFG.storage[:ds][:metrics]
11
+ @custom_metric_names = $CFG.storage[:ds][:cust_metrics]
12
+
13
+ # Parsing HOST_ID_X as normal tag_name would cause error
14
+ if @tag_names.has_key? :HOSTS_IDS
15
+ @tag_names.delete :HOSTS_IDS
16
+ end
17
+
18
+ super(xml, client)
19
+ end
20
+
21
+ # Add tag HOSTS_IDS a string containing IDs of all hosts associated
22
+ # with this datastore in form for each host associated with this datastore in
23
+ # form ,,ID_1,,ID_2...,,
24
+ # @param [array] hosts array of hosts IDs that are using this datastore
25
+ def add_hosts_ids(hosts)
26
+ unless hosts.empty?
27
+ @tags[:HOSTS_IDS] = ',,' + hosts.join(',,') + ',,'
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,47 @@
1
+ # Representation of ONE host
2
+ class One2Influx::Host < ::One2Influx::OneObject
3
+
4
+ attr_reader :datastores
5
+
6
+ #
7
+ # @param [string] xml representation of host
8
+ # @param [OpenNebula::Client] client connection link to ONE API
9
+ def initialize(xml, client)
10
+ # Load configuration
11
+ @tag_names = $CFG.storage[:host][:tags]
12
+ @metric_names = $CFG.storage[:host][:metrics]
13
+ @custom_metric_names = $CFG.storage[:host][:cust_metrics]
14
+
15
+
16
+ @doc = Nokogiri::XML(xml)
17
+ @tags = Hash.new
18
+ load_datastores
19
+ if @tag_names.has_key? :DSS_IDS
20
+ @tag_names.delete :DSS_IDS
21
+ unless @datastores.empty?
22
+ @tags[:DSS_IDS] = ',,' + @datastores.join(',,') + ',,'
23
+ end
24
+ end
25
+
26
+ super(xml, client)
27
+ end
28
+
29
+ #
30
+ # @return [array] IDs of VMs
31
+ def vms
32
+ @doc.xpath('//VMS/ID').map do |node|
33
+ node.content
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ # Initializes @datastores array of IDs for datastores associated with
40
+ # this host
41
+ def load_datastores
42
+ @datastores = []
43
+ @doc.xpath('//DATASTORES/DS/ID').each do |ds|
44
+ @datastores << ds.content
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,73 @@
1
+ # 'Abstract' class for OpenNebula's objects representation
2
+ class One2Influx::OneObject
3
+
4
+ attr_reader :tags, :metrics, :doc
5
+
6
+ # Creates mapping between ONE XML names and InfluxDB storage names.
7
+ # Loads all tags, metrics and custom metrics from given XML.
8
+ # @param [string] xml representation of OneObject
9
+ # @param [OpenNebula::Client] client connection link to ONE API
10
+ def initialize(xml, client)
11
+ @tags ||= Hash.new
12
+ @metrics ||= Hash.new
13
+ @doc ||= Nokogiri::XML(xml)
14
+ @client = client
15
+
16
+ init_tags
17
+ init_metrics
18
+ init_custom_metrics
19
+ end
20
+
21
+ # Serialize OneObject instance to InfluxDB point form
22
+ def serialize_as_points
23
+ points = []
24
+ @metrics.each do |metric_name, metric_value|
25
+ points << {
26
+ :name => metric_name,
27
+ :tags => @tags,
28
+ :fields => {
29
+ :value => metric_value.to_f
30
+ }
31
+ }
32
+ end
33
+
34
+ return points
35
+ end
36
+
37
+ # Called in case of misconfiguration and invalid custom metric method
38
+ # was called
39
+ def method_missing(name, *args, &block)
40
+ $LOG.error "Invalid method '#{name}' was called from #{self.class}! " #+
41
+ # "Stacktrace: #{e.backtrace}"
42
+ end
43
+
44
+ protected
45
+
46
+ def init_tags
47
+ @tag_names.each do |influx_name, one_name|
48
+ ni_element = @doc.css(one_name).first
49
+ if ni_element.nil?
50
+ $LOG.error "Unable to get tag '#{one_name}' in #{self.class}."
51
+ else
52
+ @tags[influx_name.to_sym] = ni_element.content
53
+ end
54
+ end
55
+ end
56
+
57
+ def init_metrics
58
+ @metric_names.each do |metric|
59
+ ni_element = @doc.css(metric).first
60
+ if ni_element.nil?
61
+ $LOG.error "Unable to get metric '#{metric}' in #{self.class}."
62
+ else
63
+ @metrics[metric.to_sym] = ni_element.content
64
+ end
65
+ end
66
+ end
67
+
68
+ def init_custom_metrics
69
+ @custom_metric_names.each do |metric|
70
+ @metrics[metric.to_sym] = self.send("get_#{metric.to_s}")
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,49 @@
1
+ # Representation of ONE virtual machine
2
+ class One2Influx::VirtualMachine < ::One2Influx::OneObject
3
+
4
+ #
5
+ # @param [string] xml representation of VM
6
+ # @param [OpenNebula::Client] client connection link to ONE API
7
+ # @param [One2Influx::Host] parent_host owner of this VM
8
+ def initialize(xml, client, parent_host)
9
+ # Load configuration
10
+ @tag_names = $CFG.storage[:vm][:tags]
11
+ @metric_names = $CFG.storage[:vm][:metrics]
12
+ @custom_metric_names = $CFG.storage[:vm][:cust_metrics]
13
+
14
+ # Assign tags inherited from parent host
15
+ @tags = Hash.new
16
+ $CFG.storage[:vm][:inh_tags].each do |name, value|
17
+ @tags[name] = parent_host.tags[value.to_sym]
18
+ end
19
+ super(xml, client)
20
+ end
21
+
22
+ # Computes percentage usage of memory for virtual machine.
23
+ # Values might go over 1.0 as there is an overhead
24
+ # @return [float] current usage over max usage
25
+ def get_MEMORY_PERC
26
+ template_id = @doc.xpath('//TEMPLATE').first
27
+ if template_id.nil? || template_id.content.nil?
28
+ $LOG.error "Unable to get metric 'MEMORY_PERC' in #{self.class}."
29
+ return
30
+ end
31
+ template_id = template_id.content
32
+ template = OpenNebula::Template.new(OpenNebula::Template.build_xml(template_id), @client)
33
+ rc = template.info
34
+ raise rc.message if OpenNebula.is_error?(rc)
35
+
36
+ doc = Nokogiri::XML(template.to_xml)
37
+ ni_element = doc.xpath('//TEMPLATE/MEMORY').first
38
+ puts @metrics
39
+ if ni_element.nil? || @metrics[:MEMORY].nil?
40
+ $LOG.error "Unable to get metric 'MEMORY_PERC' in #{self.class}."
41
+ return
42
+ end
43
+
44
+ # Convert //TEMPLATE/MEMORY from MB to kB as //VM/CPU is in kB
45
+ max_mem = ni_element.content.to_f * 1000.0
46
+
47
+ @metrics[:MEMORY].to_f / max_mem
48
+ end
49
+ end
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: one2influx
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Matej Zidek
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.8'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.8'
27
+ - !ruby/object:Gem::Dependency
28
+ name: opennebula
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '4.12'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '4.12'
41
+ - !ruby/object:Gem::Dependency
42
+ name: nokogiri
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.6'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.6'
55
+ - !ruby/object:Gem::Dependency
56
+ name: gyoku
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubystats
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.2'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.2'
83
+ description: One2influx is small ruby daemon for getting monitoring data from OpenNebula's
84
+ XML-RPC API and storing it to InfluxDB. It needs Ruby 2+ to run.
85
+ email: zidek.matej@gmail.com
86
+ executables:
87
+ - one2influx
88
+ - one2influx.log
89
+ extensions: []
90
+ extra_rdoc_files: []
91
+ files:
92
+ - bin/one2influx
93
+ - bin/one2influx.log
94
+ - lib/one2influx.rb
95
+ - lib/one2influx/config.rb
96
+ - lib/one2influx/data.rb
97
+ - lib/one2influx/influx.rb
98
+ - lib/one2influx/one_object/cluster.rb
99
+ - lib/one2influx/one_object/datastore.rb
100
+ - lib/one2influx/one_object/host.rb
101
+ - lib/one2influx/one_object/one_object.rb
102
+ - lib/one2influx/one_object/virtual_machine.rb
103
+ homepage: http://rubygems.org/gems/hola
104
+ licenses:
105
+ - Apache License 2.0
106
+ metadata: {}
107
+ post_install_message:
108
+ rdoc_options: []
109
+ require_paths:
110
+ - lib
111
+ required_ruby_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: 2.0.0
116
+ required_rubygems_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ requirements: []
122
+ rubyforge_project:
123
+ rubygems_version: 2.4.5
124
+ signing_key:
125
+ specification_version: 4
126
+ summary: Daemon for getting monitoring data from OpenNebula's XML-RPC API and storing
127
+ them to InfluxDB.
128
+ test_files: []
129
+ has_rdoc: