Commit 05859e6a authored by Bob Van Landuyt's avatar Bob Van Landuyt 💬
Browse files

Merge branch 'igor-tracing-nesting' into 'master'

tracing: nest rails spans properly

See merge request gitlab-org/labkit-ruby!30
parents fd429bdd 6349e6ca
Loading
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -4,10 +4,15 @@ module Labkit
  module Tracing
    # Rails provides classes for instrumenting Rails events
    module Rails
      autoload :ActionViewSubscriber, "labkit/tracing/rails/action_view_subscriber"
      autoload :ActiveRecordSubscriber, "labkit/tracing/rails/active_record_subscriber"
      autoload :ActiveSupportSubscriber, "labkit/tracing/rails/active_support_subscriber"
      autoload :AbstractInstrumenter, "labkit/tracing/rails/abstract_instrumenter"
      autoload :ActionView, "labkit/tracing/rails/action_view"
      autoload :ActiveRecord, "labkit/tracing/rails/active_record"
      autoload :ActiveSupport, "labkit/tracing/rails/active_support"
      autoload :RailsCommon, "labkit/tracing/rails/rails_common"

      ActionViewSubscriber = ActionView::Subscriber
      ActiveRecordSubscriber = ActiveRecord::Subscriber
      ActiveSupportSubscriber = ActiveSupport::Subscriber
    end
  end
end
+44 −0
Original line number Diff line number Diff line
# frozen_string_literal: true

require "active_support/all"

module Labkit
  module Tracing
    module Rails
      # https://edgeapi.rubyonrails.org/classes/ActiveSupport/Notifications/Instrumenter.html#method-c-new
      class AbstractInstrumenter
        def start(name, id, payload)
          scope = OpenTracing.start_active_span(span_name(payload))

          scope_stack.push scope
        end

        def finish(name, id, payload)
          scope = scope_stack.pop
          span = scope.span

          exception = payload[:exception]
          Labkit::Tracing::TracingUtils.log_exception_on_span(span, exception) if exception

          tags(payload).each do |k, v|
            span.set_tag(k, v)
          end

          scope.close
        end

        def scope_stack
          Thread.current[:_labkit_trace_scope_stack] ||= []
        end

        def span_name(payload)
          raise "span_name not implemented"
        end

        def tags(payload)
          {}
        end
      end
    end
  end
end
+16 −0
Original line number Diff line number Diff line
# frozen_string_literal: true

module Labkit
  module Tracing
    module Rails
      module ActionView
        autoload :RenderCollectionInstrumenter, "labkit/tracing/rails/action_view/render_collection_instrumenter"
        autoload :RenderPartialInstrumenter, "labkit/tracing/rails/action_view/render_partial_instrumenter"
        autoload :RenderTemplateInstrumenter, "labkit/tracing/rails/action_view/render_template_instrumenter"
        autoload :Subscriber, "labkit/tracing/rails/action_view/subscriber"

        COMPONENT_TAG = "ActionView"
      end
    end
  end
end
+25 −0
Original line number Diff line number Diff line
# frozen_string_literal: true

module Labkit
  module Tracing
    module Rails
      module ActionView
        # For more information on the payloads: https://guides.rubyonrails.org/active_support_instrumentation.html
        class RenderCollectionInstrumenter < AbstractInstrumenter
          def span_name(payload)
            "render_collection"
          end

          def tags(payload)
            {
              "component" => COMPONENT_TAG,
              "template.id" => payload[:identifier],
              "template.count" => payload[:count] || 0,
              "template.cache.hits" => payload[:cache_hits] || 0,
            }
          end
        end
      end
    end
  end
end
+20 −0
Original line number Diff line number Diff line
# frozen_string_literal: true

module Labkit
  module Tracing
    module Rails
      module ActionView
        # For more information on the payloads: https://guides.rubyonrails.org/active_support_instrumentation.html
        class RenderPartialInstrumenter < AbstractInstrumenter
          def span_name(payload)
            "render_partial"
          end

          def tags(payload)
            { "component" => COMPONENT_TAG, "template.id" => payload[:identifier] }
          end
        end
      end
    end
  end
end
Loading