From d4832b0341643d90df8323a5564521d3bcd3abc1 Mon Sep 17 00:00:00 2001
From: Yorick Peterse <yorickpeterse@gmail.com>
Date: Wed, 14 Oct 2015 12:21:57 +0200
Subject: [PATCH] Added rack-lineprof for development

This can be used to measure the time (roughly) spent on a per line
basis. This can also be used to measure timings for views, for example
by adding the following to a URL:

   ?lineprof=app/views/projects/notes/_note

rack-lineprof is only enabled when:

1. The application runs in development mode
2. The used Ruby is MRI
3. The environment variable ENABLE_LINEPROF is set to a non-empty value
---
 Gemfile                              |  1 +
 Gemfile.lock                         |  8 +++++++
 config/environments/development.rb   |  2 +-
 config/initializers/rack_lineprof.rb | 31 ++++++++++++++++++++++++++++
 4 files changed, 41 insertions(+), 1 deletion(-)
 create mode 100644 config/initializers/rack_lineprof.rb

diff --git a/Gemfile b/Gemfile
index 0524803f319..a58fc34bb74 100644
--- a/Gemfile
+++ b/Gemfile
@@ -226,6 +226,7 @@ group :development do
   gem 'rerun', '~> 0.10.0'
   gem 'bullet', require: false
   gem 'active_record_query_trace', require: false
+  gem 'rack-lineprof', platform: :mri
 
   # Better errors handler
   gem 'better_errors', '~> 1.0.1'
diff --git a/Gemfile.lock b/Gemfile.lock
index ed7ea5bb78b..d7feaa0ec58 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -138,6 +138,7 @@ GEM
     daemons (1.2.3)
     database_cleaner (1.4.1)
     debug_inspector (0.0.2)
+    debugger-ruby_core_source (1.3.8)
     default_value_for (3.0.1)
       activerecord (>= 3.2.0, < 5.0)
     descendants_tracker (0.0.4)
@@ -506,6 +507,10 @@ GEM
     rack-attack (4.3.0)
       rack
     rack-cors (0.4.0)
+    rack-lineprof (0.0.3)
+      rack (~> 1.5)
+      rblineprof (~> 0.3.6)
+      term-ansicolor (~> 1.3)
     rack-mini-profiler (0.9.7)
       rack (>= 1.1.3)
     rack-mount (0.8.3)
@@ -544,6 +549,8 @@ GEM
     rb-fsevent (0.9.5)
     rb-inotify (0.9.5)
       ffi (>= 0.5.0)
+    rblineprof (0.3.6)
+      debugger-ruby_core_source (~> 1.3)
     rbvmomi (1.8.2)
       builder
       nokogiri (>= 1.4.1)
@@ -889,6 +896,7 @@ DEPENDENCIES
   quiet_assets (~> 1.0.2)
   rack-attack (~> 4.3.0)
   rack-cors (~> 0.4.0)
+  rack-lineprof
   rack-mini-profiler (~> 0.9.0)
   rack-oauth2 (~> 1.0.5)
   rails (= 4.1.12)
diff --git a/config/environments/development.rb b/config/environments/development.rb
index d7d6aed1602..827a110c249 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -24,7 +24,7 @@ Gitlab::Application.configure do
 
   # Expands the lines which load the assets
   # config.assets.debug = true
-  
+
   # Adds additional error checking when serving assets at runtime.
   # Checks for improperly declared sprockets dependencies.
   # Raises helpful error messages.
diff --git a/config/initializers/rack_lineprof.rb b/config/initializers/rack_lineprof.rb
new file mode 100644
index 00000000000..80d232c3d36
--- /dev/null
+++ b/config/initializers/rack_lineprof.rb
@@ -0,0 +1,31 @@
+# The default colors of rack-lineprof can be very hard to look at in terminals
+# with darker backgrounds. This patch tweaks the colors a bit so the output is
+# actually readable.
+if Rails.env.development? and RUBY_ENGINE == 'ruby' and ENV['ENABLE_LINEPROF']
+  Gitlab::Application.config.middleware.use(Rack::Lineprof)
+
+  module Rack
+    class Lineprof
+      class Sample < Rack::Lineprof::Sample.superclass
+        def format(*)
+          formatted = if level == CONTEXT
+            sprintf "                 | % 3i  %s", line, code
+          else
+            sprintf "% 8.1fms %5i | % 3i  %s", ms, calls, line, code
+          end
+
+          case level
+          when CRITICAL
+            color.red formatted
+          when WARNING
+            color.yellow formatted
+          when NOMINAL
+            color.white formatted
+          else # CONTEXT
+            formatted
+          end
+        end
+      end
+    end
+  end
+end
-- 
GitLab