Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
ac7e596
starting with tab to spaces. =/
thisduck Apr 23, 2017
1b6abc8
removing text nodes.
thisduck Apr 23, 2017
9eba01f
draw the rects straight up.
thisduck Apr 23, 2017
ffaa7b7
pre process the data before rendering.
thisduck Apr 23, 2017
9fb9562
for speed, let's not draw rects that are less than width 1.
thisduck Apr 23, 2017
71e53c8
refactoring code so that rects can be redrawn.
thisduck Apr 23, 2017
22baefa
ability to switch between gem and methods.
thisduck Apr 23, 2017
c5e99a6
better zooming and filtering.
thisduck Apr 24, 2017
fa127ca
filter by field.
thisduck Apr 24, 2017
6115bbc
major rewrite to allow more detailed data analysis.
thisduck Apr 29, 2017
65a2a60
modifying backtrace display.
thisduck Apr 29, 2017
72da00e
prevent context menu on graph. hide info box on mouse out.
thisduck Apr 29, 2017
f485265
split gem by type of ruby module.
thisduck Apr 30, 2017
0c249b6
show full backtrace, even when in zoom.
thisduck Apr 30, 2017
317a77a
adding ability to zoom into to a frame from backtrace.
thisduck Apr 30, 2017
361effb
adding ability to see breakdown of frames from gems or methods.
thisduck Apr 30, 2017
c74c10f
some speed improvements.
thisduck May 3, 2017
34b4b61
update semantic css to exclude external call to font, and include bae…
thisduck May 4, 2017
963c252
adding keyboard functionality.
thisduck May 4, 2017
58d6129
committed hardcoded filter by mistake.
thisduck May 4, 2017
a95c025
fixing parsing for gems. and let's not have a border if Y is large.
thisduck May 4, 2017
2c523ad
calculate samplesLength outside loop for speed.
thisduck May 4, 2017
191910d
making things super fast. use end points instead of width to fix bugg…
thisduck May 6, 2017
daa39c0
determine parents and children while setting relations, more speed. r…
thisduck May 6, 2017
e984b4e
changed spacing.
thisduck May 6, 2017
642cafb
copy file path to clipboard. animate selected gem/method.
thisduck May 6, 2017
1dc1d5b
add a shortcut for copying file path to clipboard. fixed bug for back…
thisduck May 7, 2017
e5ab619
some clean up to makes things nice.
thisduck May 7, 2017
4276fe0
covert rects to divs in order to get text with good speeds.
thisduck May 8, 2017
3628dfd
adding help button to show shortcut modal.
thisduck May 8, 2017
f7d7e8a
text color needs to be white on highlight.
thisduck May 8, 2017
0447eb7
lower border threshold since borders are thicker now.
thisduck May 8, 2017
f8f38e3
making borders nicer.
thisduck May 8, 2017
5e8d4e8
had accidentally reversed the x axis
thisduck May 8, 2017
ec1c9ab
tinycolor does a much better job of telling dark/light. fixed gem/met…
thisduck May 8, 2017
acbca38
forgot to add tinycolor to the embed list.
thisduck May 8, 2017
73fc932
fixing test for nodes.
thisduck May 12, 2017
769a88d
fixing the code for frames with two parents.
thisduck May 12, 2017
53d55f4
fixing additional case where the grandparents are different
thisduck May 12, 2017
6a5e6af
Merge branch 'fix_node_with_different_parents' of github.com:thisduck…
thisduck May 12, 2017
9ad7537
no longer need to correct data via javascript.
thisduck May 12, 2017
8d4a6ee
saving space by creating a frames array for reference.
thisduck May 13, 2017
058ece4
more performance improvements and a few bug fixes.
thisduck May 19, 2017
263db78
fix colouring for same method name across gems.
thisduck May 20, 2017
febf799
sql display and sort.
thisduck Apr 28, 2018
527bd65
Reset line-height so the method names don't hide.
thisduck Apr 29, 2018
88d6310
Renaming SQLRecorder to Runner
thisduck Apr 29, 2018
cea7b98
refactor sql recorder.
thisduck Apr 29, 2018
783f398
adding the tablesort js files to source.
thisduck Apr 29, 2018
93b104f
profile object instead of wall time, (avoids profiling GC, etc)
thisduck Oct 19, 2018
f42d300
only load sql tracer if ActiveRecord has already been loaded and exists.
thisduck Nov 20, 2018
9456274
explicitly requre newrelic.
thisduck May 8, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ test/version_tmp
tmp
*.swp
demo/graph.html

