signalfx-rails-instrumentation 0.1.0 → 0.2.0
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 +5 -5
- data/.gitignore +2 -7
- data/.rubocop.yml +42 -0
- data/Appraisals +16 -13
- data/Gemfile +3 -7
- data/Gemfile.lock +173 -0
- data/LICENSE +2 -2
- data/README.md +118 -164
- data/Rakefile +6 -6
- data/bin/console +1 -1
- data/lib/rails/instrumentation.rb +60 -0
- data/lib/rails/instrumentation/patch.rb +38 -0
- data/lib/rails/instrumentation/subscriber.rb +45 -0
- data/lib/rails/instrumentation/subscribers/action_cable_subscriber.rb +69 -0
- data/lib/rails/instrumentation/subscribers/action_controller_subscriber.rb +172 -0
- data/lib/rails/instrumentation/subscribers/action_mailer_subscriber.rb +63 -0
- data/lib/rails/instrumentation/subscribers/action_view_subscriber.rb +48 -0
- data/lib/rails/instrumentation/subscribers/active_job_subscriber.rb +58 -0
- data/lib/rails/instrumentation/subscribers/active_record_subscriber.rb +45 -0
- data/lib/rails/instrumentation/subscribers/active_storage_subscriber.rb +91 -0
- data/lib/rails/instrumentation/subscribers/active_support_subscriber.rb +74 -0
- data/lib/rails/instrumentation/utils.rb +44 -0
- data/lib/rails/instrumentation/version.rb +5 -0
- data/rails-instrumentation.gemspec +32 -0
- metadata +54 -192
- data/.rspec +0 -2
- data/.ruby-version +0 -1
- data/.travis.yml +0 -25
- data/CHANGELOG.md +0 -47
- data/docker-compose.yml +0 -4
- data/gemfiles/.bundle/config +0 -2
- data/gemfiles/rails_32.gemfile +0 -11
- data/gemfiles/rails_4.gemfile +0 -10
- data/gemfiles/rails_40.gemfile +0 -10
- data/gemfiles/rails_41.gemfile +0 -10
- data/gemfiles/rails_42.gemfile +0 -10
- data/gemfiles/rails_5.gemfile +0 -10
- data/gemfiles/rails_50.gemfile +0 -10
- data/gemfiles/rails_51.gemfile +0 -10
- data/lib/rails-tracer.rb +0 -1
- data/lib/rails/action_controller/tracer.rb +0 -100
- data/lib/rails/action_view/tracer.rb +0 -105
- data/lib/rails/active_record/tracer.rb +0 -89
- data/lib/rails/active_support/cache/core_ext.rb +0 -11
- data/lib/rails/active_support/cache/dalli_tracer.rb +0 -106
- data/lib/rails/active_support/cache/manual_tracer.rb +0 -24
- data/lib/rails/active_support/cache/subscriber.rb +0 -62
- data/lib/rails/active_support/cache/tracer.rb +0 -55
- data/lib/rails/defer_notifications.rb +0 -78
- data/lib/rails/rack/tracer.rb +0 -61
- data/lib/rails/span_helpers.rb +0 -24
- data/lib/rails/tracer.rb +0 -38
- data/rails-tracer.gemspec +0 -44
    
        data/Rakefile
    CHANGED
    
    | @@ -1,8 +1,8 @@ | |
| 1 | 
            -
            require  | 
| 2 | 
            -
            require  | 
| 3 | 
            -
            require "bundler/gem_tasks"
         | 
| 4 | 
            -
            require "rspec/core/rake_task"
         | 
| 1 | 
            +
            require 'bundler/gem_tasks'
         | 
| 2 | 
            +
            require 'rubocop/rake_task'
         | 
| 5 3 |  | 
| 6 | 
            -
             | 
| 4 | 
            +
            RuboCop::RakeTask.new do |task|
         | 
| 5 | 
            +
              task.requires << 'rubocop-rspec'
         | 
| 6 | 
            +
            end
         | 
