Skip to content

Commit bf9f23e

Browse files
carlosdanielpohlodFabio Leandro Janiszevski
and
Fabio Leandro Janiszevski
committed
feat:
- added first version of the tracker that computes the execution time of each file. - Moved the base tracer logic to a base tracer, so that it can be reused in the two existing tracers Co-authored-by: Fabio Leandro Janiszevski <[email protected]>
1 parent 56059fa commit bf9f23e

File tree

7 files changed

+167
-15
lines changed

7 files changed

+167
-15
lines changed

lib/rails_tracepoint_stack.rb

+18
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
require 'rails_tracepoint_stack/configuration'
22
require 'rails_tracepoint_stack/log_formatter'
33
require 'rails_tracepoint_stack/tracer'
4+
require 'rails_tracepoint_stack/duration_tracer'
45

56
$rails_tracer_rtps = nil
67

@@ -36,3 +37,20 @@ def self.enable_trace
3637
$rails_tracer_rtps.disable
3738
end
3839
end
40+
41+
if ENV.fetch("ENABLE_EXECUTION_DURATION", "false") == "true"
42+
begin
43+
$rails_duration_tracer = RailsTracepointStack::DurationTracer.new
44+
45+
$rails_duration_tracer.enable
46+
47+
at_exit do
48+
$rails_duration_tracer.disable
49+
50+
RailsTracepointStack::DurationTracerLogger.new.show_top_files
51+
end
52+
53+
ensure
54+
#destroy the tmp file
55+
end
56+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
module RailsTracepointStack
2+
module Duration
3+
class Output
4+
attr :file_durations
5+
6+
def initialize
7+
@file_durations = Hash.new(0)
8+
compute_duration!
9+
end
10+
11+
def show_top_files
12+
top_10_files.each_with_index do |(file, total_duration), index|
13+
puts "#{index + 1}. File: #{file} - Total Duration: #{total_duration.round(6)} seconds"
14+
end
15+
end
16+
17+
private
18+
19+
def compute_duration!
20+
File.open("log-boot-4.txt", "r").each_line do |line|
21+
data = JSON.parse(line)
22+
23+
file = data["file"]
24+
duration = data["duration"]
25+
26+
file_durations[file] += duration
27+
end
28+
end
29+
#TODO: turn the number of files flexible
30+
def top_10_files
31+
@top_10_files ||= file_durations.sort_by { |_, total_duration| -total_duration }.first(10)
32+
end
33+
end
34+
end
35+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
module RailsTracepointStack
3+
module TmpSave
4+
def self.save(trace:, last_time:)
5+
duration = current_time - last_time
6+
log_obj = {
7+
time: current_time,
8+
class: trace.class_name,
9+
method: trace.method_name,
10+
file: trace.file_path,
11+
line: trace.line_number,
12+
duration: duration
13+
}
14+
File.open("time_log.json", "a") do |file|
15+
file.puts log_obj.to_json
16+
end
17+
end
18+
end
19+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
require "rails_tracepoint_stack/tracer_base"
2+
require "rails_tracepoint_stack/duration/tmp_save"
3+
4+
module RailsTracepointStack
5+
class DurationTracer < RailsTracepointStack::TracerBase
6+
7+
private
8+
9+
def generate_tracer
10+
TracePoint.new(:line) do |tracepoint|
11+
trace = RailsTracepointStack::Trace.new(trace_point: tracepoint)
12+
13+
next if ignore_trace?(trace: trace)
14+
15+
current_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
16+
17+
if last_time
18+
RailsTracepointStack::TmpSave.save(trace: trace, last_time: last_time)
19+
end
20+
21+
last_time = current_time
22+
end
23+
end
24+
end
25+
end

lib/rails_tracepoint_stack/tracer.rb

+2-15
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,7 @@
1-
# TODO: Move to a loader file
2-
require "rails_tracepoint_stack/logger"
3-
require "rails_tracepoint_stack/trace_filter"
4-
require "rails_tracepoint_stack/trace"
5-
require "rails_tracepoint_stack/log_formatter"
1+
require "rails_tracepoint_stack/tracer_base"
62

73
module RailsTracepointStack
8-
class Tracer
9-
include RailsTracepointStack::TraceFilter
10-
extend Forwardable
11-
12-
def_delegators :@tracer, :enable, :disable
13-
14-
def initialize
15-
generate_tracer
16-
end
17-
4+
class Tracer < RailsTracepointStack::TracerBase
185
private
196

207
def generate_tracer
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# TODO: Move to a loader file
2+
require "rails_tracepoint_stack/logger"
3+
require "rails_tracepoint_stack/trace_filter"
4+
require "rails_tracepoint_stack/trace"
5+
require "rails_tracepoint_stack/log_formatter"
6+
7+
module RailsTracepointStack
8+
class TracerBase
9+
include RailsTracepointStack::TraceFilter
10+
extend Forwardable
11+
12+
def_delegators :@tracer, :enable, :disable
13+
14+
def initialize
15+
generate_tracer
16+
end
17+
end
18+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
require "spec_helper"
2+
require "json"
3+
4+
RSpec.describe RailsTracepointStack::Duration::Output do
5+
describe "#show_top_files" do
6+
before do
7+
allow(File)
8+
.to receive(:open)
9+
.with("log-boot-4.txt", "r")
10+
.and_return(
11+
StringIO.new(
12+
{file: "file1", duration: 1}.to_json + "\n" +
13+
{file: "file1", duration: 2}.to_json + "\n" +
14+
{file: "file2", duration: 1}.to_json + "\n" +
15+
{file: "file2", duration: 1}.to_json + "\n" +
16+
{file: "file2", duration: 1}.to_json + "\n" +
17+
{file: "file3", duration: 1}.to_json + "\n" +
18+
{file: "file4", duration: 1}.to_json + "\n" +
19+
{file: "file5", duration: 1}.to_json + "\n" +
20+
{file: "file5", duration: 1}.to_json + "\n" +
21+
{file: "file5", duration: 1}.to_json + "\n" +
22+
{file: "file6", duration: 1}.to_json + "\n" +
23+
{file: "file7", duration: 1}.to_json + "\n" +
24+
{file: "file8", duration: 1}.to_json + "\n" +
25+
{file: "file9", duration: 1}.to_json + "\n" +
26+
{file: "file10", duration: 1}.to_json + "\n" +
27+
{file: "file11", duration: 1}.to_json + "\n"
28+
)
29+
)
30+
end
31+
32+
it "prints the top 10 files with their total duration" do
33+
expect { described_class.new.show_top_files }
34+
.to output(
35+
<<~OUTPUT
36+
1. File: file1 - Total Duration: 3 seconds
37+
2. File: file2 - Total Duration: 3 seconds
38+
3. File: file5 - Total Duration: 3 seconds
39+
4. File: file3 - Total Duration: 1 seconds
40+
5. File: file4 - Total Duration: 1 seconds
41+
6. File: file6 - Total Duration: 1 seconds
42+
7. File: file7 - Total Duration: 1 seconds
43+
8. File: file8 - Total Duration: 1 seconds
44+
9. File: file9 - Total Duration: 1 seconds
45+
10. File: file10 - Total Duration: 1 seconds
46+
OUTPUT
47+
).to_stdout
48+
end
49+
end
50+
end

0 commit comments

Comments
 (0)