influxer 1.1.4 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +98 -0
  3. data/{MIT-LICENSE → LICENSE.txt} +1 -1
  4. data/README.md +106 -47
  5. data/lib/influxer.rb +10 -9
  6. data/lib/influxer/client.rb +1 -1
  7. data/lib/influxer/config.rb +19 -6
  8. data/lib/influxer/engine.rb +1 -1
  9. data/lib/influxer/metrics/active_model3/model.rb +2 -4
  10. data/lib/influxer/metrics/metrics.rb +10 -13
  11. data/lib/influxer/metrics/quoting/timestamp.rb +23 -11
  12. data/lib/influxer/metrics/relation.rb +33 -17
  13. data/lib/influxer/metrics/relation/calculations.rb +1 -1
  14. data/lib/influxer/metrics/relation/time_query.rb +15 -13
  15. data/lib/influxer/metrics/relation/where_clause.rb +19 -11
  16. data/lib/influxer/metrics/scoping.rb +4 -4
  17. data/lib/influxer/metrics/scoping/current_scope.rb +2 -1
  18. data/lib/influxer/metrics/scoping/default.rb +1 -1
  19. data/lib/influxer/metrics/scoping/named.rb +2 -1
  20. data/lib/influxer/model.rb +4 -9
  21. data/lib/influxer/rails/client.rb +6 -6
  22. data/lib/influxer/version.rb +1 -1
  23. metadata +30 -95
  24. data/.gitignore +0 -37
  25. data/.rspec +0 -2
  26. data/.rubocop.yml +0 -77
  27. data/.travis.yml +0 -10
  28. data/Changelog.md +0 -111
  29. data/Gemfile +0 -10
  30. data/Rakefile +0 -13
  31. data/gemfiles/rails32.gemfile +0 -7
  32. data/gemfiles/rails42.gemfile +0 -7
  33. data/gemfiles/rails5.gemfile +0 -7
  34. data/influxer.gemspec +0 -33
  35. data/spec/cases/points_spec.rb +0 -36
  36. data/spec/cases/write_points_spec.rb +0 -85
  37. data/spec/client_spec.rb +0 -46
  38. data/spec/fixtures/empty_result.json +0 -21
  39. data/spec/fixtures/single_series.json +0 -29
  40. data/spec/metrics/metrics_spec.rb +0 -283
  41. data/spec/metrics/relation_spec.rb +0 -477
  42. data/spec/metrics/scoping_spec.rb +0 -66
  43. data/spec/model/user_spec.rb +0 -46
  44. data/spec/spec_helper.rb +0 -64
  45. data/spec/support/metrics/action_metrics.rb +0 -5
  46. data/spec/support/metrics/custom_metrics.rb +0 -6
  47. data/spec/support/metrics/dummy_metrics.rb +0 -12
  48. data/spec/support/metrics/user_metrics.rb +0 -6
  49. data/spec/support/metrics/visits_metrics.rb +0 -8
  50. data/spec/support/shared_contexts/shared_query.rb +0 -16
  51. data/spec/support/user.rb +0 -16
