rails_mini_profiler 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +220 -0
  3. data/Rakefile +18 -0
  4. data/app/assets/config/rails_mini_profiler_manifest.js +1 -0
  5. data/app/assets/images/rails_mini_profiler/bookmark.svg +10 -0
  6. data/app/assets/images/rails_mini_profiler/chart.svg +12 -0
  7. data/app/assets/images/rails_mini_profiler/delete.svg +9 -0
  8. data/app/assets/images/rails_mini_profiler/graph.svg +11 -0
  9. data/app/assets/images/rails_mini_profiler/logo.svg +18 -0
  10. data/app/assets/images/rails_mini_profiler/logo_variant.svg +32 -0
  11. data/app/assets/images/rails_mini_profiler/search.svg +10 -0
  12. data/app/assets/images/rails_mini_profiler/setting.svg +10 -0
  13. data/app/assets/images/rails_mini_profiler/show.svg +11 -0
  14. data/app/assets/javascripts/rails_mini_profiler.js +90 -0
  15. data/app/assets/stylesheets/rails_mini_profiler/application.css +164 -0
  16. data/app/assets/stylesheets/rails_mini_profiler/flamegraph.css +14 -0
  17. data/app/assets/stylesheets/rails_mini_profiler/flashes.css +17 -0
  18. data/app/assets/stylesheets/rails_mini_profiler/navbar.css +50 -0
  19. data/app/assets/stylesheets/rails_mini_profiler/profiled_requests.css +180 -0
  20. data/app/assets/stylesheets/rails_mini_profiler/traces.css +87 -0
  21. data/app/controllers/rails_mini_profiler/application_controller.rb +28 -0
  22. data/app/controllers/rails_mini_profiler/flamegraphs_controller.rb +23 -0
  23. data/app/controllers/rails_mini_profiler/profiled_requests_controller.rb +55 -0
  24. data/app/helpers/rails_mini_profiler/application_helper.rb +12 -0
  25. data/app/helpers/rails_mini_profiler/profiled_requests_helper.rb +16 -0
  26. data/app/models/rails_mini_profiler/application_record.rb +17 -0
  27. data/app/models/rails_mini_profiler/controller_trace.rb +33 -0
  28. data/app/models/rails_mini_profiler/flamegraph.rb +33 -0
  29. data/app/models/rails_mini_profiler/instantiation_trace.rb +33 -0
  30. data/app/models/rails_mini_profiler/profiled_request.rb +59 -0
  31. data/app/models/rails_mini_profiler/render_partial_trace.rb +33 -0
  32. data/app/models/rails_mini_profiler/render_template_trace.rb +33 -0
  33. data/app/models/rails_mini_profiler/rmp_trace.rb +31 -0
  34. data/app/models/rails_mini_profiler/sequel_trace.rb +33 -0
  35. data/app/models/rails_mini_profiler/trace.rb +42 -0
  36. data/app/presenters/rails_mini_profiler/base_presenter.rb +25 -0
  37. data/app/presenters/rails_mini_profiler/controller_trace_presenter.rb +18 -0
  38. data/app/presenters/rails_mini_profiler/instantiation_trace_presenter.rb +14 -0
  39. data/app/presenters/rails_mini_profiler/profiled_request_presenter.rb +45 -0
  40. data/app/presenters/rails_mini_profiler/render_partial_trace_presenter.rb +11 -0
  41. data/app/presenters/rails_mini_profiler/render_template_trace_presenter.rb +15 -0
  42. data/app/presenters/rails_mini_profiler/rmp_trace_presenter.rb +9 -0
  43. data/app/presenters/rails_mini_profiler/sequel_trace_presenter.rb +69 -0
  44. data/app/presenters/rails_mini_profiler/trace_presenter.rb +61 -0
  45. data/app/views/layouts/rails_mini_profiler/application.html.erb +26 -0
  46. data/app/views/layouts/rails_mini_profiler/flamegraph.html.erb +18 -0
  47. data/app/views/rails_mini_profiler/badge.html.erb +37 -0
  48. data/app/views/rails_mini_profiler/flamegraphs/show.html.erb +13 -0
  49. data/app/views/rails_mini_profiler/profiled_requests/index.html.erb +59 -0
  50. data/app/views/rails_mini_profiler/profiled_requests/shared/_trace.html.erb +40 -0
  51. data/app/views/rails_mini_profiler/profiled_requests/show.html.erb +40 -0
  52. data/app/views/rails_mini_profiler/shared/_flashes.html.erb +8 -0
  53. data/app/views/rails_mini_profiler/shared/_navbar.html.erb +15 -0
  54. data/config/routes.rb +11 -0
  55. data/db/migrate/20210621185018_create_rmp.rb +44 -0
  56. data/lib/generators/rails_mini_profiler/USAGE +2 -0
  57. data/lib/generators/rails_mini_profiler/install_generator.rb +16 -0
  58. data/lib/generators/rails_mini_profiler/templates/rails_mini_profiler.rb.erb +13 -0
  59. data/lib/rails_mini_profiler.rb +55 -0
  60. data/lib/rails_mini_profiler/badge.rb +62 -0
  61. data/lib/rails_mini_profiler/configuration.rb +41 -0
  62. data/lib/rails_mini_profiler/engine.rb +23 -0
  63. data/lib/rails_mini_profiler/errors.rb +8 -0
  64. data/lib/rails_mini_profiler/flamegraph_guard.rb +47 -0
  65. data/lib/rails_mini_profiler/guard.rb +46 -0
  66. data/lib/rails_mini_profiler/logger.rb +20 -0
  67. data/lib/rails_mini_profiler/middleware.rb +74 -0
  68. data/lib/rails_mini_profiler/models/base_model.rb +18 -0
  69. data/lib/rails_mini_profiler/models/trace.rb +9 -0
  70. data/lib/rails_mini_profiler/redirect.rb +25 -0
  71. data/lib/rails_mini_profiler/request_context.rb +62 -0
  72. data/lib/rails_mini_profiler/request_wrapper.rb +33 -0
  73. data/lib/rails_mini_profiler/response_wrapper.rb +32 -0
  74. data/lib/rails_mini_profiler/storage.rb +29 -0
  75. data/lib/rails_mini_profiler/tracers.rb +85 -0
  76. data/lib/rails_mini_profiler/user.rb +40 -0
  77. data/lib/rails_mini_profiler/version.rb +5 -0
  78. data/lib/tasks/rails_mini_profiler_tasks.rake +8 -0
  79. metadata +151 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5b1f043e04e0f4aaf67b7cfe22be413aa689e51553c3e30e535b2a828d5abde2
4
+ data.tar.gz: '028d6a1d92f6d66552ccf5f7ea9d1c622d15551ba16977c53b773041fd48464c'
5
+ SHA512:
6
+ metadata.gz: 4722b94b458742b5f0c3f3ebe12c119054f053f9a4c783748e5e72686f5676de3fdc7ea5ff9c7aa1bc3872e4ed1d139934aeeb7f653ab40a4818d11b268b85ef
7
+ data.tar.gz: '0958d98854d3df4c1129a2aef7a85dbf0053770f6c761b7901bf3e121acbb2d1116308d419364ce5528b1b8458d68368bb6f32938966b5a35215c45fe8cd2872'
data/README.md ADDED
@@ -0,0 +1,220 @@
1
+ <div align="center">
2
+
3
+ # Rails Mini Profiler
4
+
5
+ <img alt="logo" src="docs/images/logo.png" width="300px" height="auto">
6
+
7
+ ### Performance profiling for Rails, made simple.
8
+
9
+ [![Gem Version](https://badge.fury.io/rb/graphql-groups.svg)](https://badge.fury.io/rb/graphql-groups)
10
+ [![Main](https://github.com/hschne/rails-mini-profiler/actions/workflows/main.yml/badge.svg)](https://github.com/hschne/rails-mini-profiler/actions/workflows/main.yml)
11
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/692d4125ac8548fb145e/test_coverage)](https://codeclimate.com/github/hschne/graphql-groups/test_coverage)
12
+
13
+ </div>
14
+
15
+ ## What's this?
16
+
17
+ Rails Mini Profiler is an easy-to-use performance profiler for your Rails applications. It is heavily inspired by [Rack Mini Profiler](https://github.com/MiniProfiler/rack-mini-profiler) and other APM tools. It looks something like this:
18
+
19
+
20
+
21
+ **Note**: This gem is in early development and I'm looking for contributors. Try it out and leave some feedback, it really goes a long way in helping me out with development. Any [feature request](https://github.com/hschne/rails-mini-profiler/issues/new?assignees=&labels=type%3ABug&template=FEATURE_REQUEST.md&title=) or [bug report](https://github.com/hschne/rails-mini-profiler/issues/new?assignees=&labels=type%3AEnhancement&template=BUG_REPORT.md&title=) is welcome. If you like this project, leave a star to show your support! ⭐
22
+
23
+ ## Getting Started
24
+
25
+ Add Rails Mini Profiler to your Gemfile:
26
+
27
+ ```ruby
28
+ gem 'rails-mini-profiler'
29
+ ```
30
+
31
+ Install the gem and run the installer:
32
+
33
+ ```bash
34
+ bundle install
35
+ rails rail_mini_profiler:install
36
+ ```
37
+
38
+ Inspect the generated migration in `db/migrate` and run it:
39
+
40
+ ```
41
+ rails db:migrate
42
+ ```
43
+
44
+ Start your Rails application and perform some requests. You can either click the little hedgehog 🦔 on the top
45
+ right or navigate to `/rails_mini_profiler` to view collected performance metrics.
46
+
47
+ ## Usage
48
+
49
+ Rails Mini Profiler provides detailed information about your requests to help you figure out why certain requests perform poorly.
50
+
51
+ Installing it will generate a new initializer `config/initializers/rails_mini_profiler.rb` and add a new
52
+ route:
53
+
54
+ ```ruby
55
+ # routes.rb
56
+ Rails.application.routes.draw do
57
+ ...
58
+
59
+ mount RailsMiniProfiler::Engine => '/rails_mini_profiler'
60
+ end
61
+ ```
62
+
63
+ Once you perform requests against your applications you can inspect them using that route, or by clicking the badge on the
64
+ top right that is injected into your pages.
65
+
66
+ ### Request Overview
67
+
68
+ ![overview](docs/images/overview.png)
69
+
70
+ Requests to your application will be profiled automatically. You can view all stored requests by navigating to `yourapp/rails_mini_profiler/profiled_requests`.
71
+
72
+ ### Request Details
73
+
74
+ <p align="center">
75
+ <img alt="Light" src="docs/images/trace.png" width="45%">
76
+ &nbsp; &nbsp; &nbsp; &nbsp;
77
+ <img alt="Dark" src="docs/images/sequel.png" width="45%">
78
+ </p>
79
+
80
+ This view shows you how your requests spend their time. How much of it is spent in the DB, how much in rendering views?
81
+ By clicking on individual traces you can find out detailed information.
82
+
83
+ ### Flamegraphs
84
+
85
+ Rails Mini Profiler per default records Flamegraphs for every profiled request for convenience. Note that Flamegraphs recording
86
+ incur a significant performance penalty, and can take up a lot of space.
87
+
88
+ To change the default behavior see [Configuration](#Configuration).
89
+
90
+ Flamegraphs are rendered using [Speedscope](https://github.com/jlfwong/speedscope). If Flamegraphs are not rendering
91
+ you may have to amend your content security policy. See [Troubleshooting](#Troubleshooting)
92
+
93
+ ## Configuration
94
+
95
+ You can set the following configuration options in Rails Mini Profiler:
96
+
97
+ | Option | Default | Description |
98
+ |--------------------------|------------------------------|-------------------------------------------------------------------------------------------------|
99
+ | `enabled` | `true` (dev)/ `false` (prod) | Whether or not RMP is enabled |
100
+ | `badge_enabled` | `true` | Should the hedgehog 🦔 badge be injected into pages? |
101
+ | `badge_position` | `'top-left'` | Where to display the badge. Options are `'top-left', 'top-right', 'bottom-left, 'bottom-right'` |
102
+ | `flamegraph_enabled` | `true` | Should flamegraphs be recorded automatically? |
103
+ | `flamegraph_sample_rate` | `0.5` | The flamegraph sample rate. How many snapshots per millisecond are created. |
104
+ | `skip_paths` | `[]` | An array of request paths that should not be profiled. Regex allowed. |
105
+ | `storage` | `Storage` | Storage configuration. See [Storage](#Storage) |
106
+ | `user_provider` | `Rack::Request.new(env).ip` | How to identify users. See [Users](#Users) |
107
+
108
+ ### Request Configuration
109
+
110
+ You may override the configuration by sending request parameters. The following parameters are available:
111
+
112
+ | Option | Description |
113
+ |------------------|---------------------------------------------------------------------------------------------|
114
+ | `rmp_flamegraph` | Overrides `flamegraph_enabled` If set to `true` will redirect to the flamegraph immediatly. |
115
+
116
+ ### Storage
117
+
118
+ Rails Mini Profiler stores profiling information in your database per default. You can configure various details of how
119
+ traces and requests are stored.
120
+
121
+ | Configuration | Default | Description |
122
+ |---------------------------|-------------------------|-----------------------------------------------------------------------------------------------------------|
123
+ | `database` | `nil` | Set a custom database to be used for storing profiler information. Uses `connect_to` for profiler records |
124
+ | `profiled_requests_table` | `rmp_profiled_requests` | The table to be used to store profiled requests. |
125
+ | `flamegraphs_table` | `rmp_flamegraphs` | The table to be used to store flamegraphs. |
126
+ | `traces_table` | `rmp_traces` | The table to be used to store traces. |
127
+
128
+ Rails Mini Profiler does not offer an automatic way to clean up old profiling information. It is recommended you add a sweeper job to clean up old profiled requests periodically (e.g. using [clockwork](https://github.com/adamwiggins/clockwork). For example, with ActiveJob:
129
+
130
+ ```
131
+ # Clockwork
132
+ every(1.month, 'purge rails mini profiler' do
133
+ ProfiledRequestCleanupJob.perform_later
134
+ end
135
+
136
+ # ActiveJob
137
+ class ProfiledRequestCleanupJob < ApplicationJob
138
+ queue_as :default
139
+
140
+ def perform(*guests)
141
+ RailsMiniProfiler::ProfiledRequest.where('created_at < ?', 1.month.ago).destroy_all
142
+ end
143
+ end
144
+ ```
145
+
146
+ ### Users
147
+
148
+ Profiling information is segregated by user ID. That means users cannot see each other's profiled requests.
149
+
150
+ Per default, individual users are identified by their IP address. You may change this by setting a custom user provider:
151
+
152
+ ```ruby
153
+ config.user_provider = proc { |env| Rack::Request.new(env).ip }
154
+ ```
155
+
156
+ You may also explicitly set the user from the application itself:
157
+
158
+ ```ruby
159
+ class ApplicationController < ActionController::Base
160
+ ...
161
+
162
+ before_action do
163
+ RailsMiniProfiler::User.authorize(current_user.id)
164
+ end
165
+ end
166
+ ```
167
+
168
+ Note that you **must** set the current user when running Rails Mini Profiler in production. No profiles will be saved otherwise.
169
+
170
+ ### Profiling in Production
171
+
172
+ Rails Mini Profiler is not intended for performance reporting. There are other tools for that ( [Skylight](https://www.skylight.io/),
173
+ [New Relic](https://newrelic.com/), [DataDog](https://www.datadoghq.com/)...).
174
+
175
+ However, you can still use it in production to profile specific requests. Since profiling impacts performance, it is recommended
176
+ that you limit which requests are being profiled:
177
+
178
+ ```ruby
179
+ RailsMiniProfiler.configure do |config|
180
+ config.enabled = proc { |env| env.headers['RMP_ENABLED'].present? }
181
+ end
182
+ ```
183
+
184
+ Only requests by explicitly set users will be stored. To configure how individual users are identified see [Users](#Users)
185
+
186
+ ## Troubleshooting
187
+
188
+ ### Flamegraphs are not rendering?
189
+
190
+ Flamegraphs are loaded into [Speedscope](https://github.com/jlfwong/speedscope) using an Iframe and URI Encoded blobs (see [source](https://github.com/hschne/rails-mini-profiler/blob/main/app/views/rails_mini_profiler/flamegraphs/show.html.erb))
191
+ If your browser gives you warnings about blocking content due to CSP you _must_ enable `blob` as default source:
192
+
193
+ ```ruby
194
+ Rails.application.config.content_security_policy do |policy|
195
+ policy.default_src :self, :blob
196
+ ...
197
+ end
198
+ ```
199
+
200
+ ### Some requests have no Flamegraphs attached?
201
+
202
+ [StackProf](https://github.com/tmm1/stackprof), which is used for recording Flamegraphs, does not work on concurrent requests.
203
+ Because of this, concurrent requests may skip recording a Flamegraph.
204
+
205
+ It is recommended that you resend _only_ the request you wish to get a Flamegraph for.
206
+
207
+ ## Credit
208
+
209
+ This project was heavily inspired by projects such as [rack-mini-profiler](https://github.com/MiniProfiler/rack-mini-profiler) and
210
+ [rack-profiler](https://github.com/dawanda/rack-profiler). [Skylight](https://www.skylight.io/) was also a huge influence.
211
+
212
+ [Lena Schnedlitz](https://github.com/LenaSchnedlitz) designed the Logo and provided great support. Without her supreme CSS skills this project would not have been possible :hands_raised:
213
+
214
+ ## Contributing
215
+
216
+ See [Contributing](CONTRIBUTING.md)
217
+
218
+ ## License
219
+
220
+ This gem is available as open source under the terms of the [MIT License](LICENSE).
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+
5
+ APP_RAKEFILE = File.expand_path('spec/dummy/Rakefile', __dir__)
6
+ load 'rails/tasks/engine.rake'
7
+ load 'rails/tasks/statistics.rake'
8
+
9
+ require 'bundler/gem_tasks'
10
+
11
+ require 'rspec/core/rake_task'
12
+ rspec = RSpec::Core::RakeTask.new(:spec)
13
+ rspec.verbose = false
14
+
15
+ require 'rubocop/rake_task'
16
+ RuboCop::RakeTask.new
17
+
18
+ task default: %i[spec rubocop]
@@ -0,0 +1 @@
1
+ //= link_directory ../stylesheets/rails_mini_profiler .css
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <title>Iconly/Bulk/Bookmark</title>
4
+ <g id="Iconly/Bulk/Bookmark" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
5
+ <g id="Bookmark" transform="translate(4.000000, 2.000000)" fill="#000000" fill-rule="nonzero">
6
+ <path d="M7.99117971,16.6215262 L1.49944873,19.8641008 C1.00920819,20.1302192 0.397682727,19.9525481 0.123484013,19.4643313 C0.043404087,19.3108374 0.00105752372,19.1402321 -5.24025268e-14,18.9668404 L-5.24025268e-14,11.7088036 C-5.24025268e-14,12.4283887 0.405733186,12.872577 1.47298787,13.3700679 L7.99117971,16.6215262 Z" id="Bookmark-2" opacity="0.400000006"></path>
7
+ <path d="M11.0694598,0 C13.7772878,0 15.9735391,1.06605192 16,3.79336809 L16,3.79336809 L16,18.9668404 C15.998918,19.1374024 15.9565307,19.3051222 15.876516,19.4554476 C15.7479482,19.7006536 15.5259405,19.8826876 15.2614691,19.959752 C14.9969977,20.0368164 14.7127851,20.0022901 14.4740904,19.8641008 L14.4740904,19.8641008 L7.99117971,16.6215262 L1.47298787,13.3700679 C0.405733186,12.872577 8.17124146e-14,12.4283887 8.17124146e-14,11.7088036 L8.17124146e-14,11.7088036 L8.17124146e-14,3.79336809 C8.17124146e-14,1.06605192 2.19625138,0 4.8952591,0 L4.8952591,0 Z M11.7486218,6.04096089 L4.22491731,6.04096089 C3.79137074,6.04096089 3.4399118,6.39494927 3.4399118,6.83161607 C3.4399118,7.26828286 3.79137074,7.62227124 4.22491731,7.62227124 L4.22491731,7.62227124 L11.7486218,7.62227124 C12.1821684,7.62227124 12.5336273,7.26828286 12.5336273,6.83161607 C12.5336273,6.39494927 12.1821684,6.04096089 11.7486218,6.04096089 L11.7486218,6.04096089 Z"></path>
8
+ </g>
9
+ </g>
10
+ </svg>
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <title>Iconly/Bulk/Chart</title>
4
+ <g id="Iconly/Bulk/Chart" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
5
+ <g id="Chart" transform="translate(2.000000, 2.000000)" fill="currentColor" fill-rule="nonzero">
6
+ <path d="M14.6755556,0 L5.33333333,0 C1.92888889,0 0,1.92888889 0,5.33333333 L0,14.6666667 C0,18.0711111 1.92888889,20 5.33333333,20 L14.6755556,20 C18.08,20 20,18.0711111 20,14.6666667 L20,5.33333333 C20,1.92888889 18.08,0 14.6755556,0" id="Fill-1" opacity="0.400000006"></path>
7
+ <path d="M5.36871111,7.36897778 C4.91537778,7.36897778 4.54204444,7.74231111 4.54204444,8.20453333 L4.54204444,15.0756444 C4.54204444,15.5289778 4.91537778,15.9023111 5.36871111,15.9023111 C5.83093333,15.9023111 6.20426667,15.5289778 6.20426667,15.0756444 L6.20426667,8.20453333 C6.20426667,7.74231111 5.83093333,7.36897778 5.36871111,7.36897778" id="Fill-4"></path>
8
+ <path d="M10.0353778,4.08897778 C9.58204444,4.08897778 9.20871111,4.46231111 9.20871111,4.92453333 L9.20871111,15.0756444 C9.20871111,15.5289778 9.58204444,15.9023111 10.0353778,15.9023111 C10.4976,15.9023111 10.8709333,15.5289778 10.8709333,15.0756444 L10.8709333,4.92453333 C10.8709333,4.46231111 10.4976,4.08897778 10.0353778,4.08897778" id="Fill-6"></path>
9
+ <path d="M14.6399111,10.9956444 C14.1776889,10.9956444 13.8043556,11.3689778 13.8043556,11.8312 L13.8043556,15.0756444 C13.8043556,15.5289778 14.1776889,15.9023111 14.6310222,15.9023111 C15.0932444,15.9023111 15.4665778,15.5289778 15.4665778,15.0756444 L15.4665778,11.8312 C15.4665778,11.3689778 15.0932444,10.9956444 14.6399111,10.9956444" id="Fill-8"></path>
10
+ </g>
11
+ </g>
12
+ </svg>
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <g id="Iconly/Bulk/Delete" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
4
+ <g id="Delete" transform="translate(3.000000, 2.000000)" fill="currentColor" fill-rule="nonzero">
5
+ <path d="M16.6432894,7.4884379 C16.6432894,7.55643552 16.1103307,14.2971996 15.8059218,17.1341003 C15.6153015,18.8750394 14.492976,19.9310024 12.8094878,19.9610014 C11.5159931,19.9900003 10.2497298,20 9.00389021,20 C7.68121893,20 6.38772423,19.9900003 5.13215907,19.9610014 C3.50507888,19.9220027 2.38178085,18.8450404 2.2008861,17.1341003 C1.88772423,14.2871999 1.36449103,7.55643552 1.35476551,7.4884379 C1.34503998,7.28344508 1.41117355,7.0884519 1.54538578,6.93045743 C1.67765291,6.78446254 1.86827318,6.69646562 2.06861898,6.69646562 L15.9391614,6.69646562 C16.1385347,6.69646562 16.3194294,6.78446254 16.4623946,6.93045743 C16.5956343,7.0884519 16.6627404,7.28344508 16.6432894,7.4884379" id="Fill-1" opacity="0.400000006"></path>
6
+ <path d="M18,3.97686081 C18,3.56587519 17.67614,3.24388646 17.2871191,3.24388646 L14.371407,3.24388646 C13.77815,3.24388646 13.2626972,2.82190123 13.1304301,2.22692206 L12.9670413,1.49794757 C12.7384915,0.616978406 11.9497515,-1.50990331e-14 11.0647288,-1.50990331e-14 L6.93624379,-1.50990331e-14 C6.04149557,-1.50990331e-14 5.26053598,0.616978406 5.0232332,1.54594589 L4.87054247,2.22792202 C4.73730279,2.82190123 4.22185001,3.24388646 3.62956559,3.24388646 L0.713853469,3.24388646 C0.323859952,3.24388646 0,3.56587519 0,3.97686081 L0,4.35684751 C0,4.75783348 0.323859952,5.08982186 0.713853469,5.08982186 L17.2871191,5.08982186 C17.67614,5.08982186 18,4.75783348 18,4.35684751 L18,3.97686081 Z" id="Fill-4"></path>
7
+ </g>
8
+ </g>
9
+ </svg>
@@ -0,0 +1,11 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg">
3
+ <g id="Iconly/Bulk/Graph" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
4
+ <g id="Graph" transform="translate(2.000000, 2.000000)" fill="currentColor" fill-rule="nonzero">
5
+ <path d="M8.152754,3.55552761 C8.20368413,3.65919399 8.237323,3.77020981 8.2523868,3.88433813 L8.53082191,8.02425688 L8.53082191,8.02425688 L8.66903307,10.1050779 C8.67046167,10.3190591 8.7040335,10.5316649 8.76866587,10.7360386 C8.9355965,11.1325559 9.33716333,11.3845716 9.77405142,11.3669994 L16.4313342,10.9315476 C16.7196104,10.9267943 16.9980001,11.0346143 17.2052401,11.2312807 C17.3779401,11.3951693 17.4894372,11.6095651 17.524563,11.8401601 L17.5363525,11.9801866 C17.260866,15.7948982 14.4591587,18.9766559 10.6523561,19.797994 C6.84555351,20.6193322 2.94186389,18.8842999 1.06070995,15.534895 C0.518387516,14.5618191 0.179650312,13.4922526 0.0643819183,12.388978 C0.0162285779,12.0623771 -0.00497451535,11.7324952 0.000979225624,11.4025464 C-0.00496594783,7.31273376 2.90747021,3.77695779 6.98433295,2.92456686 C7.47500829,2.84816493 7.95602805,3.10792111 8.152754,3.55552761 Z"
6
+ id="Path"></path>
7
+ <path d="M10.8700123,0.000819186003 C15.42989,0.11682655 19.2623146,3.39578782 20,7.81229094 L19.9929553,7.84487576 L19.9929553,7.84487576 L19.9728274,7.89227188 L19.9756317,8.0223616 C19.9651826,8.19471218 19.8986437,8.36053991 19.7839681,8.49448471 C19.6645145,8.63401054 19.5013145,8.72903004 19.3215929,8.76590816 L19.2119951,8.78094898 L11.5312118,9.27860816 C11.2757261,9.30380455 11.0213466,9.22142251 10.8313499,9.05195453 C10.6730193,8.91073121 10.5717997,8.72009233 10.543203,8.5146766 L10.0276622,0.845062436 C10.0186901,0.819128783 10.0186901,0.791015148 10.0276622,0.765081496 C10.0347061,0.553672114 10.127765,0.353839855 10.2860482,0.210229821 C10.4443315,0.0666197874 10.6546487,-0.00880036929 10.8700123,0.000819186003 Z"
8
+ id="Path" opacity="0.400000006"></path>
9
+ </g>
10
+ </g>
11
+ </svg>
@@ -0,0 +1,18 @@
1
+ <svg id='logo' xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1070" height="1070" viewBox="0 0 1070 1070" version="1.1">
2
+ <style>#logo path{fill:none;stroke-width:64;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4}</style>
3
+ <defs>
4
+ <linearGradient id="shadow">
5
+ <stop offset="0" style="stop-color:#ffffff"/>
6
+ <stop offset="1" style="stop-color:#e5e7eb"/>
7
+ </linearGradient>
8
+ <linearGradient xlink:href="#shadow" id="vertical1" gradientUnits="userSpaceOnUse" x1="279" y1="855" x2="279" y2="791"/>
9
+ <linearGradient xlink:href="#shadow" id="vertical2" gradientUnits="userSpaceOnUse" x1="407" y1="855" x2="407" y2="791"/>
10
+ <linearGradient xlink:href="#shadow" id="angled" gradientUnits="userSpaceOnUse" x1="919" y1="663" x2="791" y2="535"/>
11
+ </defs>
12
+ <path d="m279 791v64" stroke="url(#vertical1)"/>
13
+ <path d="m407 791v64" stroke="url(#vertical2)"/>
14
+ <path d="m599 791c-30.074 0-64 18.798-64 64" stroke="#fff"/>
15
+ <path d="m791 535c15.784 70.529 40.556 124.09 128 128-14.698 70.947-39.743 124.835-128 128h-64c-34.335 7.22-63.695 19.822-64 64" style="stroke-linejoin:round;stroke:url(#angled)"/>
16
+ <circle cx="727" cy="663" r="32" fill="#fff"/>
17
+ <path d="m151 791h202c78.323 0 129.769-51.336 182-128 52.231-76.664 96.239-126.245 192-128h67.286c0 0-4.243-24-6.422-31-2.18-7-5.583 23-10.475 11-4.892-12-11.273-66-19.41-81-8.137-15-18.029 9-29.942-7C716.122 411 702.187 373 685.964 340 669.741 325 651.23 351 630.165 339 609.101 327 585.482 277 559.043 270 532.604 263 503.345 299 471 299 438.655 299 409.396 263 382.957 270.125 356.518 277.25 342.899 317.5 321.835 330 300.77 342.5 262.259 337.25 246.036 353.375 229.813 369.5 235.878 407 223.964 425c-11.914 18-41.806 16.5-49.942 34.625-8.137 18.125 5.482 65.875 0.59 82.375-4.892 16.5-24.295 31.75-26.475 44.875C145.957 600 161 611 161 619c0 21.333-20 42.667-20 64 0 21.333 20 26.667 20 48 0 21.333-5.959 39.677-10 60z" stroke="#fff"/>
18
+ </svg>
@@ -0,0 +1,32 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1070" height="1070" viewBox="0 0 1070 1070" version="1.1">
2
+ <style>path{fill:none;stroke-width:64;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4}</style>
3
+ <defs>
4
+ <linearGradient id="lightShadow">
5
+ <stop offset="0" style="stop-color:#c22121;stop-opacity:1"/>
6
+ <stop offset="1" style="stop-color:#9c1a1a;stop-opacity:0"/>
7
+ </linearGradient>
8
+ <linearGradient id="darkShadow">
9
+ <stop offset="0" style="stop-color:#9c1a1a;stop-opacity:1"/>
10
+ <stop offset="1" style="stop-color:#9c1a1a;stop-opacity:0"/>
11
+ </linearGradient>
12
+ <linearGradient id="pinkToOrange">
13
+ <stop offset="0" style="stop-color:#f21d88"/>
14
+ <stop offset="0.8" style="stop-color:#dc2626"/>
15
+ <stop offset="1" style="stop-color:#f23c1d"/>
16
+ </linearGradient>
17
+ <linearGradient xlink:href="#pinkToOrange" id="default" gradientUnits="userSpaceOnUse" x1="1246.198" y1="1275.081" x2="111.563" y2="237.888"/>
18
+ <linearGradient xlink:href="#pinkToOrange" id="eye" gradientUnits="userSpaceOnUse" x1="660" y1="738.714" x2="761.286" y2="637.429"/>
19
+ <linearGradient xlink:href="#darkShadow" id="leftLeg" gradientUnits="userSpaceOnUse" x1="279" y1="791" x2="279" y2="855"/>
20
+ <linearGradient xlink:href="#darkShadow" id="rightLeg" gradientUnits="userSpaceOnUse" x1="407" y1="791" x2="407" y2="855"/>
21
+ <linearGradient xlink:href="#lightShadow" id="nose" gradientUnits="userSpaceOnUse" x1="794.286" y1="535" x2="919" y2="663"/>
22
+ </defs>
23
+ <circle r="32" cy="663" cx="727" style="fill:url(#eye)"/>
24
+ <path d="m279 791v64" style="stroke:url(#default)"/>
25
+ <path d="m279 791.505v64" style="stroke:url(#leftLeg)"/>
26
+ <path d="m407 791v64" style="stroke:url(#default)"/>
27
+ <path d="m407 791v64" style="stroke:url(#rightLeg)"/>
28
+ <path d="m599 791c-30.074 0-64 18.798-64 64" style="stroke:url(#default)"/>
29
+ <path d="m791 535c15.784 70.529 40.556 124.09 128 128-14.698 70.947-39.743 124.835-128 128h-64c-34.335 7.22-63.695 19.822-64 64" style="stroke-linejoin:round;stroke:url(#default)"/>
30
+ <path d="m791 535c15.784 70.529 40.556 124.09 128 128-14.698 70.947-39.743 124.835-128 128h-64c-34.335 7.22-63.695 19.822-64 64" style="stroke-linejoin:round;stroke:url(#nose)"/>
31
+ <path d="m151 791h202c78.323 0 129.769-51.336 182-128 52.231-76.664 96.239-126.245 192-128h67.286c0 0-4.243-24-6.422-31-2.18-7-5.583 23-10.475 11-4.892-12-11.273-66-19.41-81-8.137-15-18.029 9-29.942-7C716.122 411 702.187 373 685.964 340 669.741 325 651.23 351 630.165 339 609.101 327 585.482 277 559.043 270 532.604 263 503.345 299 471 299 438.655 299 409.396 263 382.957 270.125 356.518 277.25 342.899 317.5 321.835 330 300.77 342.5 262.259 337.25 246.036 353.375 229.813 369.5 235.878 407 223.964 425c-11.914 18-41.806 16.5-49.942 34.625-8.137 18.125 5.482 65.875 0.59 82.375-4.892 16.5-24.295 31.75-26.475 44.875C145.957 600 161 611 161 619c0 21.333-20 42.667-20 64 0 21.333 20 26.667 20 48 0 21.333-5.959 39.677-10 60z" style="stroke:url(#default)"/>
32
+ </svg>
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <title>Iconly/Bulk/Search</title>
4
+ <g id="Iconly/Bulk/Search" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
5
+ <g id="Search" transform="translate(2.000000, 2.000000)" fill="#000000" fill-rule="nonzero">
6
+ <ellipse id="Ellipse_746" cx="8.59921927" cy="8.65324385" rx="8.59921927" ry="8.65324385"></ellipse>
7
+ <path d="M18.674623,19.9552573 C18.3405833,19.9444414 18.0229443,19.8069986 17.7853553,19.5704698 L15.7489321,17.1901566 C15.3123366,16.7908936 15.2766365,16.1123232 15.668898,15.6689038 L15.668898,15.6689038 C15.8525005,15.4831065 16.1021409,15.3786387 16.3625268,15.3786387 C16.6229128,15.3786387 16.8725531,15.4831065 17.0561557,15.6689038 L19.6172468,17.7181208 C19.9861582,18.0957076 20.0999999,18.656254 19.9078887,19.1492153 C19.7157774,19.6421767 19.2536179,19.9754211 18.7279791,20 L18.674623,19.9552573 Z" id="Path_34202" opacity="0.400000006"></path>
8
+ </g>
9
+ </g>
10
+ </svg>
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <title>Iconly/Bulk/Setting</title>
4
+ <g id="Iconly/Bulk/Setting" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
5
+ <g id="Setting" transform="translate(2.499897, 2.000100)" fill="#000000" fill-rule="nonzero">
6
+ <path d="M9.51207539,12.83 C7.9076023,12.83 6.60971643,11.58 6.60971643,10.01 C6.60971643,8.44 7.9076023,7.18 9.51207539,7.18 C11.1165485,7.18 12.3837756,8.44 12.3837756,10.01 C12.3837756,11.58 11.1165485,12.83 9.51207539,12.83" id="Path"></path>
7
+ <path d="M18.730131,12.37 C18.5359591,12.07 18.2600306,11.77 17.9023455,11.58 C17.6161974,11.44 17.4322451,11.21 17.2687319,10.94 C16.7475337,10.08 17.0541209,8.95 17.9227847,8.44 C18.944742,7.87 19.2717684,6.6 18.6790331,5.61 L17.9943217,4.43 C17.411806,3.44 16.1343592,3.09 15.1226214,3.67 C14.2232989,4.15 13.0684871,3.83 12.5472888,2.98 C12.3837756,2.7 12.2917995,2.4 12.3122386,2.1 C12.3428973,1.71 12.2202625,1.34 12.0363101,1.04 C11.6581859,0.42 10.9734745,0 10.217226,0 L8.77626608,0 C8.03023719,0.02 7.34552574,0.42 6.96740151,1.04 C6.77322961,1.34 6.6608143,1.71 6.68125344,2.1 C6.70169259,2.4 6.60971643,2.7 6.44620325,2.98 C5.92500498,3.83 4.77019314,4.15 3.88109021,3.67 C2.85913283,3.09 1.59190568,3.44 0.999170395,4.43 L0.314458948,5.61 C-0.26805676,6.6 0.0589696023,7.87 1.07070741,8.44 C1.93937119,8.95 2.2459584,10.08 1.73497971,10.94 C1.56124696,11.21 1.37729463,11.44 1.09114656,11.58 C0.743681049,11.77 0.437093834,12.07 0.273580653,12.37 C-0.104543579,12.99 -0.0841044313,13.77 0.2940198,14.42 L0.999170395,15.62 C1.37729463,16.26 2.08244522,16.66 2.81825454,16.66 C3.16572005,16.66 3.574503,16.56 3.90152936,16.36 C4.15701871,16.19 4.46360592,16.13 4.80085186,16.13 C5.81258967,16.13 6.6608143,16.96 6.68125344,17.95 C6.68125344,19.1 7.62145424,20 8.8069248,20 L10.1967868,20 C11.3720378,20 12.3122386,19.1 12.3122386,17.95 C12.3428973,16.96 13.191122,16.13 14.2028598,16.13 C14.5298861,16.13 14.8364734,16.19 15.1021823,16.36 C15.4292086,16.56 15.827772,16.66 16.1854571,16.66 C16.9110468,16.66 17.6161974,16.26 17.9943217,15.62 L18.7096918,14.42 C19.0775965,13.75 19.1082552,12.99 18.730131,12.37" id="Path" opacity="0.400000006"></path>
8
+ </g>
9
+ </g>
10
+ </svg>
@@ -0,0 +1,11 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg">
3
+ <g id="Iconly/Bulk/Show" stroke="none" stroke-width="1" fill-rule="evenodd">
4
+ <g id="Show" transform="translate(2.000000, 4.000000)" fill="currentColor" fill-rule="nonzero">
5
+ <path d="M10,0 C12.0682927,0 14.0292683,0.717575758 15.7365854,2.04606061 C17.4439024,3.36387879 18.897561,5.29454545 19.9414634,7.70909091 C20.0195122,7.89236364 20.0195122,8.10666667 19.9414634,8.28121212 C17.8536585,13.110303 14.1365854,16 10,16 L10,16 L9.9902439,16 C5.86341463,16 2.14634146,13.110303 0.0585365854,8.28121212 C-0.0195121951,8.10666667 -0.0195121951,7.89236364 0.0585365854,7.70909091 C2.14634146,2.8790303 5.86341463,0 9.9902439,0 L9.9902439,0 Z M10,4.12121212 C7.84390244,4.12121212 6.09756098,5.8569697 6.09756098,8 C6.09756098,10.1333333 7.84390244,11.8690909 10,11.8690909 C12.1463415,11.8690909 13.8926829,10.1333333 13.8926829,8 C13.8926829,5.8569697 12.1463415,4.12121212 10,4.12121212 Z"
6
+ id="Fill-1" opacity="0.400000006"></path>
7
+ <path d="M12.4309268,7.99689697 C12.4309268,9.32538182 11.3382439,10.4114424 10.0016585,10.4114424 C8.65531707,10.4114424 7.56263415,9.32538182 7.56263415,7.99689697 C7.56263415,7.83204848 7.58214634,7.67786667 7.61141463,7.52271515 L7.66019512,7.52271515 C8.74312195,7.52271515 9.62117073,6.66938182 9.66019512,5.60174545 C9.7675122,5.58332121 9.88458537,5.57265455 10.0016585,5.57265455 C11.3382439,5.57265455 12.4309268,6.65871515 12.4309268,7.99689697"
8
+ id="Fill-4"></path>
9
+ </g>
10
+ </g>
11
+ </svg>
@@ -0,0 +1,90 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file. JavaScript code in this file should be added after the last require_* statement.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require rails-ujs
14
+ //= require_tree .
15
+
16
+ function setupRequestSearch() {
17
+ const profiledRequestNameSearch = document.getElementById('profiled-request-search')
18
+ if (profiledRequestNameSearch) {
19
+ profiledRequestNameSearch.addEventListener('keyup', function (event) {
20
+ if (event.key === 'Enter') {
21
+ event.preventDefault()
22
+ document.getElementById('profiled-request-search-form').submit()
23
+ }
24
+ })
25
+ }
26
+ }
27
+
28
+ function setupTraceSearch() {
29
+ const traceNameSearch = document.getElementById('trace-search')
30
+ if (traceNameSearch) {
31
+ traceNameSearch.addEventListener('keyup', function (event) {
32
+ if (event.key === 'Enter') {
33
+ event.preventDefault()
34
+ document.getElementById('trace-form').submit()
35
+ }
36
+ })
37
+ }
38
+ }
39
+
40
+ function setupRequestTable() {
41
+ const profiledRequestTable = document.getElementById('profiled-requests-table');
42
+ if (profiledRequestTable) {
43
+ const rows = profiledRequestTable.getElementsByTagName('tr')
44
+ for (let i = 0; i < rows.length; i++) {
45
+ const currentRow = profiledRequestTable.rows[i]
46
+ const link = currentRow.dataset.link
47
+ const createClickHandler = function (currentRow) {
48
+ return function () {
49
+ window.location.href = link
50
+ }
51
+ }
52
+ currentRow.onclick = createClickHandler(currentRow)
53
+ }
54
+ }
55
+ }
56
+
57
+ function setupTraceBars () {
58
+ const traceBars = document.querySelectorAll('.trace-bar')
59
+ traceBars.forEach((bar) => {
60
+ const popover = bar.children[0]
61
+ tippy(bar, {
62
+ trigger: 'click',
63
+ content: popover,
64
+ theme: 'rmp',
65
+ maxWidth: '700px',
66
+ placement: 'bottom',
67
+ interactive: true,
68
+ onShow (instance) {
69
+ instance.popper.querySelector('.popover-close').addEventListener('click', () => {
70
+ instance.hide()
71
+ })
72
+ },
73
+ onHide (instance) {
74
+ instance.popper.querySelector('.popover-close').removeEventListener('click', () => {
75
+ instance.hide()
76
+ })
77
+ },
78
+ })
79
+ })
80
+ }
81
+
82
+
83
+ // Trace Bar Popovers
84
+ document.addEventListener('DOMContentLoaded', () => {
85
+ setupRequestTable();
86
+ setupRequestSearch();
87
+ setupTraceBars();
88
+ setupTraceSearch();
89
+ }, false)
90
+