| 7 7 |  | 
| 8 | 
            -
            task : | 
| 8 | 
            +
            task default: :spec
         | 
    
        data/bin/console
    CHANGED
    
    
| @@ -0,0 +1,60 @@ | |
| 1 | 
            +
            require 'rails/instrumentation/version'
         | 
| 2 | 
            +
            require 'rails/instrumentation/patch'
         | 
| 3 | 
            +
            require 'rails/instrumentation/subscriber'
         | 
| 4 | 
            +
            require 'rails/instrumentation/subscribers/action_controller_subscriber'
         | 
| 5 | 
            +
            require 'rails/instrumentation/subscribers/action_view_subscriber'
         | 
| 6 | 
            +
            require 'rails/instrumentation/subscribers/active_record_subscriber'
         | 
| 7 | 
            +
            require 'rails/instrumentation/subscribers/active_support_subscriber'
         | 
| 8 | 
            +
            require 'rails/instrumentation/subscribers/action_mailer_subscriber'
         | 
| 9 | 
            +
            require 'rails/instrumentation/subscribers/active_job_subscriber'
         | 
| 10 | 
            +
            require 'rails/instrumentation/subscribers/action_cable_subscriber'
         | 
| 11 | 
            +
            require 'rails/instrumentation/subscribers/active_storage_subscriber'
         | 
| 12 | 
            +
            require 'rails/instrumentation/utils'
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            require 'opentracing'
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            module Rails
         | 
| 17 | 
            +
              module Instrumentation
         | 
| 18 | 
            +
                class Error < StandardError; end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                TAGS = {
         | 
| 21 | 
            +
                  'component' => 'ruby-rails',
         | 
| 22 | 
            +
                  'instrumentation.version' => Rails::Instrumentation::VERSION
         | 
| 23 | 
            +
                }.freeze
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def self.instrument(tracer: OpenTracing.global_tracer,
         | 
| 26 | 
            +
                                    exclude_events: [])
         | 
| 27 | 
            +
                  @tracer = tracer
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  add_subscribers(exclude_events: exclude_events)
         | 
| 30 | 
            +
                  Patch.patch_process_action
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                def self.tracer
         | 
| 34 | 
            +
                  @tracer
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                def self.add_subscribers(exclude_events: [])
         | 
| 38 | 
            +
                  ActiveRecordSubscriber.subscribe(exclude_events: exclude_events)
         | 
| 39 | 
            +
                  ActionControllerSubscriber.subscribe(exclude_events: exclude_events)
         | 
| 40 | 
            +
                  ActionViewSubscriber.subscribe(exclude_events: exclude_events)
         | 
| 41 | 
            +
                  ActiveSupportSubscriber.subscribe(exclude_events: exclude_events)
         | 
| 42 | 
            +
                  ActionMailerSubscriber.subscribe(exclude_events: exclude_events)
         | 
| 43 | 
            +
                  ActiveJobSubscriber.subscribe(exclude_events: exclude_events)
         | 
| 44 | 
            +
                  ActionCableSubscriber.subscribe(exclude_events: exclude_events)
         | 
| 45 | 
            +
                  ActiveStorageSubscriber.subscribe(exclude_events: exclude_events)
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
                private_class_method :add_subscribers
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                def self.uninstrument
         | 
| 50 | 
            +
                  ActiveRecordSubscriber.unsubscribe
         | 
| 51 | 
            +
                  ActionControllerSubscriber.unsubscribe
         | 
| 52 | 
            +
                  ActionViewSubscriber.unsubscribe
         | 
| 53 | 
            +
                  ActiveSupportSubscriber.unsubscribe
         | 
| 54 | 
            +
                  ActionMailerSubscriber.unsubscribe
         | 
| 55 | 
            +
                  ActiveJobSubscriber.unsubscribe
         | 
| 56 | 
            +
                  ActionCableSubscriber.unsubscribe
         | 
| 57 | 
            +
                  ActiveStorageSubscriber.unsubscribe
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
              end
         | 