tags
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ gemspec

# both are optional, depending on platform
gem 'fast_stack'
gem 'stackprof', platform: :mri_21
gem 'stackprof', platform: [:mri_21, :mri_22, :mri_23]
13 changes: 11 additions & 2 deletions lib/flamegraph.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,16 @@
require "flamegraph/renderer"
require "flamegraph/sampler"

begin
require "flamegraph/active_record_sql_recorder" if defined?(ActiveRecord)
rescue
end

module Flamegraph
def self.generate(filename=nil, opts = {})
fidelity = opts[:fidelity] || 0.5
Thread.current[:sql_flame] = true

fidelity = opts[:fidelity] || 0.33

backtraces =
if defined? StackProf
Expand All @@ -47,7 +54,7 @@ def self.generate(filename=nil, opts = {})

embed_resources = (filename && !opts.key?(:embed_resources)) || opts[:embed_resources]

renderer = Flamegraph::Renderer.new(backtraces)
renderer = Flamegraph::Renderer.new(backtraces, opts)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passing opts here because I added javascript based filters. So that the page can have default filters as it loads up.

rendered = renderer.graph_html(embed_resources)

if filename
Expand All @@ -56,5 +63,7 @@ def self.generate(filename=nil, opts = {})
end
end
rendered
ensure
Thread.current[:sql_flame] = nil
end
end
96 changes: 96 additions & 0 deletions lib/flamegraph/active_record_sql_recorder.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
require 'active_record/connection_adapters/abstract/database_statements'
require 'newrelic_rpm'

module Flamegraph
class SQLRunner # :nodoc:
attr_reader :sql
def initialize(sql)
@sql = sql
end

def self.run(sql, function)
instance = new(sql)
instance.run(function)
end

def run(function)
if Thread.current[:sql_flame]
recorder.send method_name, function
else
function.call
end
end

private

def method_name
@method_name ||=
begin
sql_statement = sql.respond_to?(:to_sql) ? sql.to_sql : sql
obfuscated_sql = NewRelic::Agent::Database.obfuscate_sql(sql_statement)
ascii_sql = obfuscated_sql.gsub(/[^A-Za-z0-9]/) { |s| '_a' + s.ord.to_s }
"sql_flame_#{ascii_sql}"
end
end

def recorder
Flamegraph::SQLRecorder.instance method_name
end
end

class SQLRecorder # :nodoc:
def self.instance(method_name)
# filename is on its own so that it is not filtered as part of the flamegraph gem.
class_eval <<-CODE, 'sql_recorder.rb', __LINE__ + 1
def #{method_name}(function)
function.call
end
CODE

new
end
end
end

module ActiveRecord
module ConnectionAdapters # :nodoc:
module DatabaseStatements # :nodoc:

def insert_with_flame(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
function = lambda do
insert_without_flame(arel, name, pk, id_value, sequence_name, binds)
end

Flamegraph::SQLRunner.run(arel, function)
end
alias_method_chain :insert, :flame

def update_with_flame(arel, name = nil, binds = [])
function = lambda do
update_without_flame(arel, name, binds)
end

Flamegraph::SQLRunner.run(arel, function)
end
alias_method_chain :update, :flame

def delete_with_flame(arel, name = nil, binds = [])
function = lambda do
delete_without_flame(arel, name, binds)
end

Flamegraph::SQLRunner.run(arel, function)
end
alias_method_chain :delete, :flame

def select_with_flame(sql, name = nil, binds = [])
function = lambda do
select_without_flame(sql, name, binds)
end

Flamegraph::SQLRunner.run(sql, function)
end
alias_method_chain :select, :flame
end
end
end
7 changes: 7 additions & 0 deletions lib/flamegraph/clipboard.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading