Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean McGivern <sean@gitlab.com>2018-03-06 17:02:18 +0300
committerSean McGivern <sean@gitlab.com>2018-03-13 15:58:00 +0300
commitd30576c5a7197b167d1f2c472361dd4ce77b8262 (patch)
tree46de5962c850ad92d3f0c63e49db538a8c1e329a
parent1bab4dcffc73f8a2aca90d363a6365e71722c535 (diff)
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.
-rw-r--r--app/assets/javascripts/performance_bar.js7
-rw-r--r--app/views/peek/views/_gitaly.html.haml17
-rw-r--r--changelogs/unreleased/43805-list-gitaly-calls-and-arguments-in-the-performance-bar.yml5
-rw-r--r--lib/gitlab/gitaly_client.rb18
-rw-r--r--lib/peek/views/gitaly.rb19
-rw-r--r--vendor/assets/javascripts/peek.js72
6 files changed, 108 insertions, 30 deletions
diff --git a/app/assets/javascripts/performance_bar.js b/app/assets/javascripts/performance_bar.js
index ef44e2323ef..a224a3440b4 100644
--- a/app/assets/javascripts/performance_bar.js
+++ b/app/assets/javascripts/performance_bar.js
@@ -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');
diff --git a/app/views/peek/views/_gitaly.html.haml b/app/views/peek/views/_gitaly.html.haml
index a7d040d6821..5e7d1565825 100644
--- a/app/views/peek/views/_gitaly.html.haml
+++ b/app/views/peek/views/_gitaly.html.haml
@@ -1,7 +1,16 @@
- 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
diff --git a/changelogs/unreleased/43805-list-gitaly-calls-and-arguments-in-the-performance-bar.yml b/changelogs/unreleased/43805-list-gitaly-calls-and-arguments-in-the-performance-bar.yml
new file mode 100644
index 00000000000..4c63e69f0bb
--- /dev/null
+++ b/changelogs/unreleased/43805-list-gitaly-calls-and-arguments-in-the-performance-bar.yml
@@ -0,0 +1,5 @@
+---
+title: Add Gitaly call details to performance bar
+merge_request:
+author:
+type: added
diff --git a/lib/gitlab/gitaly_client.rb b/lib/gitlab/gitaly_client.rb
index 9cd76630484..c3aa3ccd7b1 100644
--- a/lib/gitlab/gitaly_client.rb
+++ b/lib/gitlab/gitaly_client.rb
@@ -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
diff --git a/lib/peek/views/gitaly.rb b/lib/peek/views/gitaly.rb
index d519d8e86fa..79851640318 100644
--- a/lib/peek/views/gitaly.rb
+++ b/lib/peek/views/gitaly.rb
@@ -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
diff --git a/vendor/assets/javascripts/peek.js b/vendor/assets/javascripts/peek.js
index 695eeb27c17..607517f045f 100644
--- a/vendor/assets/javascripts/peek.js
+++ b/vendor/assets/javascripts/peek.js
@@ -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', {