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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 68333c3962daf87c05e1ff1b221accc5854e4c7d671f0d0441a5c789b2322cee
4
- data.tar.gz: 56017328de99c335fd4c590fe80c2d9de1b9132f39a7d3ac6d07b87b551597f9
3
+ metadata.gz: e7b5a411b14d5a465a1a4c503498d8c642de1c818213dfe3e437a1177eefa5d1
4
+ data.tar.gz: f50dc54acb96ac4e9b758aa5be109ffd40a1396b4e43844800fc670496c1d76c
5
5
  SHA512:
6
- metadata.gz: e6c6087522e487aaefabe377698d2275270070c0e9d70eb7110fd90000f2160fc03b127879e39481ca0ff7f1f6bc5010075c4d9fe64bd30ecebd9b04b7e98df6
7
- data.tar.gz: baf2150e6140c85119da580cb89b06204a0372277c6adf7c57f15b89c214e41d80f05e0b47447df939eecc26dfb27115787750d92a22ae3ced38a047448f97bc
6
+ metadata.gz: 123a265d9418ff25a10b469cb798e9ed004af8a679fde861c40f81c5f96a20aea192576d10dfed877293afa6c59412cccb40d0b7fd14e52461aaa76c6712c092
7
+ data.tar.gz: 6189e83dfce1d8812c0ce8553f3095ee0be21608f71db0375edc1e6aab4cfaf646675d481ed53144056437b853df71a9e9085009fea936384a167bdac41d0433
data/.gitignore CHANGED
@@ -2,6 +2,7 @@
2
2
  .rvmrc
3
3
  *.gem
4
4
  Gemfile.lock
5
+ Gemfile.local
5
6
  gemfiles/*.lock
6
7
  pkg/*
7
8
  spec/support/rails*/log/*
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
1
  --format progress
2
2
  --color
3
+ --order rand
data/.rubocop.yml CHANGED
@@ -8,6 +8,7 @@ AllCops:
8
8
  - 'bin/**/*'
9
9
  - 'smoke/**/*'
10
10
  - 'Gemfile'
11
+ - 'vendor/bundle/**/*'
11
12
  DisplayCopNames: true
12
13
  StyleGuideCopsOnly: false
13
14
  TargetRubyVersion: 2.3
data/.travis.yml CHANGED
@@ -32,4 +32,4 @@ addons:
32
32
  packages:
33
33
  - haveged
34
34
  - libgmp-dev
35
- script: bundle exec rake spec
35
+ script: bundle exec rake $TEST_TASK
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
@@ -1,3 +1,9 @@
1
1
  source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
+
5
+ local_gemfile = 'Gemfile.local'
6
+
7
+ if File.exist?(local_gemfile)
8
+ eval(File.read(local_gemfile)) # rubocop:disable Lint/Eval
9
+ end
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.0+, Ruby 2.2+ and InfluxDB 0.9+.
14
+ This gem is designed for Rails 4.2+, Ruby 2.3+ and InfluxDB 0.9+.
15
15
 
16
- ## Install
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 for each request. You can also call through to the
68
- underlying `InfluxDB::Client` object to write arbitrary data like this:
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
- ```sh
169
- for gemfile in gemfiles/Gemfile.rails-*.x; do \
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
- begin
6
- targeted_files = ARGV.drop(1)
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
- require "rspec/core"
10
- require "rspec/core/rake_task"
8
+ require "rspec/core"
9
+ require "rspec/core/rake_task"
11
10
 
12
- RSpec::Core::RakeTask.new(:spec) do |t|
13
- t.pattern = FileList[file_pattern]
14
- end
11
+ RSpec::Core::RakeTask.new(:spec) do |t|
12
+ t.pattern = FileList[file_pattern]
13
+ end
15
14
 
16
- RSpec.configure do |config|
17
- config.color = true
18
- config.formatter = :documentation
19
- end
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
- puts file_pattern
20
+ task default: %i[spec rubocop]
24
21
 
25
- Spec::Rake::SpecTask.new(:spec) do |t|
26
- t.pattern = FileList[file_pattern]
27
- t.spec_opts += ["--color"]
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
@@ -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.5.0"
23
- spec.add_runtime_dependency "railties", "> 3"
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 benchmark_for_instrumentationn # rubocop:disable Metrics/MethodLength
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
- listen = lambda do |name, start, finish, id, payload|
26
- c = InfluxDB::Rails.configuration
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
- ActiveSupport::Notifications.subscribe "process_action.action_controller", &listen
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
@@ -1,5 +1,5 @@
1
1
  module InfluxDB
2
2
  module Rails
3
- VERSION = "1.0.0.beta1".freeze
3
+ VERSION = "1.0.0.beta2".freeze
4
4
  end
5
5
  end