influxdb-rails 1.0.0.beta3 → 1.0.0.beta4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|