influxdb-rails 1.0.0 → 1.0.1.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +11 -0
  3. data/.gitignore +1 -0
  4. data/.rubocop.yml +1 -1
  5. data/.travis.yml +4 -7
  6. data/CHANGELOG.md +17 -0
  7. data/README.md +47 -5
  8. data/Rakefile +0 -6
  9. data/gemfiles/Gemfile.rails-5.0.x +2 -0
  10. data/gemfiles/Gemfile.rails-6.0.x +10 -0
  11. data/influxdb-rails.gemspec +5 -3
  12. data/lib/influxdb-rails.rb +11 -0
  13. data/lib/influxdb/rails/configuration.rb +8 -12
  14. data/lib/influxdb/rails/context.rb +6 -40
  15. data/lib/influxdb/rails/helpers/rspec_matchers.rb +48 -0
  16. data/lib/influxdb/rails/metric.rb +39 -0
  17. data/lib/influxdb/rails/middleware/active_job_subscriber.rb +67 -0
  18. data/lib/influxdb/rails/middleware/active_record_subscriber.rb +26 -0
  19. data/lib/influxdb/rails/middleware/block_instrumentation_subscriber.rb +24 -0
  20. data/lib/influxdb/rails/middleware/render_subscriber.rb +15 -16
  21. data/lib/influxdb/rails/middleware/request_subscriber.rb +16 -21
  22. data/lib/influxdb/rails/middleware/sql_subscriber.rb +18 -18
  23. data/lib/influxdb/rails/middleware/subscriber.rb +40 -27
  24. data/lib/influxdb/rails/railtie.rb +15 -18
  25. data/lib/influxdb/rails/tags.rb +33 -0
  26. data/lib/influxdb/rails/test_client.rb +13 -0
  27. data/lib/influxdb/rails/values.rb +24 -0
  28. data/lib/influxdb/rails/version.rb +1 -1
  29. data/sample-dashboard/README.md +1 -1
  30. data/spec/requests/action_controller_metrics_spec.rb +83 -0
  31. data/spec/requests/action_view_collection_metrics_spec.rb +66 -0
  32. data/spec/requests/action_view_partial_metrics_spec.rb +62 -0
  33. data/spec/requests/action_view_template_metrics_spec.rb +62 -0
  34. data/spec/requests/active_job_enqueue_metrics_spec.rb +65 -0
  35. data/spec/requests/active_job_perform_metrics_spec.rb +68 -0
  36. data/spec/requests/active_job_perform_start_metrics_spec.rb +68 -0
  37. data/spec/requests/active_record_instantiation_metrics_spec.rb +65 -0
  38. data/spec/requests/active_record_sql_metrics_spec.rb +103 -0
  39. data/spec/requests/block_inistrumentation_spec.rb +64 -0
  40. data/spec/requests/context_spec.rb +27 -0
  41. data/spec/requests/logger_spec.rb +10 -0
  42. data/spec/spec_helper.rb +10 -4
  43. data/spec/support/broken_client.rb +11 -0
  44. data/spec/support/rails5/app.rb +32 -10
  45. data/spec/support/rails6/app.rb +70 -0
  46. data/spec/support/views/{widgets → metrics}/_item.html.erb +0 -0
  47. data/spec/support/views/{widgets → metrics}/index.html.erb +0 -0
  48. data/spec/support/views/metrics/show.html.erb +4 -0
  49. data/spec/unit/block_instrumentation_spec.rb +18 -0
  50. metadata +87 -37
  51. data/gemfiles/Gemfile.rails-4.2.x +0 -7
  52. data/lib/influxdb/rails/instrumentation.rb +0 -34
  53. data/lib/influxdb/rails/middleware/simple_subscriber.rb +0 -33
  54. data/spec/controllers/widgets_controller_spec.rb +0 -15
  55. data/spec/integration/integration_helper.rb +0 -1
  56. data/spec/integration/metrics_spec.rb +0 -27
  57. data/spec/shared_examples/data.rb +0 -61
  58. data/spec/support/rails4/app.rb +0 -48
  59. data/spec/unit/context_spec.rb +0 -40
  60. data/spec/unit/middleware/render_subscriber_spec.rb +0 -96
  61. data/spec/unit/middleware/request_subscriber_spec.rb +0 -103
  62. data/spec/unit/middleware/sql_subscriber_spec.rb +0 -108
@@ -1,61 +0,0 @@
1
- require "spec_helper"
2
-
3
- RSpec.shared_examples_for "with additional data" do
4
- context "values" do
5
- let(:additional_values) do
6
- { another: :value }
7
- end
8
-
9
- after do
10
- InfluxDB::Rails.current.reset
11
- end
12
-
13
- it "does include the tags" do
14
- InfluxDB::Rails.current.values = additional_values
15
-
16
- expect_any_instance_of(InfluxDB::Client).to receive(:write_point).with(config.measurement_name, hash_including(values: hash_including(another: :value)))
17
-
18
- subject.call("unused", start, finish, "unused", payload)
19
- end
20
- end
21
-
22
- context "tags" do
23
- context "when tags_middleware is overwritten" do
24
- before do
25
- allow(config).to receive(:tags_middleware).and_return(tags_middleware)
26
- end
27
-
28
- let(:tags_middleware) { ->(tags) { tags.merge(static: "value", nil: nil, empty: "") } }
29
-
30
- it "processes tags throught the middleware" do
31
- tags = data[:tags].merge(static: "value")
32
-
33
- expect_any_instance_of(InfluxDB::Client).to receive(:write_point).with(config.measurement_name, include(tags: tags))
34
-
35
- subject.call("unused", start, finish, "unused", payload)
36
- end
37
- end
38
-
39
- context "when tags are set in the current context" do
40
- let(:input) do
41
- { another: :value, nil: nil, empty: "" }
42
- end
43
- let(:output) do
44
- { another: :value }
45
- end
46
-
47
- after do
48
- InfluxDB::Rails.current.reset
49
- end
50
-
51
- it "does include the tags" do
52
- InfluxDB::Rails.current.tags = input
53
- tags = data[:tags].merge(output)
54
-
55
- expect_any_instance_of(InfluxDB::Client).to receive(:write_point).with(config.measurement_name, include(tags: tags))
56
-
57
- subject.call("unused", start, finish, "unused", payload)
58
- end
59
- end
60
- end
61
- end
@@ -1,48 +0,0 @@
1
- require "action_controller/railtie"
2
- require "active_record"
3
-
4
- app = Class.new(Rails::Application)
5
- app.config.secret_key_base = "1234567890abcdef1234567890abcdef"
6
- app.config.secret_token = "1234567890abcdef1234567890abcdef"
7
- app.config.session_store :cookie_store, key: "_myapp_session"
8
- app.config.active_support.deprecation = :log
9
- app.config.eager_load = false
10
- app.config.root = __dir__
11
- Rails.backtrace_cleaner.remove_silencers!
12
- app.initialize!
13
-
14
- app.routes.draw do
15
- resources :widgets
16
- end
17
-
18
- InfluxDB::Rails.configure do |config|
19
- end
20
-
21
- ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
22
- ActiveRecord::Schema.define do
23
- create_table :widgets, force: true do |t|
24
- t.string :title
25
-
26
- t.timestamps
27
- end
28
- end
29
-
30
- class Widget < ActiveRecord::Base; end
31
- class ApplicationController < ActionController::Base; end
32
- class WidgetsController < ApplicationController
33
- prepend_view_path File.join(__dir__, "..", "views")
34
-
35
- before_action do
36
- InfluxDB::Rails.current.values = { key: :value }
37
- end
38
-
39
- def index
40
- Widget.create!(title: "test")
41
- end
42
-
43
- def new
44
- 1 / 0
45
- end
46
- end
47
-
48
- Object.const_set(:ApplicationHelper, Module.new)
@@ -1,40 +0,0 @@
1
- require "spec_helper"
2
-
3
- RSpec.describe InfluxDB::Rails::Context do
4
- subject { described_class.new }
5
-
6
- describe "#controller" do
7
- it "does set and get" do
8
- subject.controller = "Controller"
9
- expect(subject.controller).to eq("Controller")
10
- end
11
- end
12
-
13
- describe "#action" do
14
- it "does get and set" do
15
- subject.action = "action"
16
- expect(subject.action).to eq("action")
17
- end
18
- end
19
-
20
- describe "#location" do
21
- before do
22
- subject.controller = "Controller"
23
- subject.action = "action"
24
- end
25
-
26
- it { expect(subject.location).to eq("Controller#action") }
27
- end
28
-
29
- describe "#reset" do
30
- before do
31
- subject.controller = "Controller"
32
- subject.action = "action"
33
- end
34
-
35
- it "does reset the location" do
36
- subject.reset
37
- expect(subject.location).to be_empty
38
- end
39
- end
40
- end
@@ -1,96 +0,0 @@
1
- require "spec_helper"
2
- require "shared_examples/data"
3
-
4
- RSpec.describe InfluxDB::Rails::Middleware::RenderSubscriber do
5
- let(:config) { InfluxDB::Rails::Configuration.new }
6
- let(:logger) { double(:logger) }
7
-
8
- before do
9
- allow(config).to receive(:application_name).and_return("my-rails-app")
10
- allow(config).to receive(:ignored_environments).and_return([])
11
- allow(config.client).to receive(:time_precision).and_return("ms")
12
- end
13
-
14
- describe ".call" do
15
- let(:start) { Time.at(1_517_567_368) }
16
- let(:finish) { Time.at(1_517_567_370) }
17
- let(:hook_name) { "render_partial.action_view" }
18
- let(:payload) { { identifier: "index.html", count: 43, cache_hits: 42 } }
19
- let(:data) do
20
- {
21
- values: {
22
- value: 2000,
23
- count: 43,
24
- cache_hits: 42
25
- },
26
- tags: {
27
- filename: "index.html",
28
- location: "Foo#bar",
29
- hook: "render_partial",
30
- },
31
- timestamp: 1_517_567_370_000
32
- }
33
- end
34
-
35
- subject { described_class.new(config, hook_name) }
36
-
37
- before do
38
- InfluxDB::Rails.current.controller = "Foo"
39
- InfluxDB::Rails.current.action = "bar"
40
- end
41
-
42
- after do
43
- InfluxDB::Rails.current.reset
44
- end
45
-
46
- context "successfully" do
47
- it "writes to InfluxDB" do
48
- expect_any_instance_of(InfluxDB::Client).to receive(:write_point).with(
49
- config.measurement_name, data
50
- )
51
- subject.call("name", start, finish, "id", payload)
52
- end
53
-
54
- it_behaves_like "with additional data"
55
-
56
- context "with an empty value" do
57
- before do
58
- payload[:count] = nil
59
- data[:values].delete(:count)
60
- end
61
-
62
- it "does not write empty value" do
63
- expect_any_instance_of(InfluxDB::Client).to receive(:write_point).with(
64
- config.measurement_name, data
65
- )
66
- subject.call("name", start, finish, "id", payload)
67
- end
68
- end
69
-
70
- context "disabled" do
71
- before do
72
- allow(config).to receive(:ignored_hooks).and_return(["render_partial.action_view"])
73
- end
74
-
75
- subject { described_class.new(config, nil) }
76
-
77
- it "does not write a data point" do
78
- expect_any_instance_of(InfluxDB::Client).not_to receive(:write_point)
79
- subject.call("name", start, finish, "id", payload)
80
- end
81
- end
82
- end
83
-
84
- context "unsuccessfully" do
85
- before do
86
- InfluxDB::Rails.configuration = config
87
- end
88
-
89
- it "does log exceptions" do
90
- allow_any_instance_of(InfluxDB::Client).to receive(:write_point).and_raise("boom")
91
- expect(::Rails.logger).to receive(:error).with(/boom/)
92
- subject.call("name", start, finish, "id", payload)
93
- end
94
- end
95
- end
96
- end
@@ -1,103 +0,0 @@
1
- require "spec_helper"
2
- require "shared_examples/data"
3
-
4
- RSpec.describe InfluxDB::Rails::Middleware::RequestSubscriber do
5
- let(:config) { InfluxDB::Rails::Configuration.new }
6
-
7
- before do
8
- allow(config.client).to receive(:time_precision).and_return("ms")
9
- allow(config).to receive(:environment).and_return("production")
10
- end
11
-
12
- subject { described_class.new(config, "process_action.action_controller") }
13
-
14
- describe "#call" do
15
- let(:start) { Time.at(1_517_567_368) }
16
- let(:finish) { Time.at(1_517_567_370) }
17
- let(:payload) { { view_runtime: 2, db_runtime: 2, controller: "MyController", action: "show", method: "GET", format: "*/*", status: 200 } }
18
- let(:data) do
19
- {
20
- values: {
21
- controller: 2,
22
- started: InfluxDB.convert_timestamp(start.utc, config.client.time_precision),
23
- },
24
- tags: {
25
- method: "MyController#show",
26
- hook: "process_action",
27
- status: 200,
28
- format: "*/*",
29
- http_method: "GET",
30
- server: Socket.gethostname,
31
- app_name: "my-rails-app",
32
- },
33
- timestamp: 1_517_567_370_000
34
- }
35
- end
36
-
37
- context "application_name is set" do
38
- before do
39
- allow(config).to receive(:application_name).and_return("my-rails-app")
40
- end
41
-
42
- it "sends metrics with taggings and timestamps" do
43
- expect_any_instance_of(InfluxDB::Client).to receive(:write_point).with(
44
- config.measurement_name, data.deep_merge(values: { controller: 2000, db: 2, view: 2 })
45
- )
46
-
47
- subject.call("unused", start, finish, "unused", payload)
48
- end
49
-
50
- it_behaves_like "with additional data", ["requests"]
51
- end
52
-
53
- context "application_name is nil" do
54
- let(:tags) do
55
- {
56
- method: "MyController#show",
57
- hook: "process_action",
58
- status: 200,
59
- format: "*/*",
60
- http_method: "GET",
61
- server: Socket.gethostname,
62
- }
63
- end
64
-
65
- before do
66
- allow(config).to receive(:application_name).and_return(nil)
67
- end
68
-
69
- it "does not add the app_name tag to metrics" do
70
- expect_any_instance_of(InfluxDB::Client).to receive(:write_point).with(
71
- config.measurement_name, data.merge(tags: tags).deep_merge(values: { controller: 2000, db: 2, view: 2 })
72
- )
73
-
74
- subject.call("unused", start, finish, "unused", payload)
75
- end
76
- end
77
-
78
- context "not successfull" do
79
- before do
80
- InfluxDB::Rails.configuration = config
81
- end
82
-
83
- it "does log an error" do
84
- allow_any_instance_of(InfluxDB::Client).to receive(:write_point).and_raise("boom")
85
- expect(::Rails.logger).to receive(:error).with(/boom/)
86
- subject.call("name", start, finish, "id", payload)
87
- end
88
- end
89
-
90
- context "disabled" do
91
- before do
92
- allow(config).to receive(:ignored_hooks).and_return(["process_action.action_controller"])
93
- end
94
-
95
- subject { described_class.new(config, "process_action.action_controller") }
96
-
97
- it "does not write a data point" do
98
- expect_any_instance_of(InfluxDB::Client).not_to receive(:write_point)
99
- subject.call("name", start, finish, "id", payload)
100
- end
101
- end
102
- end
103
- end
@@ -1,108 +0,0 @@
1
- require "spec_helper"
2
- require "shared_examples/data"
3
-
4
- RSpec.describe InfluxDB::Rails::Middleware::SqlSubscriber do
5
- let(:config) { InfluxDB::Rails::Configuration.new }
6
- let(:logger) { double(:logger) }
7
-
8
- before do
9
- allow(config).to receive(:application_name).and_return("my-rails-app")
10
- allow(config).to receive(:ignored_environments).and_return([])
11
- allow(config.client).to receive(:time_precision).and_return("ms")
12
- end
13
-
14
- describe ".call" do
15
- let(:start) { Time.at(1_517_567_368) }
16
- let(:finish) { Time.at(1_517_567_370) }
17
- let(:hook_name) { "sql.active_record" }
18
- let(:payload) { { sql: "SELECT * FROM POSTS WHERE id = 1", name: "Post Load", binds: %w[1 2 3] } }
19
- let(:data) do
20
- {
21
- values: {
22
- value: 2000,
23
- sql: "SELECT * FROM POSTS WHERE id = xxx"
24
- },
25
- tags: {
26
- location: "Foo#bar",
27
- operation: "SELECT",
28
- class_name: "Post",
29
- hook: "sql",
30
- name: "Post Load",
31
- },
32
- timestamp: 1_517_567_370_000
33
- }
34
- end
35
-
36
- subject { described_class.new(config, hook_name) }
37
-
38
- before do
39
- InfluxDB::Rails.current.controller = "Foo"
40
- InfluxDB::Rails.current.action = "bar"
41
- end
42
-
43
- after do
44
- InfluxDB::Rails.current.reset
45
- end
46
-
47
- context "successfully" do
48
- it "writes to InfluxDB" do
49
- expect_any_instance_of(InfluxDB::Client).to receive(:write_point).with(
50
- config.measurement_name, data
51
- )
52
- subject.call("name", start, finish, "id", payload)
53
- end
54
-
55
- context "with not relevant queries" do
56
- before do
57
- payload[:sql] = "SHOW FULL FIELDS FROM `users`"
58
- end
59
-
60
- it "does not write to InfluxDB" do
61
- expect_any_instance_of(InfluxDB::Client).not_to receive(:write_point)
62
- subject.call("name", start, finish, "id", payload)
63
- end
64
- end
65
-
66
- it_behaves_like "with additional data", ["sql"]
67
-
68
- context "without location" do
69
- before do
70
- InfluxDB::Rails.current.reset
71
- end
72
-
73
- it "does use the default location" do
74
- data[:tags] = data[:tags].merge(location: :raw)
75
- expect_any_instance_of(InfluxDB::Client).to receive(:write_point).with(
76
- config.measurement_name, data
77
- )
78
- subject.call("name", start, finish, "id", payload)
79
- end
80
- end
81
- end
82
-
83
- context "unsuccessfully" do
84
- before do
85
- InfluxDB::Rails.configuration = config
86
- end
87
-
88
- it "does log exceptions" do
89
- allow_any_instance_of(InfluxDB::Client).to receive(:write_point).and_raise("boom")
90
- expect(::Rails.logger).to receive(:error).with(/boom/)
91
- subject.call("name", start, finish, "id", payload)
92
- end
93
- end
94
-
95
- context "disabled" do
96
- before do
97
- allow(config).to receive(:ignored_hooks).and_return(["sql.active_record"])
98
- end
99
-
100
- subject { described_class.new(config, "sql.active_record") }
101
-
102
- it "does not write a data point" do
103
- expect_any_instance_of(InfluxDB::Client).not_to receive(:write_point)
104
- subject.call("name", start, finish, "id", payload)
105
- end
106
- end
107
- end
108
- end