discourse/config/initializers/006-mini_profiler.rb
2022-05-05 09:50:02 +08:00

122 lines
4.5 KiB
Ruby

# frozen_string_literal: true
# If Mini Profiler is included via gem
if Rails.configuration.respond_to?(:load_mini_profiler) && Rails.configuration.load_mini_profiler && RUBY_ENGINE == "ruby"
require 'rack-mini-profiler'
require 'stackprof'
begin
require 'memory_profiler'
rescue => e
STDERR.put "#{e} failed to require mini profiler"
end
# initialization is skipped so trigger it
Rack::MiniProfilerRails.initialize!(Rails.application)
end
if defined?(Rack::MiniProfiler) && defined?(Rack::MiniProfiler::Config)
# note, we may want to add some extra security here that disables mini profiler in a multi hosted env unless user global admin
# raw_connection means results are not namespaced
#
# namespacing gets complex, cause mini profiler is in the rack chain way before multisite
Rack::MiniProfiler.config.storage_instance = Rack::MiniProfiler::RedisStore.new(
connection: DiscourseRedis.new(nil, namespace: false)
)
Rack::MiniProfiler.config.snapshot_every_n_requests = GlobalSetting.mini_profiler_snapshots_period
Rack::MiniProfiler.config.snapshots_transport_destination_url = GlobalSetting.mini_profiler_snapshots_transport_url
Rack::MiniProfiler.config.snapshots_transport_auth_key = GlobalSetting.mini_profiler_snapshots_transport_auth_key
Rack::MiniProfiler.config.skip_paths = [
/^\/message-bus/,
/^\/extra-locales/,
/topics\/timings/,
/assets/,
/\/user_avatar\//,
/\/letter_avatar\//,
/\/letter_avatar_proxy\//,
/\/highlight-js\//,
/\/svg-sprite\//,
/qunit/,
/srv\/status/,
/commits-widget/,
/^\/cdn_asset/,
/^\/logs/,
/^\/site_customizations/,
/^\/uploads/,
/^\/secure-media-uploads/,
/^\/javascripts\//,
/^\/images\//,
/^\/stylesheets\//,
/^\/favicon\/proxied/
]
# we DO NOT WANT mini-profiler loading on anything but real desktops and laptops
# so let's rule out all handheld, tablet, and mobile devices
Rack::MiniProfiler.config.pre_authorize_cb = lambda do |env|
env['HTTP_USER_AGENT'] !~ /iPad|iPhone|Android/
end
# without a user provider our results will use the ip address for namespacing
# with a load balancer in front this becomes really bad as some results can
# be stored associated with ip1 as the user and retrieved using ip2 causing 404s
Rack::MiniProfiler.config.user_provider = lambda do |env|
request = Rack::Request.new(env)
id = request.cookies["_t"] || request.ip || "unknown"
id = id.to_s
# some security, lets not have these tokens floating about
Digest::MD5.hexdigest(id)
end
# Cookie path should be set to the base path so Discourse's session cookie path
# does not get clobbered.
Rack::MiniProfiler.config.cookie_path = Discourse.base_path.presence || "/"
Rack::MiniProfiler.config.position = 'left'
Rack::MiniProfiler.config.backtrace_ignores ||= []
Rack::MiniProfiler.config.backtrace_ignores << /lib\/rack\/message_bus.rb/
Rack::MiniProfiler.config.backtrace_ignores << /config\/initializers\/silence_logger/
Rack::MiniProfiler.config.backtrace_ignores << /config\/initializers\/quiet_logger/
Rack::MiniProfiler.config.backtrace_includes = [/^\/?(app|config|lib|test|plugins)/]
Rack::MiniProfiler.config.max_traces_to_show = 100 if Rails.env.development?
Rack::MiniProfiler.counter_method(Redis::Client, :call) { 'redis' }
# Rack::MiniProfiler.counter_method(ActiveRecord::QueryMethods, 'build_arel')
# Rack::MiniProfiler.counter_method(Array, 'uniq')
# require "#{Rails.root}/vendor/backports/notification"
# inst = Class.new
# class << inst
# def start(name,id,payload)
# if Rack::MiniProfiler.current && name !~ /(process_action.action_controller)|(render_template.action_view)/
# @prf ||= {}
# @prf[id] ||= []
# @prf[id] << Rack::MiniProfiler.start_step("#{payload[:serializer] if name =~ /serialize.serializer/} #{name}")
# end
# end
# def finish(name,id,payload)
# if Rack::MiniProfiler.current && name !~ /(process_action.action_controller)|(render_template.action_view)/
# t = @prf[id].pop
# @prf.delete id unless t
# Rack::MiniProfiler.finish_step t
# end
# end
# end
# disabling for now cause this slows stuff down too much
# ActiveSupport::Notifications.subscribe(/.*/, inst)
# Rack::MiniProfiler.profile_method ActionView::PathResolver, 'find_templates'
end
if ENV["PRINT_EXCEPTIONS"]
trace = TracePoint.new(:raise) do |tp|
puts tp.raised_exception
puts tp.raised_exception.backtrace.join("\n")
puts
end
trace.enable
end