influxdb-rails 1.0.0.beta3 → 1.0.0.beta4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +5 -0
- data/CHANGELOG.md +12 -10
- data/README.md +193 -168
- data/influxdb-rails.gemspec +13 -7
- data/lib/influxdb/rails/configuration.rb +88 -192
- data/lib/influxdb/rails/context.rb +19 -1
- data/lib/influxdb/rails/instrumentation.rb +4 -4
- data/lib/influxdb/rails/middleware/render_subscriber.rb +7 -0
- data/lib/influxdb/rails/middleware/request_subscriber.rb +22 -24
- data/lib/influxdb/rails/middleware/simple_subscriber.rb +12 -25
- data/lib/influxdb/rails/middleware/sql_subscriber.rb +7 -3
- data/lib/influxdb/rails/middleware/subscriber.rb +19 -8
- data/lib/influxdb/rails/railtie.rb +29 -32
- data/lib/influxdb/rails/version.rb +1 -1
- data/lib/influxdb-rails.rb +20 -81
- data/lib/rails/generators/influxdb/influxdb_generator.rb +1 -1
- data/lib/rails/generators/influxdb/templates/initializer.rb +39 -9
- data/sample-dashboard/Dockerfile +25 -0
- data/sample-dashboard/README.md +74 -0
- data/sample-dashboard/Rakefile +8 -0
- data/sample-dashboard/Ruby On Rails Performance (per Request).json +1053 -0
- data/sample-dashboard/Ruby On Rails Performance.json +2011 -0
- data/sample-dashboard/docker-compose.yml +33 -0
- data/sample-dashboard/provisioning/grafana-dashboards.yml +12 -0
- data/sample-dashboard/provisioning/grafana-datasource.yml +10 -0
- data/sample-dashboard/provisioning/performance-request.json +1053 -0
- data/sample-dashboard/provisioning/performance.json +2011 -0
- data/spec/integration/metrics_spec.rb +12 -13
- data/spec/shared_examples/data.rb +61 -0
- data/spec/spec_helper.rb +3 -1
- data/spec/support/rails4/app.rb +4 -0
- data/spec/support/rails5/app.rb +4 -0
- data/spec/unit/configuration_spec.rb +47 -65
- data/spec/unit/middleware/render_subscriber_spec.rb +13 -9
- data/spec/unit/middleware/request_subscriber_spec.rb +33 -21
- data/spec/unit/middleware/sql_subscriber_spec.rb +35 -8
- metadata +42 -30
- data/lib/influxdb/rails/air_traffic_controller.rb +0 -41
- data/lib/influxdb/rails/backtrace.rb +0 -44
- data/lib/influxdb/rails/exception_presenter.rb +0 -94
- data/lib/influxdb/rails/logger.rb +0 -16
- data/lib/influxdb/rails/middleware/hijack_render_exception.rb +0 -16
- data/lib/influxdb/rails/middleware/hijack_rescue_action_everywhere.rb +0 -31
- data/lib/influxdb/rails/rack.rb +0 -24
- data/spec/integration/exceptions_spec.rb +0 -37
- data/spec/shared_examples/tags.rb +0 -42
- data/spec/unit/backtrace_spec.rb +0 -85
- data/spec/unit/exception_presenter_spec.rb +0 -23
- data/spec/unit/influxdb_rails_spec.rb +0 -78
@@ -1,211 +1,107 @@
|
|
1
|
+
require "active_support/concern"
|
2
|
+
|
1
3
|
module InfluxDB
|
2
4
|
module Rails
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
attr_accessor :ignored_reports
|
44
|
-
attr_accessor :ignored_environments
|
45
|
-
attr_accessor :ignored_user_agents
|
46
|
-
attr_accessor :backtrace_filters
|
47
|
-
attr_accessor :aggregated_exception_classes
|
48
|
-
attr_accessor :environment_variables
|
49
|
-
attr_accessor :environment_variable_filters
|
50
|
-
|
51
|
-
attr_accessor :instrumentation_enabled
|
52
|
-
attr_accessor :debug
|
53
|
-
|
54
|
-
DEFAULTS = {
|
55
|
-
influxdb_hosts: ["localhost"].freeze,
|
56
|
-
influxdb_port: 8086,
|
57
|
-
influxdb_username: "root".freeze,
|
58
|
-
influxdb_password: "root".freeze,
|
59
|
-
influxdb_database: nil,
|
60
|
-
async: true,
|
61
|
-
use_ssl: false,
|
62
|
-
retry: nil,
|
63
|
-
open_timeout: 5,
|
64
|
-
read_timeout: 300,
|
65
|
-
max_delay: 30,
|
66
|
-
time_precision: "s".freeze,
|
67
|
-
|
68
|
-
series_name_for_controller_runtimes: "rails.controller".freeze,
|
69
|
-
series_name_for_view_runtimes: "rails.view".freeze,
|
70
|
-
series_name_for_db_runtimes: "rails.db".freeze,
|
71
|
-
series_name_for_exceptions: "rails.exceptions".freeze,
|
72
|
-
series_name_for_instrumentation: "instrumentation".freeze,
|
73
|
-
series_name_for_render_template: "rails.render_template".freeze,
|
74
|
-
series_name_for_render_partial: "rails.render_partial".freeze,
|
75
|
-
series_name_for_render_collection: "rails.render_collection".freeze,
|
76
|
-
series_name_for_sql: nil,
|
77
|
-
|
78
|
-
tags_middleware: ->(tags) { tags },
|
79
|
-
rails_app_name: nil,
|
80
|
-
|
81
|
-
ignored_exceptions: %w[
|
82
|
-
ActiveRecord::RecordNotFound
|
83
|
-
ActionController::RoutingError
|
84
|
-
].freeze,
|
85
|
-
|
86
|
-
ignored_exception_messages: [].freeze,
|
87
|
-
ignored_reports: [].freeze,
|
88
|
-
ignored_environments: %w[test cucumber selenium].freeze,
|
89
|
-
ignored_user_agents: %w[GoogleBot].freeze,
|
90
|
-
environment_variable_filters: [
|
91
|
-
/password/i,
|
92
|
-
/key/i,
|
93
|
-
/secret/i,
|
94
|
-
/ps1/i,
|
95
|
-
/rvm_.*_clr/i,
|
96
|
-
/color/i,
|
97
|
-
].freeze,
|
98
|
-
|
99
|
-
backtrace_filters: [
|
100
|
-
->(line) { line.gsub(%r{^\./}, "") },
|
101
|
-
lambda { |line|
|
102
|
-
return line if InfluxDB::Rails.configuration.application_root.to_s.empty?
|
103
|
-
|
104
|
-
line.gsub(/#{InfluxDB::Rails.configuration.application_root}/, "[APP_ROOT]")
|
105
|
-
},
|
106
|
-
lambda { |line|
|
107
|
-
if defined?(Gem) && !Gem.path.nil? && !Gem.path.empty?
|
108
|
-
Gem.path.each { |path| line = line.gsub(/#{path}/, "[GEM_ROOT]") }
|
109
|
-
end
|
110
|
-
line
|
111
|
-
},
|
112
|
-
].freeze,
|
113
|
-
}.freeze
|
114
|
-
|
115
|
-
# rubocop:disable Metrics/MethodLength
|
116
|
-
# rubocop:disable Metrics/AbcSize
|
5
|
+
module Configurable
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
class_methods do
|
9
|
+
def defaults
|
10
|
+
@defaults ||= {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def set_defaults(**values) # rubocop:disable Naming/AccessorMethodName:
|
14
|
+
defaults.merge! values
|
15
|
+
attr_accessor(*defaults.keys)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def load_defaults
|
20
|
+
self.class.defaults.each do |key, value|
|
21
|
+
val = value.dup rescue value
|
22
|
+
public_send "#{key}=", val
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
private_constant :Configurable
|
27
|
+
|
28
|
+
class ClientConfig
|
29
|
+
include Configurable
|
30
|
+
|
31
|
+
set_defaults(
|
32
|
+
hosts: ["localhost"].freeze,
|
33
|
+
port: 8086,
|
34
|
+
username: "root".freeze,
|
35
|
+
password: "root".freeze,
|
36
|
+
database: nil,
|
37
|
+
async: true,
|
38
|
+
use_ssl: false,
|
39
|
+
retry: nil,
|
40
|
+
open_timeout: 5,
|
41
|
+
read_timeout: 300,
|
42
|
+
max_delay: 30,
|
43
|
+
time_precision: "s".freeze
|
44
|
+
)
|
117
45
|
|
118
46
|
def initialize
|
119
|
-
|
120
|
-
@influxdb_port = DEFAULTS[:influxdb_port]
|
121
|
-
@influxdb_username = DEFAULTS[:influxdb_username]
|
122
|
-
@influxdb_password = DEFAULTS[:influxdb_password]
|
123
|
-
@influxdb_database = DEFAULTS[:influxdb_database]
|
124
|
-
@async = DEFAULTS[:async]
|
125
|
-
@use_ssl = DEFAULTS[:use_ssl]
|
126
|
-
@retry = DEFAULTS[:retry]
|
127
|
-
@open_timeout = DEFAULTS[:open_timeout]
|
128
|
-
@read_timeout = DEFAULTS[:read_timeout]
|
129
|
-
@max_delay = DEFAULTS[:max_delay]
|
130
|
-
@time_precision = DEFAULTS[:time_precision]
|
131
|
-
|
132
|
-
@series_name_for_controller_runtimes = DEFAULTS[:series_name_for_controller_runtimes]
|
133
|
-
@series_name_for_view_runtimes = DEFAULTS[:series_name_for_view_runtimes]
|
134
|
-
@series_name_for_db_runtimes = DEFAULTS[:series_name_for_db_runtimes]
|
135
|
-
@series_name_for_exceptions = DEFAULTS[:series_name_for_exceptions]
|
136
|
-
@series_name_for_instrumentation = DEFAULTS[:series_name_for_instrumentation]
|
137
|
-
@series_name_for_render_template = DEFAULTS[:series_name_for_render_template]
|
138
|
-
@series_name_for_render_partial = DEFAULTS[:series_name_for_render_partial]
|
139
|
-
@series_name_for_render_collection = DEFAULTS[:series_name_for_render_collection]
|
140
|
-
@series_name_for_sql = DEFAULTS[:series_name_for_sql]
|
141
|
-
|
142
|
-
@tags_middleware = DEFAULTS[:tags_middleware]
|
143
|
-
@rails_app_name = DEFAULTS[:rails_app_name]
|
144
|
-
|
145
|
-
@ignored_exceptions = DEFAULTS[:ignored_exceptions].dup
|
146
|
-
@ignored_exception_messages = DEFAULTS[:ignored_exception_messages].dup
|
147
|
-
@ignored_reports = DEFAULTS[:ignored_reports].dup
|
148
|
-
@ignored_environments = DEFAULTS[:ignored_environments].dup
|
149
|
-
@ignored_user_agents = DEFAULTS[:ignored_user_agents].dup
|
150
|
-
@backtrace_filters = DEFAULTS[:backtrace_filters].dup
|
151
|
-
@environment_variable_filters = DEFAULTS[:environment_variable_filters]
|
152
|
-
@aggregated_exception_classes = []
|
153
|
-
|
154
|
-
@debug = false
|
155
|
-
@rescue_global_exceptions = false
|
156
|
-
@instrumentation_enabled = true
|
47
|
+
load_defaults
|
157
48
|
end
|
49
|
+
end
|
50
|
+
private_constant :ClientConfig
|
51
|
+
|
52
|
+
class Configuration
|
53
|
+
include Configurable
|
54
|
+
|
55
|
+
set_defaults(
|
56
|
+
measurement_name: "rails".freeze,
|
57
|
+
ignored_hooks: [].freeze,
|
58
|
+
tags_middleware: ->(tags) { tags },
|
59
|
+
rails_app_name: nil,
|
60
|
+
ignored_environments: %w[test cucumber selenium].freeze,
|
61
|
+
environment: ::Rails.env,
|
62
|
+
debug: false,
|
63
|
+
instrumentation_enabled: true
|
64
|
+
)
|
65
|
+
|
66
|
+
# config option set after_initialize
|
67
|
+
attr_accessor(:environment, :application_name)
|
68
|
+
|
69
|
+
# configuration passed to InfluxDB::Client
|
70
|
+
attr_reader :client
|
71
|
+
|
72
|
+
# FIXME: Old configuration options, remove this in 1.0.1
|
73
|
+
attr_writer \
|
74
|
+
:series_name_for_controller_runtimes,
|
75
|
+
:series_name_for_view_runtimes,
|
76
|
+
:series_name_for_db_runtimes,
|
77
|
+
:series_name_for_render_template,
|
78
|
+
:series_name_for_render_partial,
|
79
|
+
:series_name_for_render_collection,
|
80
|
+
:series_name_for_sql,
|
81
|
+
:series_name_for_exceptions,
|
82
|
+
:series_name_for_instrumentation,
|
83
|
+
:ignored_exceptions,
|
84
|
+
:ignored_exception_messages,
|
85
|
+
:ignored_user_agents,
|
86
|
+
:environment_variable_filters,
|
87
|
+
:backtrace_filters
|
158
88
|
|
159
|
-
|
160
|
-
|
89
|
+
def initialize
|
90
|
+
@client = ClientConfig.new
|
91
|
+
load_defaults
|
92
|
+
end
|
161
93
|
|
162
94
|
def debug?
|
163
|
-
|
95
|
+
@debug
|
164
96
|
end
|
165
97
|
|
166
98
|
def instrumentation_enabled?
|
167
|
-
|
168
|
-
end
|
169
|
-
|
170
|
-
def ignore_user_agent?(incoming_user_agent)
|
171
|
-
return false if ignored_user_agents.nil?
|
172
|
-
|
173
|
-
ignored_user_agents.any? { |agent| incoming_user_agent =~ /#{agent}/ }
|
99
|
+
@instrumentation_enabled
|
174
100
|
end
|
175
101
|
|
176
102
|
def ignore_current_environment?
|
177
103
|
ignored_environments.include?(environment)
|
178
104
|
end
|
179
|
-
|
180
|
-
def ignore_exception?(ex)
|
181
|
-
!ignored_exception_messages.find { |msg| /.*#{msg}.*/ =~ ex.message }.nil? ||
|
182
|
-
ignored_exceptions.include?(ex.class.to_s)
|
183
|
-
end
|
184
|
-
|
185
|
-
def define_custom_exception_data(&block)
|
186
|
-
@custom_exception_data_handler = block
|
187
|
-
end
|
188
|
-
|
189
|
-
def add_custom_exception_data(exception_presenter)
|
190
|
-
@custom_exception_data_handler&.call(exception_presenter)
|
191
|
-
end
|
192
|
-
|
193
|
-
def load_rails_defaults
|
194
|
-
@logger ||= ::Rails.logger
|
195
|
-
@environment ||= ::Rails.env
|
196
|
-
@application_root ||= ::Rails.root
|
197
|
-
@application_name ||= ::Rails.application.class.parent_name
|
198
|
-
@framework = "Rails"
|
199
|
-
@framework_version = ::Rails.version
|
200
|
-
end
|
201
|
-
|
202
|
-
private
|
203
|
-
|
204
|
-
def initialize_http_connection
|
205
|
-
Net::HTTP.new(@app_host, "80")
|
206
|
-
end
|
207
105
|
end
|
208
|
-
|
209
|
-
# rubocop:enable Metrics/ClassLength
|
210
106
|
end
|
211
107
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module InfluxDB
|
2
2
|
module Rails
|
3
|
-
class Context
|
3
|
+
class Context
|
4
4
|
def controller
|
5
5
|
Thread.current[:_influxdb_rails_controller]
|
6
6
|
end
|
@@ -17,6 +17,14 @@ module InfluxDB
|
|
17
17
|
Thread.current[:_influxdb_rails_action] = value
|
18
18
|
end
|
19
19
|
|
20
|
+
def request_id=(value)
|
21
|
+
Thread.current[:_influxdb_rails_request_id] = value
|
22
|
+
end
|
23
|
+
|
24
|
+
def request_id
|
25
|
+
Thread.current[:_influxdb_rails_request_id]
|
26
|
+
end
|
27
|
+
|
20
28
|
def location
|
21
29
|
[
|
22
30
|
controller,
|
@@ -28,6 +36,8 @@ module InfluxDB
|
|
28
36
|
Thread.current[:_influxdb_rails_controller] = nil
|
29
37
|
Thread.current[:_influxdb_rails_action] = nil
|
30
38
|
Thread.current[:_influxdb_rails_tags] = nil
|
39
|
+
Thread.current[:_influxdb_rails_values] = nil
|
40
|
+
Thread.current[:_influxdb_rails_request_id] = nil
|
31
41
|
end
|
32
42
|
|
33
43
|
def tags
|
@@ -37,6 +47,14 @@ module InfluxDB
|
|
37
47
|
def tags=(tags)
|
38
48
|
Thread.current[:_influxdb_rails_tags] = tags
|
39
49
|
end
|
50
|
+
|
51
|
+
def values
|
52
|
+
Thread.current[:_influxdb_rails_values].to_h.merge(request_id: request_id)
|
53
|
+
end
|
54
|
+
|
55
|
+
def values=(values)
|
56
|
+
Thread.current[:_influxdb_rails_values] = values
|
57
|
+
end
|
40
58
|
end
|
41
59
|
end
|
42
60
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module InfluxDB
|
2
2
|
module Rails
|
3
|
-
module Instrumentation
|
3
|
+
module Instrumentation
|
4
4
|
def benchmark_for_instrumentation # rubocop:disable Metrics/MethodLength
|
5
5
|
start = Time.now
|
6
6
|
yield
|
@@ -9,11 +9,11 @@ module InfluxDB
|
|
9
9
|
return if c.ignore_current_environment?
|
10
10
|
|
11
11
|
InfluxDB::Rails.client.write_point \
|
12
|
-
|
12
|
+
"instrumentation".freeze,
|
13
13
|
values: {
|
14
14
|
value: ((Time.now - start) * 1000).ceil,
|
15
15
|
},
|
16
|
-
tags:
|
16
|
+
tags: c.tags_middleware.call(
|
17
17
|
method: "#{controller_name}##{action_name}",
|
18
18
|
server: Socket.gethostname
|
19
19
|
)
|
@@ -23,7 +23,7 @@ module InfluxDB
|
|
23
23
|
base.extend(ClassMethods)
|
24
24
|
end
|
25
25
|
|
26
|
-
module ClassMethods
|
26
|
+
module ClassMethods
|
27
27
|
def instrument(methods = [])
|
28
28
|
methods = [methods] unless methods.is_a?(Array)
|
29
29
|
around_filter :benchmark_for_instrumentation, only: methods
|
@@ -4,6 +4,12 @@ module InfluxDB
|
|
4
4
|
module Rails
|
5
5
|
module Middleware
|
6
6
|
class RenderSubscriber < SimpleSubscriber # :nodoc:
|
7
|
+
def short_hook_name
|
8
|
+
return "render_template" if hook_name.include?("render_template")
|
9
|
+
return "render_partial" if hook_name.include?("render_partial")
|
10
|
+
return "render_collection" if hook_name.include?("render_collection")
|
11
|
+
end
|
12
|
+
|
7
13
|
private
|
8
14
|
|
9
15
|
def values(started, finished, payload)
|
@@ -16,6 +22,7 @@ module InfluxDB
|
|
16
22
|
def tags(payload)
|
17
23
|
tags = {
|
18
24
|
location: location,
|
25
|
+
hook: short_hook_name,
|
19
26
|
filename: payload[:identifier],
|
20
27
|
}
|
21
28
|
super(tags)
|
@@ -4,39 +4,26 @@ module InfluxDB
|
|
4
4
|
module Rails
|
5
5
|
module Middleware
|
6
6
|
class RequestSubscriber < Subscriber # :nodoc:
|
7
|
-
def call(_name, start, finish, _id, payload)
|
7
|
+
def call(_name, start, finish, _id, payload)
|
8
8
|
return unless enabled?
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
20
|
-
rescue StandardError => e
|
21
|
-
log :error, "[InfluxDB::Rails] Unable to write points: #{e.message}"
|
22
|
-
ensure
|
23
|
-
InfluxDB::Rails.current.reset
|
24
|
-
end
|
10
|
+
InfluxDB::Rails.client.write_point \
|
11
|
+
configuration.measurement_name,
|
12
|
+
values: values(start, finish, payload),
|
13
|
+
tags: tags(payload),
|
14
|
+
timestamp: timestamp(finish)
|
15
|
+
rescue StandardError => e
|
16
|
+
::Rails.logger.error("[InfluxDB::Rails] Unable to write points: #{e.message}")
|
17
|
+
ensure
|
18
|
+
InfluxDB::Rails.current.reset
|
25
19
|
end
|
26
20
|
|
27
21
|
private
|
28
22
|
|
29
|
-
def series(payload, start, finish)
|
30
|
-
{
|
31
|
-
configuration.series_name_for_controller_runtimes => ((finish - start) * 1000).ceil,
|
32
|
-
configuration.series_name_for_view_runtimes => (payload[:view_runtime] || 0).ceil,
|
33
|
-
configuration.series_name_for_db_runtimes => (payload[:db_runtime] || 0).ceil,
|
34
|
-
}
|
35
|
-
end
|
36
|
-
|
37
23
|
def tags(payload)
|
38
24
|
tags = {
|
39
25
|
method: "#{payload[:controller]}##{payload[:action]}",
|
26
|
+
hook: "process_action",
|
40
27
|
status: payload[:status],
|
41
28
|
format: payload[:format],
|
42
29
|
http_method: payload[:method],
|
@@ -45,6 +32,17 @@ module InfluxDB
|
|
45
32
|
}
|
46
33
|
super(tags)
|
47
34
|
end
|
35
|
+
|
36
|
+
def values(started, finished, payload)
|
37
|
+
{
|
38
|
+
controller: ((finished - started) * 1000).ceil,
|
39
|
+
view: (payload[:view_runtime] || 0).ceil,
|
40
|
+
db: (payload[:db_runtime] || 0).ceil,
|
41
|
+
started: timestamp(started),
|
42
|
+
}.merge(InfluxDB::Rails.current.values).reject do |_, value|
|
43
|
+
value.nil? || value == ""
|
44
|
+
end
|
45
|
+
end
|
48
46
|
end
|
49
47
|
end
|
50
48
|
end
|
@@ -7,38 +7,25 @@ module InfluxDB
|
|
7
7
|
# which are intended as ActiveSupport::Notifications.subscribe
|
8
8
|
# consumers.
|
9
9
|
class SimpleSubscriber < Subscriber
|
10
|
-
|
11
|
-
|
12
|
-
def initialize(configuration, series_name)
|
13
|
-
super(configuration)
|
14
|
-
@series_name = series_name
|
15
|
-
end
|
16
|
-
|
17
|
-
def call(_name, started, finished, _unique_id, payload)
|
10
|
+
def call(_name, started, finished, _id, payload)
|
18
11
|
return unless enabled?
|
19
12
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
13
|
+
InfluxDB::Rails.client.write_point \
|
14
|
+
configuration.measurement_name,
|
15
|
+
values: values(started, finished, payload),
|
16
|
+
tags: tags(payload),
|
17
|
+
timestamp: timestamp(finished)
|
18
|
+
rescue StandardError => e
|
19
|
+
::Rails.logger.error("[InfluxDB::Rails] Unable to write points: #{e.message}")
|
28
20
|
end
|
29
21
|
|
30
22
|
private
|
31
23
|
|
32
24
|
def values(started, finished, _payload)
|
33
|
-
{ value: ((finished - started) * 1000).ceil }
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
InfluxDB.convert_timestamp(finished.utc, configuration.time_precision)
|
38
|
-
end
|
39
|
-
|
40
|
-
def enabled?
|
41
|
-
super && series_name.present?
|
25
|
+
result = { value: ((finished - started) * 1000).ceil }
|
26
|
+
result.merge(InfluxDB::Rails.current.values).reject do |_, value|
|
27
|
+
value.nil? || value == ""
|
28
|
+
end
|
42
29
|
end
|
43
30
|
end
|
44
31
|
end
|
@@ -6,9 +6,7 @@ module InfluxDB
|
|
6
6
|
module Middleware
|
7
7
|
class SqlSubscriber < SimpleSubscriber # :nodoc:
|
8
8
|
def call(_name, started, finished, _unique_id, payload)
|
9
|
-
|
10
|
-
|
11
|
-
super
|
9
|
+
super if InfluxDB::Rails::Sql::Query.new(payload).track?
|
12
10
|
end
|
13
11
|
|
14
12
|
private
|
@@ -17,10 +15,16 @@ module InfluxDB
|
|
17
15
|
super.merge(sql: InfluxDB::Rails::Sql::Normalizer.new(payload[:sql]).perform)
|
18
16
|
end
|
19
17
|
|
18
|
+
def location
|
19
|
+
result = super
|
20
|
+
result.empty? ? :raw : result
|
21
|
+
end
|
22
|
+
|
20
23
|
def tags(payload)
|
21
24
|
query = InfluxDB::Rails::Sql::Query.new(payload)
|
22
25
|
tags = {
|
23
26
|
location: location,
|
27
|
+
hook: "sql",
|
24
28
|
operation: query.operation,
|
25
29
|
class_name: query.class_name,
|
26
30
|
name: query.name,
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require "influxdb/rails/logger"
|
2
|
-
|
3
1
|
module InfluxDB
|
4
2
|
module Rails
|
5
3
|
module Middleware
|
@@ -7,12 +5,12 @@ module InfluxDB
|
|
7
5
|
# which are intended as ActiveSupport::Notifications.subscribe
|
8
6
|
# consumers.
|
9
7
|
class Subscriber
|
10
|
-
include InfluxDB::Rails::Logger
|
11
|
-
|
12
8
|
attr_reader :configuration
|
9
|
+
attr_reader :hook_name
|
13
10
|
|
14
|
-
def initialize(configuration)
|
11
|
+
def initialize(configuration, hook_name)
|
15
12
|
@configuration = configuration
|
13
|
+
@hook_name = hook_name
|
16
14
|
end
|
17
15
|
|
18
16
|
def call(*)
|
@@ -21,14 +19,27 @@ module InfluxDB
|
|
21
19
|
|
22
20
|
private
|
23
21
|
|
22
|
+
def timestamp(time)
|
23
|
+
InfluxDB.convert_timestamp(time.utc, client.time_precision)
|
24
|
+
end
|
25
|
+
|
26
|
+
def client
|
27
|
+
@client = configuration.client
|
28
|
+
end
|
29
|
+
|
24
30
|
def tags(tags)
|
25
|
-
|
26
|
-
configuration.tags_middleware.call(
|
31
|
+
result = tags.merge(InfluxDB::Rails.current.tags)
|
32
|
+
result = configuration.tags_middleware.call(result)
|
33
|
+
result.reject! do |_, value|
|
34
|
+
value.nil? || value == ""
|
35
|
+
end
|
36
|
+
result
|
27
37
|
end
|
28
38
|
|
29
39
|
def enabled?
|
30
40
|
configuration.instrumentation_enabled? &&
|
31
|
-
!configuration.ignore_current_environment?
|
41
|
+
!configuration.ignore_current_environment? &&
|
42
|
+
!configuration.ignored_hooks.include?(hook_name)
|
32
43
|
end
|
33
44
|
|
34
45
|
def location
|
@@ -4,47 +4,44 @@ require "rails"
|
|
4
4
|
module InfluxDB
|
5
5
|
module Rails
|
6
6
|
class Railtie < ::Rails::Railtie # :nodoc:
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
InfluxDB::Rails.configure(true, &:load_rails_defaults)
|
7
|
+
# rubocop:disable Metrics/BlockLength
|
8
|
+
config.after_initialize do
|
9
|
+
InfluxDB::Rails.configure do |config|
|
10
|
+
config.environment ||= ::Rails.env
|
11
|
+
end
|
13
12
|
|
14
13
|
ActiveSupport.on_load(:action_controller) do
|
15
|
-
require "influxdb/rails/air_traffic_controller"
|
16
|
-
include InfluxDB::Rails::AirTrafficController
|
17
14
|
require "influxdb/rails/instrumentation"
|
18
15
|
include InfluxDB::Rails::Instrumentation
|
19
|
-
end
|
20
16
|
|
21
|
-
|
22
|
-
::ActionDispatch::DebugExceptions.prepend InfluxDB::Rails::Middleware::HijackRenderException
|
23
|
-
|
24
|
-
if defined?(ActiveSupport::Notifications)
|
25
|
-
cache = lambda do |_, _, _, _, payload|
|
17
|
+
before_action do
|
26
18
|
current = InfluxDB::Rails.current
|
27
|
-
current.
|
28
|
-
current.action = payload[:action]
|
19
|
+
current.request_id = request.request_id if request.respond_to?(:request_id)
|
29
20
|
end
|
30
|
-
|
31
|
-
|
32
|
-
c = InfluxDB::Rails.configuration
|
33
|
-
requests = Middleware::RequestSubscriber.new(c)
|
34
|
-
ActiveSupport::Notifications.subscribe "process_action.action_controller", requests
|
35
|
-
|
36
|
-
templates = Middleware::RenderSubscriber.new(c, c.series_name_for_render_template)
|
37
|
-
ActiveSupport::Notifications.subscribe "render_template.action_view", templates
|
38
|
-
|
39
|
-
partials = Middleware::RenderSubscriber.new(c, c.series_name_for_render_partial)
|
40
|
-
ActiveSupport::Notifications.subscribe "render_partial.action_view", partials
|
41
|
-
|
42
|
-
collections = Middleware::RenderSubscriber.new(c, c.series_name_for_render_collection)
|
43
|
-
ActiveSupport::Notifications.subscribe "render_collection.action_view", collections
|
21
|
+
end
|
44
22
|
|
45
|
-
|
46
|
-
|
23
|
+
cache = lambda do |_, _, _, _, payload|
|
24
|
+
current = InfluxDB::Rails.current
|
25
|
+
current.controller = payload[:controller]
|
26
|
+
current.action = payload[:action]
|
47
27
|
end
|
28
|
+
ActiveSupport::Notifications.subscribe "start_processing.action_controller", &cache
|
29
|
+
|
30
|
+
{
|
31
|
+
"process_action.action_controller" => Middleware::RequestSubscriber,
|
32
|
+
"render_template.action_view" => Middleware::RenderSubscriber,
|
33
|
+
"render_partial.action_view" => Middleware::RenderSubscriber,
|
34
|
+
"render_collection.action_view" => Middleware::RenderSubscriber,
|
35
|
+
"sql.active_record" => Middleware::SqlSubscriber,
|
36
|
+
}.each do |hook_name, subscriber_class|
|
37
|
+
subscribe_to(hook_name, subscriber_class)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
# rubocop:enable Metrics/BlockLength
|
41
|
+
|
42
|
+
def subscribe_to(hook_name, subscriber_class)
|
43
|
+
subscriber = subscriber_class.new(InfluxDB::Rails.configuration, hook_name)
|
44
|
+
ActiveSupport::Notifications.subscribe hook_name, subscriber
|
48
45
|
end
|
49
46
|
end
|
50
47
|
end
|