Add backtrace to Gitaly performance bar
This adds the backtrace to a table to show exactly where the Gitaly call was made to make it easier to understand where the call originated. This change also collapses the details in the same row to improve the usability when there is a backtrace.
This commit is contained in:
parent
b0c0f81d54
commit
fbb3fd1397
7 changed files with 68 additions and 15 deletions
|
@ -1,9 +1,11 @@
|
|||
<script>
|
||||
import GlModal from '~/vue_shared/components/gl_modal.vue';
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GlModal,
|
||||
Icon,
|
||||
},
|
||||
props: {
|
||||
currentRequest: {
|
||||
|
@ -57,9 +59,31 @@ export default {
|
|||
<template v-if="detailsList.length">
|
||||
<tr v-for="(item, index) in detailsList" :key="index">
|
||||
<td>
|
||||
<strong>{{ item.duration }}ms</strong>
|
||||
<span>{{ item.duration }}ms</span>
|
||||
</td>
|
||||
<td>
|
||||
<div class="js-toggle-container">
|
||||
<div
|
||||
v-for="(key, keyIndex) in keys"
|
||||
:key="key"
|
||||
class="break-word"
|
||||
:class="{ 'mb-3 bold': keyIndex == 0 }"
|
||||
>
|
||||
{{ item[key] }}
|
||||
<button
|
||||
v-if="keyIndex == 0 && item.backtrace"
|
||||
class="text-expander js-toggle-button"
|
||||
type="button"
|
||||
:aria-label="__('Toggle backtrace')"
|
||||
>
|
||||
<icon :size="12" name="ellipsis_h" />
|
||||
</button>
|
||||
</div>
|
||||
<pre v-if="item.backtrace" class="backtrace-row js-toggle-content mt-2">{{
|
||||
item.backtrace
|
||||
}}</pre>
|
||||
</div>
|
||||
</td>
|
||||
<td v-for="key in keys" :key="key" class="break-word">{{ item[key] }}</td>
|
||||
</tr>
|
||||
</template>
|
||||
<template v-else>
|
||||
|
|
|
@ -79,8 +79,12 @@
|
|||
table {
|
||||
color: $black;
|
||||
|
||||
strong {
|
||||
color: $black;
|
||||
td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.backtrace-row {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
5
changelogs/unreleased/sh-add-gitaly-backtrace.yml
Normal file
5
changelogs/unreleased/sh-add-gitaly-backtrace.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add backtrace to Gitaly performance bar
|
||||
merge_request: 27345
|
||||
author:
|
||||
type: other
|
|
@ -165,7 +165,10 @@ module Gitlab
|
|||
current_transaction_labels.merge(gitaly_service: service.to_s, rpc: rpc.to_s),
|
||||
duration)
|
||||
|
||||
add_call_details(feature: "#{service}##{rpc}", duration: duration, request: request_hash, rpc: rpc)
|
||||
if peek_enabled?
|
||||
add_call_details(feature: "#{service}##{rpc}", duration: duration, request: request_hash, rpc: rpc,
|
||||
backtrace: Gitlab::Profiler.clean_backtrace(caller))
|
||||
end
|
||||
end
|
||||
|
||||
def self.query_time
|
||||
|
@ -350,15 +353,17 @@ module Gitlab
|
|||
Gitlab::SafeRequestStore["gitaly_call_permitted"] = 0
|
||||
end
|
||||
|
||||
def self.add_call_details(details)
|
||||
return unless Gitlab::SafeRequestStore[:peek_enabled]
|
||||
def self.peek_enabled?
|
||||
Gitlab::SafeRequestStore[:peek_enabled]
|
||||
end
|
||||
|
||||
def self.add_call_details(details)
|
||||
Gitlab::SafeRequestStore['gitaly_call_details'] ||= []
|
||||
Gitlab::SafeRequestStore['gitaly_call_details'] << details
|
||||
end
|
||||
|
||||
def self.list_call_details
|
||||
return [] unless Gitlab::SafeRequestStore[:peek_enabled]
|
||||
return [] unless peek_enabled?
|
||||
|
||||
Gitlab::SafeRequestStore['gitaly_call_details'] || []
|
||||
end
|
||||
|
|
|
@ -16,7 +16,11 @@ module Gitlab
|
|||
ee/lib/gitlab/middleware/
|
||||
lib/gitlab/performance_bar/
|
||||
lib/gitlab/request_profiler/
|
||||
lib/gitlab/query_limiting/
|
||||
lib/gitlab/tracing/
|
||||
lib/gitlab/profiler.rb
|
||||
lib/gitlab/correlation_id.rb
|
||||
lib/gitlab/webpack/dev_server_middleware.rb
|
||||
].freeze
|
||||
|
||||
# Takes a URL to profile (can be a fully-qualified URL, or an absolute path)
|
||||
|
|
|
@ -9559,6 +9559,9 @@ msgstr ""
|
|||
msgid "Toggle Sidebar"
|
||||
msgstr ""
|
||||
|
||||
msgid "Toggle backtrace"
|
||||
msgstr ""
|
||||
|
||||
msgid "Toggle comments for this file"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -27,8 +27,8 @@ describe('detailedMetric', () => {
|
|||
|
||||
describe('when the current request has details', () => {
|
||||
const requestDetails = [
|
||||
{ duration: '100', feature: 'find_commit', request: 'abcdef' },
|
||||
{ duration: '23', feature: 'rebase_in_progress', request: '' },
|
||||
{ duration: '100', feature: 'find_commit', request: 'abcdef', backtrace: ['hello', 'world'] },
|
||||
{ duration: '23', feature: 'rebase_in_progress', request: '', backtrace: ['world', 'hello'] },
|
||||
];
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -54,9 +54,11 @@ describe('detailedMetric', () => {
|
|||
});
|
||||
|
||||
it('adds a modal with a table of the details', () => {
|
||||
vm.$el.querySelectorAll('.performance-bar-modal td strong').forEach((duration, index) => {
|
||||
expect(duration.innerText).toContain(requestDetails[index].duration);
|
||||
});
|
||||
vm.$el
|
||||
.querySelectorAll('.performance-bar-modal td:nth-child(1)')
|
||||
.forEach((duration, index) => {
|
||||
expect(duration.innerText).toContain(requestDetails[index].duration);
|
||||
});
|
||||
|
||||
vm.$el
|
||||
.querySelectorAll('.performance-bar-modal td:nth-child(2)')
|
||||
|
@ -65,10 +67,16 @@ describe('detailedMetric', () => {
|
|||
});
|
||||
|
||||
vm.$el
|
||||
.querySelectorAll('.performance-bar-modal td:nth-child(3)')
|
||||
.querySelectorAll('.performance-bar-modal td:nth-child(2)')
|
||||
.forEach((request, index) => {
|
||||
expect(request.innerText).toEqual(requestDetails[index].request);
|
||||
expect(request.innerText).toContain(requestDetails[index].request);
|
||||
});
|
||||
|
||||
expect(vm.$el.querySelector('.text-expander.js-toggle-button')).not.toBeNull();
|
||||
|
||||
vm.$el.querySelectorAll('.performance-bar-modal td:nth-child(2)').forEach(request => {
|
||||
expect(request.innerText).toContain('world');
|
||||
});
|
||||
});
|
||||
|
||||
it('displays the metric name', () => {
|
||||
|
|
Loading…
Reference in a new issue