efigence-influxdb 0.1.0

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.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.rubocop.yml +41 -0
  4. data/.travis.yml +11 -0
  5. data/Gemfile +11 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +362 -0
  8. data/Rakefile +22 -0
  9. data/efigence-influxdb.gemspec +28 -0
  10. data/lib/influxdb.rb +21 -0
  11. data/lib/influxdb/client.rb +77 -0
  12. data/lib/influxdb/client/http.rb +98 -0
  13. data/lib/influxdb/config.rb +60 -0
  14. data/lib/influxdb/errors.rb +40 -0
  15. data/lib/influxdb/logging.rb +22 -0
  16. data/lib/influxdb/max_queue.rb +18 -0
  17. data/lib/influxdb/point_value.rb +31 -0
  18. data/lib/influxdb/query/cluster.rb +17 -0
  19. data/lib/influxdb/query/continuous_query.rb +36 -0
  20. data/lib/influxdb/query/core.rb +109 -0
  21. data/lib/influxdb/query/database.rb +21 -0
  22. data/lib/influxdb/query/series.rb +13 -0
  23. data/lib/influxdb/query/shard.rb +14 -0
  24. data/lib/influxdb/query/shard_space.rb +60 -0
  25. data/lib/influxdb/query/user.rb +38 -0
  26. data/lib/influxdb/version.rb +3 -0
  27. data/lib/influxdb/writer/async.rb +115 -0
  28. data/lib/influxdb/writer/udp.rb +21 -0
  29. data/spec/influxdb/cases/async_client_spec.rb +33 -0
  30. data/spec/influxdb/cases/query_cluster_spec.rb +65 -0
  31. data/spec/influxdb/cases/query_database_spec.rb +58 -0
  32. data/spec/influxdb/cases/query_series_spec.rb +50 -0
  33. data/spec/influxdb/cases/query_shard_spec.rb +43 -0
  34. data/spec/influxdb/cases/query_user_spec.rb +127 -0
  35. data/spec/influxdb/cases/querying_spec.rb +159 -0
  36. data/spec/influxdb/cases/retry_requests_spec.rb +97 -0
  37. data/spec/influxdb/cases/udp_client_spec.rb +21 -0
  38. data/spec/influxdb/cases/write_points_spec.rb +141 -0
  39. data/spec/influxdb/client_spec.rb +58 -0
  40. data/spec/influxdb/config_spec.rb +118 -0
  41. data/spec/influxdb/logging_spec.rb +48 -0
  42. data/spec/influxdb/max_queue_spec.rb +29 -0
  43. data/spec/influxdb/point_value_spec.rb +66 -0
  44. data/spec/influxdb/worker_spec.rb +23 -0
  45. data/spec/spec_helper.rb +8 -0
  46. metadata +192 -0
