-
-
Notifications
You must be signed in to change notification settings - Fork 532
Expand file tree
/
Copy pathlog_subscriber.rb
More file actions
70 lines (64 loc) · 2.47 KB
/
log_subscriber.rb
File metadata and controls
70 lines (64 loc) · 2.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# frozen_string_literal: true
require "active_support/log_subscriber"
module Sentry
module Rails
# Base class for Sentry log subscribers that extends ActiveSupport::LogSubscriber
# to provide structured logging capabilities for Rails components.
#
# This class follows Rails' LogSubscriber pattern and provides common functionality
# for capturing Rails instrumentation events and logging them through Sentry's
# structured logging system.
#
# @example Creating a custom log subscriber
# class MySubscriber < Sentry::Rails::LogSubscriber
# attach_to :my_component
#
# def my_event(event)
# log_structured_event(
# message: "My event occurred",
# level: :info,
# attributes: {
# duration_ms: event.duration,
# custom_data: event.payload[:custom_data]
# }
# )
# end
# end
class LogSubscriber < ActiveSupport::LogSubscriber
class << self
if ::Rails.version.to_f < 6.0
# Rails 5.x does not provide detach_from
def detach_from(namespace, notifications = ActiveSupport::Notifications)
listeners = public_instance_methods(false)
.flat_map { |key|
notifications.notifier.listeners_for("#{key}.#{namespace}")
}
.select { |listener| listener.instance_variable_get(:@delegate).is_a?(self) }
listeners.map do |listener|
notifications.notifier.unsubscribe(listener)
end
end
end
end
protected
# Log a structured event using Sentry's structured logger
#
# @param message [String] The log message
# @param level [Symbol] The log level (:trace, :debug, :info, :warn, :error, :fatal)
# @param attributes [Hash] Additional structured attributes to include
def log_structured_event(message:, level: :info, attributes: {})
Sentry.logger.public_send(level, message, **attributes)
rescue => e
# Silently handle any errors in logging to avoid breaking the application
Sentry.configuration.sdk_logger.debug("Failed to log structured event: #{e.message}")
end
# Calculate duration in milliseconds from an event
#
# @param event [ActiveSupport::Notifications::Event] The event
# @return [Float] Duration in milliseconds
def duration_ms(event)
event.duration.round(2)
end
end
end
end