| 60 | 
            +
            end
         | 
| @@ -0,0 +1,38 @@ | |
| 1 | 
            +
            module Rails
         | 
| 2 | 
            +
              module Instrumentation
         | 
| 3 | 
            +
                module Patch
         | 
| 4 | 
            +
                  def self.patch_process_action(klass: ::ActionController::Instrumentation)
         | 
| 5 | 
            +
                    klass.class_eval do
         | 
| 6 | 
            +
                      alias_method :process_action_original, :process_action
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                      def process_action(method_name, *args)
         | 
| 9 | 
            +
                        # this naming scheme 'class.method' is how we ensure that the notification in the
         | 
| 10 | 
            +
                        # subscriber is the same one
         | 
| 11 | 
            +
                        name = "#{self.class.name}.#{method_name}"
         | 
| 12 | 
            +
                        scope = ::Rails::Instrumentation.tracer.start_active_span(name)
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                        # skip adding tags here. Getting the complete set of information is
         | 
| 15 | 
            +
                        # easiest in the notification
         | 
| 16 | 
            +
                        process_action_original(method_name, *args)
         | 
| 17 | 
            +
                      rescue Error => error
         | 
| 18 | 
            +
                        if scope
         | 
| 19 | 
            +
                          scope.span.record_exception(error)
         | 
| 20 | 
            +
                        end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                        raise
         | 
| 23 | 
            +
                      ensure
         | 
| 24 | 
            +
                        scope.close
         | 
| 25 | 
            +
                      end
         | 
| 26 | 
            +
                    end
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  def self.restore_process_action(klass: ::ActionController::Instrumentation)
         | 
| 30 | 
            +
                    klass.class_eval do
         | 
| 31 | 
            +
                      remove_method :process_action
         | 
| 32 | 
            +
                      alias_method :process_action, :process_action_original
         | 
| 33 | 
            +
                      remove_method :process_action_original
         | 
| 34 | 
            +
                    end
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
            end
         | 
| @@ -0,0 +1,45 @@ | |
| 1 | 
            +
            module Rails
         | 
| 2 | 
            +
              module Instrumentation
         | 
| 3 | 
            +
                module Subscriber
         | 
| 4 | 
            +
                  def self.included(base)
         | 
| 5 | 
            +
                    base.extend ClassMethods
         | 
| 6 | 
            +
                  end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  module ClassMethods
         | 
| 9 | 
            +
                    def subscribe(exclude_events: [])
         | 
| 10 | 
            +
                      @subscriber_mutex = Mutex.new if @subscriber_mutex.nil?
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                      # clear
         | 
| 13 | 
            +
                      unsubscribe
         | 
| 14 | 
            +
                      @subscribers = []
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                      @subscriber_mutex.synchronize do
         | 
| 17 | 
            +
                        self::EVENTS.each do |event_name|
         | 
| 18 | 
            +
                          full_name = "#{event_name}.#{self::EVENT_NAMESPACE}"
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                          next if exclude_events.include? full_name
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                          @subscribers << Utils.register_subscriber(full_name: full_name,
         | 
| 23 | 
            +
                                                                    event_name: event_name,
         | 
| 24 | 
            +
                                                                    handler_module: self)
         | 
| 25 | 
            +
                        end
         | 
| 26 | 
            +
                      end
         | 
| 27 | 
            +
                    end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                    def unsubscribe
         | 
| 30 | 
            +
                      return if @subscribers.nil? || @subscriber_mutex.nil?
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                      @subscriber_mutex.synchronize do
         | 
| 33 | 
            +
                        @subscribers.each do |subscriber|
         | 
| 34 | 
            +
                          ::ActiveSupport::Notifications.unsubscribe(subscriber)
         | 
| 35 | 
            +
                        end
         | 
| 36 | 
            +
                      end
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                    def span_tags(tags)
         | 
| 40 | 
            +
                      self::BASE_TAGS.clone.merge(tags)
         | 
