Last active
December 18, 2015 02:09
-
-
Save spikegrobstein/5709378 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Profiler | |
## A wrapper for the rblineprof library to pretty-print the profile data | |
## and enable customization of the output | |
## Based heavily on tmm1's examples | |
## This assumes that rblineprof lib is installed in Rails.root + 'vendor/rblineprof/ext' | |
## https://github.com/tmm1/rblineprof | |
class Profiler | |
# see docs for self.log_line method | |
@@logger = Proc.new { |line| Rails.logger.info line } | |
# see docs for self.format_line method | |
@@formatter = Proc.new { |file, profile_data, line, num| | |
wall, cpu, calls = profile_data | |
if calls && calls > 0 | |
"((( % 8.1fms + % 8.1fms (% 5d) | %s" % [cpu/1000.0, (wall-cpu)/1000.0, calls, line] | |
else | |
"((( | %s" % [line] | |
end | |
} | |
# override the default logger for the profiler | |
# the block should accept an argument signature that matches Profiler.log_line, below. | |
def self.set_logger( &block ) | |
@@logger = block | |
end | |
# override the default formatter | |
# the block should accept an argument signature that matches Profiler.format_line, below. | |
def self.set_formatter( &block ) | |
@@formatter = block | |
end | |
# accessor for @@logger | |
def self.logger | |
@@logger | |
end | |
# accessor for @@formatter | |
def self.formatter | |
@@formatter | |
end | |
# log a line using the @@logger Proc. | |
# it should take the same method signature as this method | |
def self.log_line(line) | |
self.logger.call line | |
end | |
# format a given line to be passed to the logger | |
# file is the full filepath to the file in question | |
# profile data is an array of wall-time, cpu-time and number-of-calls as integers | |
# line is the line in question (actual line of code from the file) | |
# num is the line number | |
def self.format_line(file, profile_data, line, num) | |
@@formatter.call file, profile_data, line, num | |
end | |
# profile the provided block. | |
# regex is a regex for which files to include in the profile | |
# when full_trace is set to false, it will ignore anything inside ~/.rvm directory | |
# by default this will spit out a profile to the log, which is great when in development mode | |
def self.profile(regex=/./, full_trace=false, &block) | |
$:.unshift Rails.root + 'vendor/rblineprof/ext' | |
require 'rblineprof' | |
profile = lineprof(regex) do | |
block.call | |
end | |
profile.each do |file, p| | |
# skip over anything that's a gem: | |
next if !full_trace && file.match(/\/\.rvm\//) # anything in the .rvm directory | |
next if file.match(/^\(/) # anything that starts with a paren | |
# identify the file in the logger | |
self.log_line "\n/// #{ file } ===>>>" | |
# log each line from the file with profile data | |
File.readlines(file).each_with_index do |line, num| | |
self.log_line( self.format_line(file, profile[file][num+1], line, num) ) | |
end | |
end | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment