Profiling
To make it easier to track down performance problems GitLab comes with a set of profiling tools, some of these are available by default while others need to be explicitly enabled.
Profiling a URL
There is a Gitlab::Profiler.profile
method, and corresponding
bin/profile-url
script, that enable profiling a GET or POST request to a
specific URL, either as an anonymous user (the default) or as a specific user.
When using the script, command-line documentation is available by passing no arguments.
When using the method in an interactive console session, any changes to the application code within that console session will be reflected in the profiler output.
For example:
Gitlab::Profiler.profile('/my-user')
# Returns a RubyProf::Profile for the regular operation of this request
class UsersController; def show; sleep 100; end; end
Gitlab::Profiler.profile('/my-user')
# Returns a RubyProf::Profile where 100 seconds is spent in UsersController#show
For routes that require authorization you will need to provide a user to
Gitlab::Profiler
. You can do this like so:
Gitlab::Profiler.profile('/gitlab-org/gitlab-test', user: User.first)
The user you provide will need to have a personal access token in the GitLab instance.
Passing a logger:
keyword argument to Gitlab::Profiler.profile
will send
ActiveRecord and ActionController log output to that logger. Further options are
documented with the method source.
There is also a RubyProf printer available:
Gitlab::Profiler::TotalTimeFlatPrinter
. This acts like
RubyProf::FlatPrinter
, but its min_percent
option works on the method’s
total time, not its self time. (This is because we often spend most of our time
in library code, but this comes from calls in our application.) It also offers a
max_percent
option to help filter out outer calls that aren’t useful (like
ActionDispatch::Integration::Session#process
).
There is a convenience method for using this,
Gitlab::Profiler.print_by_total_time
:
result = Gitlab::Profiler.profile('/my-user')
Gitlab::Profiler.print_by_total_time(result, max_percent: 60, min_percent: 2)
# Measure Mode: wall_time
# Thread ID: 70005223698240
# Fiber ID: 70004894952580
# Total: 1.768912
# Sort by: total_time
#
# %self total self wait child calls name
# 0.00 1.017 0.000 0.000 1.017 14 *ActionView::Helpers::RenderingHelper#render
# 0.00 1.017 0.000 0.000 1.017 14 *ActionView::Renderer#render_partial
# 0.00 1.017 0.000 0.000 1.017 14 *ActionView::PartialRenderer#render
# 0.00 1.007 0.000 0.000 1.007 14 *ActionView::PartialRenderer#render_partial
# 0.00 0.930 0.000 0.000 0.930 14 Hamlit::TemplateHandler#call
# 0.00 0.928 0.000 0.000 0.928 14 Temple::Engine#call
# 0.02 0.865 0.000 0.000 0.864 638 *Enumerable#inject
To print the profile in HTML format, use the following example:
result = Gitlab::Profiler.profile('/my-user')
printer = RubyProf::CallStackPrinter.new(result)
printer.print(File.open('/tmp/profile.html', 'w'))
GitLab-Profiler is a project that builds on this to add some additional niceties, such as allowing configuration with a single Yaml file for multiple URLs, and uploading of the profile and log output to S3.
For GitLab.com, you can find the latest results here: http://redash.gitlab.com/dashboard/gitlab-profiler-statistics
Sherlock
Sherlock is a custom profiling tool built into GitLab. Sherlock is only
available when running GitLab in development mode and when setting the
environment variable ENABLE_SHERLOCK
to a non empty value. For example:
ENABLE_SHERLOCK=1 bundle exec rails s
Recorded transactions can be found by navigating to /sherlock/transactions
.
Bullet
Bullet is a Gem that can be used to track down N+1 query problems. Because
Bullet adds quite a bit of logging noise it’s disabled by default. To enable
Bullet, set the environment variable ENABLE_BULLET
to a non-empty value before
starting GitLab. For example:
ENABLE_BULLET=true bundle exec rails s
Bullet will log query problems to both the Rails log as well as the Chrome console.
As a follow up to finding N+1
queries with Bullet, consider writing a QueryRecoder test to prevent a regression.
Help and feedback
If there's something you don't like about this feature
To propose functionality that GitLab does not yet offer
To further help GitLab in shaping new features
If you didn't find what you were looking for
If you want help with something very specific to your use case, and can use some community support
POST ON GITLAB FORUM
If you have problems setting up or using this feature (depending on your GitLab subscription)
REQUEST SUPPORT
To view all GitLab tiers and features or to upgrade
If you want to try all features available in GitLab.com
If you want to try all features available in GitLab self-managed
If you spot an error or a need for improvement and would like to fix it yourself in a merge request
EDIT THIS PAGE
If you would like to suggest an improvement to this doc