influxdb-rails 0.4.999 → 1.0.0.beta1
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/.gitignore +1 -0
- data/.rubocop.yml +77 -0
- data/.travis.yml +21 -14
- data/CHANGELOG.md +27 -8
- data/README.md +14 -9
- data/Rakefile +7 -8
- data/gemfiles/Gemfile.rails-5.2.x +7 -0
- data/influxdb-rails.gemspec +26 -37
- data/lib/influxdb-rails.rb +94 -119
- data/lib/influxdb/rails/air_traffic_controller.rb +22 -20
- data/lib/influxdb/rails/backtrace.rb +5 -5
- data/lib/influxdb/rails/configuration.rb +78 -47
- data/lib/influxdb/rails/exception_presenter.rb +53 -42
- data/lib/influxdb/rails/instrumentation.rb +15 -15
- data/lib/influxdb/rails/logger.rb +7 -4
- data/lib/influxdb/rails/middleware/hijack_render_exception.rb +4 -19
- data/lib/influxdb/rails/middleware/hijack_rescue_action_everywhere.rb +11 -12
- data/lib/influxdb/rails/rack.rb +2 -2
- data/lib/influxdb/rails/railtie.rb +16 -30
- data/lib/influxdb/rails/version.rb +1 -1
- data/lib/rails/generators/influxdb/influxdb_generator.rb +5 -4
- data/spec/controllers/widgets_controller_spec.rb +2 -2
- data/spec/integration/exceptions_spec.rb +5 -9
- data/spec/integration/metrics_spec.rb +2 -4
- data/spec/spec_helper.rb +16 -13
- data/spec/support/rails4/app.rb +10 -5
- data/spec/support/rails5/app.rb +11 -5
- data/spec/unit/backtrace_spec.rb +2 -5
- data/spec/unit/configuration_spec.rb +19 -15
- data/spec/unit/exception_presenter_spec.rb +3 -3
- data/spec/unit/influxdb_rails_spec.rb +104 -56
- metadata +38 -39
- data/gemfiles/Gemfile.rails-4.0.x +0 -8
- data/gemfiles/Gemfile.rails-4.1.x +0 -7
@@ -1,30 +1,22 @@
|
|
1
1
|
module InfluxDB
|
2
2
|
module Rails
|
3
|
-
module AirTrafficController
|
4
|
-
def influxdb_request_data
|
5
|
-
unfiltered_params = params.to_hash
|
6
|
-
if respond_to?(:filter_parameters)
|
7
|
-
filtered_params = filter_parameters(unfiltered_params)
|
8
|
-
elsif defined? request.filtered_parameters
|
9
|
-
filtered_params = request.filtered_parameters
|
10
|
-
else
|
11
|
-
filtered_params = unfiltered_params.except(:password, :password_confirmation)
|
12
|
-
end
|
13
|
-
|
3
|
+
module AirTrafficController # :nodoc:
|
4
|
+
def influxdb_request_data # rubocop:disable Metrics/MethodLength
|
14
5
|
{
|
15
|
-
:
|
16
|
-
:
|
17
|
-
:
|
18
|
-
:
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:
|
22
|
-
:
|
23
|
-
:
|
6
|
+
params: influxdb_filtered_params,
|
7
|
+
session_data: influxdb_session_data,
|
8
|
+
controller: params[:controller],
|
9
|
+
action: params[:action],
|
10
|
+
request_url: influxdb_request_url,
|
11
|
+
user_agent: request.env["HTTP_USER_AGENT"],
|
12
|
+
remote_ip: request.remote_ip,
|
13
|
+
referer: request.referer,
|
14
|
+
current_user: (current_user rescue nil),
|
24
15
|
}
|
25
16
|
end
|
26
17
|
|
27
18
|
private
|
19
|
+
|
28
20
|
def influxdb_session_data
|
29
21
|
session.respond_to?(:to_hash) ? session.to_hash : session.data
|
30
22
|
end
|
@@ -34,6 +26,16 @@ module InfluxDB
|
|
34
26
|
url << ":#{request.port}" unless [80, 443].include?(request.port)
|
35
27
|
url << request.fullpath
|
36
28
|
end
|
29
|
+
|
30
|
+
def influxdb_filtered_params
|
31
|
+
if respond_to?(:filter_parameters)
|
32
|
+
filter_parameters(unfiltered_params)
|
33
|
+
elsif defined?(request.filtered_parameters)
|
34
|
+
request.filtered_parameters
|
35
|
+
else
|
36
|
+
params.to_hash.except(:password, :password_confirmation)
|
37
|
+
end
|
38
|
+
end
|
37
39
|
end
|
38
40
|
end
|
39
41
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module InfluxDB
|
2
2
|
module Rails
|
3
|
-
class Backtrace
|
4
|
-
class Line
|
5
|
-
FORMAT =
|
3
|
+
class Backtrace # rubocop:disable Style/Documentation
|
4
|
+
class Line # rubocop:disable Style/Documentation
|
5
|
+
FORMAT = /^((?:[a-zA-Z]:)?[^:]+):(\d+)(?::in `([^']+)')?$/.freeze
|
6
6
|
|
7
7
|
attr_reader :file
|
8
8
|
attr_reader :number
|
@@ -17,7 +17,7 @@ module InfluxDB
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def inspect
|
20
|
-
"<Line: #{to_s}>"
|
20
|
+
"<Line: #{to_s}>" # rubocop:disable Lint/StringConversionInInterpolation
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -37,7 +37,7 @@ module InfluxDB
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def inspect
|
40
|
-
"<Backtrace: " + lines.collect
|
40
|
+
"<Backtrace: " + lines.collect(&:to_s).join(", ") + ">"
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module InfluxDB
|
2
2
|
module Rails
|
3
|
-
|
3
|
+
# rubocop:disable Metrics/ClassLength
|
4
|
+
|
5
|
+
class Configuration # rubocop:disable Style/Documentation
|
4
6
|
attr_accessor :influxdb_hosts
|
5
7
|
attr_accessor :influxdb_port
|
6
8
|
attr_accessor :influxdb_username
|
@@ -17,9 +19,10 @@ module InfluxDB
|
|
17
19
|
attr_accessor :series_name_for_controller_runtimes
|
18
20
|
attr_accessor :series_name_for_view_runtimes
|
19
21
|
attr_accessor :series_name_for_db_runtimes
|
22
|
+
attr_accessor :series_name_for_exceptions
|
23
|
+
attr_accessor :series_name_for_instrumentation
|
20
24
|
|
21
|
-
attr_accessor :
|
22
|
-
deprecate :application_id => "This method serve no purpose and will be removed in the release after 0.1.12"
|
25
|
+
attr_accessor :rails_app_name
|
23
26
|
|
24
27
|
attr_accessor :application_name
|
25
28
|
attr_accessor :application_root
|
@@ -43,46 +46,51 @@ module InfluxDB
|
|
43
46
|
attr_accessor :instrumentation_enabled
|
44
47
|
attr_accessor :debug
|
45
48
|
|
46
|
-
attr_accessor :reraise_global_exceptions
|
47
|
-
deprecate :reraise_global_exceptions => "This method serves no purpose and will be removed in the release after 0.1.13"
|
48
|
-
|
49
|
-
|
50
49
|
DEFAULTS = {
|
51
|
-
:
|
52
|
-
:
|
53
|
-
:
|
54
|
-
:
|
55
|
-
:
|
56
|
-
:
|
57
|
-
:
|
58
|
-
:
|
59
|
-
:
|
60
|
-
:
|
61
|
-
:
|
62
|
-
:
|
63
|
-
|
64
|
-
:
|
65
|
-
:
|
66
|
-
:
|
67
|
-
|
68
|
-
:
|
69
|
-
|
70
|
-
:
|
71
|
-
|
72
|
-
:
|
73
|
-
|
74
|
-
|
50
|
+
influxdb_hosts: ["localhost"].freeze,
|
51
|
+
influxdb_port: 8086,
|
52
|
+
influxdb_username: "root".freeze,
|
53
|
+
influxdb_password: "root".freeze,
|
54
|
+
influxdb_database: nil,
|
55
|
+
async: true,
|
56
|
+
use_ssl: false,
|
57
|
+
retry: nil,
|
58
|
+
open_timeout: 5,
|
59
|
+
read_timeout: 300,
|
60
|
+
max_delay: 30,
|
61
|
+
time_precision: "s".freeze,
|
62
|
+
|
63
|
+
series_name_for_controller_runtimes: "rails.controller".freeze,
|
64
|
+
series_name_for_view_runtimes: "rails.view".freeze,
|
65
|
+
series_name_for_db_runtimes: "rails.db".freeze,
|
66
|
+
series_name_for_exceptions: "rails.exceptions".freeze,
|
67
|
+
series_name_for_instrumentation: "instrumentation".freeze,
|
68
|
+
|
69
|
+
rails_app_name: nil,
|
70
|
+
|
71
|
+
ignored_exceptions: %w[
|
72
|
+
ActiveRecord::RecordNotFound
|
73
|
+
ActionController::RoutingError
|
74
|
+
].freeze,
|
75
|
+
|
76
|
+
ignored_exception_messages: [].freeze,
|
77
|
+
ignored_reports: [].freeze,
|
78
|
+
ignored_environments: %w[test cucumber selenium].freeze,
|
79
|
+
ignored_user_agents: %w[GoogleBot].freeze,
|
80
|
+
environment_variable_filters: [
|
75
81
|
/password/i,
|
76
82
|
/key/i,
|
77
83
|
/secret/i,
|
78
84
|
/ps1/i,
|
79
85
|
/rvm_.*_clr/i,
|
80
|
-
/color/i
|
81
|
-
],
|
82
|
-
|
83
|
-
|
86
|
+
/color/i,
|
87
|
+
].freeze,
|
88
|
+
|
89
|
+
backtrace_filters: [
|
90
|
+
->(line) { line.gsub(%r{^\./}, "") },
|
84
91
|
lambda { |line|
|
85
92
|
return line if InfluxDB::Rails.configuration.application_root.to_s.empty?
|
93
|
+
|
86
94
|
line.gsub(/#{InfluxDB::Rails.configuration.application_root}/, "[APP_ROOT]")
|
87
95
|
},
|
88
96
|
lambda { |line|
|
@@ -90,9 +98,12 @@ module InfluxDB
|
|
90
98
|
Gem.path.each { |path| line = line.gsub(/#{path}/, "[GEM_ROOT]") }
|
91
99
|
end
|
92
100
|
line
|
93
|
-
}
|
94
|
-
]
|
95
|
-
}
|
101
|
+
},
|
102
|
+
].freeze,
|
103
|
+
}.freeze
|
104
|
+
|
105
|
+
# rubocop:disable Metrics/MethodLength
|
106
|
+
# rubocop:disable Metrics/AbcSize
|
96
107
|
|
97
108
|
def initialize
|
98
109
|
@influxdb_hosts = DEFAULTS[:influxdb_hosts]
|
@@ -111,6 +122,10 @@ module InfluxDB
|
|
111
122
|
@series_name_for_controller_runtimes = DEFAULTS[:series_name_for_controller_runtimes]
|
112
123
|
@series_name_for_view_runtimes = DEFAULTS[:series_name_for_view_runtimes]
|
113
124
|
@series_name_for_db_runtimes = DEFAULTS[:series_name_for_db_runtimes]
|
125
|
+
@series_name_for_exceptions = DEFAULTS[:series_name_for_exceptions]
|
126
|
+
@series_name_for_instrumentation = DEFAULTS[:series_name_for_instrumentation]
|
127
|
+
|
128
|
+
@rails_app_name = DEFAULTS[:rails_app_name]
|
114
129
|
|
115
130
|
@ignored_exceptions = DEFAULTS[:ignored_exceptions].dup
|
116
131
|
@ignored_exception_messages = DEFAULTS[:ignored_exception_messages].dup
|
@@ -126,21 +141,30 @@ module InfluxDB
|
|
126
141
|
@instrumentation_enabled = true
|
127
142
|
end
|
128
143
|
|
144
|
+
# rubocop:enable Metrics/MethodLength
|
145
|
+
# rubocop:enable Metrics/AbcSize
|
146
|
+
|
129
147
|
def debug?
|
130
|
-
!!@debug
|
148
|
+
!!@debug # rubocop:disable Style/DoubleNegation
|
131
149
|
end
|
132
150
|
|
133
151
|
def instrumentation_enabled?
|
134
|
-
!!@instrumentation_enabled
|
152
|
+
!!@instrumentation_enabled # rubocop:disable Style/DoubleNegation
|
135
153
|
end
|
136
154
|
|
137
155
|
def ignore_user_agent?(incoming_user_agent)
|
138
|
-
return false if
|
139
|
-
|
156
|
+
return false if ignored_user_agents.nil?
|
157
|
+
|
158
|
+
ignored_user_agents.any? { |agent| incoming_user_agent =~ /#{agent}/ }
|
140
159
|
end
|
141
160
|
|
142
161
|
def ignore_current_environment?
|
143
|
-
|
162
|
+
ignored_environments.include?(environment)
|
163
|
+
end
|
164
|
+
|
165
|
+
def ignore_exception?(ex)
|
166
|
+
!ignored_exception_messages.find { |msg| /.*#{msg}.*/ =~ ex.message }.nil? ||
|
167
|
+
ignored_exceptions.include?(ex.class.to_s)
|
144
168
|
end
|
145
169
|
|
146
170
|
def define_custom_exception_data(&block)
|
@@ -148,18 +172,25 @@ module InfluxDB
|
|
148
172
|
end
|
149
173
|
|
150
174
|
def add_custom_exception_data(exception_presenter)
|
151
|
-
@custom_exception_data_handler
|
175
|
+
@custom_exception_data_handler&.call(exception_presenter)
|
152
176
|
end
|
153
177
|
|
154
|
-
def
|
155
|
-
@
|
178
|
+
def load_rails_defaults
|
179
|
+
@logger ||= ::Rails.logger
|
180
|
+
@environment ||= ::Rails.env
|
181
|
+
@application_root ||= ::Rails.root
|
182
|
+
@application_name ||= ::Rails.application.class.parent_name
|
183
|
+
@framework = "Rails"
|
184
|
+
@framework_version = ::Rails.version
|
156
185
|
end
|
157
|
-
deprecate :database_name => "This method will be removed in the release after 0.1.12, you ought to use #influxdb_database"
|
158
186
|
|
159
187
|
private
|
188
|
+
|
160
189
|
def initialize_http_connection
|
161
190
|
Net::HTTP.new(@app_host, "80")
|
162
191
|
end
|
163
192
|
end
|
193
|
+
|
194
|
+
# rubocop:enable Metrics/ClassLength
|
164
195
|
end
|
165
196
|
end
|
@@ -4,7 +4,7 @@ require "json"
|
|
4
4
|
|
5
5
|
module InfluxDB
|
6
6
|
module Rails
|
7
|
-
class ExceptionPresenter
|
7
|
+
class ExceptionPresenter # rubocop:disable Style/Documentation
|
8
8
|
attr_reader :exception
|
9
9
|
attr_reader :backtrace
|
10
10
|
attr_reader :params
|
@@ -18,38 +18,27 @@ module InfluxDB
|
|
18
18
|
attr_reader :user_agent
|
19
19
|
attr_reader :custom_data
|
20
20
|
|
21
|
-
def initialize(
|
22
|
-
|
23
|
-
|
21
|
+
def initialize(ex, params = {})
|
22
|
+
ex = ex.continued_exception if ex.respond_to?(:continued_exception)
|
23
|
+
ex = ex.original_exception if ex.respond_to?(:original_exception)
|
24
|
+
|
25
|
+
@exception = ex.is_a?(String) ? Exception.new(ex) : ex
|
26
|
+
@backtrace = InfluxDB::Rails::Backtrace.new(@exception.backtrace)
|
27
|
+
@dimensions = {}
|
28
|
+
configure_from_params(params)
|
24
29
|
|
25
|
-
@exception = e.is_a?(String) ? Exception.new(e) : e
|
26
|
-
@backtrace = InfluxDB::Rails::Backtrace.new(@exception.backtrace)
|
27
|
-
@params = params[:params]
|
28
|
-
@session_data = params[:session_data] || {}
|
29
|
-
@current_user = params[:current_user]
|
30
|
-
@controller = params[:controller]
|
31
|
-
@action = params[:action]
|
32
|
-
@request_url = params[:request_url]
|
33
|
-
@user_agent = params[:user_agent]
|
34
|
-
@referer = params[:referer]
|
35
|
-
@remote_ip = params[:remote_ip]
|
36
|
-
@custom_data = params[:custom_data] || {}
|
37
30
|
@environment_variables = ENV.to_hash || {}
|
38
|
-
@dimensions = {}
|
39
31
|
end
|
40
32
|
|
41
|
-
def context
|
33
|
+
def context # rubocop:disable Metrics/MethodLength
|
42
34
|
c = {
|
43
|
-
:
|
44
|
-
:
|
45
|
-
:
|
46
|
-
:
|
47
|
-
:
|
48
|
-
:
|
49
|
-
:
|
50
|
-
:language => "Ruby",
|
51
|
-
:language_version => "#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}",
|
52
|
-
:custom_data => @custom_data
|
35
|
+
application_name: InfluxDB::Rails.configuration.application_name,
|
36
|
+
application_root: InfluxDB::Rails.configuration.application_root,
|
37
|
+
framework: InfluxDB::Rails.configuration.framework,
|
38
|
+
framework_version: InfluxDB::Rails.configuration.framework_version,
|
39
|
+
language: "Ruby",
|
40
|
+
language_version: "#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}",
|
41
|
+
custom_data: @custom_data,
|
53
42
|
}
|
54
43
|
|
55
44
|
InfluxDB::Rails.configuration.add_custom_exception_data(self)
|
@@ -57,27 +46,49 @@ module InfluxDB
|
|
57
46
|
end
|
58
47
|
|
59
48
|
def dimensions
|
60
|
-
|
61
|
-
:
|
62
|
-
:
|
63
|
-
:
|
64
|
-
:
|
65
|
-
:
|
49
|
+
{
|
50
|
+
class: @exception.class.to_s,
|
51
|
+
method: "#{@controller}##{@action}",
|
52
|
+
filename: File.basename(@backtrace.lines.first.try(:file)),
|
53
|
+
server: Socket.gethostname,
|
54
|
+
status: "open",
|
66
55
|
}.merge(@dimensions)
|
67
56
|
end
|
68
57
|
|
58
|
+
def values
|
59
|
+
{
|
60
|
+
exception_message: @exception.message,
|
61
|
+
exception_backtrace: JSON.generate(@backtrace.to_a),
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
69
65
|
def request_data
|
70
66
|
{
|
71
|
-
:
|
72
|
-
:
|
73
|
-
:
|
74
|
-
:
|
75
|
-
:
|
76
|
-
:
|
77
|
-
:
|
78
|
-
:
|
67
|
+
params: @params,
|
68
|
+
session_data: @session_data,
|
69
|
+
controller: @controller,
|
70
|
+
action: @action,
|
71
|
+
request_url: @request_url,
|
72
|
+
referer: @referer,
|
73
|
+
remote_ip: @remote_ip,
|
74
|
+
user_agent: @user_agent,
|
79
75
|
}
|
80
76
|
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def configure_from_params(params)
|
81
|
+
@params = params[:params]
|
82
|
+
@session_data = params[:session_data] || {}
|
83
|
+
@current_user = params[:current_user]
|
84
|
+
@controller = params[:controller]
|
85
|
+
@action = params[:action]
|
86
|
+
@request_url = params[:request_url]
|
87
|
+
@user_agent = params[:user_agent]
|
88
|
+
@referer = params[:referer]
|
89
|
+
@remote_ip = params[:remote_ip]
|
90
|
+
@custom_data = params[:custom_data] || {}
|
91
|
+
end
|
81
92
|
end
|
82
93
|
end
|
83
94
|
end
|
@@ -1,32 +1,32 @@
|
|
1
1
|
module InfluxDB
|
2
2
|
module Rails
|
3
|
-
module Instrumentation
|
4
|
-
def
|
3
|
+
module Instrumentation # rubocop:disable Style/Documentation
|
4
|
+
def benchmark_for_instrumentationn # rubocop:disable Metrics/MethodLength
|
5
5
|
start = Time.now
|
6
6
|
yield
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
},
|
8
|
+
c = InfluxDB::Rails.configuration
|
9
|
+
return if c.ignore_current_environment?
|
10
|
+
|
11
|
+
InfluxDB::Rails.client.write_point \
|
12
|
+
c.series_name_for_instrumentation,
|
13
|
+
values: {
|
14
|
+
value: ((Time.now - start) * 1000).ceil,
|
15
|
+
},
|
16
|
+
tags: {
|
17
|
+
method: "#{controller_name}##{action_name}",
|
18
|
+
server: Socket.gethostname,
|
18
19
|
}
|
19
|
-
end
|
20
20
|
end
|
21
21
|
|
22
22
|
def self.included(base)
|
23
23
|
base.extend(ClassMethods)
|
24
24
|
end
|
25
25
|
|
26
|
-
module ClassMethods
|
26
|
+
module ClassMethods # rubocop:disable Style/Documentation
|
27
27
|
def instrument(methods = [])
|
28
28
|
methods = [methods] unless methods.is_a?(Array)
|
29
|
-
around_filter :benchmark_for_instrumentation, :
|
29
|
+
around_filter :benchmark_for_instrumentation, only: methods
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|