@@ -0,0 +1,97 @@
1
+ require "spec_helper"
2
+ require "json"
3
+
4
+ describe InfluxDB::Client do
5
+ let(:client) do
6
+ described_class.new(
7
+ "database",
8
+ {
9
+ host: "influxdb.test",
10
+ port: 9999,
11
+ username: "username",
12
+ password: "password",
13
+ time_precision: "s"
14
+ }.merge(args)
15
+ )
16
+ end
17
+
18
+ let(:args) { {} }
19
+
20
+ let(:database) { client.config.database }
21
+
22
+ describe "retrying requests" do
23
+
24
+ let(:series) { "cpu" }
25
+ let(:data) do
26
+ { tags: { region: 'us', host: 'server_1' },
27
+ values: { temp: 88, value: 54 } }
28
+ end
29
+ let(:body) do
30
+ InfluxDB::PointValue.new(data.merge(series: series)).dump
31
+ end
32
+
33
+ subject { client.write_point(series, data) }
34
+
35
+ before do
36
+ allow(client).to receive(:log)
37
+ stub_request(:post, "http://influxdb.test:9999/write").with(
38
+ :query => {:u => "username", :p => "password", :precision => 's', :db => database},
39
+ :headers => {"Content-Type" => "application/octet-stream"},
40
+ :body => body
41
+ ).to_raise(Timeout::Error)
42
+ end
43
+
44
+ it "raises when stopped" do
45
+ client.stop!
46
+ expect(client).not_to receive(:sleep)
47
+ expect { subject }.to raise_error(Timeout::Error)
48
+ end
49
+
50
+ context "when retry is 0" do
51
+ let(:args) { { retry: 0 } }
52
+ it "raise error directly" do
53
+ expect(client).not_to receive(:sleep)
54
+ expect { subject }.to raise_error(Timeout::Error)
55
+ end
56
+ end
57
+
58
+ context "when retry is 'n'" do
59
+ let(:args) { { retry: 3 } }
60
+
61
+ it "raise error after 'n' attemps" do
62
+ expect(client).to receive(:sleep).exactly(3).times
63
+ expect { subject }.to raise_error(Timeout::Error)
64
+ end
65
+ end
66
+
67
+ context "when retry is -1" do
68
+ let(:args) { { retry: -1 } }
69
+ before do
70
+ stub_request(:post, "http://influxdb.test:9999/write").with(
71
+ :query => {:u => "username", :p => "password", :precision => 's', :db => database},
72
+ :headers => {"Content-Type" => "application/octet-stream"},
73
+ :body => body
74
+ ).to_raise(Timeout::Error).then
75
+ .to_raise(Timeout::Error).then
76
+ .to_raise(Timeout::Error).then
77
+ .to_raise(Timeout::Error).then
78
+ .to_return(:status => 200)
79
+ end
80
+
81
+ it "keep trying until get the connection" do
82
+ expect(client).to receive(:sleep).exactly(4).times
83
+ expect { subject }.to_not raise_error
84
+ end
85
+ end
86
+
87
+ it "raise an exception if the server didn't return 200" do
88
+ stub_request(:post, "http://influxdb.test:9999/write").with(
89
+ :query => {:u => "username", :p => "password", :precision => 's', :db => database},
90
+ :headers => {"Content-Type" => "application/octet-stream"},
91
+ :body => body
92
+ ).to_return(:status => 401)
93
+
94
+ expect { client.write_point(series, data) }.to raise_error
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,21 @@
1
+ require "spec_helper"
2
+
3
+ describe InfluxDB::Client do
4
+ let(:client) { described_class.new(udp: { host: "localhost", port: 44_444 }) }
5
+
6
+ specify { expect(client.writer).to be_a(InfluxDB::Writer::UDP) }
7
+
8
+ describe "#write" do
9
+ let(:message) { "responses,region=eu value=5" }
10
+
11
+ it "sends a UPD packet" do
12
+ s = UDPSocket.new
13
+ s.bind("localhost", 44_444)
14
+
15
+ client.write_point("responses", values: {value: 5}, tags: {region: 'eu'})
16
+
17
+ rec_message = s.recvfrom(30).first
18
+ expect(rec_message).to eq message
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,141 @@
1
+ require "spec_helper"
2
+ require "json"
3
+
4
+ describe InfluxDB::Client do
5
+ let(:subject) do
6
+ described_class.new(
7
+ "database",
8
+ {
9
+ host: "influxdb.test",
10
+ port: 9999,
11
+ username: "username",
12
+ password: "password",
13
+ time_precision: "s"
14
+ }.merge(args)
15
+ )
16
+ end
17
+
18
+ let(:args) { {} }
19
+
20
+ let(:database) { subject.config.database }
21
+
22
+ describe "#write_point" do
23
+ let(:series) { "cpu" }
24
+ let(:data) do
25
+ { tags: { region: 'us', host: 'server_1' },
26
+ values: { temp: 88, value: 54 } }
27
+ end
28
+ let(:body) do
29
+ InfluxDB::PointValue.new(data.merge(series: series)).dump
30
+ end
31
+
32
+ before do
33
+ stub_request(:post, "http://influxdb.test:9999/write").with(
34
+ :query => {:u => "username", :p => "password", :precision => 's', :db => database},
35
+ :headers => {"Content-Type" => "application/octet-stream"},
36
+ :body => body
37
+ )
38
+ end
39
+
40
+ it "should POST to add single point" do
41
+ expect(subject.write_point(series, data)).to be_a(Net::HTTPOK)
42
+ end
43
+ end
44
+
45
+ describe "#write_points" do
46
+
47
+ context "with multiple series" do
48
+ let(:data) do
49
+ [{
50
+ series: 'cpu',
51
+ tags: { region: 'us', host: 'server_1' },
52
+ values: { temp: 88, value: 54 }
53
+ },
54
+ {
55
+ series: 'gpu',
56
+ tags: { region: 'uk', host: 'server_5'},
57
+ values: { value: 0.5435345}
58
+ }]
59
+ end
60
+ let(:body) do
61
+ data.map do |point|
62
+ InfluxDB::PointValue.new(point).dump
63
+ end.join("\n")
64
+ end
65
+
66
+ before do
67
+ stub_request(:post, "http://influxdb.test:9999/write").with(
68
+ :query => {:u => "username", :p => "password", :precision => 's', :db => database},
69
+ :headers => {"Content-Type" => "application/octet-stream"},
70
+ :body => body
71
+ )
72
+ end
73
+
74
+ it "should POST multiple points" do
75
+ expect(subject.write_points(data)).to be_a(Net::HTTPOK)
76
+ end
77
+ end
78
+
79
+ context "with no tags" do
80
+ let(:data) do
81
+ [{
82
+ series: 'cpu',
83
+ values: { temp: 88, value: 54 }
84
+ },
85
+ {
86
+ series: 'gpu',
87
+ values: { value: 0.5435345 }
88
+ }]
89
+ end
90
+ let(:body) do
91
+ data.map do |point|
92
+ InfluxDB::PointValue.new(point).dump
93
+ end.join("\n")
94
+ end
95
+
96
+ before do
97
+ stub_request(:post, "http://influxdb.test:9999/write").with(
98
+ :query => {:u => "username", :p => "password", :precision => 's', :db => database},
99
+ :headers => {"Content-Type" => "application/octet-stream"},
100
+ :body => body
101
+ )
102
+ end
103
+
104
+ it "should POST multiple points" do
105
+ expect(subject.write_points(data)).to be_a(Net::HTTPOK)
106
+ end
107
+ end
108
+
109
+ context "with time precision set to milisceconds" do
110
+ let(:data) do
111
+ [{
112
+ series: 'cpu',
113
+ values: { temp: 88, value: 54 },
114
+ timestamp: (Time.now.to_f * 1000).to_i
115
+ },
116
+ {
117
+ series: 'gpu',
118
+ values: { value: 0.5435345 },
119
+ timestamp: (Time.now.to_f * 1000).to_i
120
+ }]
121
+ end
122
+
123
+ let(:body) do
124
+ data.map do |point|
125
+ InfluxDB::PointValue.new(point).dump
126
+ end.join("\n")
127
+ end
128
+
129
+ before do
130
+ stub_request(:post, "http://influxdb.test:9999/write").with(
131
+ :query => {:u => "username", :p => "password", :precision => 'm', :db => database},
132
+ :headers => {"Content-Type" => "application/octet-stream"},
133
+ :body => body
134
+ )
135
+ end
136
+ it "should POST multiple points" do
137
+ expect(subject.write_points(data, 'm')).to be_a(Net::HTTPOK)
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,58 @@
1
+ require "spec_helper"
2
+ require "json"
3
+
4
+ describe InfluxDB::Client do
5
+ let(:subject) do
6
+ described_class.new(
7
+ "database",
8
+ {
9
+ host: "influxdb.test",
10
+ port: 9999,
11
+ username: "username",
12
+ password: "password",
13
+ time_precision: "s"
14
+ }.merge(args)
15
+ )
16
+ end
17
+
18
+ let(:args) { {} }
19
+
20
+ specify { is_expected.not_to be_stopped }
21
+
22
+ context "with basic auth" do
23
+ let(:args) { { auth_method: 'basic_auth' } }
24
+
25
+ let(:stub_url) { "http://username:password@influxdb.test:9999/" }
26
+ let(:url) { subject.send(:full_url, '/') }
27
+
28
+ it "GET" do
29
+ stub_request(:get, stub_url).to_return(body: '[]')
30
+ expect(subject.get(url, parse: true)).to eq []
31
+ end
32
+
33
+ it "POST" do
34
+ stub_request(:post, stub_url)
35
+ expect(subject.post(url, {})).to be_a(Net::HTTPOK)
36
+ end
37
+ end
38
+
39
+ describe "#full_url" do
40
+ it "returns String" do
41
+ expect(subject.send(:full_url, "/unknown")).to be_a String
42
+ end
43
+
44
+ it "escapes params" do
45
+ url = subject.send(:full_url, "/unknown", value: ' !@#$%^&*()/\\_+-=?|`~')
46
+ expect(url).to include("value=+%21%40%23%24%25%5E%26%2A%28%29%2F%5C_%2B-%3D%3F%7C%60%7E")
47
+ end
48
+ end
49
+
50
+ describe "GET #ping" do
51
+ it "returns OK" do
52
+ stub_request(:get, "http://influxdb.test:9999/ping")
53
+ .to_return(status: 204)
54
+
55
+ expect(subject.ping).to be_a(Net::HTTPNoContent)
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,118 @@
1
+ require 'spec_helper'
2
+
3
+ describe InfluxDB::Config do
4
+ let(:conf) do
5
+ InfluxDB::Client.new(*args).config
6
+ end
7
+
8
+ let(:args) { {} }
9
+
10
+ context "with no parameters specified" do
11
+ specify { expect(conf.database).to be_nil }
12
+ specify { expect(conf.hosts).to eq ["localhost"] }
13
+ specify { expect(conf.port).to eq 8086 }
14
+ specify { expect(conf.username).to eq "root" }
15
+ specify { expect(conf.password).to eq "root" }
16
+ specify { expect(conf.use_ssl).to be_falsey }
17
+ specify { expect(conf.time_precision).to eq "s" }
18
+ specify { expect(conf.auth_method).to eq "params" }
19
+ specify { expect(conf.denormalize).to be_truthy }
20
+ specify { expect(conf).not_to be_udp }
21
+ specify { expect(conf).not_to be_async }
22
+ end
23
+
24
+ context "with no database specified" do
25
+ let(:args) do
26
+ [{
27
+ host: "host",
28
+ port: "port",
29
+ username: "username",
30
+ password: "password",
31
+ time_precision: "m"
32
+ }]
33
+ end
34
+
35
+ specify { expect(conf.database).to be_nil }
36
+ specify { expect(conf.hosts).to eq ["host"] }
37
+ specify { expect(conf.port).to eq "port" }
38
+ specify { expect(conf.username).to eq "username" }
39
+ specify { expect(conf.password).to eq "password" }
40
+ specify { expect(conf.time_precision).to eq "m" }
41
+ end
42
+
43
+ context "with both a database and options specified" do
44
+ let(:args) do
45
+ [
46
+ "database",
47
+ host: "host",
48
+ port: "port",
49
+ username: "username",
50
+ password: "password",
51
+ time_precision: "m"
52
+ ]
53
+ end
54
+
55
+ specify { expect(conf.database).to eq "database" }
56
+ specify { expect(conf.hosts).to eq ["host"] }
57
+ specify { expect(conf.port).to eq "port" }
58
+ specify { expect(conf.username).to eq "username" }
59
+ specify { expect(conf.password).to eq "password" }
60
+ specify { expect(conf.time_precision).to eq "m" }
61
+ end
62
+
63
+ context "with ssl option specified" do
64
+ let(:args) { [{ use_ssl: true }] }
65
+
66
+ specify { expect(conf.database).to be_nil }
67
+ specify { expect(conf.hosts).to eq ["localhost"] }
68
+ specify { expect(conf.port).to eq 8086 }
69
+ specify { expect(conf.username).to eq "root" }
70
+ specify { expect(conf.password).to eq "root" }
71
+ specify { expect(conf.use_ssl).to be_truthy }
72
+ end
73
+
74
+ context "with multiple hosts specified" do
75
+ let(:args) { [{ hosts: ["1.1.1.1", "2.2.2.2"] }] }
76
+
77
+ specify { expect(conf.database).to be_nil }
78
+ specify { expect(conf.port).to eq 8086 }
79
+ specify { expect(conf.username).to eq "root" }
80
+ specify { expect(conf.password).to eq "root" }
81
+ specify { expect(conf.hosts).to eq ["1.1.1.1", "2.2.2.2"] }
82
+ end
83
+
84
+ context "with auth_method basic auth specified" do
85
+ let(:args) { [{ auth_method: 'basic_auth' }] }
86
+
87
+ specify { expect(conf.database).to be_nil }
88
+ specify { expect(conf.hosts).to eq ["localhost"] }
89
+ specify { expect(conf.port).to eq 8086 }
90
+ specify { expect(conf.username).to eq "root" }
91
+ specify { expect(conf.password).to eq "root" }
92
+ specify { expect(conf.auth_method).to eq "basic_auth" }
93
+ end
94
+
95
+ context "with udp specified with params" do
96
+ let(:args) { [{ udp: { host: 'localhost', port: 4444 } }] }
97
+
98
+ specify { expect(conf).to be_udp }
99
+ end
100
+
101
+ context "with udp specified as true" do
102
+ let(:args) { [{ udp: true }] }
103
+
104
+ specify { expect(conf).to be_udp }
105
+ end
106
+
107
+ context "with async specified with params" do
108
+ let(:args) { [{ async: { max_queue: 20_000 } }] }
109
+
110
+ specify { expect(conf).to be_async }
111
+ end
112
+
113
+ context "with async specified as true" do
114
+ let(:args) { [{ async: true }] }
115
+
116
+ specify { expect(conf).to be_async }
117
+ end
118
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+ require 'logger'
3
+
4
+ describe InfluxDB::Logging do
5
+ class LoggerTest # :nodoc:
6
+ include InfluxDB::Logging
7
+
8
+ def write_to_log(level, message)
9
+ log(level, message)
10
+ end
11
+ end
12
+
13
+ before { @old_logger = InfluxDB::Logging.logger }
14
+ after { InfluxDB::Logging.logger = @old_logger }
15
+
16
+ it "has a default logger" do
17
+ expect(InfluxDB::Logging.logger).to be_a(Logger)
18
+ end
19
+
20
+ it "allows setting of a logger" do
21
+ new_logger = Logger.new(STDOUT)
22
+ InfluxDB::Logging.logger = new_logger
23
+ expect(InfluxDB::Logging.logger).to eq(new_logger)
24
+ end
25
+
26
+ it "allows disabling of a logger" do
27
+ InfluxDB::Logging.logger = false
28
+ expect(InfluxDB::Logging.logger).to eql false
29
+ end
30
+
31
+ context "when logging is disabled" do
32
+ subject { LoggerTest.new }
33
+ it "does not log" do
34
+ InfluxDB::Logging.logger = false
35
+ expect(InfluxDB::Logging.logger).not_to receive(:debug)
36
+ subject.write_to_log(:debug, 'test')
37
+ end
38
+ end
39
+
40
+ context "when included in classes" do
41
+ subject { LoggerTest.new }
42
+
43
+ it "logs" do
44
+ expect(InfluxDB::Logging.logger).to receive(:debug).with(an_instance_of(String)).once
45
+ subject.write_to_log(:debug, 'test')
46
+ end
47
+ end
48
+ end