mini-sharp-hub 0.0.1
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.
- checksums.yaml +7 -0
- data/mini-sharp-hub.gemspec +12 -0
- data/rack-mini-profiler-4.0.1/CHANGELOG.md +424 -0
- data/rack-mini-profiler-4.0.1/README.md +542 -0
- data/rack-mini-profiler-4.0.1/lib/enable_rails_patches.rb +5 -0
- data/rack-mini-profiler-4.0.1/lib/generators/rack_mini_profiler/USAGE +9 -0
- data/rack-mini-profiler-4.0.1/lib/generators/rack_mini_profiler/install_generator.rb +13 -0
- data/rack-mini-profiler-4.0.1/lib/generators/rack_mini_profiler/templates/rack_mini_profiler.rb +8 -0
- data/rack-mini-profiler-4.0.1/lib/generators/rack_profiler/USAGE +2 -0
- data/rack-mini-profiler-4.0.1/lib/generators/rack_profiler/install_generator.rb +16 -0
- data/rack-mini-profiler-4.0.1/lib/html/dot.1.1.2.min.js +2 -0
- data/rack-mini-profiler-4.0.1/lib/html/includes.css +474 -0
- data/rack-mini-profiler-4.0.1/lib/html/includes.js +1520 -0
- data/rack-mini-profiler-4.0.1/lib/html/includes.scss +698 -0
- data/rack-mini-profiler-4.0.1/lib/html/includes.tmpl +333 -0
- data/rack-mini-profiler-4.0.1/lib/html/pretty-print.js +810 -0
- data/rack-mini-profiler-4.0.1/lib/html/profile_handler.js +1 -0
- data/rack-mini-profiler-4.0.1/lib/html/rack-mini-profiler.css +3 -0
- data/rack-mini-profiler-4.0.1/lib/html/rack-mini-profiler.js +2 -0
- data/rack-mini-profiler-4.0.1/lib/html/share.html +10 -0
- data/rack-mini-profiler-4.0.1/lib/html/speedscope/LICENSE +21 -0
- data/rack-mini-profiler-4.0.1/lib/html/speedscope/README.md +3 -0
- data/rack-mini-profiler-4.0.1/lib/html/speedscope/demangle-cpp.1768f4cc.js +4 -0
- data/rack-mini-profiler-4.0.1/lib/html/speedscope/favicon-16x16.f74b3187.png +0 -0
- data/rack-mini-profiler-4.0.1/lib/html/speedscope/favicon-32x32.bc503437.png +0 -0
- data/rack-mini-profiler-4.0.1/lib/html/speedscope/file-format-schema.json +324 -0
- data/rack-mini-profiler-4.0.1/lib/html/speedscope/fonts/source-code-pro-regular.css +8 -0
- data/rack-mini-profiler-4.0.1/lib/html/speedscope/fonts/source-code-pro-v13-regular.woff +0 -0
- data/rack-mini-profiler-4.0.1/lib/html/speedscope/fonts/source-code-pro-v13-regular.woff2 +0 -0
- data/rack-mini-profiler-4.0.1/lib/html/speedscope/import.8ae8aa3d.js +123 -0
- data/rack-mini-profiler-4.0.1/lib/html/speedscope/index.html +2 -0
- data/rack-mini-profiler-4.0.1/lib/html/speedscope/release.txt +3 -0
- data/rack-mini-profiler-4.0.1/lib/html/speedscope/reset.8c46b7a1.css +2 -0
- data/rack-mini-profiler-4.0.1/lib/html/speedscope/source-map.438fa06b.js +24 -0
- data/rack-mini-profiler-4.0.1/lib/html/speedscope/speedscope.f27db165.js +193 -0
- data/rack-mini-profiler-4.0.1/lib/html/vendor.js +848 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler/actions.rb +157 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler/asset_version.rb +6 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler/client_settings.rb +127 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler/config.rb +146 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler/context.rb +14 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler/gc_profiler.rb +158 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler/profiling_methods.rb +167 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler/snapshots_transporter.rb +111 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler/storage/abstract_store.rb +97 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler/storage/file_store.rb +179 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler/storage/memcache_store.rb +105 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler/storage/memory_store.rb +233 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler/storage/redis_store.rb +353 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler/storage.rb +7 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler/timer_struct/base.rb +39 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler/timer_struct/client.rb +90 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler/timer_struct/custom.rb +25 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler/timer_struct/page.rb +146 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler/timer_struct/request.rb +186 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler/timer_struct/sql.rb +89 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler/timer_struct.rb +8 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler/version.rb +8 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler/views.rb +198 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler.rb +670 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler_rails/railtie.rb +234 -0
- data/rack-mini-profiler-4.0.1/lib/mini_profiler_rails/railtie_methods.rb +61 -0
- data/rack-mini-profiler-4.0.1/lib/patches/db/activerecord.rb +44 -0
- data/rack-mini-profiler-4.0.1/lib/patches/db/mongo.rb +18 -0
- data/rack-mini-profiler-4.0.1/lib/patches/db/moped.rb +14 -0
- data/rack-mini-profiler-4.0.1/lib/patches/db/mysql2/alias_method.rb +30 -0
- data/rack-mini-profiler-4.0.1/lib/patches/db/mysql2/prepend.rb +34 -0
- data/rack-mini-profiler-4.0.1/lib/patches/db/mysql2.rb +7 -0
- data/rack-mini-profiler-4.0.1/lib/patches/db/neo4j.rb +16 -0
- data/rack-mini-profiler-4.0.1/lib/patches/db/nobrainer.rb +31 -0
- data/rack-mini-profiler-4.0.1/lib/patches/db/oracle_enhanced.rb +70 -0
- data/rack-mini-profiler-4.0.1/lib/patches/db/pg/alias_method.rb +121 -0
- data/rack-mini-profiler-4.0.1/lib/patches/db/pg/prepend.rb +115 -0
- data/rack-mini-profiler-4.0.1/lib/patches/db/pg.rb +7 -0
- data/rack-mini-profiler-4.0.1/lib/patches/db/plucky.rb +49 -0
- data/rack-mini-profiler-4.0.1/lib/patches/db/riak.rb +105 -0
- data/rack-mini-profiler-4.0.1/lib/patches/db/rsolr.rb +26 -0
- data/rack-mini-profiler-4.0.1/lib/patches/db/sequel.rb +12 -0
- data/rack-mini-profiler-4.0.1/lib/patches/net_patches.rb +27 -0
- data/rack-mini-profiler-4.0.1/lib/patches/sql_patches.rb +74 -0
- data/rack-mini-profiler-4.0.1/lib/prepend_mysql2_patch.rb +5 -0
- data/rack-mini-profiler-4.0.1/lib/prepend_net_http_patch.rb +5 -0
- data/rack-mini-profiler-4.0.1/lib/prepend_pg_patch.rb +5 -0
- data/rack-mini-profiler-4.0.1/lib/rack-mini-profiler.rb +13 -0
- data/rack-mini-profiler-4.0.1/rack-mini-profiler.gemspec +49 -0
- metadata +125 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
require_relative './railtie_methods'
|
|
5
|
+
|
|
6
|
+
module Rack::MiniProfilerRails
|
|
7
|
+
extend Rack::MiniProfilerRailsMethods
|
|
8
|
+
|
|
9
|
+
# call direct if needed to do a defer init
|
|
10
|
+
def self.initialize!(app)
|
|
11
|
+
|
|
12
|
+
raise "MiniProfilerRails initialized twice. Set `require: false' for rack-mini-profiler in your Gemfile" if defined?(@already_initialized) && @already_initialized
|
|
13
|
+
|
|
14
|
+
c = Rack::MiniProfiler.config
|
|
15
|
+
|
|
16
|
+
# By default, only show the MiniProfiler in development mode.
|
|
17
|
+
# To use the MiniProfiler in production, call Rack::MiniProfiler.authorize_request
|
|
18
|
+
# from a hook in your ApplicationController
|
|
19
|
+
#
|
|
20
|
+
# Example:
|
|
21
|
+
# before_action { Rack::MiniProfiler.authorize_request if current_user.is_admin? }
|
|
22
|
+
#
|
|
23
|
+
# NOTE: this must be set here with = and not ||=
|
|
24
|
+
# The out of the box default is "true"
|
|
25
|
+
c.pre_authorize_cb = lambda { |env|
|
|
26
|
+
!Rails.env.test?
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
c.skip_paths ||= []
|
|
30
|
+
|
|
31
|
+
if serves_static_assets?(app)
|
|
32
|
+
c.skip_paths << app.config.assets.prefix
|
|
33
|
+
wp_assets_path = get_webpacker_assets_path()
|
|
34
|
+
c.skip_paths << wp_assets_path if wp_assets_path
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
unless Rails.env.development? || Rails.env.test?
|
|
38
|
+
c.authorization_mode = :allow_authorized
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
if Rails.logger
|
|
42
|
+
c.logger = Rails.logger
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# The file store is just so much less flaky
|
|
46
|
+
# If the user has not changed from the default memory store then switch to the file store, otherwise keep what the user set
|
|
47
|
+
if c.storage == Rack::MiniProfiler::MemoryStore && c.storage_options.nil?
|
|
48
|
+
base_path = Rails.application.config.paths['tmp'].first rescue "#{Rails.root}/tmp"
|
|
49
|
+
tmp = base_path + '/miniprofiler'
|
|
50
|
+
|
|
51
|
+
c.storage_options = { path: tmp }
|
|
52
|
+
c.storage = Rack::MiniProfiler::FileStore
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Quiet the SQL stack traces
|
|
56
|
+
c.backtrace_remove = Rails.root.to_s + "/"
|
|
57
|
+
c.backtrace_includes = [/^\/?(app|config|lib|test)/]
|
|
58
|
+
c.skip_schema_queries = (Rails.env.development? || Rails.env.test?)
|
|
59
|
+
|
|
60
|
+
# Install the Middleware
|
|
61
|
+
app.middleware.insert(0, Rack::MiniProfiler)
|
|
62
|
+
c.enable_advanced_debugging_tools = Rails.env.development?
|
|
63
|
+
|
|
64
|
+
if ::Rack::MiniProfiler.patch_rails?
|
|
65
|
+
# Attach to various Rails methods
|
|
66
|
+
ActiveSupport.on_load(:action_controller) do
|
|
67
|
+
::Rack::MiniProfiler.profile_method(ActionController::Base, :process) { |action| "Executing action: #{action}" }
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
ActiveSupport.on_load(:action_view) do
|
|
71
|
+
::Rack::MiniProfiler.profile_method(ActionView::Template, :render) { |x, y| "Rendering: #{@virtual_path}" }
|
|
72
|
+
end
|
|
73
|
+
else
|
|
74
|
+
subscribe("start_processing.action_controller") do |name, start, finish, id, payload|
|
|
75
|
+
next if !should_measure?
|
|
76
|
+
|
|
77
|
+
current = Rack::MiniProfiler.current
|
|
78
|
+
controller_name = payload[:controller].sub(/Controller\z/, '').downcase
|
|
79
|
+
description = "Executing: #{controller_name}##{payload[:action]}"
|
|
80
|
+
Thread.current[get_key(payload)] = current.current_timer
|
|
81
|
+
Rack::MiniProfiler.current.current_timer = current.current_timer.add_child(description)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
subscribe("process_action.action_controller") do |name, start, finish, id, payload|
|
|
85
|
+
next if !should_measure?
|
|
86
|
+
|
|
87
|
+
key = get_key(payload)
|
|
88
|
+
parent_timer = Thread.current[key]
|
|
89
|
+
next if !parent_timer
|
|
90
|
+
|
|
91
|
+
Thread.current[key] = nil
|
|
92
|
+
Rack::MiniProfiler.current.current_timer.record_time
|
|
93
|
+
Rack::MiniProfiler.current.current_timer = parent_timer
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
subscribe("render_partial.action_view") do |name, start, finish, id, payload|
|
|
97
|
+
render_notification_handler(shorten_identifier(payload[:identifier]), finish, start)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
subscribe("render_template.action_view") do |name, start, finish, id, payload|
|
|
101
|
+
render_notification_handler(shorten_identifier(payload[:identifier]), finish, start)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
if Rack::MiniProfiler.subscribe_sql_active_record
|
|
105
|
+
# we don't want to subscribe if we've already patched a DB driver
|
|
106
|
+
# otherwise we would end up with 2 records for every query
|
|
107
|
+
subscribe("sql.active_record") do |name, start, finish, id, payload|
|
|
108
|
+
next if !should_measure?
|
|
109
|
+
next if payload[:name] =~ /SCHEMA/ && Rack::MiniProfiler.config.skip_schema_queries
|
|
110
|
+
|
|
111
|
+
Rack::MiniProfiler.record_sql(
|
|
112
|
+
payload[:sql],
|
|
113
|
+
(finish - start) * 1000,
|
|
114
|
+
Rack::MiniProfiler.binds_to_params(payload[:binds]),
|
|
115
|
+
payload[:cached]
|
|
116
|
+
)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
subscribe("instantiation.active_record") do |name, start, finish, id, payload|
|
|
120
|
+
next if !should_measure?
|
|
121
|
+
|
|
122
|
+
Rack::MiniProfiler.report_reader_duration(
|
|
123
|
+
(finish - start) * 1000,
|
|
124
|
+
payload[:record_count],
|
|
125
|
+
payload[:class_name]
|
|
126
|
+
)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
@already_initialized = true
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def self.create_engine
|
|
134
|
+
return if defined?(Rack::MiniProfilerRails::Engine)
|
|
135
|
+
klass = Class.new(::Rails::Engine) do
|
|
136
|
+
engine_name 'rack-mini-profiler'
|
|
137
|
+
config.assets.paths << File.expand_path('../../html', __FILE__)
|
|
138
|
+
config.assets.precompile << 'rack-mini-profiler.js'
|
|
139
|
+
config.assets.precompile << 'rack-mini-profiler.css'
|
|
140
|
+
end
|
|
141
|
+
Rack::MiniProfilerRails.const_set("Engine", klass)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def self.subscribe(event, &blk)
|
|
145
|
+
if ActiveSupport::Notifications.respond_to?(:monotonic_subscribe)
|
|
146
|
+
ActiveSupport::Notifications.monotonic_subscribe(event) { |*args| blk.call(*args) }
|
|
147
|
+
else
|
|
148
|
+
ActiveSupport::Notifications.subscribe(event) do |name, start, finish, id, payload|
|
|
149
|
+
blk.call(name, start.to_f, finish.to_f, id, payload)
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def self.get_key(payload)
|
|
155
|
+
"mini_profiler_parent_timer_#{payload[:controller]}_#{payload[:action]}".to_sym
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def self.shorten_identifier(identifier)
|
|
159
|
+
identifier.split('/').last(2).join('/')
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def self.serves_static_assets?(app)
|
|
163
|
+
config = app.config
|
|
164
|
+
|
|
165
|
+
if !config.respond_to?(:assets) || !config.assets.respond_to?(:prefix)
|
|
166
|
+
return false
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
if ::Rails.version >= "5.0.0"
|
|
170
|
+
::Rails.configuration.public_file_server.enabled
|
|
171
|
+
elsif ::Rails.version >= "4.2.0"
|
|
172
|
+
::Rails.configuration.serve_static_files
|
|
173
|
+
else
|
|
174
|
+
::Rails.configuration.serve_static_assets
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
class Railtie < ::Rails::Railtie
|
|
179
|
+
|
|
180
|
+
initializer "rack_mini_profiler.configure_rails_initialization" do |app|
|
|
181
|
+
Rack::MiniProfilerRails.initialize!(app)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# Suppress compression when Rack::Deflater is lower in the middleware
|
|
185
|
+
# stack than Rack::MiniProfiler
|
|
186
|
+
config.after_initialize do |app|
|
|
187
|
+
middlewares = app.middleware.middlewares
|
|
188
|
+
if Rack::MiniProfiler.config.suppress_encoding.nil? &&
|
|
189
|
+
middlewares.include?(Rack::Deflater) &&
|
|
190
|
+
middlewares.include?(Rack::MiniProfiler) &&
|
|
191
|
+
middlewares.index(Rack::Deflater) > middlewares.index(Rack::MiniProfiler)
|
|
192
|
+
Rack::MiniProfiler.config.suppress_encoding = true
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# TODO: Implement something better here
|
|
197
|
+
# config.after_initialize do
|
|
198
|
+
#
|
|
199
|
+
# class ::ActionView::Helpers::AssetTagHelper::JavascriptIncludeTag
|
|
200
|
+
# alias_method :asset_tag_orig, :asset_tag
|
|
201
|
+
# def asset_tag(source,options)
|
|
202
|
+
# current = Rack::MiniProfiler.current
|
|
203
|
+
# return asset_tag_orig(source,options) unless current
|
|
204
|
+
# wrapped = ""
|
|
205
|
+
# unless current.mpt_init
|
|
206
|
+
# current.mpt_init = true
|
|
207
|
+
# wrapped << Rack::MiniProfiler::ClientTimerStruct.init_instrumentation
|
|
208
|
+
# end
|
|
209
|
+
# name = source.split('/')[-1]
|
|
210
|
+
# wrapped << Rack::MiniProfiler::ClientTimerStruct.instrument(name, asset_tag_orig(source,options)).html_safe
|
|
211
|
+
# wrapped
|
|
212
|
+
# end
|
|
213
|
+
# end
|
|
214
|
+
|
|
215
|
+
# class ::ActionView::Helpers::AssetTagHelper::StylesheetIncludeTag
|
|
216
|
+
# alias_method :asset_tag_orig, :asset_tag
|
|
217
|
+
# def asset_tag(source,options)
|
|
218
|
+
# current = Rack::MiniProfiler.current
|
|
219
|
+
# return asset_tag_orig(source,options) unless current
|
|
220
|
+
# wrapped = ""
|
|
221
|
+
# unless current.mpt_init
|
|
222
|
+
# current.mpt_init = true
|
|
223
|
+
# wrapped << Rack::MiniProfiler::ClientTimerStruct.init_instrumentation
|
|
224
|
+
# end
|
|
225
|
+
# name = source.split('/')[-1]
|
|
226
|
+
# wrapped << Rack::MiniProfiler::ClientTimerStruct.instrument(name, asset_tag_orig(source,options)).html_safe
|
|
227
|
+
# wrapped
|
|
228
|
+
# end
|
|
229
|
+
# end
|
|
230
|
+
|
|
231
|
+
# end
|
|
232
|
+
|
|
233
|
+
end
|
|
234
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rack::MiniProfilerRailsMethods
|
|
4
|
+
def render_notification_handler(name, finish, start, name_as_description: false)
|
|
5
|
+
return if !should_measure?
|
|
6
|
+
|
|
7
|
+
description = name_as_description ? name : "Rendering: #{name}"
|
|
8
|
+
current = Rack::MiniProfiler.current.current_timer
|
|
9
|
+
node = current.add_child(description)
|
|
10
|
+
duration = finish - start
|
|
11
|
+
duration_ms = duration * 1000
|
|
12
|
+
node.start -= duration
|
|
13
|
+
node[:start_milliseconds] -= duration_ms
|
|
14
|
+
node.record_time(duration_ms)
|
|
15
|
+
|
|
16
|
+
children_duration = 0
|
|
17
|
+
to_be_moved = { requests: [], sql: [], custom: {} }
|
|
18
|
+
current.children.each do |child|
|
|
19
|
+
next if child == node
|
|
20
|
+
if should_move?(child, node)
|
|
21
|
+
to_be_moved[:requests] << child
|
|
22
|
+
children_duration += child[:duration_milliseconds]
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
node[:duration_without_children_milliseconds] = duration_ms - children_duration
|
|
26
|
+
to_be_moved[:requests].each { |req| current.move_child(req, node) }
|
|
27
|
+
|
|
28
|
+
current.sql_timings.each do |sql|
|
|
29
|
+
to_be_moved[:sql] << sql if should_move?(sql, node)
|
|
30
|
+
end
|
|
31
|
+
to_be_moved[:sql].each { |sql| current.move_sql(sql, node) }
|
|
32
|
+
|
|
33
|
+
current.custom_timings.each do |type, timings|
|
|
34
|
+
to_be_moved[:custom] = []
|
|
35
|
+
timings.each do |custom|
|
|
36
|
+
to_be_moved[:custom] << custom if should_move?(custom, node)
|
|
37
|
+
end
|
|
38
|
+
to_be_moved[:custom].each { |custom| current.move_custom(type, custom, node) }
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def should_measure?
|
|
43
|
+
current = Rack::MiniProfiler.current
|
|
44
|
+
current && current.measure
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def should_move?(child, node)
|
|
48
|
+
start = :start_milliseconds
|
|
49
|
+
duration = :duration_milliseconds
|
|
50
|
+
child[start] >= node[start] &&
|
|
51
|
+
child[start] + child[duration] <= node[start] + node[duration]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def get_webpacker_assets_path
|
|
55
|
+
if defined?(Webpacker) && Webpacker.try(:config)&.config_path&.exist?
|
|
56
|
+
Webpacker.config.public_output_path.to_s.gsub(Webpacker.config.public_path.to_s, "")
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
extend self
|
|
61
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
## based off https://github.com/newrelic/rpm/blob/master/lib/new_relic/agent/instrumentation/active_record.rb
|
|
4
|
+
## fallback for alls sorts of weird dbs
|
|
5
|
+
module Rack
|
|
6
|
+
class MiniProfiler
|
|
7
|
+
module ActiveRecordInstrumentation
|
|
8
|
+
def self.included(instrumented_class)
|
|
9
|
+
instrumented_class.class_eval do
|
|
10
|
+
unless instrumented_class.method_defined?(:log_without_miniprofiler)
|
|
11
|
+
alias_method :log_without_miniprofiler, :log
|
|
12
|
+
alias_method :log, :log_with_miniprofiler
|
|
13
|
+
protected :log
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def log_with_miniprofiler(*args, **kwargs, &block)
|
|
19
|
+
return log_without_miniprofiler(*args, **kwargs, &block) unless SqlPatches.should_measure?
|
|
20
|
+
|
|
21
|
+
sql, name, binds = args
|
|
22
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
23
|
+
rval = log_without_miniprofiler(*args, **kwargs, &block)
|
|
24
|
+
|
|
25
|
+
# Don't log schema queries if the option is set
|
|
26
|
+
return rval if Rack::MiniProfiler.config.skip_schema_queries && name =~ (/SCHEMA/)
|
|
27
|
+
|
|
28
|
+
elapsed_time = SqlPatches.elapsed_time(start)
|
|
29
|
+
Rack::MiniProfiler.record_sql(sql, elapsed_time, Rack::MiniProfiler.binds_to_params(binds))
|
|
30
|
+
rval
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.insert_instrumentation
|
|
36
|
+
ActiveRecord::ConnectionAdapters::AbstractAdapter.module_eval do
|
|
37
|
+
include ::Rack::MiniProfiler::ActiveRecordInstrumentation
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
if defined?(::Rails)
|
|
42
|
+
insert_instrumentation
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Mongo/Mongoid 5 patches
|
|
4
|
+
class Mongo::Server::Connection
|
|
5
|
+
def dispatch_with_timing(*args, &blk)
|
|
6
|
+
return dispatch_without_timing(*args, &blk) unless SqlPatches.should_measure?
|
|
7
|
+
|
|
8
|
+
result, _record = SqlPatches.record_sql(args[0][0].payload.inspect) do
|
|
9
|
+
dispatch_without_timing(*args, &blk)
|
|
10
|
+
end
|
|
11
|
+
result
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# TODO: change to Module#prepend as soon as Ruby 1.9.3 support is dropped
|
|
15
|
+
alias_method :dispatch_without_timing, :dispatch
|
|
16
|
+
alias_method :dispatch, :dispatch_with_timing
|
|
17
|
+
|
|
18
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Mongoid 3 patches
|
|
4
|
+
class Moped::Node
|
|
5
|
+
alias_method :process_without_profiling, :process
|
|
6
|
+
def process(*args, &blk)
|
|
7
|
+
return process_without_profiling(*args, &blk) unless SqlPatches.should_measure?
|
|
8
|
+
|
|
9
|
+
result, _record = SqlPatches.record_sql(args[0].log_inspect) do
|
|
10
|
+
process_without_profiling(*args, &blk)
|
|
11
|
+
end
|
|
12
|
+
result
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# The best kind of instrumentation is in the actual db provider, however we don't want to double instrument
|
|
4
|
+
|
|
5
|
+
class Mysql2::Result
|
|
6
|
+
alias_method :each_without_profiling, :each
|
|
7
|
+
def each(*args, &blk)
|
|
8
|
+
return each_without_profiling(*args, &blk) unless defined?(@miniprofiler_sql_id)
|
|
9
|
+
|
|
10
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
11
|
+
result = each_without_profiling(*args, &blk)
|
|
12
|
+
elapsed_time = SqlPatches.elapsed_time(start)
|
|
13
|
+
|
|
14
|
+
@miniprofiler_sql_id.report_reader_duration(elapsed_time)
|
|
15
|
+
result
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class Mysql2::Client
|
|
20
|
+
alias_method :query_without_profiling, :query
|
|
21
|
+
def query(*args, &blk)
|
|
22
|
+
return query_without_profiling(*args, &blk) unless SqlPatches.should_measure?
|
|
23
|
+
|
|
24
|
+
result, record = SqlPatches.record_sql(args[0]) do
|
|
25
|
+
query_without_profiling(*args, &blk)
|
|
26
|
+
end
|
|
27
|
+
result.instance_variable_set("@miniprofiler_sql_id", record) if result
|
|
28
|
+
result
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Mysql2::Result
|
|
4
|
+
module MiniProfiler
|
|
5
|
+
def each(*args, &blk)
|
|
6
|
+
return super unless defined?(@miniprofiler_sql_id)
|
|
7
|
+
|
|
8
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
9
|
+
result = super
|
|
10
|
+
elapsed_time = SqlPatches.elapsed_time(start)
|
|
11
|
+
|
|
12
|
+
@miniprofiler_sql_id.report_reader_duration(elapsed_time)
|
|
13
|
+
result
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
prepend MiniProfiler
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class Mysql2::Client
|
|
21
|
+
module MiniProfiler
|
|
22
|
+
def query(*args, &blk)
|
|
23
|
+
return super unless SqlPatches.should_measure?
|
|
24
|
+
|
|
25
|
+
result, record = SqlPatches.record_sql(args[0]) do
|
|
26
|
+
super
|
|
27
|
+
end
|
|
28
|
+
result.instance_variable_set("@miniprofiler_sql_id", record) if result
|
|
29
|
+
result
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
prepend MiniProfiler
|
|
34
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Neo4j::Core::Query
|
|
4
|
+
alias_method :response_without_miniprofiler, :response
|
|
5
|
+
|
|
6
|
+
def response
|
|
7
|
+
return @response if @response
|
|
8
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
9
|
+
rval = response_without_miniprofiler
|
|
10
|
+
elapsed_time = SqlPatches.elapsed_time(start)
|
|
11
|
+
Rack::MiniProfiler.record_sql(to_cypher, elapsed_time)
|
|
12
|
+
rval
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
alias_method :response_with_miniprofiler, :response
|
|
16
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Rack::MiniProfiler::NoBrainerProfiler
|
|
4
|
+
|
|
5
|
+
def on_query(env)
|
|
6
|
+
if SqlPatches.should_measure?
|
|
7
|
+
not_indexed = env[:criteria] && env[:criteria].where_present? &&
|
|
8
|
+
!env[:criteria].where_indexed? &&
|
|
9
|
+
!env[:criteria].model.try(:perf_warnings_disabled)
|
|
10
|
+
|
|
11
|
+
query = "".dup
|
|
12
|
+
|
|
13
|
+
# per-model/query database overrides
|
|
14
|
+
query << "[#{env[:options][:db]}] " if env[:options][:db]
|
|
15
|
+
|
|
16
|
+
# "read", "write" prefix
|
|
17
|
+
# query << "(#{NoBrainer::RQL.type_of(env[:query]).to_s}) "
|
|
18
|
+
|
|
19
|
+
query << "NOT USING INDEX: " if not_indexed
|
|
20
|
+
query << env[:query].inspect.delete("\n").gsub(/ +/, ' ') + " "
|
|
21
|
+
|
|
22
|
+
if env[:exception]
|
|
23
|
+
query << "exception: #{env[:exception].class} #{env[:exception].message.split("\n").first} "
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
::Rack::MiniProfiler.record_sql query.strip, env[:duration] * 1000.0
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
NoBrainer::Profiler.register self.new
|
|
31
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class ActiveRecord::Result
|
|
4
|
+
alias_method :each_without_profiling, :each
|
|
5
|
+
def each(&blk)
|
|
6
|
+
return each_without_profiling(&blk) unless defined?(@miniprofiler_sql_id)
|
|
7
|
+
|
|
8
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
9
|
+
result = each_without_profiling(&blk)
|
|
10
|
+
elapsed_time = SqlPatches.elapsed_time(start)
|
|
11
|
+
@miniprofiler_sql_id.report_reader_duration(elapsed_time)
|
|
12
|
+
|
|
13
|
+
result
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter
|
|
18
|
+
SCHEMA_QUERY_TYPES = ["Sequence", "Primary Key", "Primary Key Trigger", nil].freeze
|
|
19
|
+
|
|
20
|
+
alias_method :execute_without_profiling, :execute
|
|
21
|
+
def execute(sql, name = nil)
|
|
22
|
+
mp_profile_sql(sql, name) { execute_without_profiling(sql, name) }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
alias_method :exec_query_without_profiling, :exec_query
|
|
26
|
+
def exec_query(sql, name = 'SQL', binds = [])
|
|
27
|
+
mp_profile_sql(sql, name) { exec_query_without_profiling(sql, name, binds) }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
alias_method :exec_insert_without_profiling, :exec_insert
|
|
31
|
+
def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
|
|
32
|
+
mp_profile_sql(sql, name) { exec_insert_without_profiling(sql, name, binds, pk, sequence_name) }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
alias_method :exec_update_without_profiling, :exec_update
|
|
36
|
+
def exec_update(sql, name, binds)
|
|
37
|
+
mp_profile_sql(sql, name) { exec_update_without_profiling(sql, name, binds) }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# See oracle-enhanced/lib/active_record/connection_adapters/oracle_enhanced_database_statements.rb:183
|
|
41
|
+
# where the exec delete method is aliased in the same way. We just have to do it again here to make sure
|
|
42
|
+
# the new exec_delete alias is linked to our profiling-enabled version.
|
|
43
|
+
alias :exec_delete :exec_update
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def mp_profile_sql(sql, name, &blk)
|
|
48
|
+
return yield unless mp_should_measure?(name)
|
|
49
|
+
|
|
50
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
51
|
+
result = yield
|
|
52
|
+
elapsed_time = SqlPatches.elapsed_time(start)
|
|
53
|
+
record = ::Rack::MiniProfiler.record_sql(sql, elapsed_time)
|
|
54
|
+
|
|
55
|
+
# Some queries return the row count as a Fixnum and will be frozen, don't save a record
|
|
56
|
+
# for those.
|
|
57
|
+
result.instance_variable_set("@miniprofiler_sql_id", record) if (result && !result.frozen?)
|
|
58
|
+
|
|
59
|
+
result
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Only measure when profiling is enabled
|
|
63
|
+
# When skip_schema_queries is set to true, it will ignore any query of the types
|
|
64
|
+
# in the schema_query_types array
|
|
65
|
+
def mp_should_measure?(name)
|
|
66
|
+
return false unless SqlPatches.should_measure?
|
|
67
|
+
|
|
68
|
+
!(Rack::MiniProfiler.config.skip_schema_queries && SCHEMA_QUERY_TYPES.include?(name))
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class PG::Result
|
|
4
|
+
alias_method :each_without_profiling, :each
|
|
5
|
+
alias_method :values_without_profiling, :values
|
|
6
|
+
|
|
7
|
+
def values(*args, &blk)
|
|
8
|
+
return values_without_profiling(*args, &blk) unless defined?(@miniprofiler_sql_id)
|
|
9
|
+
mp_report_sql do
|
|
10
|
+
values_without_profiling(*args , &blk)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def each(*args, &blk)
|
|
15
|
+
return each_without_profiling(*args, &blk) unless defined?(@miniprofiler_sql_id)
|
|
16
|
+
mp_report_sql do
|
|
17
|
+
each_without_profiling(*args, &blk)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def mp_report_sql(&block)
|
|
22
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
23
|
+
result = yield
|
|
24
|
+
elapsed_time = SqlPatches.elapsed_time(start)
|
|
25
|
+
@miniprofiler_sql_id.report_reader_duration(elapsed_time)
|
|
26
|
+
result
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
class PG::Connection
|
|
31
|
+
alias_method :exec_without_profiling, :exec
|
|
32
|
+
alias_method :async_exec_without_profiling, :async_exec
|
|
33
|
+
alias_method :exec_prepared_without_profiling, :exec_prepared
|
|
34
|
+
alias_method :send_query_prepared_without_profiling, :send_query_prepared
|
|
35
|
+
alias_method :prepare_without_profiling, :prepare
|
|
36
|
+
|
|
37
|
+
if Gem::Version.new(PG::VERSION) >= Gem::Version.new("1.1.0")
|
|
38
|
+
alias_method :exec_params_without_profiling, :exec_params
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def prepare(*args, &blk)
|
|
42
|
+
# we have no choice but to do this here,
|
|
43
|
+
# if we do the check for profiling first, our cache may miss critical stuff
|
|
44
|
+
|
|
45
|
+
@prepare_map ||= {}
|
|
46
|
+
@prepare_map[args[0]] = args[1]
|
|
47
|
+
# dont leak more than 10k ever
|
|
48
|
+
@prepare_map = {} if @prepare_map.length > 1000
|
|
49
|
+
|
|
50
|
+
return prepare_without_profiling(*args, &blk) unless SqlPatches.should_measure?
|
|
51
|
+
prepare_without_profiling(*args, &blk)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def exec(*args, &blk)
|
|
55
|
+
return exec_without_profiling(*args, &blk) unless SqlPatches.should_measure?
|
|
56
|
+
|
|
57
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
58
|
+
result = exec_without_profiling(*args, &blk)
|
|
59
|
+
elapsed_time = SqlPatches.elapsed_time(start)
|
|
60
|
+
record = ::Rack::MiniProfiler.record_sql(args[0], elapsed_time)
|
|
61
|
+
result.instance_variable_set("@miniprofiler_sql_id", record) if result
|
|
62
|
+
|
|
63
|
+
result
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
if Gem::Version.new(PG::VERSION) >= Gem::Version.new("1.1.0")
|
|
67
|
+
def exec_params(*args, &blk)
|
|
68
|
+
return exec_params_without_profiling(*args, &blk) unless SqlPatches.should_measure?
|
|
69
|
+
|
|
70
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
71
|
+
result = exec_params_without_profiling(*args, &blk)
|
|
72
|
+
elapsed_time = SqlPatches.elapsed_time(start)
|
|
73
|
+
record = ::Rack::MiniProfiler.record_sql(args[0], elapsed_time)
|
|
74
|
+
result.instance_variable_set("@miniprofiler_sql_id", record) if result
|
|
75
|
+
|
|
76
|
+
result
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def exec_prepared(*args, &blk)
|
|
81
|
+
return exec_prepared_without_profiling(*args, &blk) unless SqlPatches.should_measure?
|
|
82
|
+
|
|
83
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
84
|
+
result = exec_prepared_without_profiling(*args, &blk)
|
|
85
|
+
elapsed_time = SqlPatches.elapsed_time(start)
|
|
86
|
+
mapped = args[0]
|
|
87
|
+
mapped = @prepare_map[mapped] || args[0] if @prepare_map
|
|
88
|
+
record = ::Rack::MiniProfiler.record_sql(mapped, elapsed_time)
|
|
89
|
+
result.instance_variable_set("@miniprofiler_sql_id", record) if result
|
|
90
|
+
|
|
91
|
+
result
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def send_query_prepared(*args, &blk)
|
|
95
|
+
return send_query_prepared_without_profiling(*args, &blk) unless SqlPatches.should_measure?
|
|
96
|
+
|
|
97
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
98
|
+
result = send_query_prepared_without_profiling(*args, &blk)
|
|
99
|
+
elapsed_time = SqlPatches.elapsed_time(start)
|
|
100
|
+
mapped = args[0]
|
|
101
|
+
mapped = @prepare_map[mapped] || args[0] if @prepare_map
|
|
102
|
+
record = ::Rack::MiniProfiler.record_sql(mapped, elapsed_time)
|
|
103
|
+
result.instance_variable_set("@miniprofiler_sql_id", record) if result
|
|
104
|
+
|
|
105
|
+
result
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def async_exec(*args, &blk)
|
|
109
|
+
return async_exec_without_profiling(*args, &blk) unless SqlPatches.should_measure?
|
|
110
|
+
|
|
111
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
112
|
+
result = exec_without_profiling(*args, &blk)
|
|
113
|
+
elapsed_time = SqlPatches.elapsed_time(start)
|
|
114
|
+
record = ::Rack::MiniProfiler.record_sql(args[0], elapsed_time)
|
|
115
|
+
result.instance_variable_set("@miniprofiler_sql_id", record) if result
|
|
116
|
+
|
|
117
|
+
result
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
alias_method :query, :exec
|
|
121
|
+
end
|