Loading lib/labkit/tracing/rails/action_view_subscriber.rb +21 −22 Original line number Diff line number Diff line Loading @@ -19,40 +19,32 @@ module Labkit subscriber = new subscriptions = [ ActiveSupport::Notifications.subscribe(RENDER_TEMPLATE_NOTIFICATION_TOPIC) do |_, start, finish, _, payload| subscriber.notify_render_template(start, finish, payload) end, ActiveSupport::Notifications.subscribe(RENDER_COLLECTION_NOTIFICATION_TOPIC) do |_, start, finish, _, payload| subscriber.notify_render_collection(start, finish, payload) end, ActiveSupport::Notifications.subscribe(RENDER_PARTIAL_NOTIFICATION_TOPIC) do |_, start, finish, _, payload| subscriber.notify_render_partial(start, finish, payload) end, ActiveSupport::Notifications.subscribe(RENDER_TEMPLATE_NOTIFICATION_TOPIC, ActionViewRenderTemplateSubscriber.new), ActiveSupport::Notifications.subscribe(RENDER_COLLECTION_NOTIFICATION_TOPIC, ActionViewRenderCollectionSubscriber.new), ActiveSupport::Notifications.subscribe(RENDER_PARTIAL_NOTIFICATION_TOPIC, ActionViewRenderPartialSubscriber.new), ] create_unsubscriber subscriptions end # For more information on the payloads: https://guides.rubyonrails.org/active_support_instrumentation.html def notify_render_template(start, finish, payload) generate_span_for_notification("render_template", start, finish, payload, tags_for_render_template(payload)) end def notify_render_collection(start, finish, payload) generate_span_for_notification("render_collection", start, finish, payload, tags_for_render_collection(payload)) class ActionViewRenderTemplateSubscriber < AbstractSubscriber def span_name(payload) "render_template" end def notify_render_partial(start, finish, payload) generate_span_for_notification("render_partial", start, finish, payload, tags_for_render_partial(payload)) def tags(payload) { "component" => COMPONENT_TAG, "template.id" => payload[:identifier], "template.layout" => payload[:layout] } end end private def tags_for_render_template(payload) { "component" => COMPONENT_TAG, "template.id" => payload[:identifier], "template.layout" => payload[:layout] } class ActionViewRenderCollectionSubscriber < AbstractSubscriber def span_name(payload) "render_collection" end def tags_for_render_collection(payload) def tags(payload) { "component" => COMPONENT_TAG, "template.id" => payload[:identifier], Loading @@ -60,11 +52,18 @@ module Labkit "template.cache.hits" => payload[:cache_hits] || 0, } end end class ActionViewRenderPartialSubscriber < AbstractSubscriber def span_name(payload) "render_partial" end def tags_for_render_partial(payload) def tags(payload) { "component" => COMPONENT_TAG, "template.id" => payload[:identifier] } end end end end end end lib/labkit/tracing/rails/active_record_subscriber.rb +5 −11 Original line number Diff line number Diff line Loading @@ -17,26 +17,19 @@ module Labkit def self.instrument subscriber = new subscription = ActiveSupport::Notifications.subscribe(ACTIVE_RECORD_NOTIFICATION_TOPIC) do |_, start, finish, _, payload| subscriber.notify(start, finish, payload) end subscription = ActiveSupport::Notifications.subscribe(ACTIVE_RECORD_NOTIFICATION_TOPIC, ActiveRecordSqlSubscriber.new) create_unsubscriber [subscription] end # For more information on the payloads: https://guides.rubyonrails.org/active_support_instrumentation.html def notify(start, finish, payload) generate_span_for_notification(notification_name(payload), start, finish, payload, tags_for_notification(payload)) end private def notification_name(payload) class ActiveRecordSqlSubscriber < AbstractSubscriber def span_name(payload) OPERATION_NAME_PREFIX + (payload[:name].presence || DEFAULT_OPERATION_NAME) end def tags_for_notification(payload) def tags(payload) { "component" => "ActiveRecord", "span.kind" => "client", Loading @@ -50,3 +43,4 @@ module Labkit end end end end lib/labkit/tracing/rails/active_support_subscriber.rb +46 −38 Original line number Diff line number Diff line Loading @@ -22,63 +22,71 @@ module Labkit subscriber = new subscriptions = [ ActiveSupport::Notifications.subscribe(CACHE_READ_TOPIC) do |_, start, finish, _, payload| subscriber.notify_cache_read(start, finish, payload) end, ActiveSupport::Notifications.subscribe(CACHE_GENERATE_TOPIC) do |_, start, finish, _, payload| subscriber.notify_cache_generate(start, finish, payload) end, ActiveSupport::Notifications.subscribe(CACHE_FETCH_HIT_TOPIC) do |_, start, finish, _, payload| subscriber.notify_cache_fetch_hit(start, finish, payload) end, ActiveSupport::Notifications.subscribe(CACHE_WRITE_TOPIC) do |_, start, finish, _, payload| subscriber.notify_cache_write(start, finish, payload) end, ActiveSupport::Notifications.subscribe(CACHE_DELETE_TOPIC) do |_, start, finish, _, payload| subscriber.notify_cache_delete(start, finish, payload) end, ActiveSupportCacheReadSubscriber.new, ActiveSupportCacheGenerateSubscriber.new, ActiveSupportCacheFetchHitSubscriber.new, ActiveSupportCacheWriteSubscriber.new, ActiveSupportCacheDeleteSubscriber.new, ] create_unsubscriber subscriptions end # For more information on the payloads: https://guides.rubyonrails.org/active_support_instrumentation.html#active-support def notify_cache_read(start, finish, payload) generate_span_for_notification("cache_read", start, finish, payload, tags_for_cache_read(payload)) class ActiveSupportCacheReadSubscriber < AbstractSubscriber def span_name(payload) "cache_read" end def notify_cache_generate(start, finish, payload) generate_span_for_notification("cache_generate", start, finish, payload, tags_for_key(payload)) def tags(payload) { "component" => COMPONENT_TAG, "cache.key" => payload[:key], "cache.hit" => payload[:hit], "cache.super_operation" => payload[:super_operation], } end end def notify_cache_fetch_hit(start, finish, payload) generate_span_for_notification("cache_fetch_hit", start, finish, payload, tags_for_key(payload)) class ActiveSupportCacheGenerateSubscriber < AbstractSubscriber def span_name(payload) "cache_generate" end def notify_cache_write(start, finish, payload) generate_span_for_notification("cache_write", start, finish, payload, tags_for_key(payload)) def tags(payload) { "component" => COMPONENT_TAG, "cache.key" => payload[:key] } end end def notify_cache_delete(start, finish, payload) generate_span_for_notification("cache_delete", start, finish, payload, tags_for_key(payload)) class ActiveSupportCacheFetchHitSubscriber < AbstractSubscriber def span_name(payload) "cache_fetch_hit" end private def tags(payload) { "component" => COMPONENT_TAG, "cache.key" => payload[:key] } end end def tags_for_cache_read(payload) { "component" => COMPONENT_TAG, "cache.key" => payload[:key], "cache.hit" => payload[:hit], "cache.super_operation" => payload[:super_operation], } class ActiveSupportCacheWriteSubscriber < AbstractSubscriber def span_name(payload) "cache_write" end def tags_for_key(payload) { "component" => COMPONENT_TAG, "cache.key" => payload[:key], } def tags(payload) { "component" => COMPONENT_TAG, "cache.key" => payload[:key] } end end class ActiveSupportCacheDeleteSubscriber < AbstractSubscriber def span_name(payload) "cache_delete" end def tags(payload) { "component" => COMPONENT_TAG, "cache.key" => payload[:key] } end end end end Loading lib/labkit/tracing/rails/rails_common.rb +32 −6 Original line number Diff line number Diff line Loading @@ -10,16 +10,42 @@ module Labkit module RailsCommon extend ActiveSupport::Concern class_methods do def create_unsubscriber(subscriptions) -> { subscriptions.each { |subscriber| ActiveSupport::Notifications.unsubscribe(subscriber) } } end class AbstractSubscriber def start(name, id, payload) scope = OpenTracing.start_active_span(span_name(payload)) stack = Thread.current[:_labkit_span_stack] ||= [] stack.push scope end def generate_span_for_notification(operation_name, start, finish, payload, tags) def finish(name, id, payload) stack = Thread.current[:_labkit_span_stack] 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 TracingUtils.postnotify_span(operation_name, start, finish, tags: tags, exception: exception) def span_name(payload) raise 'span_name not implemented' end def tags(payload) {} end end class_methods do def create_unsubscriber(subscriptions) -> { subscriptions.each { |subscriber| ActiveSupport::Notifications.unsubscribe(subscriber) } } end end end end Loading Loading
lib/labkit/tracing/rails/action_view_subscriber.rb +21 −22 Original line number Diff line number Diff line Loading @@ -19,40 +19,32 @@ module Labkit subscriber = new subscriptions = [ ActiveSupport::Notifications.subscribe(RENDER_TEMPLATE_NOTIFICATION_TOPIC) do |_, start, finish, _, payload| subscriber.notify_render_template(start, finish, payload) end, ActiveSupport::Notifications.subscribe(RENDER_COLLECTION_NOTIFICATION_TOPIC) do |_, start, finish, _, payload| subscriber.notify_render_collection(start, finish, payload) end, ActiveSupport::Notifications.subscribe(RENDER_PARTIAL_NOTIFICATION_TOPIC) do |_, start, finish, _, payload| subscriber.notify_render_partial(start, finish, payload) end, ActiveSupport::Notifications.subscribe(RENDER_TEMPLATE_NOTIFICATION_TOPIC, ActionViewRenderTemplateSubscriber.new), ActiveSupport::Notifications.subscribe(RENDER_COLLECTION_NOTIFICATION_TOPIC, ActionViewRenderCollectionSubscriber.new), ActiveSupport::Notifications.subscribe(RENDER_PARTIAL_NOTIFICATION_TOPIC, ActionViewRenderPartialSubscriber.new), ] create_unsubscriber subscriptions end # For more information on the payloads: https://guides.rubyonrails.org/active_support_instrumentation.html def notify_render_template(start, finish, payload) generate_span_for_notification("render_template", start, finish, payload, tags_for_render_template(payload)) end def notify_render_collection(start, finish, payload) generate_span_for_notification("render_collection", start, finish, payload, tags_for_render_collection(payload)) class ActionViewRenderTemplateSubscriber < AbstractSubscriber def span_name(payload) "render_template" end def notify_render_partial(start, finish, payload) generate_span_for_notification("render_partial", start, finish, payload, tags_for_render_partial(payload)) def tags(payload) { "component" => COMPONENT_TAG, "template.id" => payload[:identifier], "template.layout" => payload[:layout] } end end private def tags_for_render_template(payload) { "component" => COMPONENT_TAG, "template.id" => payload[:identifier], "template.layout" => payload[:layout] } class ActionViewRenderCollectionSubscriber < AbstractSubscriber def span_name(payload) "render_collection" end def tags_for_render_collection(payload) def tags(payload) { "component" => COMPONENT_TAG, "template.id" => payload[:identifier], Loading @@ -60,11 +52,18 @@ module Labkit "template.cache.hits" => payload[:cache_hits] || 0, } end end class ActionViewRenderPartialSubscriber < AbstractSubscriber def span_name(payload) "render_partial" end def tags_for_render_partial(payload) def tags(payload) { "component" => COMPONENT_TAG, "template.id" => payload[:identifier] } end end end end end end
lib/labkit/tracing/rails/active_record_subscriber.rb +5 −11 Original line number Diff line number Diff line Loading @@ -17,26 +17,19 @@ module Labkit def self.instrument subscriber = new subscription = ActiveSupport::Notifications.subscribe(ACTIVE_RECORD_NOTIFICATION_TOPIC) do |_, start, finish, _, payload| subscriber.notify(start, finish, payload) end subscription = ActiveSupport::Notifications.subscribe(ACTIVE_RECORD_NOTIFICATION_TOPIC, ActiveRecordSqlSubscriber.new) create_unsubscriber [subscription] end # For more information on the payloads: https://guides.rubyonrails.org/active_support_instrumentation.html def notify(start, finish, payload) generate_span_for_notification(notification_name(payload), start, finish, payload, tags_for_notification(payload)) end private def notification_name(payload) class ActiveRecordSqlSubscriber < AbstractSubscriber def span_name(payload) OPERATION_NAME_PREFIX + (payload[:name].presence || DEFAULT_OPERATION_NAME) end def tags_for_notification(payload) def tags(payload) { "component" => "ActiveRecord", "span.kind" => "client", Loading @@ -50,3 +43,4 @@ module Labkit end end end end
lib/labkit/tracing/rails/active_support_subscriber.rb +46 −38 Original line number Diff line number Diff line Loading @@ -22,63 +22,71 @@ module Labkit subscriber = new subscriptions = [ ActiveSupport::Notifications.subscribe(CACHE_READ_TOPIC) do |_, start, finish, _, payload| subscriber.notify_cache_read(start, finish, payload) end, ActiveSupport::Notifications.subscribe(CACHE_GENERATE_TOPIC) do |_, start, finish, _, payload| subscriber.notify_cache_generate(start, finish, payload) end, ActiveSupport::Notifications.subscribe(CACHE_FETCH_HIT_TOPIC) do |_, start, finish, _, payload| subscriber.notify_cache_fetch_hit(start, finish, payload) end, ActiveSupport::Notifications.subscribe(CACHE_WRITE_TOPIC) do |_, start, finish, _, payload| subscriber.notify_cache_write(start, finish, payload) end, ActiveSupport::Notifications.subscribe(CACHE_DELETE_TOPIC) do |_, start, finish, _, payload| subscriber.notify_cache_delete(start, finish, payload) end, ActiveSupportCacheReadSubscriber.new, ActiveSupportCacheGenerateSubscriber.new, ActiveSupportCacheFetchHitSubscriber.new, ActiveSupportCacheWriteSubscriber.new, ActiveSupportCacheDeleteSubscriber.new, ] create_unsubscriber subscriptions end # For more information on the payloads: https://guides.rubyonrails.org/active_support_instrumentation.html#active-support def notify_cache_read(start, finish, payload) generate_span_for_notification("cache_read", start, finish, payload, tags_for_cache_read(payload)) class ActiveSupportCacheReadSubscriber < AbstractSubscriber def span_name(payload) "cache_read" end def notify_cache_generate(start, finish, payload) generate_span_for_notification("cache_generate", start, finish, payload, tags_for_key(payload)) def tags(payload) { "component" => COMPONENT_TAG, "cache.key" => payload[:key], "cache.hit" => payload[:hit], "cache.super_operation" => payload[:super_operation], } end end def notify_cache_fetch_hit(start, finish, payload) generate_span_for_notification("cache_fetch_hit", start, finish, payload, tags_for_key(payload)) class ActiveSupportCacheGenerateSubscriber < AbstractSubscriber def span_name(payload) "cache_generate" end def notify_cache_write(start, finish, payload) generate_span_for_notification("cache_write", start, finish, payload, tags_for_key(payload)) def tags(payload) { "component" => COMPONENT_TAG, "cache.key" => payload[:key] } end end def notify_cache_delete(start, finish, payload) generate_span_for_notification("cache_delete", start, finish, payload, tags_for_key(payload)) class ActiveSupportCacheFetchHitSubscriber < AbstractSubscriber def span_name(payload) "cache_fetch_hit" end private def tags(payload) { "component" => COMPONENT_TAG, "cache.key" => payload[:key] } end end def tags_for_cache_read(payload) { "component" => COMPONENT_TAG, "cache.key" => payload[:key], "cache.hit" => payload[:hit], "cache.super_operation" => payload[:super_operation], } class ActiveSupportCacheWriteSubscriber < AbstractSubscriber def span_name(payload) "cache_write" end def tags_for_key(payload) { "component" => COMPONENT_TAG, "cache.key" => payload[:key], } def tags(payload) { "component" => COMPONENT_TAG, "cache.key" => payload[:key] } end end class ActiveSupportCacheDeleteSubscriber < AbstractSubscriber def span_name(payload) "cache_delete" end def tags(payload) { "component" => COMPONENT_TAG, "cache.key" => payload[:key] } end end end end Loading
lib/labkit/tracing/rails/rails_common.rb +32 −6 Original line number Diff line number Diff line Loading @@ -10,16 +10,42 @@ module Labkit module RailsCommon extend ActiveSupport::Concern class_methods do def create_unsubscriber(subscriptions) -> { subscriptions.each { |subscriber| ActiveSupport::Notifications.unsubscribe(subscriber) } } end class AbstractSubscriber def start(name, id, payload) scope = OpenTracing.start_active_span(span_name(payload)) stack = Thread.current[:_labkit_span_stack] ||= [] stack.push scope end def generate_span_for_notification(operation_name, start, finish, payload, tags) def finish(name, id, payload) stack = Thread.current[:_labkit_span_stack] 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 TracingUtils.postnotify_span(operation_name, start, finish, tags: tags, exception: exception) def span_name(payload) raise 'span_name not implemented' end def tags(payload) {} end end class_methods do def create_unsubscriber(subscriptions) -> { subscriptions.each { |subscriber| ActiveSupport::Notifications.unsubscribe(subscriber) } } end end end end Loading