logister-ruby 0.1.1 → 0.1.2

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: cc4c81cdfeef4f713ac40e5324e8d845da2190dacfcaf9e295e0da5d4d1a75a1
4
- data.tar.gz: 3fdb07135981647437afae77a787645c89143847619edc46969f121b750a0c90
3
+ metadata.gz: c3ffbd6d90538c5e0cf39deab256aaf1b0c5c15f5899051e67cfedc6657ac4b5
4
+ data.tar.gz: af860be23dab9bd73c8d394e9b1b91b6076f62a6a5f67272991afafba75d83a6
5
5
  SHA512:
6
- metadata.gz: 3d53d3e80a01927a2ae08fec30d30eeb9d7d7987c3e5c1d624433c0683fc25b232675208e62ff7e563a9cbefcd1ae33e0bae32c9a6deb0fb084e307be0755e40
7
- data.tar.gz: c869dc8bb9c120b90d7f13b05ee291f1a82053ff3523a2bd8a4eafdd4159ee8553f975d0afc2eda97f9441a3b25df6f5c0bbf2c813b575f23b01386147e8eec9
6
+ metadata.gz: 59875a74fdee52e22b697b80e4840ba070db495eb905b47d6522576f2e745d4f64081bf0fbf5f8e7cfc48917466c1a8724a389fe36f728b29080ff71dcb79165
7
+ data.tar.gz: fb8e6d1898621e57f2fdb9c66a3e08b655151f3f06ed830e5e2a8c96313c4b1e181c1281846a2a62ada0d7332d8a9631630bb5b9abe9bf7a4fc4f14e04a781a3
data/README.md CHANGED
@@ -56,6 +56,20 @@ end
56
56
 
57
57
  If Rails is present, the gem installs middleware that reports unhandled exceptions automatically.
58
58
 
59
+ ## Database load metrics (ActiveRecord)
60
+
61
+ You can capture SQL timing metrics using ActiveSupport notifications:
62
+
63
+ ```ruby
64
+ Logister.configure do |config|
65
+ config.capture_db_metrics = true
66
+ config.db_metric_min_duration_ms = 10.0
67
+ config.db_metric_sample_rate = 1.0
68
+ end
69
+ ```
70
+
71
+ This emits metric events with `message: "db.query"` and context fields such as `duration_ms`, `name`, `sql`, and `binds_count`.
72
+
59
73
  ## Manual reporting
60
74
 
61
75
  ```ruby
@@ -17,6 +17,11 @@ Logister.configure do |config|
17
17
  config.ignore_exceptions = []
18
18
  config.ignore_paths = []
19
19
 
20
+ # Optional ActiveRecord SQL instrumentation.
21
+ config.capture_db_metrics = false
22
+ config.db_metric_min_duration_ms = 10.0
23
+ config.db_metric_sample_rate = 1.0
24
+
20
25
  config.before_notify = lambda do |payload|
21
26
  payload
22
27
  end
@@ -4,7 +4,8 @@ module Logister
4
4
  class Configuration
5
5
  attr_accessor :api_key, :endpoint, :environment, :service, :release, :enabled, :timeout_seconds, :logger,
6
6
  :ignore_exceptions, :ignore_environments, :ignore_paths, :before_notify,
7
- :async, :queue_size, :max_retries, :retry_base_interval
7
+ :async, :queue_size, :max_retries, :retry_base_interval,
8
+ :capture_db_metrics, :db_metric_min_duration_ms, :db_metric_sample_rate
8
9
 
9
10
  def initialize
10
11
  @api_key = ENV['LOGISTER_API_KEY']
@@ -26,6 +27,10 @@ module Logister
26
27
  @queue_size = 1000
27
28
  @max_retries = 3
28
29
  @retry_base_interval = 0.5
30
+
31
+ @capture_db_metrics = false
32
+ @db_metric_min_duration_ms = 0.0
33
+ @db_metric_sample_rate = 1.0
29
34
  end
30
35
  end
31
36
  end
@@ -21,6 +21,9 @@ module Logister
21
21
  copy_setting(app, config, :queue_size)
22
22
  copy_setting(app, config, :max_retries)
23
23
  copy_setting(app, config, :retry_base_interval)
24
+ copy_setting(app, config, :capture_db_metrics)
25
+ copy_setting(app, config, :db_metric_min_duration_ms)
26
+ copy_setting(app, config, :db_metric_sample_rate)
24
27
  end
25
28
  end
26
29
 
@@ -28,6 +31,10 @@ module Logister
28
31
  app.middleware.use Logister::Middleware
29
32
  end
30
33
 
34
+ initializer 'logister.sql_subscriber' do
35
+ Logister::SqlSubscriber.install!
36
+ end
37
+
31
38
  private
32
39
 
33
40
  def copy_setting(app, config, key)
@@ -0,0 +1,57 @@
1
+ module Logister
2
+ class SqlSubscriber
3
+ IGNORED_SQL_NAMES = %w[SCHEMA TRANSACTION].freeze
4
+
5
+ class << self
6
+ def install!
7
+ return if @installed
8
+
9
+ ActiveSupport::Notifications.subscribe('sql.active_record') do |name, started, finished, _id, payload|
10
+ handle_sql_event(name, started, finished, payload)
11
+ end
12
+
13
+ @installed = true
14
+ end
15
+
16
+ private
17
+
18
+ def handle_sql_event(_name, started, finished, payload)
19
+ config = Logister.configuration
20
+ return unless config.capture_db_metrics
21
+ return if payload[:cached]
22
+ return if IGNORED_SQL_NAMES.include?(payload[:name].to_s)
23
+
24
+ duration_ms = (finished - started) * 1000.0
25
+ return if duration_ms < config.db_metric_min_duration_ms.to_f
26
+ return if sampled_out?(config.db_metric_sample_rate)
27
+
28
+ level = duration_ms >= 500 ? 'warn' : 'info'
29
+
30
+ Logister.report_metric(
31
+ message: 'db.query',
32
+ level: level,
33
+ context: {
34
+ duration_ms: duration_ms.round(2),
35
+ name: payload[:name].to_s,
36
+ sql: payload[:sql].to_s,
37
+ cached: false,
38
+ binds_count: Array(payload[:binds]).size
39
+ },
40
+ tags: {
41
+ category: 'database'
42
+ }
43
+ )
44
+ rescue StandardError => e
45
+ config.logger.warn("logister sql subscriber failed: #{e.class} #{e.message}")
46
+ end
47
+
48
+ def sampled_out?(sample_rate)
49
+ rate = sample_rate.to_f
50
+ return true if rate <= 0.0
51
+ return false if rate >= 1.0
52
+
53
+ rand > rate
54
+ end
55
+ end
56
+ end
57
+ end
@@ -1,3 +1,3 @@
1
1
  module Logister
2
- VERSION = '0.1.1'
2
+ VERSION = '0.1.2'
3
3
  end
data/lib/logister.rb CHANGED
@@ -3,6 +3,7 @@ require_relative 'logister/configuration'
3
3
  require_relative 'logister/client'
4
4
  require_relative 'logister/reporter'
5
5
  require_relative 'logister/middleware'
6
+ require_relative 'logister/sql_subscriber'
6
7
 
7
8
  module Logister
8
9
  class << self
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logister-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Logister
@@ -55,6 +55,7 @@ files:
55
55
  - lib/logister/middleware.rb
56
56
  - lib/logister/railtie.rb
57
57
  - lib/logister/reporter.rb
58
+ - lib/logister/sql_subscriber.rb
58
59
  - lib/logister/version.rb
59
60
  - logister-ruby.gemspec
60
61
  homepage: https://logister.org