Commit 3f3d2c06 authored by Sean McGivern's avatar Sean McGivern

Merge branch 'sh-add-gitaly-backtrace' into 'master'

Add backtrace to Gitaly performance bar

Closes #60092

See merge request gitlab-org/gitlab-ce!27345
parents 35182706 fbb3fd13
<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: {
......@@ -61,9 +63,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;
}
}
......
---
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)
......
......@@ -9565,6 +9565,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,7 +54,9 @@ describe('detailedMetric', () => {
});
it('adds a modal with a table of the details', () => {
vm.$el.querySelectorAll('.performance-bar-modal td strong').forEach((duration, index) => {
vm.$el
.querySelectorAll('.performance-bar-modal td:nth-child(1)')
.forEach((duration, index) => {
expect(duration.innerText).toContain(requestDetails[index].duration);
});
......@@ -65,9 +67,15 @@ 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');
});
});
......
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