| 41 | 
            +
                    end
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
            end
         | 
| @@ -0,0 +1,69 @@ | |
| 1 | 
            +
            module Rails
         | 
| 2 | 
            +
              module Instrumentation
         | 
| 3 | 
            +
                module ActionCableSubscriber
         | 
| 4 | 
            +
                  include Subscriber
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  EVENT_NAMESPACE = 'action_cable'.freeze
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  EVENTS = %w[
         | 
| 9 | 
            +
                    perform_action
         | 
| 10 | 
            +
                    transmit
         | 
| 11 | 
            +
                    transmit_subscription_confirmation
         | 
| 12 | 
            +
                    transmit_subscription_rejection
         | 
| 13 | 
            +
                    broadcast
         | 
| 14 | 
            +
                  ].freeze
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  # rubocop:disable Style/MutableConstant
         | 
| 17 | 
            +
                  BASE_TAGS = { 'component' => 'ActionCable' }
         | 
| 18 | 
            +
                  # rubocop:enable Style/MutableConstant.
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  class << self
         | 
| 21 | 
            +
                    def perform_action(event)
         | 
| 22 | 
            +
                      tags = span_tags(
         | 
| 23 | 
            +
                        'channel_class' => event.payload[:channel_class],
         | 
| 24 | 
            +
                        'action' => event.payload[:action],
         | 
| 25 | 
            +
                        'data' => event.payload[:data]
         | 
| 26 | 
            +
                      )
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                      Utils.trace_notification(event: event, tags: tags)
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    def transmit(event)
         | 
| 32 | 
            +
                      tags = span_tags(
         | 
| 33 | 
            +
                        'channel_class' => event.payload[:channel_class],
         | 
| 34 | 
            +
                        'data' => event.payload[:data],
         | 
| 35 | 
            +
                        'via' => event.payload[:via]
         | 
| 36 | 
            +
                      )
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                      Utils.trace_notification(event: event, tags: tags)
         | 
| 39 | 
            +
                    end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                    def transmit_subscription_confirmation(event)
         | 
| 42 | 
            +
                      tags = span_tags(
         | 
| 43 | 
            +
                        'channel_class' => event.payload[:channel_class]
         | 
| 44 | 
            +
                      )
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                      Utils.trace_notification(event: event, tags: tags)
         | 
| 47 | 
            +
                    end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                    def transmit_subscription_rejection(event)
         | 
| 50 | 
            +
                      tags = span_tags(
         | 
| 51 | 
            +
                        'channel_class' => event.payload[:channel_class]
         | 
| 52 | 
            +
                      )
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                      Utils.trace_notification(event: event, tags: tags)
         | 
| 55 | 
            +
                    end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                    def broadcast(event)
         | 
| 58 | 
            +
                      tags = span_tags(
         | 
| 59 | 
            +
                        'broadcasting' => event.payload[:broadcasting],
         | 
| 60 | 
            +
                        'message' => event.payload[:message],
         | 
| 61 | 
            +
                        'coder' => event.payload[:coder]
         | 
| 62 | 
            +
                      )
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                      Utils.trace_notification(event: event, tags: tags)
         | 
| 65 | 
            +
                    end
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
              end
         | 
| 69 | 
            +
            end
         | 
| @@ -0,0 +1,172 @@ | |
| 1 | 
            +
            module Rails
         | 
| 2 | 
            +
              module Instrumentation
         | 
| 3 | 
            +
                module ActionControllerSubscriber
         | 
