Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
3eaf18fc
Commit
3eaf18fc
authored
Nov 09, 2021
by
Paul Slaughter
Committed by
Bob Van Landuyt
Nov 09, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Step 3 - Add MetricsTracer to Graphql Schema
parent
b378ddef
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
161 additions
and
5 deletions
+161
-5
app/graphql/gitlab_schema.rb
app/graphql/gitlab_schema.rb
+1
-0
lib/gitlab/graphql/known_operations.rb
lib/gitlab/graphql/known_operations.rb
+5
-0
lib/gitlab/graphql/tracers/metrics_tracer.rb
lib/gitlab/graphql/tracers/metrics_tracer.rb
+48
-0
lib/gitlab/metrics/rails_slis.rb
lib/gitlab/metrics/rails_slis.rb
+17
-3
spec/lib/gitlab/graphql/known_operations_spec.rb
spec/lib/gitlab/graphql/known_operations_spec.rb
+8
-0
spec/lib/gitlab/graphql/tracers/metrics_tracer_spec.rb
spec/lib/gitlab/graphql/tracers/metrics_tracer_spec.rb
+60
-0
spec/lib/gitlab/metrics/rails_slis_spec.rb
spec/lib/gitlab/metrics/rails_slis_spec.rb
+22
-2
No files found.
app/graphql/gitlab_schema.rb
View file @
3eaf18fc
...
@@ -12,6 +12,7 @@ class GitlabSchema < GraphQL::Schema
...
@@ -12,6 +12,7 @@ class GitlabSchema < GraphQL::Schema
# Tracers (order is important)
# Tracers (order is important)
use
Gitlab
::
Graphql
::
Tracers
::
ApplicationContextTracer
use
Gitlab
::
Graphql
::
Tracers
::
ApplicationContextTracer
use
Gitlab
::
Graphql
::
Tracers
::
MetricsTracer
use
Gitlab
::
Graphql
::
Tracers
::
LoggerTracer
use
Gitlab
::
Graphql
::
Tracers
::
LoggerTracer
use
Gitlab
::
Graphql
::
GenericTracing
# Old tracer which will be removed eventually
use
Gitlab
::
Graphql
::
GenericTracing
# Old tracer which will be removed eventually
use
Gitlab
::
Graphql
::
Tracers
::
TimerTracer
use
Gitlab
::
Graphql
::
Tracers
::
TimerTracer
...
...
lib/gitlab/graphql/known_operations.rb
View file @
3eaf18fc
...
@@ -7,6 +7,11 @@ module Gitlab
...
@@ -7,6 +7,11 @@ module Gitlab
def
to_caller_id
def
to_caller_id
"graphql:
#{
name
}
"
"graphql:
#{
name
}
"
end
end
def
query_urgency
# We'll be able to actually correlate query_urgency with https://gitlab.com/gitlab-org/gitlab/-/issues/345141
::
Gitlab
::
EndpointAttributes
::
DEFAULT_URGENCY
end
end
end
ANONYMOUS
=
Operation
.
new
(
"anonymous"
).
freeze
ANONYMOUS
=
Operation
.
new
(
"anonymous"
).
freeze
...
...
lib/gitlab/graphql/tracers/metrics_tracer.rb
0 → 100644
View file @
3eaf18fc
# frozen_string_literal: true
module
Gitlab
module
Graphql
module
Tracers
class
MetricsTracer
def
self
.
use
(
schema
)
schema
.
tracer
(
self
.
new
)
end
# See https://graphql-ruby.org/api-doc/1.12.16/GraphQL/Tracing for full list of events
def
trace
(
key
,
data
)
result
=
yield
case
key
when
"execute_query"
increment_query_sli
(
data
)
end
result
end
private
def
increment_query_sli
(
data
)
duration_s
=
data
.
fetch
(
:duration_s
,
nil
)
query
=
data
.
fetch
(
:query
,
nil
)
# We're just being defensive here...
# duration_s comes from TimerTracer and we should be pretty much guaranteed it exists
return
unless
duration_s
&&
query
operation
=
::
Gitlab
::
Graphql
::
KnownOperations
.
default
.
from_query
(
query
)
query_urgency
=
operation
.
query_urgency
Gitlab
::
Metrics
::
RailsSlis
.
graphql_query_apdex
.
increment
(
labels:
{
endpoint_id:
::
Gitlab
::
ApplicationContext
.
current_context_attribute
(
:caller_id
),
feature_category:
::
Gitlab
::
ApplicationContext
.
current_context_attribute
(
:feature_category
),
query_urgency:
query_urgency
.
name
},
success:
duration_s
<=
query_urgency
.
duration
)
end
end
end
end
end
lib/gitlab/metrics/rails_slis.rb
View file @
3eaf18fc
...
@@ -5,17 +5,31 @@ module Gitlab
...
@@ -5,17 +5,31 @@ module Gitlab
module
RailsSlis
module
RailsSlis
class
<<
self
class
<<
self
def
initialize_request_slis_if_needed!
def
initialize_request_slis_if_needed!
return
if
Gitlab
::
Metrics
::
Sli
.
initialized?
(
:rails_request_apdex
)
Gitlab
::
Metrics
::
Sli
.
initialize_sli
(
:rails_request_apdex
,
possible_request_labels
)
unless
Gitlab
::
Metrics
::
Sli
.
initialized?
(
:rails_request_apdex
)
Gitlab
::
Metrics
::
Sli
.
initialize_sli
(
:graphql_query_apdex
,
possible_graphql_query_labels
)
unless
Gitlab
::
Metrics
::
Sli
.
initialized?
(
:graphql_query_apdex
)
Gitlab
::
Metrics
::
Sli
.
initialize_sli
(
:rails_request_apdex
,
possible_request_labels
)
end
end
def
request_apdex
def
request_apdex
Gitlab
::
Metrics
::
Sli
[
:rails_request_apdex
]
Gitlab
::
Metrics
::
Sli
[
:rails_request_apdex
]
end
end
def
graphql_query_apdex
Gitlab
::
Metrics
::
Sli
[
:graphql_query_apdex
]
end
private
private
def
possible_graphql_query_labels
::
Gitlab
::
Graphql
::
KnownOperations
.
default
.
operations
.
map
do
|
op
|
{
endpoint_id:
op
.
to_caller_id
,
# We'll be able to correlate feature_category with https://gitlab.com/gitlab-org/gitlab/-/issues/328535
feature_category:
nil
,
query_urgency:
op
.
query_urgency
.
name
}
end
end
def
possible_request_labels
def
possible_request_labels
possible_controller_labels
+
possible_api_labels
possible_controller_labels
+
possible_api_labels
end
end
...
...
spec/lib/gitlab/graphql/known_operations_spec.rb
View file @
3eaf18fc
...
@@ -54,6 +54,14 @@ RSpec.describe Gitlab::Graphql::KnownOperations do
...
@@ -54,6 +54,14 @@ RSpec.describe Gitlab::Graphql::KnownOperations do
end
end
end
end
describe
"Opeartion#query_urgency"
do
it
"returns the associated query urgency"
do
query
=
::
GraphQL
::
Query
.
new
(
fake_schema
,
"query foo { helloWorld }"
)
expect
(
subject
.
from_query
(
query
).
query_urgency
).
to
equal
(
::
Gitlab
::
EndpointAttributes
::
DEFAULT_URGENCY
)
end
end
describe
".default"
do
describe
".default"
do
it
"returns a memoization of values from webpack"
,
:aggregate_failures
do
it
"returns a memoization of values from webpack"
,
:aggregate_failures
do
# .default could have been referenced in another spec, so we need to clean it up here
# .default could have been referenced in another spec, so we need to clean it up here
...
...
spec/lib/gitlab/graphql/tracers/metrics_tracer_spec.rb
0 → 100644
View file @
3eaf18fc
# frozen_string_literal: true
require
'fast_spec_helper'
require
'rspec-parameterized'
require
"support/graphql/fake_query_type"
RSpec
.
describe
Gitlab
::
Graphql
::
Tracers
::
MetricsTracer
do
using
RSpec
::
Parameterized
::
TableSyntax
let
(
:default_known_operations
)
{
::
Gitlab
::
Graphql
::
KnownOperations
.
new
(
%w(lorem foo bar)
)
}
let
(
:fake_schema
)
do
Class
.
new
(
GraphQL
::
Schema
)
do
use
Gitlab
::
Graphql
::
Tracers
::
ApplicationContextTracer
use
Gitlab
::
Graphql
::
Tracers
::
MetricsTracer
use
Gitlab
::
Graphql
::
Tracers
::
TimerTracer
query
Graphql
::
FakeQueryType
end
end
around
do
|
example
|
::
Gitlab
::
ApplicationContext
.
with_context
(
feature_category:
'test_feature_category'
)
do
example
.
run
end
end
before
do
allow
(
::
Gitlab
::
Graphql
::
KnownOperations
).
to
receive
(
:default
).
and_return
(
default_known_operations
)
end
describe
'when used as tracer and query is executed'
do
where
(
:duration
,
:expected_success
)
do
0.1
|
true
0.1
+
::
Gitlab
::
EndpointAttributes
::
DEFAULT_URGENCY
.
duration
|
false
end
with_them
do
it
'increments sli'
do
# Trigger initialization
fake_schema
# setup timer
current_time
=
0
allow
(
Gitlab
::
Metrics
::
System
).
to
receive
(
:monotonic_time
)
{
current_time
+=
duration
}
expect
(
Gitlab
::
Metrics
::
RailsSlis
.
graphql_query_apdex
).
to
receive
(
:increment
).
with
(
labels:
{
endpoint_id:
'graphql:lorem'
,
feature_category:
'test_feature_category'
,
query_urgency:
::
Gitlab
::
EndpointAttributes
::
DEFAULT_URGENCY
.
name
},
success:
expected_success
)
fake_schema
.
execute
(
"query lorem { helloWorld }"
)
end
end
end
end
spec/lib/gitlab/metrics/rails_slis_spec.rb
View file @
3eaf18fc
...
@@ -10,10 +10,11 @@ RSpec.describe Gitlab::Metrics::RailsSlis do
...
@@ -10,10 +10,11 @@ RSpec.describe Gitlab::Metrics::RailsSlis do
allow
(
Gitlab
::
RequestEndpoints
).
to
receive
(
:all_api_endpoints
).
and_return
([
api_route
])
allow
(
Gitlab
::
RequestEndpoints
).
to
receive
(
:all_api_endpoints
).
and_return
([
api_route
])
allow
(
Gitlab
::
RequestEndpoints
).
to
receive
(
:all_controller_actions
).
and_return
([[
ProjectsController
,
'show'
]])
allow
(
Gitlab
::
RequestEndpoints
).
to
receive
(
:all_controller_actions
).
and_return
([[
ProjectsController
,
'show'
]])
allow
(
Gitlab
::
Graphql
::
KnownOperations
).
to
receive
(
:default
).
and_return
(
Gitlab
::
Graphql
::
KnownOperations
.
new
(
%w(foo bar)
))
end
end
describe
'.initialize_request_slis_if_needed!'
do
describe
'.initialize_request_slis_if_needed!'
do
it
"initializes the SLI for all possible endpoints if they weren't"
do
it
"initializes the SLI for all possible endpoints if they weren't"
,
:aggregate_failures
do
possible_labels
=
[
possible_labels
=
[
{
{
endpoint_id:
"GET /api/:version/version"
,
endpoint_id:
"GET /api/:version/version"
,
...
@@ -27,14 +28,25 @@ RSpec.describe Gitlab::Metrics::RailsSlis do
...
@@ -27,14 +28,25 @@ RSpec.describe Gitlab::Metrics::RailsSlis do
}
}
]
]
possible_graphql_labels
=
[
'graphql:foo'
,
'graphql:bar'
,
'graphql:unknown'
,
'graphql:anonymous'
].
map
do
|
endpoint_id
|
{
endpoint_id:
endpoint_id
,
feature_category:
nil
,
query_urgency:
::
Gitlab
::
EndpointAttributes
::
DEFAULT_URGENCY
.
name
}
end
expect
(
Gitlab
::
Metrics
::
Sli
).
to
receive
(
:initialized?
).
with
(
:rails_request_apdex
)
{
false
}
expect
(
Gitlab
::
Metrics
::
Sli
).
to
receive
(
:initialized?
).
with
(
:rails_request_apdex
)
{
false
}
expect
(
Gitlab
::
Metrics
::
Sli
).
to
receive
(
:initialized?
).
with
(
:graphql_query_apdex
)
{
false
}
expect
(
Gitlab
::
Metrics
::
Sli
).
to
receive
(
:initialize_sli
).
with
(
:rails_request_apdex
,
array_including
(
*
possible_labels
)).
and_call_original
expect
(
Gitlab
::
Metrics
::
Sli
).
to
receive
(
:initialize_sli
).
with
(
:rails_request_apdex
,
array_including
(
*
possible_labels
)).
and_call_original
expect
(
Gitlab
::
Metrics
::
Sli
).
to
receive
(
:initialize_sli
).
with
(
:graphql_query_apdex
,
array_including
(
*
possible_graphql_labels
)).
and_call_original
described_class
.
initialize_request_slis_if_needed!
described_class
.
initialize_request_slis_if_needed!
end
end
it
'does not initialize the SLI if they were initialized already'
do
it
'does not initialize the SLI if they were initialized already'
,
:aggregate_failures
do
expect
(
Gitlab
::
Metrics
::
Sli
).
to
receive
(
:initialized?
).
with
(
:rails_request_apdex
)
{
true
}
expect
(
Gitlab
::
Metrics
::
Sli
).
to
receive
(
:initialized?
).
with
(
:rails_request_apdex
)
{
true
}
expect
(
Gitlab
::
Metrics
::
Sli
).
to
receive
(
:initialized?
).
with
(
:graphql_query_apdex
)
{
true
}
expect
(
Gitlab
::
Metrics
::
Sli
).
not_to
receive
(
:initialize_sli
)
expect
(
Gitlab
::
Metrics
::
Sli
).
not_to
receive
(
:initialize_sli
)
described_class
.
initialize_request_slis_if_needed!
described_class
.
initialize_request_slis_if_needed!
...
@@ -48,4 +60,12 @@ RSpec.describe Gitlab::Metrics::RailsSlis do
...
@@ -48,4 +60,12 @@ RSpec.describe Gitlab::Metrics::RailsSlis do
expect
(
described_class
.
request_apdex
).
to
be_initialized
expect
(
described_class
.
request_apdex
).
to
be_initialized
end
end
end
end
describe
'.graphql_query_apdex'
do
it
'returns the initialized request apdex SLI object'
do
described_class
.
initialize_request_slis_if_needed!
expect
(
described_class
.
graphql_query_apdex
).
to
be_initialized
end
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment