Monitor GraphQL with Prometheus

Extends graphql's platform tracing class to observe duration
of graphql methods.

In graphql 1.8.11 is added prometheus class but it's not very useful
for us because it uses prometheus_exporter to export results.
This commit is contained in:
Jan Provaznik 2019-04-02 10:26:53 +00:00 committed by Dmitriy Zaporozhets
parent b7b6f8483d
commit 0e66357a3e
4 changed files with 84 additions and 0 deletions

View file

@ -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)

View file

@ -0,0 +1,5 @@
---
title: Added prometheus monitoring to GraphQL
merge_request:
author:
type: added

View file

@ -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

View file

@ -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