diff --git a/lib/influxdb/rails/metric.rb b/lib/influxdb/rails/metric.rb index fdbf798..e7ca820 100644 --- a/lib/influxdb/rails/metric.rb +++ b/lib/influxdb/rails/metric.rb @@ -4,23 +4,20 @@ module InfluxDB module Rails class Metric - def initialize(configuration:, timestamp:, tags: {}, values: {}, hook_name:) + def initialize(configuration:, timestamp:, tags: {}, values: {}) @configuration = configuration @timestamp = timestamp @tags = tags @values = values - @hook_name = hook_name end def write - return unless enabled? - client.write_point configuration.measurement_name, options end private - attr_reader :configuration, :tags, :values, :timestamp, :hook_name + attr_reader :configuration, :tags, :values, :timestamp def options { @@ -34,11 +31,6 @@ def timestamp_with_precision InfluxDB.convert_timestamp(timestamp.utc, configuration.client.time_precision) end - def enabled? - !configuration.ignore_current_environment? && - !configuration.ignored_hooks.include?(hook_name) - end - def client InfluxDB::Rails.client end diff --git a/lib/influxdb/rails/middleware/active_job_subscriber.rb b/lib/influxdb/rails/middleware/active_job_subscriber.rb index 4d0d9f2..094c90b 100644 --- a/lib/influxdb/rails/middleware/active_job_subscriber.rb +++ b/lib/influxdb/rails/middleware/active_job_subscriber.rb @@ -6,30 +6,23 @@ module Middleware class ActiveJobSubscriber < Subscriber # :nodoc: private - def values(_start, duration, _payload) - value = measure_performance? ? duration : 1 + def values { value: value, } end - def tags(payload) + def tags { hook: short_hook_name, - state: job_state(payload), - job: payload[:job].class.name, - queue: payload[:job].queue_name, + state: job_state, + job: job.class.name, + queue: job.queue_name, } end - def short_hook_name - return "enqueue" if hook_name.include?("enqueue") - return "perform_start" if hook_name.include?("perform_start") - return "perform" if hook_name.include?("perform") - end - - def job_state(payload) - return "failed" if payload[:exception_object] + def job_state + return "failed" if failed? case short_hook_name when "enqueue" @@ -44,6 +37,30 @@ def job_state(payload) def measure_performance? short_hook_name == "perform" end + + def short_hook_name + @short_hook_name ||= fetch_short_hook_name + end + + def fetch_short_hook_name + return "enqueue" if hook_name.include?("enqueue") + return "perform_start" if hook_name.include?("perform_start") + return "perform" if hook_name.include?("perform") + end + + def job + @job ||= payload[:job] + end + + def value + return duration if measure_performance? + + 1 + end + + def failed? + payload[:exception_object] + end end end end diff --git a/lib/influxdb/rails/middleware/active_record_subscriber.rb b/lib/influxdb/rails/middleware/active_record_subscriber.rb index e983fb7..c404616 100644 --- a/lib/influxdb/rails/middleware/active_record_subscriber.rb +++ b/lib/influxdb/rails/middleware/active_record_subscriber.rb @@ -7,14 +7,14 @@ module Middleware class ActiveRecordSubscriber < Subscriber # :nodoc: private - def values(_start, duration, payload) + def values { value: duration, record_count: payload[:record_count], } end - def tags(payload) + def tags { hook: "instantiation", class_name: payload[:class_name], diff --git a/lib/influxdb/rails/middleware/block_instrumentation_subscriber.rb b/lib/influxdb/rails/middleware/block_instrumentation_subscriber.rb index abefe11..9569fe2 100644 --- a/lib/influxdb/rails/middleware/block_instrumentation_subscriber.rb +++ b/lib/influxdb/rails/middleware/block_instrumentation_subscriber.rb @@ -4,13 +4,15 @@ module InfluxDB module Rails module Middleware class BlockInstrumentationSubscriber < Subscriber - def values(_start, duration, payload) + private + + def values { value: duration, }.merge(payload[:values].to_h) end - def tags(payload) + def tags { hook: "block_instrumentation", name: payload[:name], diff --git a/lib/influxdb/rails/middleware/render_subscriber.rb b/lib/influxdb/rails/middleware/render_subscriber.rb index 4500bbe..9db6a67 100644 --- a/lib/influxdb/rails/middleware/render_subscriber.rb +++ b/lib/influxdb/rails/middleware/render_subscriber.rb @@ -4,15 +4,9 @@ module InfluxDB module Rails module Middleware class RenderSubscriber < Subscriber # :nodoc: - def short_hook_name - return "render_template" if hook_name.include?("render_template") - return "render_partial" if hook_name.include?("render_partial") - return "render_collection" if hook_name.include?("render_collection") - end - private - def values(_start, duration, payload) + def values { value: duration, count: payload[:count], @@ -20,12 +14,18 @@ def values(_start, duration, payload) } end - def tags(payload) + def tags { hook: short_hook_name, filename: payload[:identifier], } end + + def short_hook_name + return "render_template" if hook_name.include?("render_template") + return "render_partial" if hook_name.include?("render_partial") + return "render_collection" if hook_name.include?("render_collection") + end end end end diff --git a/lib/influxdb/rails/middleware/request_subscriber.rb b/lib/influxdb/rails/middleware/request_subscriber.rb index fa1f635..559d9e8 100644 --- a/lib/influxdb/rails/middleware/request_subscriber.rb +++ b/lib/influxdb/rails/middleware/request_subscriber.rb @@ -4,7 +4,7 @@ module InfluxDB module Rails module Middleware class RequestSubscriber < Subscriber # :nodoc: - def call(_name, started, finished, _unique_id, payload) + def write super ensure InfluxDB::Rails.current.reset @@ -12,7 +12,7 @@ def call(_name, started, finished, _unique_id, payload) private - def tags(payload) + def tags { method: "#{payload[:controller]}##{payload[:action]}", hook: "process_action", @@ -22,17 +22,21 @@ def tags(payload) } end - def values(start, duration, payload) + def values { controller: duration, view: (payload[:view_runtime] || 0).ceil, db: (payload[:db_runtime] || 0).ceil, - started: InfluxDB.convert_timestamp( - start.utc, - configuration.client.time_precision - ), + started: started, } end + + def started + InfluxDB.convert_timestamp( + start.utc, + configuration.client.time_precision + ) + end end end end diff --git a/lib/influxdb/rails/middleware/sql_subscriber.rb b/lib/influxdb/rails/middleware/sql_subscriber.rb index a051dad..bfd970d 100644 --- a/lib/influxdb/rails/middleware/sql_subscriber.rb +++ b/lib/influxdb/rails/middleware/sql_subscriber.rb @@ -5,21 +5,16 @@ module InfluxDB module Rails module Middleware class SqlSubscriber < Subscriber # :nodoc: - def call(_name, started, finished, _unique_id, payload) - super if InfluxDB::Rails::Sql::Query.new(payload).track? - end - private - def values(_start, duration, payload) + def values { value: duration, sql: InfluxDB::Rails::Sql::Normalizer.new(payload[:sql]).perform, } end - def tags(payload) - query = InfluxDB::Rails::Sql::Query.new(payload) + def tags { hook: "sql", operation: query.operation, @@ -28,6 +23,14 @@ def tags(payload) location: :raw, } end + + def disabled? + super || !query.track? + end + + def query + @query ||= InfluxDB::Rails::Sql::Query.new(payload) + end end end end diff --git a/lib/influxdb/rails/middleware/subscriber.rb b/lib/influxdb/rails/middleware/subscriber.rb index 6254e3d..b2042e3 100644 --- a/lib/influxdb/rails/middleware/subscriber.rb +++ b/lib/influxdb/rails/middleware/subscriber.rb @@ -7,39 +7,61 @@ module Middleware # which are intended as ActiveSupport::Notifications.subscribe # consumers. class Subscriber - attr_reader :configuration - attr_reader :hook_name - - def initialize(configuration, hook_name) + def initialize(configuration:, hook_name:, start:, finish:, payload:) @configuration = configuration @hook_name = hook_name + @start = start + @finish = finish + @payload = payload + end + + def self.call(name, start, finish, _id, payload) + new( + configuration: InfluxDB::Rails.configuration, + start: start, + finish: finish, + payload: payload, + hook_name: name + ).write end - def call(_name, start, finish, _id, payload) - write_metric(start, finish, payload) + def write + return if disabled? + + metric.write rescue StandardError => e ::Rails.logger.error("[InfluxDB::Rails] Unable to write points: #{e.message}") end private - def write_metric(start, finish, payload) + attr_reader :configuration, :hook_name, :start, :finish, :payload + + def metric InfluxDB::Rails::Metric.new( - values: values(start, ((finish - start) * 1000).ceil, payload), - tags: tags(payload), + values: values, + tags: tags, configuration: configuration, - timestamp: finish, - hook_name: hook_name - ).write + timestamp: finish + ) end - def tags(*) + def tags raise NotImplementedError, "must be implemented in subclass" end - def values(*) + def values raise NotImplementedError, "must be implemented in subclass" end + + def duration + ((finish - start) * 1000).ceil + end + + def disabled? + configuration.ignore_current_environment? || + configuration.ignored_hooks.include?(hook_name) + end end end end diff --git a/lib/influxdb/rails/railtie.rb b/lib/influxdb/rails/railtie.rb index 657af22..17677a5 100644 --- a/lib/influxdb/rails/railtie.rb +++ b/lib/influxdb/rails/railtie.rb @@ -35,16 +35,11 @@ class Railtie < ::Rails::Railtie # :nodoc: "perform_start.active_job" => Middleware::ActiveJobSubscriber, "perform.active_job" => Middleware::ActiveJobSubscriber, "block_instrumentation.influxdb_rails" => Middleware::BlockInstrumentationSubscriber, - }.each do |hook_name, subscriber_class| - subscribe_to(hook_name, subscriber_class) + }.each do |hook_name, subscriber| + ActiveSupport::Notifications.subscribe(hook_name, subscriber) end end # rubocop:enable Metrics/BlockLength - - def subscribe_to(hook_name, subscriber_class) - subscriber = subscriber_class.new(InfluxDB::Rails.configuration, hook_name) - ActiveSupport::Notifications.subscribe hook_name, subscriber - end end end end diff --git a/lib/influxdb/rails/tags.rb b/lib/influxdb/rails/tags.rb index 8ad7758..0ede8ef 100644 --- a/lib/influxdb/rails/tags.rb +++ b/lib/influxdb/rails/tags.rb @@ -1,9 +1,10 @@ module InfluxDB module Rails class Tags - def initialize(tags: {}, config:) + def initialize(tags: {}, config:, additional_tags: InfluxDB::Rails.current.tags) @tags = tags @config = config + @additional_tags = additional_tags end def to_h @@ -14,7 +15,7 @@ def to_h private - attr_reader :tags, :config + attr_reader :additional_tags, :tags, :config def expanded_tags config.tags_middleware.call(tags.merge(default_tags)) @@ -25,11 +26,7 @@ def default_tags server: Socket.gethostname, app_name: config.application_name, location: :raw, - }.merge(InfluxDB::Rails.current.tags) - end - - def current - @current ||= InfluxDB::Rails.current + }.merge(additional_tags) end end end diff --git a/lib/influxdb/rails/values.rb b/lib/influxdb/rails/values.rb index 0706fc9..31a2b35 100644 --- a/lib/influxdb/rails/values.rb +++ b/lib/influxdb/rails/values.rb @@ -1,8 +1,9 @@ module InfluxDB module Rails class Values - def initialize(values: {}) + def initialize(values: {}, additional_values: InfluxDB::Rails.current.values) @values = values + @additional_values = additional_values end def to_h @@ -13,15 +14,11 @@ def to_h private - attr_reader :values + attr_reader :additional_values, :values def expanded_values values.merge(additional_values) end - - def additional_values - InfluxDB::Rails.current.values - end end end end