Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAndrew Newdigate <andrew@gitlab.com>2019-01-28 16:47:48 +0300
committerAndrew Newdigate <andrew@gitlab.com>2019-01-30 14:38:19 +0300
commitd022ce865502c051c9177fc0f5b2453eae7e7cc2 (patch)
treea2cb931fc9b75dfe538979b1e478048b2a0591de /lib
parentc2b3f64cb44114e69ddeeb453412ad4dd762baf9 (diff)
Add OpenTracing instrumentation for Action View Render events
This change adds three new instrumentations, driven through rails notifications: render_template.action_view, render_collection.action_view and render_partial.action_view. These can help developers understand why renders are taking a long time which may in turn help them to improve their performance.
Diffstat (limited to 'lib')
-rw-r--r--lib/gitlab/tracing/rails/action_view_subscriber.rb75
-rw-r--r--lib/gitlab/tracing/rails/active_record_subscriber.rb27
-rw-r--r--lib/gitlab/tracing/rails/rails_common.rb24
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