| 4 | 
            +
                  include Subscriber
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  EVENT_NAMESPACE = 'action_controller'.freeze
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  EVENTS = %w[
         | 
| 9 | 
            +
                    write_fragment
         | 
| 10 | 
            +
                    read_fragment
         | 
| 11 | 
            +
                    expire_fragment
         | 
| 12 | 
            +
                    exist_fragment?
         | 
| 13 | 
            +
                    write_page
         | 
| 14 | 
            +
                    expire_page
         | 
| 15 | 
            +
                    start_processing
         | 
| 16 | 
            +
                    process_action
         | 
| 17 | 
            +
                    send_file
         | 
| 18 | 
            +
                    send_data
         | 
| 19 | 
            +
                    redirect_to
         | 
| 20 | 
            +
                    halted_callback
         | 
| 21 | 
            +
                    unpermitted_parameters
         | 
| 22 | 
            +
                  ].freeze
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  # rubocop:disable Style/MutableConstant
         | 
| 25 | 
            +
                  BASE_TAGS = { 'component' => 'ActionController' }
         | 
| 26 | 
            +
                  # rubocop:enable Style/MutableConstant.
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  class << self
         | 
| 29 | 
            +
                    def write_fragment(event)
         | 
| 30 | 
            +
                      tags = span_tags(
         | 
| 31 | 
            +
                        'key.write' => event.payload[:key]
         | 
| 32 | 
            +
                      )
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                      Utils.trace_notification(event: event, tags: tags)
         | 
| 35 | 
            +
                    end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                    def read_fragment(event)
         | 
| 38 | 
            +
                      tags = span_tags(
         | 
| 39 | 
            +
                        'key.read' => event.payload[:key]
         | 
| 40 | 
            +
                      )
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                      Utils.trace_notification(event: event, tags: tags)
         | 
| 43 | 
            +
                    end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                    def expire_fragment(event)
         | 
| 46 | 
            +
                      tags = span_tags(
         | 
| 47 | 
            +
                        'key.expire' => event.payload[:key]
         | 
| 48 | 
            +
                      )
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                      Utils.trace_notification(event: event, tags: tags)
         | 
| 51 | 
            +
                    end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                    def exist_fragment?(event)
         | 
| 54 | 
            +
                      tags = span_tags(
         | 
| 55 | 
            +
                        'key.exist' => event.payload[:key]
         | 
| 56 | 
            +
                      )
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                      Utils.trace_notification(event: event, tags: tags)
         | 
| 59 | 
            +
                    end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                    def write_page(event)
         | 
| 62 | 
            +
                      tags = span_tags(
         | 
| 63 | 
            +
                        'path.write' => event.payload[:path]
         | 
| 64 | 
            +
                      )
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                      Utils.trace_notification(event: event, tags: tags)
         | 
| 67 | 
            +
                    end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                    def expire_page(event)
         | 
| 70 | 
            +
                      tags = span_tags(
         | 
| 71 | 
            +
                        'path.expire' => event.payload[:path]
         | 
| 72 | 
            +
                      )
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                      Utils.trace_notification(event: event, tags: tags)
         | 
| 75 | 
            +
                    end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                    def start_processing(event)
         | 
| 78 | 
            +
                      tags = span_tags(
         | 
| 79 | 
            +
                        'controller' => event.payload[:controller],
         | 
| 80 | 
            +
                        'controller.action' => event.payload[:action],
         | 
| 81 | 
            +
                        'request.params' => event.payload[:params],
         | 
| 82 | 
            +
                        'request.format' => event.payload[:format],
         | 
| 83 | 
            +
                        'http.method' => event.payload[:method],
         | 
| 84 | 
            +
                        'http.url' => event.payload[:path]
         | 
| 85 | 
            +
                      )
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                      Utils.trace_notification(event: event, tags: tags)
         | 
| 88 | 
            +
                    end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                    def process_action(event)
         | 
| 91 | 
            +
                      span_name = "#{event.payload[:controller]}.#{event.payload[:action]}"
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                      tags = span_tags(
         | 
| 94 | 
            +
                        'controller' => event.payload[:controller],
         | 
| 95 | 
            +
                        'controller.action' => event.payload[:action],
         | 
| 96 | 
            +
                        'request.params' => event.payload[:params],
         | 
| 97 | 
            +
                        'request.format' => event.payload[:format],
         | 
| 98 | 
            +
                        'http.method' => event.payload[:method],
         | 
| 99 | 
            +
                        'http.url' => event.payload[:path],
         | 
| 100 | 
            +
                        'http.status_code' => event.payload[:status],
         | 
| 101 | 
            +
                        'view.runtime.ms' => event.payload[:view_runtime],
         | 
| 102 | 
            +
                        'db.runtime.ms' => event.payload[:db_runtime],
         | 
| 103 | 
            +
                        'span.kind' => 'server'
         | 
| 104 | 
            +
                      )
         | 
