提交 d30576c5 编写于 作者: S Sean McGivern

Add Gitaly call details to the performance bar

The same as the SQL queries, show the details of Gitaly calls in the performance
bar, as a modal that can be opened in the same way.
上级 1bab4dcf
......@@ -18,6 +18,8 @@ export default class PerformanceBar {
this.$sqlProfileModal = $container.find('#modal-peek-pg-queries');
this.$lineProfileLink = $container.find('.js-toggle-modal-peek-line-profile');
this.$lineProfileModal = $('#modal-peek-line-profile');
this.$gitalyProfileLink = $container.find('.js-toggle-modal-peek-gitaly');
this.$gitalyProfileModal = $container.find('#modal-peek-gitaly-details');
this.initEventListeners();
this.showModalOnLoad();
}
......@@ -25,6 +27,7 @@ export default class PerformanceBar {
initEventListeners() {
this.$sqlProfileLink.on('click', () => this.handleSQLProfileLink());
this.$lineProfileLink.on('click', e => this.handleLineProfileLink(e));
this.$gitalyProfileLink.on('click', () => this.handleGitalyProfileLink());
$(document).on('click', '.js-lineprof-file', PerformanceBar.toggleLineProfileFile);
}
......@@ -52,6 +55,10 @@ export default class PerformanceBar {
}
}
handleGitalyProfileLink() {
PerformanceBar.toggleModal(this.$gitalyProfileModal);
}
static toggleModal($modal) {
if ($modal.length) {
$modal.modal('toggle');
......
- local_assigns.fetch(:view)
%strong
%span{ data: { defer_to: "#{view.defer_key}-duration" } } ...
\/
%span{ data: { defer_to: "#{view.defer_key}-calls" } } ...
Gitaly
%a.js-toggle-modal-peek-gitaly
%span{ data: { defer_to: "#{view.defer_key}-duration" } }...
\/
%span{ data: { defer_to: "#{view.defer_key}-calls" } }...
#modal-peek-gitaly-details.modal{ tabindex: -1 }
.modal-dialog.modal-full
.modal-content
.modal-header
%button.close.btn.btn-link.btn-sm{ type: 'button', data: { dismiss: 'modal' } } X
%h4
Gitaly requests
.modal-body{ data: { defer_to: "#{view.defer_key}-details" } }...
Gitaly
---
title: Add Gitaly call details to performance bar
merge_request:
author:
type: added
......@@ -119,6 +119,8 @@ module Gitlab
#
def self.call(storage, service, rpc, request, remote_storage: nil, timeout: nil)
start = Gitlab::Metrics::System.monotonic_time
@last_request = request.is_a?(Google::Protobuf::MessageExts) ? request.to_h : nil
enforce_gitaly_request_limits(:call)
kwargs = request_kwargs(storage, timeout, remote_storage: remote_storage)
......@@ -258,6 +260,9 @@ module Gitlab
gitaly_migrate_call_duration_seconds.observe({ gitaly_enabled: is_enabled, feature: feature }, total_time)
feature_stack.shift
Thread.current[:gitaly_feature_stack] = nil if feature_stack.empty?
add_call_details(feature: feature,
duration: total_time,
request: is_enabled ? @last_request : {})
end
end
end
......@@ -344,6 +349,19 @@ module Gitlab
end
end
def self.add_call_details(details)
return unless RequestStore.active? && RequestStore.store[:peek_enabled]
RequestStore.store['gitaly_call_details'] ||= []
RequestStore.store['gitaly_call_details'] << details
end
def self.call_details
return [] unless RequestStore.active? && RequestStore.store[:peek_enabled]
RequestStore.store['gitaly_call_details'] || []
end
def self.expected_server_version
path = Rails.root.join(SERVER_VERSION_FILE)
path.read.chomp
......
......@@ -10,11 +10,28 @@ module Peek
end
def results
{ duration: formatted_duration, calls: calls }
{
duration: formatted_duration,
calls: calls,
details: details
}
end
private
def details
::Gitlab::GitalyClient.call_details
.sort { |a, b| b[:duration] <=> a[:duration] }
.map(&method(:format_call_details))
end
def format_call_details(call)
pretty_request = call[:request].reject { |k, v| v.blank? }.to_h.pretty_inspect
call.merge(duration: (call[:duration] * 1000).round(3),
request: pretty_request)
end
def formatted_duration
ms = duration * 1000
if ms >= 1000
......
......@@ -3,12 +3,12 @@
*
* - Removed the dependency on jquery.tipsy
* - Removed the initializeTipsy and toggleBar functions
* - Customized updatePerformanceBar to handle SQL queries report specificities
* - Customized updatePerformanceBar to handle SQL query and Gitaly call lists
* - Changed /peek/results to /-/peek/results
* - Removed the keypress, pjax:end, page:change, and turbolinks:load handlers
*/
(function($) {
var fetchRequestResults, getRequestId, peekEnabled, updatePerformanceBar;
var fetchRequestResults, getRequestId, peekEnabled, updatePerformanceBar, createTable, createTableRow;
getRequestId = function() {
return $('#peek').data('requestId');
};
......@@ -16,39 +16,61 @@
return $('#peek').length;
};
updatePerformanceBar = function(results) {
var key, label, data, table, html, tr, duration_td, sql_td, strong;
Object.keys(results.data).forEach(function(key) {
Object.keys(results.data[key]).forEach(function(label) {
var data, table, target;
data = results.data[key][label];
table = createTable(key, label, data);
target = $("[data-defer-to=" + key + "-" + label + "]");
if (label == 'queries') {
table = document.createElement('table');
if (table) {
target.html(table);
} else {
target.text(data);
}
});
});
return $(document).trigger('peek:render', [getRequestId(), results]);
};
createTable = function(key, label, data) {
var table;
for (var i = 0; i < data.length; i += 1) {
tr = document.createElement('tr');
duration_td = document.createElement('td');
sql_td = document.createElement('td');
strong = document.createElement('strong');
if (label != 'queries' && label != 'details') { return; }
strong.append(data[i]['duration'] + 'ms');
duration_td.appendChild(strong);
tr.appendChild(duration_td);
table = document.createElement('table');
sql_td.appendChild(document.createTextNode(data[i]['sql']));
tr.appendChild(sql_td);
for (var i = 0; i < data.length; i += 1) {
table.appendChild(createTableRow(data[i]));
}
table.appendChild(tr);
}
table.className = 'table';
table.className = 'table';
$("[data-defer-to=" + key + "-" + label + "]").html(table);
} else {
$("[data-defer-to=" + key + "-" + label + "]").text(results.data[key][label]);
}
});
return table;
};
createTableRow = function(row) {
var tr, duration_td, strong;
tr = document.createElement('tr');
duration_td = document.createElement('td');
strong = document.createElement('strong');
strong.append(row['duration'] + 'ms');
duration_td.appendChild(strong);
tr.appendChild(duration_td);
['sql', 'feature', 'enabled', 'request'].forEach(function(key) {
var td;
if (!row[key]) { return; }
td = document.createElement('td');
td.appendChild(document.createTextNode(row[key]));
tr.appendChild(td);
});
return $(document).trigger('peek:render', [getRequestId(), results]);
return tr;
};
fetchRequestResults = function() {
return $.ajax('/-/peek/results', {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册