diff --git a/app/graphql/gitlab_schema.rb b/app/graphql/gitlab_schema.rb index 06d26309b5b..ecc34eacc7d 100644 --- a/app/graphql/gitlab_schema.rb +++ b/app/graphql/gitlab_schema.rb @@ -5,6 +5,7 @@ class GitlabSchema < GraphQL::Schema use Gitlab::Graphql::Authorize use Gitlab::Graphql::Present use Gitlab::Graphql::Connections + use Gitlab::Graphql::Tracing query(Types::QueryType) diff --git a/changelogs/unreleased/graphql-prometheus.yml b/changelogs/unreleased/graphql-prometheus.yml new file mode 100644 index 00000000000..180577f3aec --- /dev/null +++ b/changelogs/unreleased/graphql-prometheus.yml @@ -0,0 +1,5 @@ +--- +title: Added prometheus monitoring to GraphQL +merge_request: +author: +type: added diff --git a/lib/gitlab/graphql/tracing.rb b/lib/gitlab/graphql/tracing.rb new file mode 100644 index 00000000000..6b505e4262b --- /dev/null +++ b/lib/gitlab/graphql/tracing.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +module Gitlab + module Graphql + class Tracing < GraphQL::Tracing::PlatformTracing + self.platform_keys = { + 'lex' => 'graphql.lex', + 'parse' => 'graphql.parse', + 'validate' => 'graphql.validate', + 'analyze_query' => 'graphql.analyze', + 'analyze_multiplex' => 'graphql.analyze', + 'execute_multiplex' => 'graphql.execute', + 'execute_query' => 'graphql.execute', + 'execute_query_lazy' => 'graphql.execute', + 'execute_field' => 'graphql.execute', + 'execute_field_lazy' => 'graphql.execute' + } + + def platform_field_key(type, field) + "#{type.name}.#{field.name}" + end + + def platform_trace(platform_key, key, data, &block) + start = Gitlab::Metrics::System.monotonic_time + + yield + ensure + duration = Gitlab::Metrics::System.monotonic_time - start + + graphql_duration_seconds.observe({ platform_key: platform_key, key: key }, duration) + end + + private + + def graphql_duration_seconds + @graphql_duration_seconds ||= Gitlab::Metrics.histogram( + :graphql_duration_seconds, + 'GraphQL execution time' + ) + end + end + end +end diff --git a/spec/lib/gitlab/graphql/tracing_spec.rb b/spec/lib/gitlab/graphql/tracing_spec.rb new file mode 100644 index 00000000000..6bae737d0f6 --- /dev/null +++ b/spec/lib/gitlab/graphql/tracing_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Graphql::Tracing do + let!(:graphql_duration_seconds) { double('Gitlab::Metrics::NullMetric') } + + before do + allow(Gitlab::Metrics) + .to receive(:histogram) + .with(:graphql_duration_seconds, 'GraphQL execution time') + .and_return(graphql_duration_seconds) + end + + it 'updates graphql histogram with expected labels' do + query = 'query { users { id } }' + + 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) + end + + private + + def expect_metric(platform_key, key) + expect(graphql_duration_seconds) + .to receive(:observe) + .with({ platform_key: platform_key, key: key }, be > 0.0) + end +end