influxdb-rails 1.0.0.beta1 → 1.0.0.beta2
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/.rspec +1 -0
- data/.rubocop.yml +1 -0
- data/.travis.yml +1 -1
- data/CHANGELOG.md +8 -0
- data/Gemfile +6 -0
- data/README.md +75 -9
- data/Rakefile +17 -18
- data/influxdb-rails.gemspec +4 -2
- data/lib/influxdb/rails/configuration.rb +15 -0
- data/lib/influxdb/rails/instrumentation.rb +4 -4
- data/lib/influxdb/rails/middleware/render_subscriber.rb +20 -0
- data/lib/influxdb/rails/middleware/request_subscriber.rb +51 -0
- data/lib/influxdb/rails/middleware/simple_subscriber.rb +46 -0
- data/lib/influxdb/rails/middleware/sql_subscriber.rb +32 -0
- data/lib/influxdb/rails/middleware/subscriber.rb +38 -0
- data/lib/influxdb/rails/railtie.rb +20 -12
- data/lib/influxdb/rails/sql/normalizer.rb +27 -0
- data/lib/influxdb/rails/sql/query.rb +30 -0
- data/lib/influxdb/rails/version.rb +1 -1
- data/lib/influxdb-rails.rb +9 -47
- data/spec/integration/metrics_spec.rb +17 -10
- data/spec/support/rails4/app.rb +16 -2
- data/spec/support/rails5/app.rb +15 -2
- data/spec/support/views/widgets/_item.html.erb +1 -0
- data/spec/support/views/widgets/index.html.erb +5 -0
- data/spec/unit/configuration_spec.rb +17 -0
- data/spec/unit/influxdb_rails_spec.rb +7 -93
- data/spec/unit/middleware/render_subscriber_spec.rb +90 -0
- data/spec/unit/middleware/request_subscriber_spec.rb +106 -0
- data/spec/unit/middleware/sql_subscriber_spec.rb +79 -0
- data/spec/unit/sql/normalizer_spec.rb +15 -0
- data/spec/unit/sql/query_spec.rb +28 -0
- metadata +63 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e7b5a411b14d5a465a1a4c503498d8c642de1c818213dfe3e437a1177eefa5d1
|
4
|
+
data.tar.gz: f50dc54acb96ac4e9b758aa5be109ffd40a1396b4e43844800fc670496c1d76c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 123a265d9418ff25a10b469cb798e9ed004af8a679fde861c40f81c5f96a20aea192576d10dfed877293afa6c59412cccb40d0b7fd14e52461aaa76c6712c092
|
7
|
+
data.tar.gz: 6189e83dfce1d8812c0ce8553f3095ee0be21608f71db0375edc1e6aab4cfaf646675d481ed53144056437b853df71a9e9085009fea936384a167bdac41d0433
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,14 @@
|
|
3
3
|
For the full commit log, [see here](https://github.com/influxdata/influxdb-rails/commits/master).
|
4
4
|
|
5
5
|
|
6
|
+
## v1.0.0.beta2, released 2018-12-07
|
7
|
+
|
8
|
+
- Added `tags_middleware` config option (#47, @ @Kukunin)
|
9
|
+
- Removed path tag from metrics (introduced with #50), because it
|
10
|
+
potentially produces "exceed tag value limit" (#54, @ChrisBr)
|
11
|
+
- Added render instrumentation (#53, @ChrisBr)
|
12
|
+
- Added SQL instrumentation (#55, @ChrisBr)
|
13
|
+
|
6
14
|
## v1.0.0.beta1, released 2018-11-22
|
7
15
|
|
8
16
|
- Added app name to the measurement's tag sets (#44, @stefanhorning)
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -11,9 +11,10 @@
|
|
11
11
|
Automatically instrument your Ruby on Rails applications and write the
|
12
12
|
metrics directly into [InfluxDB](http://influxdb.org/).
|
13
13
|
|
14
|
-
This gem is designed for Rails 4.
|
14
|
+
This gem is designed for Rails 4.2+, Ruby 2.3+ and InfluxDB 0.9+.
|
15
15
|
|
16
|
-
|
16
|
+
|
17
|
+
## Installation
|
17
18
|
|
18
19
|
```
|
19
20
|
$ [sudo] gem install influxdb-rails
|
@@ -21,6 +22,7 @@ $ [sudo] gem install influxdb-rails
|
|
21
22
|
|
22
23
|
Or add it to your `Gemfile`, etc.
|
23
24
|
|
25
|
+
|
24
26
|
## Usage
|
25
27
|
|
26
28
|
To get things set up, just create an initializer:
|
@@ -48,9 +50,15 @@ InfluxDB::Rails.configure do |config|
|
|
48
50
|
# config.max_delay = 300
|
49
51
|
# config.time_precision = 'ms'
|
50
52
|
|
53
|
+
# config.tags_middleware = ->(tags) { tags }
|
54
|
+
|
51
55
|
# config.series_name_for_controller_runtimes = "rails.controller"
|
52
56
|
# config.series_name_for_view_runtimes = "rails.view"
|
53
57
|
# config.series_name_for_db_runtimes = "rails.db"
|
58
|
+
# config.series_name_for_render_template = "rails.render_template"
|
59
|
+
# config.series_name_for_render_partial = "rails.render_partial"
|
60
|
+
# config.series_name_for_render_collection = "rails.render_collection"
|
61
|
+
# config.series_name_for_sql = nil
|
54
62
|
# config.series_name_for_exceptions = "rails.exceptions"
|
55
63
|
# config.series_name_for_instrumentation = "instrumentation"
|
56
64
|
|
@@ -64,8 +72,21 @@ To see all default values, take a look into `InfluxDB::Rails::Configuration::DEF
|
|
64
72
|
defined in `lib/influxdb/rails/configuration.rb`
|
65
73
|
|
66
74
|
Out of the box, you'll automatically get reporting of your controller,
|
67
|
-
view, and db runtimes
|
68
|
-
|
75
|
+
view, and db runtimes and rendering of template, partial and collection for each request.
|
76
|
+
Reporting of SQL queries is disabled by default because it is still in experimental mode
|
77
|
+
and currently requires String parsing which might cause performance issues on query
|
78
|
+
intensive applications. You can enable it by setting the `series_name_for_sql`
|
79
|
+
configuration.
|
80
|
+
|
81
|
+
It is possible to disable the rendering series by setting the series_name to nil.
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
# config.series_name_for_render_template = nil
|
85
|
+
# config.series_name_for_render_partial = nil
|
86
|
+
# config.series_name_for_render_collection = nil
|
87
|
+
```
|
88
|
+
|
89
|
+
You can also call through to the underlying `InfluxDB::Client` object to write arbitrary data like this:
|
69
90
|
|
70
91
|
``` ruby
|
71
92
|
InfluxDB::Rails.client.write_point "events",
|
@@ -76,6 +97,53 @@ InfluxDB::Rails.client.write_point "events",
|
|
76
97
|
Additional documentation for `InfluxDB::Client` lives in the
|
77
98
|
[influxdb-ruby](http://github.com/influxdata/influxdb-ruby) repo.
|
78
99
|
|
100
|
+
|
101
|
+
### Tags
|
102
|
+
|
103
|
+
You can modify the tags sent to InfluxDB by defining a middleware, which
|
104
|
+
receives the current tag set (`Hash` with `Symbol` keys and `String`
|
105
|
+
values) as argument and returns a hash in the same form. The middleware
|
106
|
+
can be any object, as long it responds to `#call` (like a `Proc`):
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
InfluxDB::Rails.configure do |config|
|
110
|
+
config.tags_middleware = lambda do |tags|
|
111
|
+
tags.merge(env: Rails.env)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
```
|
115
|
+
|
116
|
+
By default, the following tags are sent for *non-exception series*
|
117
|
+
(`rails.controller`, `rails.view`, `rails.db` and `instrumentation`):
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
{
|
121
|
+
method: "#{payload[:controller]}##{payload[:action]}",
|
122
|
+
server: Socket.gethostname,
|
123
|
+
app_name: configuration.application_name,
|
124
|
+
}
|
125
|
+
```
|
126
|
+
|
127
|
+
and for the exceptions (series name `rails.exceptions`):
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
{
|
131
|
+
application_name: InfluxDB::Rails.configuration.application_name,
|
132
|
+
application_root: InfluxDB::Rails.configuration.application_root,
|
133
|
+
framework: InfluxDB::Rails.configuration.framework,
|
134
|
+
framework_version: InfluxDB::Rails.configuration.framework_version,
|
135
|
+
language: "Ruby",
|
136
|
+
language_version: "#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}",
|
137
|
+
custom_data: @custom_data,
|
138
|
+
class: @exception.class.to_s,
|
139
|
+
method: "#{@controller}##{@action}",
|
140
|
+
filename: File.basename(@backtrace.lines.first.try(:file)),
|
141
|
+
server: Socket.gethostname,
|
142
|
+
status: "open",
|
143
|
+
}
|
144
|
+
```
|
145
|
+
|
146
|
+
|
79
147
|
## Frequently Asked Questions
|
80
148
|
|
81
149
|
|
@@ -157,6 +225,7 @@ bundle
|
|
157
225
|
bundle exec rake
|
158
226
|
```
|
159
227
|
|
228
|
+
|
160
229
|
## Contributing
|
161
230
|
|
162
231
|
- Fork this repository on GitHub.
|
@@ -165,11 +234,8 @@ bundle exec rake
|
|
165
234
|
- Add an entry in the `CHANGELOG.md` in the "unreleased" section on top.
|
166
235
|
- Run the tests:
|
167
236
|
- Either run them manually:
|
168
|
-
```
|
169
|
-
|
170
|
-
BUNDLE_GEMFILE=$gemfile bundle install --quiet; \
|
171
|
-
BUNDLE_GEMFILE=$gemfile bundle exec rspec; \
|
172
|
-
done
|
237
|
+
```console
|
238
|
+
$ rake test:all
|
173
239
|
```
|
174
240
|
- or wait for [Travis][travis-pr] to pick up your changes, *after*
|
175
241
|
you made a pull request.
|
data/Rakefile
CHANGED
@@ -2,28 +2,27 @@ require "bundler/gem_tasks"
|
|
2
2
|
require "rubocop/rake_task"
|
3
3
|
RuboCop::RakeTask.new
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
file_pattern = targeted_files.empty? ? "spec/**/*_spec.rb" : targeted_files
|
5
|
+
targeted_files = ARGV.drop(1)
|
6
|
+
file_pattern = targeted_files.empty? ? "spec/**/*_spec.rb" : targeted_files
|
8
7
|
|
9
|
-
|
10
|
-
|
8
|
+
require "rspec/core"
|
9
|
+
require "rspec/core/rake_task"
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
12
|
+
t.pattern = FileList[file_pattern]
|
13
|
+
end
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
rescue LoadError
|
21
|
-
require "spec/rake/spectask"
|
15
|
+
RSpec.configure do |config|
|
16
|
+
config.color = true
|
17
|
+
config.formatter = :documentation
|
18
|
+
end
|
22
19
|
|
23
|
-
|
20
|
+
task default: %i[spec rubocop]
|
24
21
|
|
25
|
-
|
26
|
-
|
27
|
-
|
22
|
+
task "test:all" => :default do
|
23
|
+
Dir.glob("gemfiles/Gemfile.rails-*.x") do |gemfile|
|
24
|
+
puts RSpec::Core::Formatters::ConsoleCodes.wrap(gemfile, :cyan)
|
25
|
+
sh({ "BUNDLE_GEMFILE" => gemfile }, "bundle", "install", "--quiet", "--retry=2", "--jobs=2")
|
26
|
+
sh({ "BUNDLE_GEMFILE" => gemfile }, "bundle", "exec", "rspec")
|
28
27
|
end
|
29
28
|
end
|
data/influxdb-rails.gemspec
CHANGED
@@ -19,9 +19,10 @@ Gem::Specification.new do |spec|
|
|
19
19
|
|
20
20
|
spec.required_ruby_version = ">= 2.3.0"
|
21
21
|
|
22
|
-
spec.add_runtime_dependency "influxdb", "~> 0.
|
23
|
-
spec.add_runtime_dependency "railties", "
|
22
|
+
spec.add_runtime_dependency "influxdb", "~> 0.6", ">= 0.6.4"
|
23
|
+
spec.add_runtime_dependency "railties", ">= 4.2"
|
24
24
|
|
25
|
+
spec.add_development_dependency "activerecord"
|
25
26
|
spec.add_development_dependency "bundler", ">= 1.0.0"
|
26
27
|
spec.add_development_dependency "fakeweb"
|
27
28
|
spec.add_development_dependency "rake"
|
@@ -29,5 +30,6 @@ Gem::Specification.new do |spec|
|
|
29
30
|
spec.add_development_dependency "rspec"
|
30
31
|
spec.add_development_dependency "rspec-rails", ">= 3.0.0"
|
31
32
|
spec.add_development_dependency "rubocop", "~> 0.60.0"
|
33
|
+
spec.add_development_dependency "sqlite3"
|
32
34
|
spec.add_development_dependency "tzinfo"
|
33
35
|
end
|
@@ -21,7 +21,12 @@ module InfluxDB
|
|
21
21
|
attr_accessor :series_name_for_db_runtimes
|
22
22
|
attr_accessor :series_name_for_exceptions
|
23
23
|
attr_accessor :series_name_for_instrumentation
|
24
|
+
attr_accessor :series_name_for_render_template
|
25
|
+
attr_accessor :series_name_for_render_partial
|
26
|
+
attr_accessor :series_name_for_render_collection
|
27
|
+
attr_accessor :series_name_for_sql
|
24
28
|
|
29
|
+
attr_accessor :tags_middleware
|
25
30
|
attr_accessor :rails_app_name
|
26
31
|
|
27
32
|
attr_accessor :application_name
|
@@ -65,7 +70,12 @@ module InfluxDB
|
|
65
70
|
series_name_for_db_runtimes: "rails.db".freeze,
|
66
71
|
series_name_for_exceptions: "rails.exceptions".freeze,
|
67
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,
|
68
77
|
|
78
|
+
tags_middleware: ->(tags) { tags },
|
69
79
|
rails_app_name: nil,
|
70
80
|
|
71
81
|
ignored_exceptions: %w[
|
@@ -124,7 +134,12 @@ module InfluxDB
|
|
124
134
|
@series_name_for_db_runtimes = DEFAULTS[:series_name_for_db_runtimes]
|
125
135
|
@series_name_for_exceptions = DEFAULTS[:series_name_for_exceptions]
|
126
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]
|
127
141
|
|
142
|
+
@tags_middleware = DEFAULTS[:tags_middleware]
|
128
143
|
@rails_app_name = DEFAULTS[:rails_app_name]
|
129
144
|
|
130
145
|
@ignored_exceptions = DEFAULTS[:ignored_exceptions].dup
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module InfluxDB
|
2
2
|
module Rails
|
3
3
|
module Instrumentation # rubocop:disable Style/Documentation
|
4
|
-
def
|
4
|
+
def benchmark_for_instrumentation # rubocop:disable Metrics/MethodLength
|
5
5
|
start = Time.now
|
6
6
|
yield
|
7
7
|
|
@@ -13,10 +13,10 @@ module InfluxDB
|
|
13
13
|
values: {
|
14
14
|
value: ((Time.now - start) * 1000).ceil,
|
15
15
|
},
|
16
|
-
tags:
|
16
|
+
tags: configuration.tags_middleware.call(
|
17
17
|
method: "#{controller_name}##{action_name}",
|
18
|
-
server: Socket.gethostname
|
19
|
-
|
18
|
+
server: Socket.gethostname
|
19
|
+
)
|
20
20
|
end
|
21
21
|
|
22
22
|
def self.included(base)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "influxdb/rails/middleware/simple_subscriber"
|
2
|
+
|
3
|
+
module InfluxDB
|
4
|
+
module Rails
|
5
|
+
module Middleware
|
6
|
+
class RenderSubscriber < SimpleSubscriber # :nodoc:
|
7
|
+
private
|
8
|
+
|
9
|
+
def tags(payload)
|
10
|
+
{
|
11
|
+
location: location,
|
12
|
+
filename: payload[:identifier],
|
13
|
+
count: payload[:count],
|
14
|
+
cache_hits: payload[:cache_hits],
|
15
|
+
}.reject { |_, value| value.blank? }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require "influxdb/rails/middleware/subscriber"
|
2
|
+
|
3
|
+
module InfluxDB
|
4
|
+
module Rails
|
5
|
+
module Middleware
|
6
|
+
class RequestSubscriber < Subscriber # :nodoc:
|
7
|
+
def call(_name, start, finish, _id, payload) # rubocop:disable Metrics/MethodLength
|
8
|
+
return unless enabled?
|
9
|
+
|
10
|
+
ts = InfluxDB.convert_timestamp(finish.utc, configuration.time_precision)
|
11
|
+
tags = tags(payload)
|
12
|
+
begin
|
13
|
+
series(payload, start, finish).each do |series_name, value|
|
14
|
+
InfluxDB::Rails.client.write_point \
|
15
|
+
series_name,
|
16
|
+
values: { value: value },
|
17
|
+
tags: tags,
|
18
|
+
timestamp: ts
|
19
|
+
end
|
20
|
+
rescue StandardError => e
|
21
|
+
log :error, "[InfluxDB::Rails] Unable to write points: #{e.message}"
|
22
|
+
ensure
|
23
|
+
Thread.current[:_influxdb_rails_controller] = nil
|
24
|
+
Thread.current[:_influxdb_rails_action] = nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def series(payload, start, finish)
|
31
|
+
{
|
32
|
+
configuration.series_name_for_controller_runtimes => ((finish - start) * 1000).ceil,
|
33
|
+
configuration.series_name_for_view_runtimes => (payload[:view_runtime] || 0).ceil,
|
34
|
+
configuration.series_name_for_db_runtimes => (payload[:db_runtime] || 0).ceil,
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def tags(payload)
|
39
|
+
configuration.tags_middleware.call({
|
40
|
+
method: "#{payload[:controller]}##{payload[:action]}",
|
41
|
+
status: payload[:status],
|
42
|
+
format: payload[:format],
|
43
|
+
http_method: payload[:method],
|
44
|
+
server: Socket.gethostname,
|
45
|
+
app_name: configuration.application_name,
|
46
|
+
}.reject { |_, value| value.nil? })
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require "influxdb/rails/middleware/subscriber"
|
2
|
+
|
3
|
+
module InfluxDB
|
4
|
+
module Rails
|
5
|
+
module Middleware
|
6
|
+
# Subscriber acts as base class for different *Subscriber classes,
|
7
|
+
# which are intended as ActiveSupport::Notifications.subscribe
|
8
|
+
# consumers.
|
9
|
+
class SimpleSubscriber < Subscriber
|
10
|
+
attr_reader :series_name
|
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)
|
18
|
+
return unless enabled?
|
19
|
+
|
20
|
+
begin
|
21
|
+
InfluxDB::Rails.client.write_point series_name,
|
22
|
+
values: values(started, finished, payload),
|
23
|
+
tags: tags(payload),
|
24
|
+
timestamp: timestamp(finished.utc)
|
25
|
+
rescue StandardError => e
|
26
|
+
log :error, "[InfluxDB::Rails] Unable to write points: #{e.message}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def values(started, finished, _payload)
|
33
|
+
{ value: ((finished - started) * 1000).ceil }
|
34
|
+
end
|
35
|
+
|
36
|
+
def timestamp(finished)
|
37
|
+
InfluxDB.convert_timestamp(finished.utc, configuration.time_precision)
|
38
|
+
end
|
39
|
+
|
40
|
+
def enabled?
|
41
|
+
super && series_name.present?
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "influxdb/rails/middleware/simple_subscriber"
|
2
|
+
require "influxdb/rails/sql/query"
|
3
|
+
|
4
|
+
module InfluxDB
|
5
|
+
module Rails
|
6
|
+
module Middleware
|
7
|
+
class SqlSubscriber < SimpleSubscriber # :nodoc:
|
8
|
+
def call(_name, started, finished, _unique_id, payload)
|
9
|
+
return unless InfluxDB::Rails::Sql::Query.new(payload).track?
|
10
|
+
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def values(started, finished, payload)
|
17
|
+
super.merge(sql: InfluxDB::Rails::Sql::Normalizer.new(payload[:sql]).perform)
|
18
|
+
end
|
19
|
+
|
20
|
+
def tags(payload)
|
21
|
+
query = InfluxDB::Rails::Sql::Query.new(payload)
|
22
|
+
{
|
23
|
+
location: location,
|
24
|
+
operation: query.operation,
|
25
|
+
class_name: query.class_name,
|
26
|
+
name: query.name,
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "influxdb/rails/logger"
|
2
|
+
|
3
|
+
module InfluxDB
|
4
|
+
module Rails
|
5
|
+
module Middleware
|
6
|
+
# Subscriber acts as base class for different *Subscriber classes,
|
7
|
+
# which are intended as ActiveSupport::Notifications.subscribe
|
8
|
+
# consumers.
|
9
|
+
class Subscriber
|
10
|
+
include InfluxDB::Rails::Logger
|
11
|
+
|
12
|
+
attr_reader :configuration
|
13
|
+
|
14
|
+
def initialize(configuration)
|
15
|
+
@configuration = configuration
|
16
|
+
end
|
17
|
+
|
18
|
+
def call(*)
|
19
|
+
raise NotImplementedError, "must be implemented in subclass"
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def enabled?
|
25
|
+
configuration.instrumentation_enabled? &&
|
26
|
+
!configuration.ignore_current_environment?
|
27
|
+
end
|
28
|
+
|
29
|
+
def location
|
30
|
+
[
|
31
|
+
Thread.current[:_influxdb_rails_controller],
|
32
|
+
Thread.current[:_influxdb_rails_action],
|
33
|
+
].reject(&:blank?).join("#")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -8,7 +8,7 @@ module InfluxDB
|
|
8
8
|
app.config.middleware.insert 0, InfluxDB::Rails::Rack
|
9
9
|
end
|
10
10
|
|
11
|
-
config.after_initialize do
|
11
|
+
config.after_initialize do # rubocop:disable Metrics/BlockLength
|
12
12
|
InfluxDB::Rails.configure(true, &:load_rails_defaults)
|
13
13
|
|
14
14
|
ActiveSupport.on_load(:action_controller) do
|
@@ -22,19 +22,27 @@ module InfluxDB
|
|
22
22
|
::ActionDispatch::DebugExceptions.prepend InfluxDB::Rails::Middleware::HijackRenderException
|
23
23
|
|
24
24
|
if defined?(ActiveSupport::Notifications)
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
if c.instrumentation_enabled? && !c.ignore_current_environment?
|
29
|
-
begin
|
30
|
-
InfluxDB::Rails.handle_action_controller_metrics(name, start, finish, id, payload)
|
31
|
-
rescue StandardError => e
|
32
|
-
c.logger.error "[InfluxDB::Rails] Failed writing points to InfluxDB: #{e.message}"
|
33
|
-
end
|
34
|
-
end
|
25
|
+
cache = lambda do |_, _, _, _, payload|
|
26
|
+
Thread.current[:_influxdb_rails_controller] = payload[:controller]
|
27
|
+
Thread.current[:_influxdb_rails_action] = payload[:action]
|
35
28
|
end
|
29
|
+
ActiveSupport::Notifications.subscribe "start_processing.action_controller", &cache
|
36
30
|
|
37
|
-
|
31
|
+
c = InfluxDB::Rails.configuration
|
32
|
+
requests = Middleware::RequestSubscriber.new(c)
|
33
|
+
ActiveSupport::Notifications.subscribe "process_action.action_controller", requests
|
34
|
+
|
35
|
+
templates = Middleware::RenderSubscriber.new(c, c.series_name_for_render_template)
|
36
|
+
ActiveSupport::Notifications.subscribe "render_template.action_view", templates
|
37
|
+
|
38
|
+
partials = Middleware::RenderSubscriber.new(c, c.series_name_for_render_partial)
|
39
|
+
ActiveSupport::Notifications.subscribe "render_partial.action_view", partials
|
40
|
+
|
41
|
+
collections = Middleware::RenderSubscriber.new(c, c.series_name_for_render_collection)
|
42
|
+
ActiveSupport::Notifications.subscribe "render_collection.action_view", collections
|
43
|
+
|
44
|
+
sql = Middleware::SqlSubscriber.new(c, c.series_name_for_sql)
|
45
|
+
ActiveSupport::Notifications.subscribe "sql.active_record", sql
|
38
46
|
end
|
39
47
|
end
|
40
48
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module InfluxDB
|
2
|
+
module Rails
|
3
|
+
module Sql
|
4
|
+
class Normalizer # :nodoc:
|
5
|
+
def initialize(query)
|
6
|
+
@query = query.dup
|
7
|
+
end
|
8
|
+
|
9
|
+
def perform
|
10
|
+
query.squish!
|
11
|
+
query.gsub!(/(\s(=|>|<|>=|<=|<>|!=)\s)('[^']+'|[\$\+\-\w\.]+)/, '\1xxx')
|
12
|
+
query.gsub!(/(\sIN\s)\([^\(\)]+\)/i, '\1(xxx)')
|
13
|
+
regex = /(\sBETWEEN\s)('[^']+'|[\+\-\w\.]+)(\sAND\s)('[^']+'|[\+\-\w\.]+)/i
|
14
|
+
query.gsub!(regex, '\1xxx\3xxx')
|
15
|
+
query.gsub!(/(\sVALUES\s)\(.+\)/i, '\1(xxx)')
|
16
|
+
query.gsub!(/(\s(LIKE|ILIKE|SIMILAR TO|NOT SIMILAR TO)\s)('[^']+')/i, '\1xxx')
|
17
|
+
query.gsub!(/(\s(LIMIT|OFFSET)\s)(\d+)/i, '\1xxx')
|
18
|
+
query
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :query
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "influxdb/rails/sql/normalizer"
|
2
|
+
|
3
|
+
module InfluxDB
|
4
|
+
module Rails
|
5
|
+
module Sql
|
6
|
+
class Query # :nodoc:
|
7
|
+
attr_reader :query, :name
|
8
|
+
|
9
|
+
TRACKED_SQL_COMMANDS = %w[SELECT INSERT UPDATE DELETE].freeze
|
10
|
+
|
11
|
+
def initialize(payload)
|
12
|
+
@query = payload[:sql].to_s.dup
|
13
|
+
@name = payload[:name].to_s.dup
|
14
|
+
end
|
15
|
+
|
16
|
+
def operation
|
17
|
+
query.split.first.upcase
|
18
|
+
end
|
19
|
+
|
20
|
+
def class_name
|
21
|
+
name.split.first
|
22
|
+
end
|
23
|
+
|
24
|
+
def track?
|
25
|
+
@track ||= query.start_with?(*TRACKED_SQL_COMMANDS)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|