one2influx 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: