summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorStan Hu <stanhu@gmail.com>2019-07-20 22:34:46 -0700
committerStan Hu <stanhu@gmail.com>2019-07-23 21:38:05 -0700
commit291df05e434f5678c47bce9521ff15748d6c767f (patch)
treea9ebe8e457d875b18998ac1a997c2faa0b1889f8 /lib
parent4482b82687e5b647459946338686eca0b53b7ce4 (diff)
downloadgitlab-ce-291df05e434f5678c47bce9521ff15748d6c767f.tar.gz
Add Rugged calls to performance bar
This will help diagnose the source of excessive I/O from Rugged calls. To implement this, we need to obtain the full list of arguments sent to each request method.
Diffstat (limited to 'lib')
-rw-r--r--lib/gitlab/git/repository.rb4
-rw-r--r--lib/gitlab/git/rugged_impl/blob.rb2
-rw-r--r--lib/gitlab/git/rugged_impl/commit.rb6
-rw-r--r--lib/gitlab/git/rugged_impl/repository.rb2
-rw-r--r--lib/gitlab/git/rugged_impl/tree.rb2
-rw-r--r--lib/gitlab/git/rugged_impl/use_rugged.rb10
-rw-r--r--lib/gitlab/rugged_instrumentation.rb19
-rw-r--r--lib/peek/views/rugged.rb56
8 files changed, 92 insertions, 9 deletions
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
index 6e8aa5d578e..27032602828 100644
--- a/lib/gitlab/git/repository.rb
+++ b/lib/gitlab/git/repository.rb
@@ -55,6 +55,10 @@ module Gitlab
@name = @relative_path.split("/").last
end
+ def to_s
+ "<#{self.class.name}: #{self.gl_project_path}>"
+ end
+
def ==(other)
other.is_a?(self.class) && [storage, relative_path] == [other.storage, other.relative_path]
end
diff --git a/lib/gitlab/git/rugged_impl/blob.rb b/lib/gitlab/git/rugged_impl/blob.rb
index 9aea736527b..5c73c0c66a9 100644
--- a/lib/gitlab/git/rugged_impl/blob.rb
+++ b/lib/gitlab/git/rugged_impl/blob.rb
@@ -16,7 +16,7 @@ module Gitlab
override :tree_entry
def tree_entry(repository, sha, path, limit)
if use_rugged?(repository, :rugged_tree_entry)
- wrap_rugged_call { rugged_tree_entry(repository, sha, path, limit) }
+ execute_rugged_call(:rugged_tree_entry, repository, sha, path, limit)
else
super
end
diff --git a/lib/gitlab/git/rugged_impl/commit.rb b/lib/gitlab/git/rugged_impl/commit.rb
index 29ae9bdd851..0eff35ab1c4 100644
--- a/lib/gitlab/git/rugged_impl/commit.rb
+++ b/lib/gitlab/git/rugged_impl/commit.rb
@@ -36,7 +36,7 @@ module Gitlab
override :find_commit
def find_commit(repo, commit_id)
if use_rugged?(repo, :rugged_find_commit)
- wrap_rugged_call { rugged_find(repo, commit_id) }
+ execute_rugged_call(:rugged_find, repo, commit_id)
else
super
end
@@ -45,7 +45,7 @@ module Gitlab
override :batch_by_oid
def batch_by_oid(repo, oids)
if use_rugged?(repo, :rugged_list_commits_by_oid)
- wrap_rugged_call { rugged_batch_by_oid(repo, oids) }
+ execute_rugged_call(:rugged_batch_by_oid, repo, oids)
else
super
end
@@ -68,7 +68,7 @@ module Gitlab
override :commit_tree_entry
def commit_tree_entry(path)
if use_rugged?(@repository, :rugged_commit_tree_entry)
- wrap_rugged_call { rugged_tree_entry(path) }
+ execute_rugged_call(:rugged_tree_entry, path)
else
super
end
diff --git a/lib/gitlab/git/rugged_impl/repository.rb b/lib/gitlab/git/rugged_impl/repository.rb
index 7bed553393c..8fde93e71e2 100644
--- a/lib/gitlab/git/rugged_impl/repository.rb
+++ b/lib/gitlab/git/rugged_impl/repository.rb
@@ -48,7 +48,7 @@ module Gitlab
override :ancestor?
def ancestor?(from, to)
if use_rugged?(self, :rugged_commit_is_ancestor)
- wrap_rugged_call { rugged_is_ancestor?(from, to) }
+ execute_rugged_call(:rugged_is_ancestor?, from, to)
else
super
end
diff --git a/lib/gitlab/git/rugged_impl/tree.rb b/lib/gitlab/git/rugged_impl/tree.rb
index 479c5f9d8b7..389c9d32ccb 100644
--- a/lib/gitlab/git/rugged_impl/tree.rb
+++ b/lib/gitlab/git/rugged_impl/tree.rb
@@ -16,7 +16,7 @@ module Gitlab
override :tree_entries
def tree_entries(repository, sha, path, recursive)
if use_rugged?(repository, :rugged_tree_entries)
- wrap_rugged_call { tree_entries_with_flat_path_from_rugged(repository, sha, path, recursive) }
+ execute_rugged_call(:tree_entries_with_flat_path_from_rugged, repository, sha, path, recursive)
else
super
end
diff --git a/lib/gitlab/git/rugged_impl/use_rugged.rb b/lib/gitlab/git/rugged_impl/use_rugged.rb
index badf943e39c..80b75689334 100644
--- a/lib/gitlab/git/rugged_impl/use_rugged.rb
+++ b/lib/gitlab/git/rugged_impl/use_rugged.rb
@@ -11,17 +11,23 @@ module Gitlab
Gitlab::GitalyClient.can_use_disk?(repo.storage)
end
- def wrap_rugged_call(&block)
+ def execute_rugged_call(method_name, *args)
Gitlab::GitalyClient::StorageSettings.allow_disk_access do
start = Gitlab::Metrics::System.monotonic_time
- result = yield
+ result = send(method_name, *args) # rubocop:disable GitlabSecurity/PublicSend
duration = Gitlab::Metrics::System.monotonic_time - start
if Gitlab::RuggedInstrumentation.active?
Gitlab::RuggedInstrumentation.increment_query_count
Gitlab::RuggedInstrumentation.query_time += duration
+
+ Gitlab::RuggedInstrumentation.add_call_details(
+ feature: method_name,
+ args: args,
+ duration: duration,
+ backtrace: Gitlab::Profiler.clean_backtrace(caller))
end
result
diff --git a/lib/gitlab/rugged_instrumentation.rb b/lib/gitlab/rugged_instrumentation.rb
index 70c06e8b308..8bb8c547ae1 100644
--- a/lib/gitlab/rugged_instrumentation.rb
+++ b/lib/gitlab/rugged_instrumentation.rb
@@ -24,7 +24,24 @@ module Gitlab
end
def self.active?
- Gitlab::SafeRequestStore.active?
+ SafeRequestStore.active?
+ end
+
+ def self.peek_enabled?
+ SafeRequestStore[:peek_enabled]
+ end
+
+ def self.add_call_details(details)
+ return unless peek_enabled?
+
+ Gitlab::SafeRequestStore[:rugged_call_details] ||= []
+ Gitlab::SafeRequestStore[:rugged_call_details] << details
+ end
+
+ def self.list_call_details
+ return [] unless peek_enabled?
+
+ Gitlab::SafeRequestStore[:rugged_call_details] || []
end
end
end
diff --git a/lib/peek/views/rugged.rb b/lib/peek/views/rugged.rb
new file mode 100644
index 00000000000..7e2730e2ae4
--- /dev/null
+++ b/lib/peek/views/rugged.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+module Peek
+ module Views
+ class Rugged < View
+ def duration
+ ::Gitlab::RuggedInstrumentation.query_time
+ end
+
+ def calls
+ ::Gitlab::RuggedInstrumentation.query_count
+ end
+
+ def results
+ {
+ duration: formatted_duration,
+ calls: calls,
+ details: details
+ }
+ end
+
+ private
+
+ def details
+ ::Gitlab::RuggedInstrumentation.list_call_details
+ .sort { |a, b| b[:duration] <=> a[:duration] }
+ .map(&method(:format_call_details))
+ end
+
+ def format_call_details(call)
+ call.merge(duration: (call[:duration] * 1000).round(3),
+ args: format_args(call[:args]))
+ end
+
+ def format_args(args)
+ args.map do |arg|
+ # Needed to avoid infinite as_json calls
+ if arg.is_a?(Gitlab::Git::Repository)
+ arg.to_s
+ else
+ arg
+ end
+ end
+ end
+
+ def formatted_duration
+ ms = duration * 1000
+ if ms >= 1000
+ "%.2fms" % ms
+ else
+ "%.0fms" % ms
+ end
+ end
+ end
+ end
+end