Skip to content

Instantly share code, notes, and snippets.

@klondaiker
Created September 22, 2021 13:39
Show Gist options
  • Save klondaiker/d83be9d36d9eac289fc0c5ef858cdf4f to your computer and use it in GitHub Desktop.
Save klondaiker/d83be9d36d9eac289fc0c5ef858cdf4f to your computer and use it in GitHub Desktop.
class Profiler
SUBSCRIPTIONS = [
'sql.active_record',
'render_template.action_view',
'render_partial.action_view',
'process_action.action_controller'
].freeze
PATH = './log/profiler.log'
IGNORE_SQL_NAMES = %w(SCHEMA CACHE).freeze
IGNORE_SQL_QUERIES = %w(COMMIT BEGIN).freeze
class << self
attr_reader :instance
def run
@instance ||= Profiler.new.run
end
end
def run
SUBSCRIPTIONS.each do |subscription|
ActiveSupport::Notifications.subscribe(subscription) do |_name, start, finish, _id, payload|
if Thread.current[:request_id].present?
message = build_message(start: start, finish: finish, payload: payload , subscription: subscription)
logger.info message if message.present?
end
end
end
end
private
def build_message(start: ,finish: , payload:, subscription: )
duration = (finish.to_f - start.to_f) * 1000
message = case subscription
when 'render_partial.action_view', 'render_template.action_view'
render_partial_message(payload)
when 'sql.active_record'
sql_request_message(payload)
end
[Time.now.to_s, Thread.current[:request_id], subscription, duration.round(2), message].join(':') if message.present?
end
def render_partial_message(payload)
path = payload[:identifier].split('/')
app_index = path.index('app')
path[app_index..path.length].join('/')
end
def sql_request_message(payload)
return if IGNORE_SQL_NAMES.include? payload[:name]
return if IGNORE_SQL_QUERIES.map { |query| payload[:sql].strip.start_with?(query) }.reduce(:&)
payload[:sql].strip
end
def logger
@logger ||= ActiveSupport::Logger.new Rails.root.join(PATH)
end
end
Profiler.run if Settings.profiler_enable?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment