diff options
author | Jan Provaznik <jprovaznik@gitlab.com> | 2019-05-02 07:01:14 +0000 |
---|---|---|
committer | Bob Van Landuyt <bob@gitlab.com> | 2019-05-02 07:01:14 +0000 |
commit | 96750fac4c4060d0a9e321039cab3dcf52a31105 (patch) | |
tree | c5f0f735bc80021e39193dac3ca10026e138c948 | |
parent | 2b3b0bb1847e5d910b3e5dc5e151f194c12d3907 (diff) | |
download | gitlab-ce-96750fac4c4060d0a9e321039cab3dcf52a31105.tar.gz |
Add opentracing integration for graphql
Extends existing graphql's tracer with opentracing measurements. Because
it also adds Tracing::Graphql class (for opentracing), it also renames
Graphql::Tracing class to Graphql::GenericTracing to minimize confusion
with similar class names.
-rw-r--r-- | Gemfile | 2 | ||||
-rw-r--r-- | Gemfile.lock | 4 | ||||
-rw-r--r-- | app/graphql/gitlab_schema.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/graphql/generic_tracing.rb (renamed from lib/gitlab/graphql/tracing.rb) | 22 | ||||
-rw-r--r-- | spec/lib/gitlab/graphql/generic_tracing_spec.rb | 67 | ||||
-rw-r--r-- | spec/lib/gitlab/graphql/tracing_spec.rb | 33 |
6 files changed, 90 insertions, 40 deletions
@@ -276,7 +276,7 @@ gem 'sentry-raven', '~> 2.7' gem 'premailer-rails', '~> 1.9.7' # LabKit: Tracing and Correlation -gem 'gitlab-labkit', '~> 0.1.2' +gem 'gitlab-labkit', '~> 0.2.0' # I18n gem 'ruby_parser', '~> 3.8', require: false diff --git a/Gemfile.lock b/Gemfile.lock index 3b03a8ef691..4db00ba4e18 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -288,7 +288,7 @@ GEM github-markup (1.7.0) gitlab-default_value_for (3.1.1) activerecord (>= 3.2.0, < 6.0) - gitlab-labkit (0.1.2) + gitlab-labkit (0.2.0) actionpack (~> 5) activesupport (~> 5) grpc (~> 1.15) @@ -1059,7 +1059,7 @@ DEPENDENCIES gitaly-proto (~> 1.26.0) github-markup (~> 1.7.0) gitlab-default_value_for (~> 3.1.1) - gitlab-labkit (~> 0.1.2) + gitlab-labkit (~> 0.2.0) gitlab-markup (~> 1.7.0) gitlab-sidekiq-fetcher (~> 0.4.0) gitlab-styles (~> 2.5) diff --git a/app/graphql/gitlab_schema.rb b/app/graphql/gitlab_schema.rb index 1afe000c5f8..a12568d5d31 100644 --- a/app/graphql/gitlab_schema.rb +++ b/app/graphql/gitlab_schema.rb @@ -11,7 +11,7 @@ class GitlabSchema < GraphQL::Schema use Gitlab::Graphql::Authorize use Gitlab::Graphql::Present use Gitlab::Graphql::Connections - use Gitlab::Graphql::Tracing + use Gitlab::Graphql::GenericTracing query_analyzer Gitlab::Graphql::QueryAnalyzers::LogQueryComplexity.analyzer diff --git a/lib/gitlab/graphql/tracing.rb b/lib/gitlab/graphql/generic_tracing.rb index 6b505e4262b..936b22d5afa 100644 --- a/lib/gitlab/graphql/tracing.rb +++ b/lib/gitlab/graphql/generic_tracing.rb @@ -1,8 +1,11 @@ # frozen_string_literal: true +# This class is used as a hook to observe graphql runtime events. From this +# hook both gitlab metrics and opentracking measurements are generated + module Gitlab module Graphql - class Tracing < GraphQL::Tracing::PlatformTracing + class GenericTracing < GraphQL::Tracing::PlatformTracing self.platform_keys = { 'lex' => 'graphql.lex', 'parse' => 'graphql.parse', @@ -21,17 +24,30 @@ module Gitlab end def platform_trace(platform_key, key, data, &block) + tags = { platform_key: platform_key, key: key } start = Gitlab::Metrics::System.monotonic_time - yield + with_labkit_tracing(tags, &block) ensure duration = Gitlab::Metrics::System.monotonic_time - start - graphql_duration_seconds.observe({ platform_key: platform_key, key: key }, duration) + graphql_duration_seconds.observe(tags, duration) end private + def with_labkit_tracing(tags, &block) + return yield unless Labkit::Tracing.enabled? + + name = "#{tags[:platform_key]}.#{tags[:key]}" + span_tags = { + 'component' => 'web', + 'span.kind' => 'server' + }.merge(tags.stringify_keys) + + Labkit::Tracing.with_tracing(operation_name: name, tags: span_tags, &block) + end + def graphql_duration_seconds @graphql_duration_seconds ||= Gitlab::Metrics.histogram( :graphql_duration_seconds, diff --git a/spec/lib/gitlab/graphql/generic_tracing_spec.rb b/spec/lib/gitlab/graphql/generic_tracing_spec.rb new file mode 100644 index 00000000000..ae92dcc40af --- /dev/null +++ b/spec/lib/gitlab/graphql/generic_tracing_spec.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Graphql::GenericTracing do + let(:graphql_duration_seconds_histogram) { double('Gitlab::Metrics::NullMetric') } + + it 'updates graphql histogram with expected labels' do + query = 'query { users { id } }' + tracer = described_class.new + + allow(tracer) + .to receive(:graphql_duration_seconds) + .and_return(graphql_duration_seconds_histogram) + + expect_metric('graphql.lex', 'lex') + expect_metric('graphql.parse', 'parse') + expect_metric('graphql.validate', 'validate') + expect_metric('graphql.analyze', 'analyze_multiplex') + expect_metric('graphql.execute', 'execute_query_lazy') + expect_metric('graphql.execute', 'execute_multiplex') + + GitlabSchema.execute(query, context: { tracers: [tracer] }) + end + + context "when labkit tracing is enabled" do + before do + expect(Labkit::Tracing).to receive(:enabled?).and_return(true) + end + + it 'yields with labkit tracing' do + expected_tags = { + 'component' => 'web', + 'span.kind' => 'server', + 'platform_key' => 'pkey', + 'key' => 'key' + } + + expect(Labkit::Tracing) + .to receive(:with_tracing) + .with(operation_name: "pkey.key", tags: expected_tags) + .and_yield + + expect { |b| described_class.new.platform_trace('pkey', 'key', nil, &b) }.to yield_control + end + end + + context "when labkit tracing is disabled" do + before do + expect(Labkit::Tracing).to receive(:enabled?).and_return(false) + end + + it 'yields without measurement' do + expect(Labkit::Tracing).not_to receive(:with_tracing) + + expect { |b| described_class.new.platform_trace('pkey', 'key', nil, &b) }.to yield_control + end + end + + private + + def expect_metric(platform_key, key) + expect(graphql_duration_seconds_histogram) + .to receive(:observe) + .with({ platform_key: platform_key, key: key }, be > 0.0) + end +end diff --git a/spec/lib/gitlab/graphql/tracing_spec.rb b/spec/lib/gitlab/graphql/tracing_spec.rb deleted file mode 100644 index 7300a9a572e..00000000000 --- a/spec/lib/gitlab/graphql/tracing_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -describe Gitlab::Graphql::Tracing do - let(:graphql_duration_seconds_histogram) { double('Gitlab::Metrics::NullMetric') } - - it 'updates graphql histogram with expected labels' do - query = 'query { users { id } }' - tracer = described_class.new - - allow(tracer) - .to receive(:graphql_duration_seconds) - .and_return(graphql_duration_seconds_histogram) - - expect_metric('graphql.lex', 'lex') - expect_metric('graphql.parse', 'parse') - expect_metric('graphql.validate', 'validate') - expect_metric('graphql.analyze', 'analyze_multiplex') - expect_metric('graphql.execute', 'execute_query_lazy') - expect_metric('graphql.execute', 'execute_multiplex') - - GitlabSchema.execute(query, context: { tracers: [tracer] }) - end - - private - - def expect_metric(platform_key, key) - expect(graphql_duration_seconds_histogram) - .to receive(:observe) - .with({ platform_key: platform_key, key: key }, be > 0.0) - end -end |