stack_tracy 0.1.3 → 0.1.4

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.
data/CHANGELOG.rdoc CHANGED
@@ -1,5 +1,23 @@
1
1
  = StackTracy CHANGELOG
2
2
 
3
+ == Version 0.1.4 (August 25, 2012)
4
+
5
+ * Added major improvements regarding browser performance when opening heavy HTML stack trace pages:
6
+ - using padding instead of non-breakable spaces (doh!)
7
+ - reduced white lines and white space
8
+ - added a threshold (< 0.001s) for folding calls at default and rendering its 'child calls' as comment (see http://ravirajsblog.blogspot.nl/2010/12/another-hack-to-render-heavy-html-pages.html)
9
+ - parsing commented 'child calls' at initial unfold
10
+ * Falling back to current directory when invoking StackTracy.open (or `tracy` within the Terminal)
11
+ * Letting StackTracy auto-determine its dump directory when calling `stack_tracy(:open) {}`
12
+ * Clearing StackTracy.stack_trace after having invoked StackTracy.dump
13
+ * Displaying passed path when invoking StackTracy.open with use_current_stack_trace == true
14
+ * Improved StackTracy::Sinatra middleware a bit regarding the `/tracy` route
15
+ * Added three configuration options:
16
+ - dump_source_location (default: `false`) include the source location when dumping recorded stack trace
17
+ - limit (default: `7500`) stack traces with more calls than the limit will be limited (core class / module calls will be excluded) when displaying
18
+ - threshold (default: `0.001`) fold calls faster than the threshold when exceeding the calls limit
19
+ * Enhanced the CLI interface `tracy` by using Thor in order to process the :limit and :threshold option
20
+
3
21
  == Version 0.1.3 (August 19, 2012)
4
22
 
5
23
  * Being able to compile StackTracy native extension on Windows (thanks ramsees for issuing)
data/README.md CHANGED
@@ -10,7 +10,7 @@ The gem is partly written in C to reduce the application performance as minimal
10
10
 
11
11
  ![Dick .. Stack Tracy](http://codehero.es/images/stack_tracy.jpg)
12
12
 
13
- Watch ["**Using StackTracy within a small Sinatra application**"](https://vimeo.com/archan937/stacktracy) to see StackTracy in action!
13
+ Watch the ["**Using StackTracy within a small Sinatra application**"](https://vimeo.com/archan937/stacktracy) **screencast** to see StackTracy in action!
14
14
 
15
15
  ## Installation
16
16
 
@@ -80,12 +80,15 @@ A couple of examples:
80
80
 
81
81
  ### Configure StackTracy
82
82
 
83
- You can configure the default stack tree reduction behaviour and dump directory of `StackTracy`:
83
+ You can configure `StackTracy` regarding the default stack tree reduction behaviour, its dump directory and whether to include the source location when dumping recorded stack events:
84
84
 
85
85
  StackTracy.configure do |c|
86
- c.dump_dir = "." #=> default: Dir::tmpdir
87
- c.only = "Foo*" #=> default: nil
88
- c.exclude = %w(Foo::Bar Foo::CandyBar) #=> default: nil
86
+ c.dump_dir = "." #=> default: Dir::tmpdir
87
+ c.dump_source_location = "." #=> default: false
88
+ c.limit = 1000 #=> default: 7500
89
+ c.threshold = 0.005 #=> default: 0.001
90
+ c.only = "Foo*" #=> default: nil
91
+ c.exclude = %w(Foo::Bar Foo::CandyBar) #=> default: nil
89
92
  end
90
93
 
91
94
  ### Using recorded stack events
@@ -155,6 +158,14 @@ You can dump (optionally filtered) recorded stack events to a CSV file.
155
158
 
156
159
  This is what the contents of `result.csv` would look like:
157
160
 
161
+ event;;;singleton;object;method;nsec;call;depth;duration
162
+ c-call;;;false;Kernel;puts;1344466943040581120;Kernel#puts;0;0.000120832
163
+ c-call;;;false;IO;puts;1344466943040599040;IO#puts;1;9.1904e-05
164
+ c-call;;;false;IO;write;1344466943040613120;IO#write;2;3.2768e-05
165
+ c-call;;;false;IO;write;1344466943040658944;IO#write;2;1.9968e-05
166
+
167
+ When invoking `StackTracy.dump "result.csv", true` and thus including the source location:
168
+
158
169
  event;file;line;singleton;object;method;nsec;call;depth;duration
159
170
  c-call;(pry);2;false;Kernel;puts;1344466943040581120;Kernel#puts;0;0.000120832
160
171
  c-call;(pry);2;false;IO;puts;1344466943040599040;IO#puts;1;9.1904e-05
@@ -167,16 +178,32 @@ You can easily view the dumped stack events within your browser by either callin
167
178
 
168
179
  [1] pry(main)> StackTracy.open "some/dir/file.csv"
169
180
 
170
- or the following within the Terminal:
171
-
172
- $ tracy "some/dir/file.csv"
173
-
174
181
  Your default browser will be launched in which the stack events will be displayed.
175
182
 
176
- When passing no path, `tracy` will look for `stack_events-<random generated postfix>.csv` in either the default dump directory or in `Dir::tmpdir` and display it in the browser. When not found, it will display the last compiled stack tree when available:
183
+ When passing no path, StackTracy will look for `stack_events-<random generated postfix>.csv` in either the default dump directory, the current directory or `Dir::tmpdir` and display it in the browser. When not found, it will display the last compiled stack tree when available:
177
184
 
178
185
  $ tracy
179
186
 
187
+ ### Using the CLI (command line interface)
188
+
189
+ Another way for viewing stack events in your browser is using the CLI `tracy` within the Terminal:
190
+
191
+ $ tracy #=> let StackTracy auto-determine which file to display
192
+ $ tracy . #=> display the last data file within the current directory
193
+ $ tracy foo/bar.csv #=> display foo/bar.csv
194
+
195
+ To get info about its options, type `tracy help open`:
196
+
197
+ $ tracy help open
198
+ Usage:
199
+ tracy open [PATH]
200
+
201
+ Options:
202
+ -l, [--limit=LIMIT]
203
+ -t, [--threshold=THRESHOLD]
204
+
205
+ Display StackTracy data within the browser (PATH is optional)
206
+
180
207
  ### Kernel#stack_tracy
181
208
 
182
209
  As already mentioned, there is a convenience method called `stack_tracy` convenience method. The following shows a couple variants with its equivalent "normal implementation".
@@ -268,8 +295,9 @@ Its equivalent:
268
295
  [1] pry(main)> StackTracy.start
269
296
  [2] pry(main)> puts "testing"
270
297
  [3] pry(main)> StackTracy.stop
271
- [4] pry(main)> file = StackTracy.dump Dir::tmpdir
272
- [5] pry(main)> StackTracy.open file
298
+ [4] pry(main)> StackTracy.dump do |file|
299
+ [4] pry(main)> StackTracy.open file, true
300
+ [4] pry(main)> end
273
301
 
274
302
  ## Hooking into Sinatra requests
275
303
 
@@ -278,7 +306,7 @@ You can easily hook `StackTracy` into [Sinatra](http://www.sinatrarb.com) reques
278
306
  require "sinatra"
279
307
  require "stack_tracy"
280
308
 
281
- use StackTracy::Sinatra
309
+ use StackTracy::Sinatra, :open
282
310
 
283
311
  get "/" do
284
312
  "Hello world!"
@@ -286,7 +314,9 @@ You can easily hook `StackTracy` into [Sinatra](http://www.sinatrarb.com) reques
286
314
 
287
315
  **Note**: Make sure you have the `sinatra` and `stack_tracy` gems installed.
288
316
 
289
- Open the Sinatra application in your browser at [http://localhost:4567](http://localhost:4567) and open [http://localhost:4567/tracy](http://localhost:4567/tracy) afterwards and the complete stack tree will be displayed in your browser! ^^
317
+ Open the Sinatra application in your browser at [http://localhost:4567](http://localhost:4567) and the complete stack tree will be displayed in your browser! ^^
318
+
319
+ You can also open [http://localhost:4567/tracy](http://localhost:4567/tracy) afterwards by the way.
290
320
 
291
321
  ### Taking more control
292
322
 
@@ -354,6 +384,7 @@ For support, remarks and requests, please mail me at [paul.engel@holder.nl](mail
354
384
 
355
385
  * Two functions within the StackTracy C implementation are taken from [ruby-prof](https://github.com/rdp/ruby-prof).
356
386
  * The table sort within the Cumulatives tab is implemented with [TinySort](http://tinysort.sjeiti.com/).
387
+ * Being able to improve browser performance when loading heavy HTML stack trace pages using Ravi Raj's ([@raviraj4u](https://twitter.com/raviraj4u)) blog post: [http://ravirajsblog.blogspot.nl/2010/12/another-hack-to-render-heavy-html-pages.html](http://ravirajsblog.blogspot.nl/2010/12/another-hack-to-render-heavy-html-pages.html)
357
388
 
358
389
  ## License
359
390
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.3
1
+ 0.1.4
data/bin/tracy CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require "rubygems"
4
- require "stack_tracy"
4
+ require "stack_tracy/cli"
5
5
 
6
6
  begin
7
- StackTracy.open ARGV.first
7
+ StackTracy::CLI.start
8
8
  rescue StackTracy::Error => e
9
9
  puts e.message.red
10
10
  end
data/demo.rb ADDED
@@ -0,0 +1,8 @@
1
+ require "sinatra"
2
+ require "stack_tracy"
3
+
4
+ use StackTracy::Sinatra, :open, :threshold => 0.002, :limit => 250
5
+
6
+ get "/" do
7
+ "Hello World!"
8
+ end
@@ -0,0 +1,26 @@
1
+ require "thor"
2
+ require "stack_tracy"
3
+
4
+ module StackTracy
5
+ class CLI < Thor
6
+
7
+ default_task :open
8
+
9
+ desc "open [PATH]", "Display StackTracy data within the browser (PATH is optional)"
10
+ method_options [:limit, "-l"] => :numeric, [:threshold, "-t"] => :numeric
11
+ def open(path = ".")
12
+ StackTracy.open path, false, options.threshold, options.limit
13
+ end
14
+
15
+ private
16
+
17
+ def method_missing(method, *args)
18
+ if File.exists? File.expand_path(method.to_s)
19
+ `tracy open #{method} #{args.join " "}`
20
+ else
21
+ raise Error, "Unrecognized command \"#{method}\". Please consult `tracy help`."
22
+ end
23
+ end
24
+
25
+ end
26
+ end
@@ -5,6 +5,8 @@ module Kernel
5
5
  options = arg
6
6
  arg = nil
7
7
  end
8
+ threshold = options.delete :threshold
9
+ limit = options.delete :limit
8
10
  StackTracy.start options
9
11
  yield
10
12
  StackTracy.stop
@@ -13,8 +15,9 @@ module Kernel
13
15
  elsif arg == :dump
14
16
  StackTracy.dump
15
17
  elsif arg == :open
16
- file = StackTracy.dump Dir::tmpdir
17
- StackTracy.open file, true
18
+ StackTracy.dump do |file|
19
+ StackTracy.open file, true, threshold, limit
20
+ end
18
21
  elsif arg.is_a? String
19
22
  StackTracy.dump arg
20
23
  end
@@ -10,10 +10,9 @@ module StackTracy
10
10
 
11
11
  def call(env)
12
12
  request = ::Sinatra::Request.new env
13
- if request.path.match /^\/tracy-?(.*)?/
14
- return open($1)
13
+ if request.path.match /^\/tracy(-.*)?/
14
+ return open($1.to_s.gsub(/^-/, ""))
15
15
  end
16
-
17
16
  if @before_filter.nil? || !!@before_filter.call(request.path, request.params)
18
17
  result = nil
19
18
  stack_tracy @arg || Dir::tmpdir, @options do
@@ -28,7 +27,17 @@ module StackTracy
28
27
  private
29
28
 
30
29
  def open(match)
31
- StackTracy.open match.to_s.empty? ? nil : match, (match.to_s.empty? && @arg.to_s != "dump" && !StackTracy.stack_trace.empty?)
30
+ if match.empty?
31
+ if StackTracy.stack_trace.empty?
32
+ StackTracy.open nil, false, @options[:threshold], @options[:limit]
33
+ else
34
+ StackTracy.dump do |file|
35
+ StackTracy.open file, true, @options[:threshold], @options[:limit]
36
+ end
37
+ end
38
+ else
39
+ StackTracy.open match, false, @options[:threshold], @options[:limit]
40
+ end
32
41
  [200, {"Content-Type" => "text/html;charset=utf-8", "Content-Length" => Rack::Utils.bytesize("").to_s}, ""]
33
42
  end
34
43
 
@@ -1,7 +1,7 @@
1
1
  module StackTracy #:nodoc:
2
2
  MAJOR = 0
3
3
  MINOR = 1
4
- TINY = 3
4
+ TINY = 4
5
5
 
6
6
  VERSION = [MAJOR, MINOR, TINY].join(".")
7
7
  end
data/lib/stack_tracy.rb CHANGED
@@ -18,7 +18,7 @@ module StackTracy
18
18
  :active_record => "ActiveRecord::Base",
19
19
  :data_mapper => "DataMapper::Resource"
20
20
  }
21
- @options = Struct.new(:dump_dir, :only, :exclude).new(Dir::tmpdir)
21
+ @options = Struct.new(:dump_dir, :dump_source_location, :limit, :threshold, :only, :exclude).new(Dir::tmpdir, false, 7500, 0.001)
22
22
 
23
23
  class Error < StandardError; end
24
24
 
@@ -67,26 +67,32 @@ module StackTracy
67
67
  }
68
68
  end
69
69
 
70
- def dump(path = nil, *only)
70
+ def dump(path = nil, dump_source_location = nil, *only)
71
71
  unless path && path.match(/\.csv$/)
72
72
  path = File.join [path || @options.dump_dir, "stack_events-#{SecureRandom.hex(3)}.csv"].compact
73
73
  end
74
74
  File.expand_path(path).tap do |path|
75
- keys = [:event, :file, :line, :singleton, :object, :method, :nsec, :time, :call, :depth, :duration]
75
+ bool = dump_source_location.nil? ? @options[:dump_source_location] : dump_source_location
76
+ keys = [:event, (:file if bool), (:line if bool), :singleton, :object, :method, :nsec, :time, :call, :depth, :duration]
76
77
  File.open(path, "w") do |file|
77
78
  file << keys.join(";") + "\n"
78
79
  select(only).each do |event|
79
80
  file << event.values_at(*keys).join(";") + "\n"
80
81
  end
81
82
  end
83
+ yield path if block_given?
84
+ stack_trace.clear
82
85
  end
83
86
  end
84
87
 
85
- def open(path = nil, use_current_stack_trace = false)
86
- unless use_current_stack_trace
88
+ def open(path = nil, use_current_stack_trace = false, threshold = nil, limit = nil)
89
+ if use_current_stack_trace
90
+ file = File.expand_path(path) if path
91
+ else
87
92
  unless path && path.match(/\.csv$/)
88
- path = Dir[File.join(path || @options.dump_dir, "stack_events-*.csv")].sort_by{|f| File.mtime(f)}.last
89
- path ||= Dir[File.join(path || Dir::tmpdir, "stack_events-*.csv")].sort_by{|f| File.mtime(f)}.last
93
+ path = Dir[File.join(path || @options.dump_dir, "stack_events-*.csv")].sort_by{|f| File.mtime(f)}.last
94
+ path ||= Dir[File.join(".", "stack_events-*.csv")].sort_by{|f| File.mtime(f)}.last
95
+ path ||= Dir[File.join(Dir::tmpdir, "stack_events-*.csv")].sort_by{|f| File.mtime(f)}.last
90
96
  end
91
97
  if path
92
98
  file = File.expand_path(path)
@@ -98,6 +104,8 @@ module StackTracy
98
104
  index = ui("index.html")
99
105
 
100
106
  if use_current_stack_trace || (file && File.exists?(file))
107
+ threshold = threshold.nil? ? @options[:threshold] : threshold
108
+ limit = limit.nil? ? @options[:limit] : limit
101
109
  events = use_current_stack_trace ? select : StackTracy::EventInfo.to_hashes(File.read(file))
102
110
  erb = ERB.new File.new(ui("index.html.erb")).read
103
111
  File.open(index, "w"){|f| f.write erb.result(binding)}
data/stack_tracy.gemspec CHANGED
@@ -13,8 +13,9 @@ Gem::Specification.new do |gem|
13
13
  gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
14
  gem.name = "stack_tracy"
15
15
  gem.require_paths = ["lib"]
16
- gem.version = "0.1.3"
16
+ gem.version = "0.1.4"
17
17
 
18
18
  gem.add_dependency "rich_support", "~> 0.1.2"
19
19
  gem.add_dependency "launchy", "2.1.0"
20
+ gem.add_dependency "thor"
20
21
  end
@@ -25,7 +25,7 @@ module Unit
25
25
  it "should be configurable" do
26
26
  StackTracy.config do |c|
27
27
  assert_equal true, c.is_a?(Struct)
28
- assert_equal [:dump_dir, :only, :exclude], c.members
28
+ assert_equal [:dump_dir, :dump_source_location, :limit, :threshold, :only, :exclude], c.members
29
29
  c.only = "Kernel"
30
30
  c.exclude = ["IO", "String"]
31
31
  end
@@ -77,8 +77,8 @@ module Unit
77
77
  end
78
78
  }
79
79
 
80
- assert StackTracy.stack_trace.first.call?
81
- assert !StackTracy.stack_trace.first.return?
80
+ assert_equal true, StackTracy.stack_trace.first.call?
81
+ assert_equal false, StackTracy.stack_trace.first.return?
82
82
 
83
83
  StackTracy.config do |c|
84
84
  c.exclude = ["IO"]
@@ -130,6 +130,30 @@ module Unit
130
130
  }
131
131
  end
132
132
 
133
+ it "should clear StackTracy.stack_trace after having invoked StackTracy.dump" do
134
+ stack_tracy do
135
+ puts "testing"
136
+ end
137
+ assert_equal false, StackTracy.stack_trace.empty?
138
+
139
+ StackTracy.dump
140
+ assert_equal true, StackTracy.stack_trace.empty?
141
+
142
+ stack_tracy do
143
+ puts "testing"
144
+ end
145
+ assert_equal false, StackTracy.stack_trace.empty?
146
+
147
+ StackTracy.expects(:foo)
148
+ StackTracy.dump do |file|
149
+ assert file.match(/\/.*\.csv/)
150
+ assert_equal false, StackTracy.stack_trace.empty?
151
+ StackTracy.foo
152
+ end
153
+
154
+ assert_equal true, StackTracy.stack_trace.empty?
155
+ end
156
+
133
157
  it "should filter methods as expected" do
134
158
  stack_tracy do
135
159
  puts "testing"
@@ -0,0 +1,15 @@
1
+ jQuery.fn.comments = function() {
2
+ var comments = [];
3
+
4
+ this.each(function(i, node) {
5
+ var child = node.firstChild;
6
+ while (child) {
7
+ if (child.nodeType === 8) {
8
+ comments.push(child.nodeValue);
9
+ }
10
+ child = child.nextSibling;
11
+ }
12
+ });
13
+
14
+ return comments;
15
+ };
@@ -56,24 +56,25 @@ a {
56
56
  #page .tab-pane {
57
57
  line-height: 28px; }
58
58
 
59
- #page .tab-pane div {
60
- border-bottom: 1px solid #EFEFEF; }
61
-
62
59
  #page .tab-pane div.head {
63
60
  padding-bottom: 4px;
64
61
  font-weight: bold; }
65
62
  #page .tab-pane div.head a {
66
63
  color: #222; }
67
64
 
68
- #page .tab-pane div.group {
65
+ #page .tab-pane div.head,
66
+ #page .tab-pane div.body div {
67
+ border-bottom: 1px solid #EFEFEF; }
68
+
69
+ #page .tab-pane div.body div.group {
69
70
  border: 0; }
70
71
 
71
72
  #page .tab-pane div span.time,
72
73
  #page .tab-pane div span.average,
73
74
  #page .tab-pane div span.duration,
74
75
  #page .tab-pane div span.count {
75
- width: 100px;
76
- padding-right: 15px;
76
+ width: 70px;
77
+ padding-right: 20px;
77
78
  text-align: right;
78
79
  display: -moz-inline-block;
79
80
  display: inline-block;
@@ -82,17 +83,13 @@ a {
82
83
 
83
84
  #page .tab-pane div span.call {
84
85
  width: 950px;
85
- padding-left: 15px;
86
86
  display: -moz-inline-block;
87
87
  display: inline-block;
88
88
  *display: inline;
89
89
  zoom: 1; }
90
90
 
91
91
  #page #cumulatives div span.count {
92
- width: 65px; }
93
-
94
- #page #cumulatives div span.call {
95
- width: 790px; }
92
+ width: 45px; }
96
93
 
97
94
  #footer {
98
95
  padding-top: 45px;
@@ -4,7 +4,13 @@ StackTracy = (function() {
4
4
  var sortation = [];
5
5
 
6
6
  var toggle = function(event) {
7
- $(event.target).closest("div").next("div.group").toggle();
7
+ var group = $(event.target).closest("div").next("div.group");
8
+ var comments = group.comments();
9
+ if (comments.length) {
10
+ group.html(comments.join("\n"));
11
+ } else {
12
+ group.toggle();
13
+ }
8
14
  };
9
15
 
10
16
  $(function() {
@@ -16,7 +22,7 @@ StackTracy = (function() {
16
22
  });
17
23
 
18
24
  return {
19
- version: "0.1.3",
25
+ version: "0.1.4",
20
26
  sort: function(column) {
21
27
  sortation[column] = sortation[column] == "asc" ? "desc" : "asc";
22
28
  $("#cumulatives>.body>div").tsort("span:eq(" + column + ")[abbr]", {
data/ui/index.html.erb CHANGED
@@ -8,6 +8,7 @@
8
8
  <script src="assets/jquery.js" type="text/javascript"></script>
9
9
  <script src="assets/bootstrap-tab.js" type="text/javascript"></script>
10
10
  <script src="assets/tiny_sort.js" type="text/javascript"></script>
11
+ <script src="assets/comments.js" type="text/javascript"></script>
11
12
  <script src="assets/stack_tracy.js" type="text/javascript"></script>
12
13
  <link href="assets/bootstrap-tab.css" type="text/css" rel="stylesheet" media="screen"/>
13
14
  <link href="assets/stack_tracy.css" type="text/css" rel="stylesheet" media="screen"/>
@@ -26,26 +27,27 @@
26
27
  <a href="#cumulatives" data-toggle="tab">Cumulatives</a>
27
28
  </li>
28
29
  </ul>
29
- <div class="tab-content">
30
- <%
31
- current_depth = 0
32
- excluded_objects = if events.size > 7500
33
- %w(Array BasicObject Enumerable Fixnum Float Hash IO Kernel Module Mutex Numeric Object Rational String Symbol Thread Time)
34
- else
35
- []
36
- end
37
- corrections = []
38
- cumulatives = {}
39
- %>
30
+ <div class="tab-content"><%
31
+ limited = events.size > limit
32
+ threshold = nil unless limited
33
+ excluded_objects = if limited
34
+ %w(Array BasicObject Enumerable Fixnum Float Hash IO Integer Kernel Module Mutex Numeric Object Rational String Symbol Thread Time)
35
+ else
36
+ []
37
+ end
38
+ comment_depth = nil
39
+ last_depth = nil
40
+ last_duration = nil
41
+ corrections = []
42
+ cumulatives = {} %>
40
43
  <div class="tab-pane active" id="stack_trace">
41
44
  <div class="head">
42
45
  <span class="time">Time</span>
43
46
  <span class="duration">Duration</span>
44
47
  <span class="call">Call</span>
45
48
  </div>
46
- <div class="body">
47
- <% events.each_with_index do |event, index| %>
48
- <%
49
+ <div class="body"><%
50
+ events.each_with_index do |event, index|
49
51
  skip = excluded_objects.include?(event[:object]) || "#{event[:object]}".match(/^#/)
50
52
  cumulatives[event[:call]] ||= {:duration => 0.0, :count => 0}
51
53
  cumulatives[event[:call]][:duration] += event[:duration].to_f
@@ -54,37 +56,38 @@
54
56
  corrections.size.times do |i|
55
57
  event[:depth] <= corrections[0] ? corrections.shift : break
56
58
  end
57
- %>
58
- <% if skip %>
59
- <% corrections.unshift event[:depth] if corrections.empty? || corrections.first != event[:depth] %>
60
- <% else %>
61
- <% if current_depth < event[:depth] - corrections.size %>
62
- <div class="group">
63
- <% elsif current_depth > event[:depth] - corrections.size %>
64
- <%= "</div>" * (current_depth - (event[:depth] - corrections.size)) %>
65
- <% end %>
66
- <div>
67
- <span class="time">
68
- <%= "%.6f" % event[:time] %>
69
- </span>
70
- <span class="duration">
71
- <%= event[:duration] ? ("%.6f" % event[:duration]) : "?" %>
72
- </span>
73
- <span class="call">
74
- <%= "&nbsp;&nbsp;&nbsp;" * (event[:depth] - corrections.size) %>
75
- <% if (next_event = events[index + 1]) && next_event[:depth] > event[:depth] %>
76
- <a class="toggler" href="#" onclick="return false">
77
- <%= event[:call] %>
78
- </a>
79
- <% else %>
80
- <%= event[:call] %>
81
- <% end %>
82
- </span>
83
- </div>
84
- <% current_depth = event[:depth] - corrections.size %>
85
- <% end %>
86
- <% end %>
87
- <%= "</div>" * current_depth %>
59
+ if skip
60
+ corrections.unshift event[:depth] if corrections.empty? || corrections.first != event[:depth]
61
+ else
62
+ if last_depth.to_i < event[:depth] - corrections.size %>
63
+ <div class="group"><% if threshold && comment_depth.nil? && last_duration && last_duration < threshold %><% comment_depth = event[:depth] - corrections.size %><%= "\n<!--" %><% end %><% else
64
+ close_tags = ((event[:depth] - corrections.size + 1)..last_depth.to_i).collect do |depth|
65
+ if comment_depth && depth == comment_depth
66
+ comment_depth = nil
67
+ "\n-->\n</div>"
68
+ else
69
+ "\n</div>"
70
+ end
71
+ end.reverse.join("")
72
+ %><%= close_tags %><% end %>
73
+ <div>
74
+ <span class="time"><%= "%.6f" % event[:time] %></span>
75
+ <span class="duration"><%= event[:duration] ? ("%.6f" % event[:duration]) : "?" %></span>
76
+ <span style="padding-left: <%= 10 * (event[:depth] - corrections.size) %>px"><% if (next_event = events[index + 1]) && next_event[:depth] > event[:depth] %><a class="toggler" href="#" onclick="return false"><%= event[:call] %></a><% else %><%= event[:call] %><% end %></span>
77
+ </div><%
78
+ last_depth = event[:depth] - corrections.size
79
+ last_duration = event[:duration]
80
+ end
81
+ end
82
+ close_tags = (1..last_depth.to_i).collect do |depth|
83
+ if comment_depth && depth == comment_depth
84
+ comment_depth = nil
85
+ "\n-->\n</div>"
86
+ else
87
+ "\n</div>"
88
+ end
89
+ end.reverse.join("")
90
+ %><%= close_tags %>
88
91
  </div>
89
92
  </div>
90
93
  <div class="tab-pane" id="cumulatives">
@@ -94,23 +97,13 @@
94
97
  <span class="count"><a href="javascript:StackTracy.sort(2)">Count</a></span>
95
98
  <span class="call"><a href="javascript:StackTracy.sort(3)">Call</a></span>
96
99
  </div>
97
- <div class="body">
98
- <% cumulatives.sort{|(ak, av), (bk, bv)| bv[:average] <=> av[:average]}.each do |call, stats| %>
99
- <div>
100
- <span class="average" abbr="<%= "%.6f" % stats[:average] %>">
101
- <%= "%.6f" % stats[:average] %>
102
- </span>
103
- <span class="duration" abbr="<%= "%.6f" % stats[:duration] %>">
104
- <%= "%.6f" % stats[:duration] %>
105
- </span>
106
- <span class="count" abbr="<%= stats[:count] %>">
107
- <%= stats[:count] %>
108
- </span>
109
- <span class="call" abbr="<%= call.gsub("<", "&lt;").gsub(">", "&gt;") %>">
110
- <%= call.gsub("<", "&lt;").gsub(">", "&gt;") %>
111
- </span>
112
- </div>
113
- <% end %>
100
+ <div class="body"><% cumulatives.sort{|(ak, av), (bk, bv)| bv[:average] <=> av[:average]}.each do |call, stats| %>
101
+ <div>
102
+ <span class="average" abbr="<%= "%.6f" % stats[:average] %>"><%= "%.6f" % stats[:average] %></span>
103
+ <span class="duration" abbr="<%= "%.6f" % stats[:duration] %>"><%= "%.6f" % stats[:duration] %></span>
104
+ <span class="count" abbr="<%= stats[:count] %>"><%= stats[:count] %></span>
105
+ <span class="call" abbr="<%= call.gsub("<", "&lt;").gsub(">", "&gt;") %>"><%= call.gsub("<", "&lt;").gsub(">", "&gt;") %></span>
106
+ </div><% end %>
114
107
  </div>
115
108
  </div>
116
109
  </div>
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: stack_tracy
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.3
5
+ version: 0.1.4
6
6
  platform: ruby
7
7
  authors:
8
8
  - Paul Engel
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-08-18 00:00:00 Z
13
+ date: 2012-08-26 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rich_support
@@ -34,6 +34,17 @@ dependencies:
34
34
  version: 2.1.0
35
35
  type: :runtime
36
36
  version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: thor
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ type: :runtime
47
+ version_requirements: *id003
37
48
  description: Investigate and detect slow methods within the stack trace of your Ruby (optionally Sinatra) application
38
49
  email:
39
50
  - paul.engel@holder.nl
@@ -53,10 +64,12 @@ files:
53
64
  - VERSION
54
65
  - benchmarks/benchmark.rb
55
66
  - bin/tracy
67
+ - demo.rb
56
68
  - ext/stack_tracy/extconf.rb
57
69
  - ext/stack_tracy/stack_tracy.c
58
70
  - ext/stack_tracy/stack_tracy.h
59
71
  - lib/stack_tracy.rb
72
+ - lib/stack_tracy/cli.rb
60
73
  - lib/stack_tracy/core_ext.rb
61
74
  - lib/stack_tracy/core_ext/kernel.rb
62
75
  - lib/stack_tracy/event_info.rb
@@ -69,6 +82,7 @@ files:
69
82
  - test/unit/test_tracy.rb
70
83
  - ui/assets/bootstrap-tab.css
71
84
  - ui/assets/bootstrap-tab.js
85
+ - ui/assets/comments.js
72
86
  - ui/assets/jquery.js
73
87
  - ui/assets/stack_tracy.css
74
88
  - ui/assets/stack_tracy.js