data/Gemfile DELETED
@@ -1,10 +0,0 @@
1
- source "https://rubygems.org"
2
- gemspec
3
-
4
- local_gemfile = 'Gemfile.local'
5
-
6
- if File.exist?(local_gemfile)
7
- eval(File.read(local_gemfile)) # rubocop:disable Lint/Eval
8
- else
9
- gem 'activerecord', '~>4.2'
10
- end
data/Rakefile DELETED
@@ -1,13 +0,0 @@
1
- require "bundler/gem_tasks"
2
-
3
- require 'rspec/core/rake_task'
4
- RSpec::Core::RakeTask.new(:spec)
5
-
6
- require "rubocop/rake_task"
7
- RuboCop::RakeTask.new
8
-
9
- task default: [:rubocop, :spec]
10
-
11
- task :console do
12
- sh 'pry -r ./lib/influxer.rb'
13
- end
@@ -1,7 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gem 'sqlite3', platform: :mri
4
- gem 'activerecord-jdbcsqlite3-adapter', platform: :jruby
5
- gem 'activerecord', '~> 3.2.22'
6
-
7
- gemspec path: '..'
@@ -1,7 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gem 'sqlite3', platform: :mri
4
- gem 'activerecord-jdbcsqlite3-adapter', platform: :jruby
5
- gem 'activerecord', '~> 4.2.0'
6
-
7
- gemspec path: '..'
@@ -1,7 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gem 'sqlite3', platform: :mri
4
- gem 'activerecord-jdbcsqlite3-adapter', platform: :jruby
5
- gem 'activerecord', '~> 5.0.0'
6
-
7
- gemspec path: '..'
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- $LOAD_PATH.push File.expand_path("../lib", __FILE__)
4
-
5
- require "influxer/version"
6
-
7
- Gem::Specification.new do |s|
8
- s.name = "influxer"
9
- s.version = Influxer::VERSION
10
- s.authors = ["Vlad Dem"]
11
- s.email = ["dementiev.vm@gmail.com"]
12
- s.homepage = "http://github.com/palkan/influxer"
13
- s.summary = "InfluxDB for Rails"
14
- s.description = "InfluxDB the Rails way"
15
- s.license = "MIT"
16
-
17
- s.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
18
- s.require_paths = ["lib"]
19
-
20
- s.add_dependency "activemodel", '>= 3.2.0'
21
- s.add_dependency "influxdb", "~> 0.3"
22
- s.add_dependency "anyway_config", "~> 1.0"
23
-
24
- s.add_development_dependency "timecop"
25
- s.add_development_dependency "simplecov", ">= 0.3.8"
26
- s.add_development_dependency 'rake', '~> 10.1'
27
- s.add_development_dependency 'sqlite3'
28
- s.add_development_dependency 'activerecord', '>= 3.2.0'
29
- s.add_development_dependency 'pry-byebug'
30
- s.add_development_dependency "rspec", ">= 3.1.0"
31
- s.add_development_dependency "webmock", "~> 2.1"
32
- s.add_development_dependency "rubocop", "~> 0.52"
33
- end
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe DummyMetrics do
6
- before do
7
- stub_request(:get, "http://localhost:8086/query")
8
- .with(
9
- query: { q: 'select * from "dummy"', u: "root", p: "root", precision: 'ns', db: 'db' }
10
- )
11
- .to_return(body: fixture_file)
12
- end
13
-
14
- context "single_series" do
15
- let(:fixture_file) { File.read('./spec/fixtures/single_series.json') }
16
-
17
- context "default format (values merged with tags)" do
18
- subject { described_class.all.to_a }
19
-
20
- it "returns array of hashes" do
21
- expect(subject.first).to include("host" => "server01", "region" => "us-west", "value" => 0.64)
22
- expect(subject.second).to include("host" => "server01", "region" => "us-west", "value" => 0.93)
23
- end
24
- end
25
- end
26
-
27
- context "empty result" do
28
- let(:fixture_file) { File.read('./spec/fixtures/empty_result.json') }
29
-
30
- subject { described_class.all.to_a }
31
-
32
- it "returns empty array" do
33
- expect(subject).to eq []
34
- end
35
- end
36
- end
@@ -1,85 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe "Write points" do
6
- before do
7
- stub_request(:post, /write/)
8
- .to_return(
9
- status: 204
10
- )
11
- end
12
-
13
- let(:metrics_class) do
14
- Class.new(Influxer::Metrics) do
15
- set_series :test
16
-
17
- tags :user_id
18
-
19
- attributes :val
20
- end
21
- end
22
-
23
- let(:point) { 'test,user_id=1 val="2"' }
24
-
25
- subject { metrics_class.write! user_id: 1, val: '2' }
26
-
27
- it "calls HTTP with correct params" do
28
- subject
29
- expect(
30
- a_request(:post, "http://localhost:8086/write")
31
- .with(
32
- query: { u: "root", p: "root", precision: 'ns', db: 'db' },
33
- body: point
34
- )
35
- ).to have_been_made
36
- end
37
-
38
- context "with retention policy" do
39
- it "calls HTTP with correct params" do
40
- metrics_class.set_retention_policy 'yearly'
41
-
42
- subject
43
-
44
- expect(
45
- a_request(:post, "http://localhost:8086/write")
46
- .with(
47
- query: { u: "root", p: "root", precision: 'ns', db: 'db', rp: 'yearly' },
48
- body: point
49
- )
50
- ).to have_been_made
51
- end
52
- end
53
-
54
- context "with custom db" do
55
- it "calls HTTP with correct params" do
56
- metrics_class.set_database 'another_db'
57
-
58
- subject
59
-
60
- expect(
61
- a_request(:post, "http://localhost:8086/write")
62
- .with(
63
- query: { u: "root", p: "root", precision: 'ns', db: 'another_db' },
64
- body: point
65
- )
66
- ).to have_been_made
67
- end
68
- end
69
-
70
- context "with custom db" do
71
- it "calls HTTP with correct params" do
72
- metrics_class.set_precision 'ms'
73
-
74
- subject
75
-
76
- expect(
77
- a_request(:post, "http://localhost:8086/write")
78
- .with(
79
- query: { u: "root", p: "root", precision: 'ms', db: 'db' },
80
- body: point
81
- )
82
- ).to have_been_made
83
- end
84
- end
85
- end
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe Influxer::Client do
6
- let(:conf) { Influxer.config }
7
- subject { Influxer.client }
8
-
9
- describe "#initialize" do
10
- it "sets config database value" do
11
- expect(subject.config.database).to eq conf.database
12
- end
13
-
14
- it "passes config params" do
15
- conf.username = 'admin'
16
- conf.port = 2222
17
- expect(subject.config.username).to eq 'admin'
18
- expect(subject.config.port).to eq 2222
19
- end
20
- end
21
-
22
- describe "cache", :query do
23
- let(:q) { "list series" }
24
- after { Rails.cache.clear }
25
-
26
- it "writes data to cache" do
27
- conf.cache = {}
28
-
29
- subject.query(q)
30
- expect(Rails.cache.exist?("influxer:listseries")).to be_truthy
31
- end
32
-
33
- it "should write data to cache with expiration" do
34
- conf.cache = { expires_in: 90 }
35
-
36
- subject.query(q)
37
- expect(Rails.cache.exist?("influxer:listseries")).to be_truthy
38
-
39
- Timecop.travel(1.minute.from_now)
40
- expect(Rails.cache.exist?("influxer:listseries")).to be_truthy
41
-
42
- Timecop.travel(2.minutes.from_now)
43
- expect(Rails.cache.exist?("influxer:listseries")).to be_falsey
44
- end
45
- end
46
- end
@@ -1,21 +0,0 @@
1
- {
2
- "results": [
3
- {
4
- "series": [
5
- {
6
- "name": "cpu_load_short",
7
- "tags": {
8
- "host": "server01",
9
- "region": "us-west"
10
- },
11
- "columns": [
12
- "time",
13
- "value"
14
- ],
15
- "values": [
16
- ]
17
- }
18
- ]
19
- }
20
- ]
21
- }
@@ -1,29 +0,0 @@
1
- {
2
- "results": [
3
- {
4
- "series": [
5
- {
6
- "name": "cpu_load_short",
7
- "tags": {
8
- "host": "server01",
9
- "region": "us-west"
10
- },
11
- "columns": [
12
- "time",
13
- "value"
14
- ],
15
- "values": [
16
- [
17
- "2015-01-29T21:51:28.968422294Z",
18
- 0.64
19
- ],
20
- [
21
- "2015-01-29T21:51:38.968422294Z",
22
- 0.93
23
- ]
24
- ]
25
- }
26
- ]
27
- }
28
- ]
29
- }
@@ -1,283 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe Influxer::Metrics, :query do
6
- let(:metrics) { described_class.new }
7
- let(:dummy_metrics) { DummyMetrics.new dummy_id: 1, user_id: 1 }
8
-
9
- subject { metrics }
10
-
11
- context "class methods" do
12
- subject { described_class }
13
-
14
- specify { is_expected.to respond_to :attributes }
15
- specify { is_expected.to respond_to :set_series }
16
- specify { is_expected.to respond_to :set_retention_policy }
17
- specify { is_expected.to respond_to :series }
18
- specify { is_expected.to respond_to :write }
19
- specify { is_expected.to respond_to :write! }
20
-
21
- specify { is_expected.to respond_to :all }
22
- specify { is_expected.to respond_to :where }
23
- specify { is_expected.to respond_to :offset }
24
- specify { is_expected.to respond_to :time }
25
- specify { is_expected.to respond_to :past }
26
- specify { is_expected.to respond_to :since }
27
- specify { is_expected.to respond_to :limit }
28
- specify { is_expected.to respond_to :select }
29
- specify { is_expected.to respond_to :delete_all }
30
- end
31
-
32
- context "instance methods" do
33
- specify { is_expected.to respond_to :write }
34
- specify { is_expected.to respond_to :write! }
35
- specify { is_expected.to respond_to :persisted? }
36
- specify { is_expected.to respond_to :series }
37
- if Influxer.active_model3?
38
- specify { is_expected.to be_a Influxer::ActiveModel3::Model }
39
- else
40
- specify { is_expected.to be_a ActiveModel::Model }
41
- end
42
- end
43
-
44
- describe "#initialize" do
45
- it "assigns initial values in constructor" do
46
- m = DummyMetrics.new(dummy_id: 1)
47
- expect(m.dummy_id).to eq 1
48
- end
49
- end
50
-
51
- describe "#write" do
52
- it "doesn't write if required attribute is missing" do
53
- m = DummyMetrics.new(dummy_id: 1)
54
- expect(client).not_to receive(:write_point)
55
- expect(m.write).to be false
56
- expect(m.errors.size).to eq(1)
57
- end
58
-
59
- it "raises error if required attribute is missing" do
60
- expect { DummyMetrics.new(user_id: 1).write! }.to raise_error(Influxer::MetricsInvalid)
61
- end
62
-
63
- it "raises error if you want to write twice" do
64
- expect(dummy_metrics.write).to be_truthy
65
- expect { dummy_metrics.write! }.to raise_error(Influxer::MetricsError)
66
- end
67
-
68
- it "writes successfully" do
69
- expect(client).to receive(:write_point).with("dummy", anything, nil, nil, nil)
70
- expect(dummy_metrics.write).to be_truthy
71
- expect(dummy_metrics.persisted?).to be_truthy
72
- end
73
-
74
- context "after_write callback" do
75
- it "sets current time" do
76
- Timecop.freeze(Time.local(2015))
77
- dummy_metrics.write!
78
- expect(dummy_metrics.timestamp).to eq Time.local(2015)
79
- end
80
- end
81
- end
82
-
83
- describe "#series" do
84
- let(:dummy_metrics) do
85
- Class.new(described_class) do
86
- set_series :dummies
87
- attributes :user_id, :dummy_id
88
- end
89
- end
90
-
91
- let(:dummy_metrics_2) do
92
- Class.new(described_class) do
93
- set_series "dummy \"A\""
94
- end
95
- end
96
-
97
- let(:dummy_metrics_3) do
98
- Class.new(described_class) do
99
- set_series /^.*$/
100
- end
101
- end
102
-
103
- let(:dummy_with_2_series) do
104
- Class.new(described_class) do
105
- set_series :events, :errors
106
- end
107
- end
108
-
109
- let(:dummy_with_2_series_quoted) do
110
- Class.new(described_class) do
111
- set_series "dummy \"A\"", "dummy \"B\""
112
- end
113
- end
114
-
115
- let(:dummy_with_proc_series) do
116
- Class.new(described_class) do
117
- attributes :user_id, :test_id
118
- set_series ->(metrics) { "test/#{metrics.test_id}/user/#{metrics.user_id}" }
119
- end
120
- end
121
-
122
- it "sets series name from class name by default" do
123
- expect(DummyMetrics.new.series).to eq "\"dummy\""
124
- end
125
-
126
- it "sets series from subclass" do
127
- expect(dummy_metrics.new.series).to eq "\"dummies\""
128
- end
129
-
130
- it "sets series as regexp" do
131
- expect(dummy_metrics_3.new.series).to eq '/^.*$/'
132
- end
133
-
134
- it "quotes series" do
135
- expect(dummy_metrics_2.new.series).to eq "\"dummy \\\"A\\\"\""
136
- end
137
-
138
- it "set several series" do
139
- expect(dummy_with_2_series.new.series).to eq "merge(\"events\",\"errors\")"
140
- end
141
-
142
- it "quotes several series" do
143
- expect(dummy_with_2_series_quoted.new.series)
144
- .to eq "merge(\"dummy \\\"A\\\"\",\"dummy \\\"B\\\"\")"
145
- end
146
-
147
- it "sets series from proc" do
148
- expect(dummy_with_proc_series.series).to be_an_instance_of Proc
149
-
150
- m = dummy_with_proc_series.new user_id: 2, test_id: 123
151
- expect(m.series).to eq "\"test/123/user/2\""
152
- end
153
- end
154
-
155
- describe "#quoted_series" do
156
- context "with retention policy" do
157
- let(:dummy_with_retention_policy) do
158
- Class.new(described_class) do
159
- attributes :user_id, :test_id
160
- set_series :dummies
161
- set_retention_policy :week
162
- end
163
- end
164
-
165
- it "sets retention policy" do
166
- expect(dummy_with_retention_policy.retention_policy).to eq :week
167
- end
168
-
169
- it "sets quoted series with retention policy" do
170
- expect(dummy_with_retention_policy.quoted_series).to eq "\"week\".\"dummies\""
171
- end
172
- end
173
- end
174
-
175
- describe ".tags" do
176
- let(:dummy1) { Class.new(DummyMetrics) }
177
- let!(:dummy2) do
178
- Class.new(dummy1) do
179
- tags :zone
180
- end
181
- end
182
-
183
- it "inherits tags" do
184
- expect(dummy2.tag_names).to include('dummy_id', 'host', 'zone')
185
- end
186
-
187
- it "clones tags" do
188
- dummy1.tags :status
189
- expect(dummy1.tag_names).to include('status')
190
- expect(dummy2.tag_names).not_to include('status')
191
- end
192
- end
193
-
194
- describe "#dup" do
195
- let(:point) { DummyMetrics.new(user_id: 1, dummy_id: 2) }
196
- subject { point.dup }
197
-
198
- specify { expect(subject.user_id).to eq 1 }
199
- specify { expect(subject.dummy_id).to eq 2 }
200
-
201
- context "dup is not persisted" do
202
- before { point.write }
203
- specify { expect(subject.persisted?).to be_falsey }
204
- end
205
- end
206
-
207
- describe ".write" do
208
- let(:dummy_metrics) do
209
- Class.new(described_class) do
210
- set_series :dummies
211
- tags :dummy_id, :host
212
- attributes :user_id
213
- end
214
- end
215
-
216
- it "write data and return point" do
217
- expect(client)
218
- .to receive(:write_point).with(
219
- "dummies",
220
- { tags: { dummy_id: 2, host: 'test' }, values: { user_id: 1 }, timestamp: nil },
221
- nil,
222
- nil,
223
- nil
224
- )
225
-
226
- point = dummy_metrics.write(user_id: 1, dummy_id: 2, host: 'test')
227
- expect(point.persisted?).to be_truthy
228
- expect(point.user_id).to eq 1
229
- expect(point.dummy_id).to eq 2
230
- end
231
-
232
- it "test write data with time and return point" do
233
- timestamp_test = Time.now
234
- expected_time = (timestamp_test.to_r * 1_000_000_000).to_i
235
-
236
- expect(client)
237
- .to receive(:write_point).with(
238
- "dummies",
239
- { tags: { dummy_id: 2, host: 'test' }, values: { user_id: 1 }, timestamp: expected_time },
240
- nil,
241
- nil,
242
- nil
243
- )
244
-
245
- point = dummy_metrics.write(user_id: 1, dummy_id: 2, host: 'test', timestamp: timestamp_test)
246
- expect(point.persisted?).to be_truthy
247
- expect(point.user_id).to eq 1
248
- expect(point.dummy_id).to eq 2
249
- expect(point.timestamp).to eq timestamp_test
250
- end
251
-
252
- it "test write data with string time" do
253
- base_time = Time.now
254
- timestamp_test = base_time.to_s
255
-
256
- expect(client)
257
- .to receive(:write_point).with(
258
- "dummies",
259
- { tags: { dummy_id: 2, host: 'test' }, values: { user_id: 1 }, timestamp: (base_time.to_i * 1_000_000_000).to_i },
260
- nil,
261
- nil,
262
- nil
263
- )
264
-
265
- point = dummy_metrics.write(user_id: 1, dummy_id: 2, host: 'test', timestamp: timestamp_test)
266
- expect(point.persisted?).to be_truthy
267
- expect(point.user_id).to eq 1
268
- expect(point.dummy_id).to eq 2
269
- expect(point.timestamp).to eq(timestamp_test)
270
- end
271
-
272
- it "doesn't write data and return false if invalid" do
273
- expect(client).not_to receive(:write_point)
274
- expect(DummyMetrics.write(dummy_id: 2)).to be false
275
- end
276
- end
277
-
278
- describe ".all" do
279
- it "responds with relation" do
280
- expect(described_class.all).to be_a Influxer::Relation
281
- end
282
- end
283
- end