| 105 | 
            +
             | 
| 106 | 
            +
             | 
| 107 | 
            +
                      status_code = event.payload[:status]
         | 
| 108 | 
            +
                      if status_code.is_a? Integer and status_code >= 500
         | 
| 109 | 
            +
                        tags['error'] = true
         | 
| 110 | 
            +
                      end
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                      # Only append these tags onto the active span created by the patched 'process_action'
         | 
| 113 | 
            +
                      # Otherwise, create a new span for this notification as usual
         | 
| 114 | 
            +
                      active_span = ::Rails::Instrumentation.tracer.active_span
         | 
| 115 | 
            +
                      if active_span && active_span.operation_name == span_name
         | 
| 116 | 
            +
                        tags.each do |key, value|
         | 
| 117 | 
            +
                          ::Rails::Instrumentation.tracer.active_span.set_tag(key, value)
         | 
| 118 | 
            +
                        end
         | 
| 119 | 
            +
                        if event.payload.key? :exception
         | 
| 120 | 
            +
                          Utils.tag_error(active_span, event.payload)
         | 
| 121 | 
            +
                        end
         | 
| 122 | 
            +
                      else
         | 
| 123 | 
            +
                        Utils.trace_notification(event: event, tags: tags)
         | 
| 124 | 
            +
                      end
         | 
| 125 | 
            +
                    end
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                    def send_file(event)
         | 
| 128 | 
            +
                      tags = span_tags(
         | 
| 129 | 
            +
                        'path.send' => event.payload[:path]
         | 
| 130 | 
            +
                      )
         | 
| 131 | 
            +
             | 
| 132 | 
            +
                      # there may be additional keys in the payload. It might be worth
         | 
| 133 | 
            +
                      # trying to tag them too
         | 
| 134 | 
            +
             | 
| 135 | 
            +
                      Utils.trace_notification(event: event, tags: tags)
         | 
| 136 | 
            +
                    end
         | 
| 137 | 
            +
             | 
| 138 | 
            +
                    def send_data(event)
         | 
| 139 | 
            +
                      # no defined keys, but user keys may be passed in. Might want to add
         | 
| 140 | 
            +
                      # them at some point
         | 
| 141 | 
            +
             | 
| 142 | 
            +
                      Utils.trace_notification(event: event, tags: BASE_TAGS)
         | 
| 143 | 
            +
                    end
         | 
| 144 | 
            +
             | 
| 145 | 
            +
                    def redirect_to(event)
         | 
| 146 | 
            +
                      tags = span_tags(
         | 
| 147 | 
            +
                        'http.status_code' => event.payload[:status],
         | 
| 148 | 
            +
                        'redirect.url' => event.payload[:location]
         | 
| 149 | 
            +
                      )
         | 
| 150 | 
            +
             | 
| 151 | 
            +
                      Utils.trace_notification(event: event, tags: tags)
         | 
| 152 | 
            +
                    end
         | 
| 153 | 
            +
             | 
| 154 | 
            +
                    def halted_callback(event)
         | 
| 155 | 
            +
                      tags = span_tags(
         | 
| 156 | 
            +
                        'filter' => event.payload[:filter]
         | 
| 157 | 
            +
                      )
         | 
| 158 | 
            +
             | 
| 159 | 
            +
                      Utils.trace_notification(event: event, tags: tags)
         | 
| 160 | 
            +
                    end
         | 
| 161 | 
            +
             | 
| 162 | 
            +
                    def unpermitted_parameters(event)
         | 
| 163 | 
            +
                      tags = span_tags(
         | 
| 164 | 
            +
                        'unpermitted_keys' => event.payload[:keys]
         | 
| 165 | 
            +
                      )
         | 
| 166 | 
            +
             | 
| 167 | 
            +
                      Utils.trace_notification(event: event, tags: tags)
         | 
| 168 | 
            +
                    end
         | 
| 169 | 
            +
                  end
         | 
| 170 | 
            +
                end
         | 
| 171 | 
            +
              end
         | 
| 172 | 
            +
            end
         | 
| @@ -0,0 +1,63 @@ | |
| 1 | 
            +
            module Rails
         | 
| 2 | 
            +
              module Instrumentation
         | 
| 3 | 
            +
                module ActionMailerSubscriber
         | 
| 4 | 
            +
                  include Subscriber
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  EVENT_NAMESPACE = 'action_mailer'.freeze
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  EVENTS = %w[
         | 
| 9 | 
            +
                    receive
         | 
| 10 | 
            +
                    deliver
         | 
| 11 | 
            +
                    process
         | 
| 12 | 
            +
                  ].freeze
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  # rubocop:disable Style/MutableConstant
         | 
| 15 | 
            +
                  BASE_TAGS = { 'component' => 'ActionMailer' }
         | 
| 16 | 
            +
                  # rubocop:enable Style/MutableConstant.
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  class << self
         | 
| 19 | 
            +
                    def receive(event)
         | 
| 20 | 
            +
                      tags = span_tags(
         | 
| 21 | 
            +
                        'mailer' => event.payload[:mailer],
         | 
| 22 | 
            +
                        'message.id' => event.payload[:message_id],
         | 
| 23 | 
            +
                        'message.subject' => event.payload[:subject],
         | 
| 24 | 
            +
                        'message.to' => event.payload[:to],
         | 
| 25 | 
            +
                        'message.from' => event.payload[:from],
         | 
| 26 | 
            +
                        'message.bcc' => event.payload[:bcc],
         | 
| 27 | 
            +
                        'message.cc' => event.payload[:cc],
         | 
| 28 | 
            +
                        'message.date' => event.payload[:date],
         | 
| 29 | 
            +
                        'message.body' => event.payload[:mail]
         | 
| 30 | 
            +
                      )
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                      Utils.trace_notification(event: event, tags: tags)
         | 
| 33 | 
            +
                    end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                    def deliver(event)
         | 
| 36 | 
            +
                      tags = span_tags(
         | 
| 37 | 
            +
                        'mailer' => event.payload[:mailer],
         | 
| 38 | 
            +
                        'message.id' => event.payload[:message_id],
         | 
| 39 | 
            +
                        'message.subject' => event.payload[:subject],
         | 
| 40 | 
            +
                        'message.to' => event.payload[:to],
         | 
| 41 | 
            +
                        'message.from' => event.payload[:from],
         | 
| 42 | 
            +
                        'message.bcc' => event.payload[:bcc],
         | 
| 43 | 
            +
                        'message.cc' => event.payload[:cc],
         | 
| 44 | 
            +
                        'message.date' => event.payload[:date],
         | 
| 45 | 
            +
                        'message.body' => event.payload[:mail]
         | 
| 46 | 
            +
                      )
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                      Utils.trace_notification(event: event, tags: tags)
         | 
| 49 | 
            +
                    end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                    def process(event)
         | 
| 52 | 
            +
                      tags = span_tags(
         | 
| 53 | 
            +
                        'mailer' => event.payload[:mailer],
         | 
| 54 | 
            +
                        'action' => event.payload[:action],
         | 
| 55 | 
            +
                        'args' => event.payload[:args]
         | 
| 56 | 
            +
                      )
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                      Utils.trace_notification(event: event, tags: tags)
         | 
| 59 | 
            +
                    end
         | 
| 60 | 
            +
                  end
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
              end
         | 
| 63 | 
            +
            end
         |