Commit 96750fac authored by Jan Provaznik's avatar Jan Provaznik Committed by Bob Van Landuyt

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.
parent 2b3b0bb1
...@@ -276,7 +276,7 @@ gem 'sentry-raven', '~> 2.7' ...@@ -276,7 +276,7 @@ gem 'sentry-raven', '~> 2.7'
gem 'premailer-rails', '~> 1.9.7' gem 'premailer-rails', '~> 1.9.7'
# LabKit: Tracing and Correlation # LabKit: Tracing and Correlation
gem 'gitlab-labkit', '~> 0.1.2' gem 'gitlab-labkit', '~> 0.2.0'
# I18n # I18n
gem 'ruby_parser', '~> 3.8', require: false gem 'ruby_parser', '~> 3.8', require: false
......
...@@ -288,7 +288,7 @@ GEM ...@@ -288,7 +288,7 @@ GEM
github-markup (1.7.0) github-markup (1.7.0)
gitlab-default_value_for (3.1.1) gitlab-default_value_for (3.1.1)
activerecord (>= 3.2.0, < 6.0) activerecord (>= 3.2.0, < 6.0)
gitlab-labkit (0.1.2) gitlab-labkit (0.2.0)
actionpack (~> 5) actionpack (~> 5)
activesupport (~> 5) activesupport (~> 5)
grpc (~> 1.15) grpc (~> 1.15)
...@@ -1059,7 +1059,7 @@ DEPENDENCIES ...@@ -1059,7 +1059,7 @@ DEPENDENCIES
gitaly-proto (~> 1.26.0) gitaly-proto (~> 1.26.0)
github-markup (~> 1.7.0) github-markup (~> 1.7.0)
gitlab-default_value_for (~> 3.1.1) gitlab-default_value_for (~> 3.1.1)
gitlab-labkit (~> 0.1.2) gitlab-labkit (~> 0.2.0)
gitlab-markup (~> 1.7.0) gitlab-markup (~> 1.7.0)
gitlab-sidekiq-fetcher (~> 0.4.0) gitlab-sidekiq-fetcher (~> 0.4.0)
gitlab-styles (~> 2.5) gitlab-styles (~> 2.5)
......
...@@ -11,7 +11,7 @@ class GitlabSchema < GraphQL::Schema ...@@ -11,7 +11,7 @@ class GitlabSchema < GraphQL::Schema
use Gitlab::Graphql::Authorize use Gitlab::Graphql::Authorize
use Gitlab::Graphql::Present use Gitlab::Graphql::Present
use Gitlab::Graphql::Connections use Gitlab::Graphql::Connections
use Gitlab::Graphql::Tracing use Gitlab::Graphql::GenericTracing
query_analyzer Gitlab::Graphql::QueryAnalyzers::LogQueryComplexity.analyzer query_analyzer Gitlab::Graphql::QueryAnalyzers::LogQueryComplexity.analyzer
......
# frozen_string_literal: true # 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 Gitlab
module Graphql module Graphql
class Tracing < GraphQL::Tracing::PlatformTracing class GenericTracing < GraphQL::Tracing::PlatformTracing
self.platform_keys = { self.platform_keys = {
'lex' => 'graphql.lex', 'lex' => 'graphql.lex',
'parse' => 'graphql.parse', 'parse' => 'graphql.parse',
...@@ -21,17 +24,30 @@ module Gitlab ...@@ -21,17 +24,30 @@ module Gitlab
end end
def platform_trace(platform_key, key, data, &block) def platform_trace(platform_key, key, data, &block)
tags = { platform_key: platform_key, key: key }
start = Gitlab::Metrics::System.monotonic_time start = Gitlab::Metrics::System.monotonic_time
yield with_labkit_tracing(tags, &block)
ensure ensure
duration = Gitlab::Metrics::System.monotonic_time - start 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 end
private 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 def graphql_duration_seconds
@graphql_duration_seconds ||= Gitlab::Metrics.histogram( @graphql_duration_seconds ||= Gitlab::Metrics.histogram(
:graphql_duration_seconds, :graphql_duration_seconds,
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
describe Gitlab::Graphql::Tracing do describe Gitlab::Graphql::GenericTracing do
let(:graphql_duration_seconds_histogram) { double('Gitlab::Metrics::NullMetric') } let(:graphql_duration_seconds_histogram) { double('Gitlab::Metrics::NullMetric') }
it 'updates graphql histogram with expected labels' do it 'updates graphql histogram with expected labels' do
...@@ -23,6 +23,40 @@ describe Gitlab::Graphql::Tracing do ...@@ -23,6 +23,40 @@ describe Gitlab::Graphql::Tracing do
GitlabSchema.execute(query, context: { tracers: [tracer] }) GitlabSchema.execute(query, context: { tracers: [tracer] })
end 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 private
def expect_metric(platform_key, key) def expect_metric(platform_key, key)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment