summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/stylesheets/pages/sherlock.scss33
-rw-r--r--app/controllers/sherlock/application_controller.rb12
-rw-r--r--app/controllers/sherlock/file_samples_controller.rb7
-rw-r--r--app/controllers/sherlock/queries_controller.rb7
-rw-r--r--app/controllers/sherlock/transactions_controller.rb19
-rw-r--r--app/views/sherlock/file_samples/show.html.haml55
-rw-r--r--app/views/sherlock/queries/_backtrace.html.haml27
-rw-r--r--app/views/sherlock/queries/_general.html.haml50
-rw-r--r--app/views/sherlock/queries/show.html.haml26
-rw-r--r--app/views/sherlock/transactions/_file_samples.html.haml22
-rw-r--r--app/views/sherlock/transactions/_general.html.haml33
-rw-r--r--app/views/sherlock/transactions/_queries.html.haml24
-rw-r--r--app/views/sherlock/transactions/index.html.haml40
-rw-r--r--app/views/sherlock/transactions/show.html.haml36
14 files changed, 391 insertions, 0 deletions
diff --git a/app/assets/stylesheets/pages/sherlock.scss b/app/assets/stylesheets/pages/sherlock.scss
new file mode 100644
index 00000000000..92d84d9640f
--- /dev/null
+++ b/app/assets/stylesheets/pages/sherlock.scss
@@ -0,0 +1,33 @@
+table .sherlock-code {
+ max-width: 700px;
+}
+
+.sherlock-code {
+ pre {
+ word-wrap: normal;
+ }
+
+ pre code {
+ white-space: pre;
+ }
+}
+
+.sherlock-line-samples-table {
+ margin-bottom: 0px !important;
+
+ thead tr th,
+ tbody tr td {
+ font-size: 13px !important;
+ text-align: right;
+ padding: 0px 10px !important;
+ }
+}
+
+.sherlock-file-sample pre {
+ padding-top: 28px !important;
+}
+
+.sherlock-line-samples-table .slow {
+ color: $red-light;
+ font-weight: bold;
+}
diff --git a/app/controllers/sherlock/application_controller.rb b/app/controllers/sherlock/application_controller.rb
new file mode 100644
index 00000000000..682ca5e3821
--- /dev/null
+++ b/app/controllers/sherlock/application_controller.rb
@@ -0,0 +1,12 @@
+module Sherlock
+ class ApplicationController < ::ApplicationController
+ before_action :find_transaction
+
+ def find_transaction
+ if params[:transaction_id]
+ @transaction = Gitlab::Sherlock.collection.
+ find_transaction(params[:transaction_id])
+ end
+ end
+ end
+end
diff --git a/app/controllers/sherlock/file_samples_controller.rb b/app/controllers/sherlock/file_samples_controller.rb
new file mode 100644
index 00000000000..0c3bc100106
--- /dev/null
+++ b/app/controllers/sherlock/file_samples_controller.rb
@@ -0,0 +1,7 @@
+module Sherlock
+ class FileSamplesController < Sherlock::ApplicationController
+ def show
+ @file_sample = @transaction.find_file_sample(params[:id])
+ end
+ end
+end
diff --git a/app/controllers/sherlock/queries_controller.rb b/app/controllers/sherlock/queries_controller.rb
new file mode 100644
index 00000000000..63b26aab1a4
--- /dev/null
+++ b/app/controllers/sherlock/queries_controller.rb
@@ -0,0 +1,7 @@
+module Sherlock
+ class QueriesController < Sherlock::ApplicationController
+ def show
+ @query = @transaction.find_query(params[:id])
+ end
+ end
+end
diff --git a/app/controllers/sherlock/transactions_controller.rb b/app/controllers/sherlock/transactions_controller.rb
new file mode 100644
index 00000000000..ccc739da879
--- /dev/null
+++ b/app/controllers/sherlock/transactions_controller.rb
@@ -0,0 +1,19 @@
+module Sherlock
+ class TransactionsController < Sherlock::ApplicationController
+ def index
+ @transactions = Gitlab::Sherlock.collection.newest_first
+ end
+
+ def show
+ @transaction = Gitlab::Sherlock.collection.find_transaction(params[:id])
+
+ render_404 unless @transaction
+ end
+
+ def destroy_all
+ Gitlab::Sherlock.collection.clear
+
+ redirect_to(:back)
+ end
+ end
+end
diff --git a/app/views/sherlock/file_samples/show.html.haml b/app/views/sherlock/file_samples/show.html.haml
new file mode 100644
index 00000000000..cfd11e45b6a
--- /dev/null
+++ b/app/views/sherlock/file_samples/show.html.haml
@@ -0,0 +1,55 @@
+- page_title t('sherlock.title'), t('sherlock.transaction'),
+ t('sherlock.file_sample')
+
+- header_title t('sherlock.title'), sherlock_transactions_path
+
+.gray-content-block
+ .pull-right
+ = link_to(sherlock_transaction_path(@transaction), class: 'btn') do
+ %i.fa.fa-arrow-left
+ = t('sherlock.transaction')
+ .oneline
+ = t('sherlock.file_sample')
+ = @file_sample.id
+
+.prepend-top-default
+ %p
+ %span.light
+ #{t('sherlock.time')}:
+ %strong
+ = @file_sample.duration.round(2)
+ = t('sherlock.milliseconds')
+ %p
+ %span.light
+ #{t('sherlock.events')}:
+ %strong
+ = @file_sample.events
+
+%article.file-holder
+ .file-title
+ %i.fa.fa-file-text-o.fa-fw
+ %strong
+ = @file_sample.file
+ .code.file-content.js-syntax-highlight
+ .line-numbers
+ %table.sherlock-line-samples-table
+ %thead
+ %tr
+ %th= t('sherlock.line_capitalized')
+ %th= t('sherlock.events')
+ %th= t('sherlock.time')
+ %th= t('sherlock.percent')
+ %tbody
+ - @file_sample.line_samples.each_with_index do |sample, index|
+ %tr{class: sample.majority_of?(@file_sample.duration) ? 'slow' : ''}
+ %td= index + 1
+ %td= sample.events
+ %td
+ = sample.duration.round(2)
+ = t('sherlock.milliseconds')
+ %td
+ = sample.percentage_of(@file_sample.duration).round
+ = t('sherlock.percent')
+
+ .sherlock-file-sample
+ = highlight(@file_sample.file, @file_sample.source)
diff --git a/app/views/sherlock/queries/_backtrace.html.haml b/app/views/sherlock/queries/_backtrace.html.haml
new file mode 100644
index 00000000000..5c9294c0ab5
--- /dev/null
+++ b/app/views/sherlock/queries/_backtrace.html.haml
@@ -0,0 +1,27 @@
+.prepend-top-default
+ .panel.panel-default
+ .panel-heading
+ %strong
+ = t('sherlock.application_backtrace')
+ %ul.well-list
+ - @query.application_backtrace.each do |location|
+ %li
+ = location.path
+ %small.light
+ = t('sherlock.line')
+ = location.line
+
+ .panel.panel-default
+ .panel-heading
+ %strong
+ = t('sherlock.full_backtrace')
+ %ul.well-list
+ - @query.backtrace.each do |location|
+ %li
+ - if location.application?
+ %strong= location.path
+ - else
+ = location.path
+ %small.light
+ = t('sherlock.line')
+ = location.line
diff --git a/app/views/sherlock/queries/_general.html.haml b/app/views/sherlock/queries/_general.html.haml
new file mode 100644
index 00000000000..549b47430e6
--- /dev/null
+++ b/app/views/sherlock/queries/_general.html.haml
@@ -0,0 +1,50 @@
+.prepend-top-default
+ .panel.panel-default
+ .panel-heading
+ %strong
+ = t('sherlock.general')
+ %ul.well-list
+ %li
+ %span.light
+ #{t('sherlock.time')}:
+ %strong
+ = @query.duration.round(4)
+ = t('sherlock.milliseconds')
+ %li
+ %span.light
+ #{t('sherlock.origin')}:
+ %strong
+ = @query.last_application_frame.path
+ %small.light
+ = t('sherlock.line')
+ = @query.last_application_frame.line
+
+ .panel.panel-default
+ .panel-heading
+ .pull-right
+ %button.js-clipboard-trigger.btn.btn-xs{title: t('sherlock.copy_to_clipboard'), type: :button}
+ %i.fa.fa-clipboard
+ %pre.hidden
+ = @query.formatted_query
+ %strong
+ = t('sherlock.query')
+ %ul.well-list
+ %li
+ .code.js-syntax-highlight.sherlock-code
+ :preserve
+ #{highlight("#{@query.id}.sql", @query.formatted_query)}
+
+ .panel.panel-default
+ .panel-heading
+ .pull-right
+ %button.js-clipboard-trigger.btn.btn-xs{title: t('sherlock.copy_to_clipboard'), type: :button}
+ %i.fa.fa-clipboard
+ %pre.hidden
+ = @query.explain
+ %strong
+ = t('sherlock.query_plan')
+ %ul.well-list
+ %li
+ .code.js-syntax-highlight.sherlock-code
+ %pre
+ %code= @query.explain
diff --git a/app/views/sherlock/queries/show.html.haml b/app/views/sherlock/queries/show.html.haml
new file mode 100644
index 00000000000..4a84348ac82
--- /dev/null
+++ b/app/views/sherlock/queries/show.html.haml
@@ -0,0 +1,26 @@
+- page_title t('sherlock.title'), t('sherlock.transaction'), t('sherlock.query')
+- header_title t('sherlock.title'), sherlock_transactions_path
+
+%ul.center-top-menu
+ %li.active
+ %a(href="#tab-general" data-toggle="tab")
+ = t('sherlock.general')
+ %li
+ %a(href="#tab-backtrace" data-toggle="tab")
+ = t('sherlock.backtrace')
+
+.gray-content-block
+ .pull-right
+ = link_to(sherlock_transaction_path(@transaction), class: 'btn') do
+ %i.fa.fa-arrow-left
+ = t('sherlock.transaction')
+ .oneline
+ = t('sherlock.query')
+ = @query.id
+
+.tab-content
+ .tab-pane.active#tab-general
+ = render(partial: 'general')
+
+ .tab-pane#tab-backtrace
+ = render(partial: 'backtrace')
diff --git a/app/views/sherlock/transactions/_file_samples.html.haml b/app/views/sherlock/transactions/_file_samples.html.haml
new file mode 100644
index 00000000000..0afdbc8dffa
--- /dev/null
+++ b/app/views/sherlock/transactions/_file_samples.html.haml
@@ -0,0 +1,22 @@
+- if @transaction.file_samples.empty?
+ .nothing-here-block
+ = t('sherlock.no_file_samples')
+- else
+ .table-holder
+ %table.table
+ %thead
+ %tr
+ %th= t('sherlock.time_inclusive')
+ %th= t('sherlock.path')
+ %th
+ %tbody
+ - @transaction.sorted_file_samples.each do |sample|
+ %tr
+ %td
+ = sample.duration.round(2)
+ = t('sherlock.milliseconds')
+ %td= sample.relative_path
+ %td
+ = link_to(t('sherlock.view'),
+ sherlock_transaction_file_sample_path(@transaction, sample),
+ class: 'btn btn-xs')
diff --git a/app/views/sherlock/transactions/_general.html.haml b/app/views/sherlock/transactions/_general.html.haml
new file mode 100644
index 00000000000..4287a0c3203
--- /dev/null
+++ b/app/views/sherlock/transactions/_general.html.haml
@@ -0,0 +1,33 @@
+.prepend-top-default
+ .panel.panel-default
+ .panel-heading
+ %strong
+ = t('sherlock.general')
+ %ul.well-list
+ %li
+ %span.light
+ #{t('sherlock.id')}:
+ %strong
+ = @transaction.id
+ %li
+ %span.light
+ #{t('sherlock.type')}:
+ %strong
+ = @transaction.type
+ %li
+ %span.light
+ #{t('sherlock.path')}:
+ %strong
+ = @transaction.path
+ %li
+ %span.light
+ #{t('sherlock.time')}:
+ %strong
+ = @transaction.duration.round(2)
+ = t('sherlock.seconds')
+ %li
+ %span.light
+ #{t('sherlock.finished_at')}:
+ %strong
+ = time_ago_in_words(@transaction.finished_at)
+ = t('sherlock.ago')
diff --git a/app/views/sherlock/transactions/_queries.html.haml b/app/views/sherlock/transactions/_queries.html.haml
new file mode 100644
index 00000000000..b7e0162e80d
--- /dev/null
+++ b/app/views/sherlock/transactions/_queries.html.haml
@@ -0,0 +1,24 @@
+- if @transaction.queries.empty?
+ .nothing-here-block
+ = t('sherlock.no_queries')
+- else
+ .table-holder
+ %table.table#sherlock-queries
+ %thead
+ %tr
+ %th= t('sherlock.time')
+ %th= t('sherlock.query')
+ %td
+ %tbody
+ - @transaction.sorted_queries.each do |query|
+ %tr
+ %td
+ = query.duration.round(2)
+ = t('sherlock.milliseconds')
+ %td
+ .code.js-syntax-highlight.sherlock-code
+ = highlight("#{query.id}.sql", query.formatted_query)
+ %td
+ = link_to(t('sherlock.view'),
+ sherlock_transaction_query_path(@transaction, query),
+ class: 'btn btn-xs')
diff --git a/app/views/sherlock/transactions/index.html.haml b/app/views/sherlock/transactions/index.html.haml
new file mode 100644
index 00000000000..fb31131ba88
--- /dev/null
+++ b/app/views/sherlock/transactions/index.html.haml
@@ -0,0 +1,40 @@
+- page_title t('sherlock.title')
+- header_title t('sherlock.title'), sherlock_transactions_path
+
+.gray-content-block
+ .pull-right
+ = link_to(destroy_all_sherlock_transactions_path,
+ class: 'btn btn-danger',
+ method: :delete) do
+ %i.fa.fa-trash
+ = t('sherlock.delete_all_transactions')
+ .oneline= t('sherlock.introduction')
+
+- if @transactions.empty?
+ .nothing-here-block= t('sherlock.no_transactions')
+- else
+ .table-holder
+ %table.table
+ %thead
+ %tr
+ %th= t('sherlock.type')
+ %th= t('sherlock.path')
+ %th= t('sherlock.time')
+ %th= t('sherlock.queries')
+ %th= t('sherlock.finished_at')
+ %th
+ %tbody
+ - @transactions.each do |trans|
+ %tr
+ %td= trans.type
+ %td= trans.path
+ %td
+ = trans.duration.round(2)
+ = t('sherlock.seconds')
+ %td= trans.queries.length
+ %td
+ = time_ago_in_words(trans.finished_at)
+ = t('sherlock.ago')
+ %td
+ = link_to(sherlock_transaction_path(trans), class: 'btn btn-xs') do
+ = t('sherlock.view')
diff --git a/app/views/sherlock/transactions/show.html.haml b/app/views/sherlock/transactions/show.html.haml
new file mode 100644
index 00000000000..3c8ffb06648
--- /dev/null
+++ b/app/views/sherlock/transactions/show.html.haml
@@ -0,0 +1,36 @@
+- page_title t('sherlock.title'), t('sherlock.transaction')
+- header_title t('sherlock.title'), sherlock_transactions_path
+
+%ul.center-top-menu
+ %li.active
+ %a(href="#tab-general" data-toggle="tab")
+ = t('sherlock.general')
+ %li
+ %a(href="#tab-queries" data-toggle="tab")
+ = t('sherlock.queries')
+ %span.badge
+ #{@transaction.queries.length}
+ %li
+ %a(href="#tab-file-samples" data-toggle="tab")
+ = t('sherlock.file_samples')
+ %span.badge
+ #{@transaction.file_samples.length}
+
+.gray-content-block
+ .pull-right
+ = link_to(sherlock_transactions_path, class: 'btn') do
+ %i.fa.fa-arrow-left
+ = t('sherlock.all_transactions')
+ .oneline
+ = t('sherlock.transaction')
+ = @transaction.id
+
+.tab-content
+ .tab-pane.active#tab-general
+ = render(partial: 'general')
+
+ .tab-pane#tab-queries
+ = render(partial: 'queries')
+
+ .tab-pane#tab-file-samples
+ = render(partial: 'file_samples')