diff options
author | Douwe Maan <douwe@gitlab.com> | 2019-01-30 12:33:02 +0000 |
---|---|---|
committer | Douwe Maan <douwe@gitlab.com> | 2019-01-30 12:33:02 +0000 |
commit | 4c2096b46a8e3674b4b7a0d1bb9cff46d3216fe8 (patch) | |
tree | fddb1572ed02f3b363ec297a5d3c70ce2b83c78f /lib | |
parent | 24d3a387b00ee586ed6f964650be8417844537e6 (diff) | |
parent | d022ce865502c051c9177fc0f5b2453eae7e7cc2 (diff) | |
download | gitlab-ce-4c2096b46a8e3674b4b7a0d1bb9cff46d3216fe8.tar.gz |
Merge branch 'an-opentracing-render-tracing' into 'master'
Add OpenTracing instrumentation for Action View Render events
See merge request gitlab-org/gitlab-ce!24728
Diffstat (limited to 'lib')
-rw-r--r-- | lib/gitlab/tracing/rails/action_view_subscriber.rb | 75 | ||||
-rw-r--r-- | lib/gitlab/tracing/rails/active_record_subscriber.rb | 27 | ||||
-rw-r--r-- | lib/gitlab/tracing/rails/rails_common.rb | 24 |
3 files changed, 118 insertions, 8 deletions
diff --git a/lib/gitlab/tracing/rails/action_view_subscriber.rb b/lib/gitlab/tracing/rails/action_view_subscriber.rb new file mode 100644 index 00000000000..88816e1fb32 --- /dev/null +++ b/lib/gitlab/tracing/rails/action_view_subscriber.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +module Gitlab + module Tracing + module Rails + class ActionViewSubscriber + include RailsCommon + + COMPONENT_TAG = 'ActionView' + RENDER_TEMPLATE_NOTIFICATION_TOPIC = 'render_template.action_view' + RENDER_COLLECTION_NOTIFICATION_TOPIC = 'render_collection.action_view' + RENDER_PARTIAL_NOTIFICATION_TOPIC = 'render_partial.action_view' + + # Instruments Rails ActionView events for opentracing. + # Returns a lambda, which, when called will unsubscribe from the notifications + def self.instrument + 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 + ] + + 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)) + end + + def notify_render_partial(start, finish, payload) + generate_span_for_notification("render_partial", start, finish, payload, tags_for_render_partial(payload)) + end + + private + + def tags_for_render_template(payload) + { + 'component' => COMPONENT_TAG, + 'template.id' => payload[:identifier], + 'template.layout' => payload[:layout] + } + end + + def tags_for_render_collection(payload) + { + 'component' => COMPONENT_TAG, + 'template.id' => payload[:identifier], + 'template.count' => payload[:count] || 0, + 'template.cache.hits' => payload[:cache_hits] || 0 + } + end + + def tags_for_render_partial(payload) + { + 'component' => COMPONENT_TAG, + 'template.id' => payload[:identifier] + } + end + end + end + end +end diff --git a/lib/gitlab/tracing/rails/active_record_subscriber.rb b/lib/gitlab/tracing/rails/active_record_subscriber.rb index 214eac47e14..32f5658e57e 100644 --- a/lib/gitlab/tracing/rails/active_record_subscriber.rb +++ b/lib/gitlab/tracing/rails/active_record_subscriber.rb @@ -4,24 +4,37 @@ module Gitlab module Tracing module Rails class ActiveRecordSubscriber - include Gitlab::Tracing::Common + include RailsCommon ACTIVE_RECORD_NOTIFICATION_TOPIC = 'sql.active_record' - DEFAULT_OPERATION_NAME = "sqlquery" + OPERATION_NAME_PREFIX = 'active_record:' + DEFAULT_OPERATION_NAME = 'sqlquery' + # Instruments Rails ActiveRecord events for opentracing. + # Returns a lambda, which, when called will unsubscribe from the notifications def self.instrument subscriber = new - ActiveSupport::Notifications.subscribe(ACTIVE_RECORD_NOTIFICATION_TOPIC) do |_, start, finish, _, payload| + subscription = ActiveSupport::Notifications.subscribe(ACTIVE_RECORD_NOTIFICATION_TOPIC) do |_, start, finish, _, payload| subscriber.notify(start, finish, payload) end + + create_unsubscriber [subscription] end # For more information on the payloads: https://guides.rubyonrails.org/active_support_instrumentation.html def notify(start, finish, payload) - operation_name = payload[:name].presence || DEFAULT_OPERATION_NAME - exception = payload[:exception] - tags = { + generate_span_for_notification(notification_name(payload), start, finish, payload, tags_for_notification(payload)) + end + + private + + def notification_name(payload) + OPERATION_NAME_PREFIX + (payload[:name].presence || DEFAULT_OPERATION_NAME) + end + + def tags_for_notification(payload) + { 'component' => 'ActiveRecord', 'span.kind' => 'client', 'db.type' => 'sql', @@ -29,8 +42,6 @@ module Gitlab 'db.cached' => payload[:cached] || false, 'db.statement' => payload[:sql] } - - postnotify_span("active_record:#{operation_name}", start, finish, tags: tags, exception: exception) end end end diff --git a/lib/gitlab/tracing/rails/rails_common.rb b/lib/gitlab/tracing/rails/rails_common.rb new file mode 100644 index 00000000000..88e914f62f8 --- /dev/null +++ b/lib/gitlab/tracing/rails/rails_common.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Gitlab + module Tracing + module Rails + module RailsCommon + extend ActiveSupport::Concern + include Gitlab::Tracing::Common + + class_methods do + def create_unsubscriber(subscriptions) + -> { subscriptions.each { |subscriber| ActiveSupport::Notifications.unsubscribe(subscriber) } } + end + end + + def generate_span_for_notification(operation_name, start, finish, payload, tags) + exception = payload[:exception] + + postnotify_span(operation_name, start, finish, tags: tags, exception: exception) + end + end + end + end +end |