timmy 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9d197122524ccb2e1140f5cce09773a107679bfe
4
- data.tar.gz: 463efa752c2bb2d56b33aa2886e792e9156f2ffd
3
+ metadata.gz: 22d313c4caa316badf7f3aa3a2dd286ca7409290
4
+ data.tar.gz: 79ed29b958c3b909f6ee30710d04029eb6349f70
5
5
  SHA512:
6
- metadata.gz: b036c9c0a24faedfbf0407cb51b6353e60413115cc191922aa76f6cfeb3edb36727fee3be628920fd2124f970baf307c3f3b0dc575d12a113a239e9c8f59ce82
7
- data.tar.gz: 96a35e620a984c902c18c317baca1890db96a6aa76bd53524aa8fbc7d3c44a590c016d42c27aa118974abed18033b5a783bc03fcb419ae673992d59c08edd473
6
+ metadata.gz: 86b21b72ed5bda63389081cf14a7bf185cc316ff85b564700c9df0d3470285726268f71e882ca0001994aa2da4dcc9dc513f5a6a7e5565a6307626429ae64852
7
+ data.tar.gz: c2a2ce42c84555784dbc00318e8a44a4da8082c4b85595e6b583ea5f845048f3a61c60c73b62a444348159e02b3f2a78a8450ccdb942ad746ea5e6c472c5e4ac
@@ -10,5 +10,29 @@ module Timmy
10
10
  end
11
11
  end
12
12
  end
13
+
14
+ def add_timer(id, start_regex:, stop_regex: nil)
15
+ TargetedTimerDefinition.add(id, start_regex: start_regex, stop_regex: stop_regex)
16
+ end
17
+
18
+ def delete_timer(id)
19
+ TargetedTimerDefinition.delete(id)
20
+ end
21
+
22
+ def set_precision(precision)
23
+ Logger.set_precision(precision)
24
+ end
25
+
26
+ def set_logger_output_dir(dir)
27
+ Logger.set_output_dir(dir)
28
+ end
29
+
30
+ def set_profile(profile)
31
+ Logger.set_profile(profile)
32
+ end
33
+
34
+ def set_replay_speed(speed)
35
+ Runner.set_replay_speed(speed)
36
+ end
13
37
  end
14
38
  end
data/lib/timmy/logger.rb CHANGED
@@ -1,14 +1,18 @@
1
1
  module Timmy
2
2
  class Logger
3
3
  class << self
4
- def set_output_directory(dir)
5
- @output_directory = dir
4
+ def set_output_dir(dir)
5
+ @output_dir = File.expand_path(dir)
6
6
  end
7
7
 
8
8
  def set_precision(precision)
9
9
  @precision = precision
10
10
  end
11
11
 
12
+ def set_profile(profile)
13
+ @profile = profile
14
+ end
15
+
12
16
  def put_output(output)
13
17
  duration = MasterTimer.get
14
18
  formatted_duration = format_duration(duration)
@@ -19,18 +23,39 @@ module Timmy
19
23
  @output += sprintf("%.9f %s\n", duration, output)
20
24
  end
21
25
 
26
+ def put_eof
27
+ put_output(feint("EOF"))
28
+ end
29
+
22
30
  def put_timer(timer)
23
31
  puts format_timer(timer)
24
32
  end
25
33
 
26
- def put_stopped_profiles
27
- puts "Slowest targeted timers:"
34
+ def finalize
35
+ suffix = "#{MasterTimer.start.to_i}+#{MasterTimer.get.to_i}"
36
+ filename = File.join(output_dir, "timmy-#{suffix}.log")
37
+ header = sprintf("TIMMY-SESSION:v1:%.9f\n", MasterTimer.start)
38
+
39
+ File.write(filename, header + @output)
40
+
41
+ puts feint("Log written to #{filename}")
42
+ puts
43
+
44
+ put_profile if profile?
45
+ end
46
+
47
+ private
28
48
 
49
+ def put_profile
29
50
  slowest_timers = TargetedTimerManager
30
51
  .stopped
31
52
  .sort_by { |timer| -timer.duration }
32
53
  .slice(0, 10)
33
54
 
55
+ return unless slowest_timers.any?
56
+
57
+ puts "Slowest targeted timers:"
58
+
34
59
  slowest_timers.each do |timer|
35
60
  put_timer(timer)
36
61
  end
@@ -38,18 +63,6 @@ module Timmy
38
63
  puts
39
64
  end
40
65
 
41
- def finalize
42
- suffix = "#{MasterTimer.start.to_i}+#{MasterTimer.get.to_i}"
43
- filename = File.join(output_directory, "timmy-#{suffix}.log")
44
-
45
- File.write(filename, @output)
46
-
47
- puts feint("Log written to #{filename}")
48
- puts
49
- end
50
-
51
- private
52
-
53
66
  def format_timer(timer)
54
67
  string = "#{bold(format_duration(timer.duration))} #{format_id(timer.definition.id)}"
55
68
  string += " (#{timer.group})" if timer.group
@@ -79,13 +92,18 @@ module Timmy
79
92
  "\e[0m\e[2m#{string}\e[0m"
80
93
  end
81
94
 
82
- def output_directory
83
- @output_directory ||= "/tmp"
95
+ def output_dir
96
+ @output_dir ||= "/tmp"
84
97
  end
85
98
 
86
99
  def precision
87
100
  @precision ||= 0
88
101
  end
102
+
103
+ def profile?
104
+ @profile = false if @profile == nil
105
+ @profile
106
+ end
89
107
  end
90
108
  end
91
109
  end
@@ -2,12 +2,7 @@ module Timmy
2
2
  class OptionParser
3
3
  class << self
4
4
  def parse
5
- options = {
6
- replay: nil,
7
- profile: false,
8
- logger_output_directory: nil,
9
- logger_precision: nil
10
- }
5
+ opts = {}
11
6
 
12
7
  ::OptionParser.new do |parser|
13
8
  parser.banner = <<-EOS
@@ -19,35 +14,26 @@ Pipe output from arbitrary command:
19
14
 
20
15
  \e[36m[COMMAND] | timmy [OPTIONS]\e[0m
21
16
 
22
- Run without a pipe (usually with --replay):
17
+ Replay previous session:
23
18
 
24
- \e[36mtimmy [OPTIONS]\e[0m
19
+ \e[36mcat [LOGFILE] | timmy [OPTIONS]\e[0m
25
20
  EOS
26
21
 
27
22
  parser.separator ""
28
23
  parser.separator "\e[33mOptions:\e[0m"
29
24
  parser.separator ""
30
25
 
31
- parser.on("-r LOG", "--replay LOG", "Replay specific log file") do |replay|
32
- options[:replay] = replay
33
- end
34
-
35
- parser.on("-p", "--profile", "Profile targeted timers") do |profile|
36
- options[:profile] = profile
37
- end
38
-
39
- parser.on("--logger-output-dir DIR", "Save logs to different directory (default: \"/tmp\")") do |logger_output_directory|
40
- options[:logger_output_directory] = logger_output_directory
41
- end
42
-
43
- parser.on("--logger-precision NUM", Integer, "Set precision used when printing time (default: 0)") do |logger_precision|
44
- options[:logger_precision] = logger_precision
45
- end
26
+ parser.on("-p", "--precision NUM", Integer,
27
+ "Set precision used when printing time (default: 0)")
28
+ parser.on("-r", "--[no-]profile",
29
+ "Profile slowest targeted timers (default: false)")
30
+ parser.on("-x", "--replay-speed NUM", Float,
31
+ "Replay with given speed (default: instant)")
46
32
 
47
33
  parser.separator ""
48
- end.parse!
34
+ end.parse!(into: opts)
49
35
 
50
- options
36
+ opts.map { |key, value| [key.to_s.gsub('-', '_').to_sym, value] }.to_h
51
37
  end
52
38
  end
53
39
  end
data/lib/timmy/runner.rb CHANGED
@@ -1,74 +1,82 @@
1
1
  module Timmy
2
2
  class Runner
3
3
  class << self
4
+ def set_replay_speed(speed)
5
+ @replay_speed = speed
6
+ end
7
+
4
8
  def run
5
9
  ConfigLoader.load
6
10
 
7
11
  options = OptionParser.parse
12
+ replay_speed = options[:replay_speed] || @replay_speed
13
+ Logger.set_precision(options[:precision]) if options.key?(:precision)
14
+ Logger.set_profile(options[:profile]) if options.key?(:profile)
8
15
 
9
- if value = options[:logger_output_directory]
10
- Logger.set_output_directory(value)
11
- end
12
-
13
- if value = options[:logger_precision]
14
- Logger.set_precision(value)
15
- end
16
+ self.new(replay_speed: replay_speed).consume_stdin
17
+ end
18
+ end
16
19
 
17
- if replay = options[:replay]
18
- replay_log(replay)
19
- else
20
- consume_stdin
21
- end
20
+ def initialize(replay_speed:)
21
+ @replay_speed = replay_speed
22
+ @last_replay_time = 0
23
+ end
22
24
 
23
- if options[:profile]
24
- Logger.put_stopped_profiles
25
- end
26
- end
25
+ def consume_stdin
26
+ around_run_lines do
27
+ STDIN.each_line do |line|
28
+ next if init_replay_mode(line)
27
29
 
28
- def consume_stdin
29
- around_run_lines do
30
- STDIN.each_line do |line|
30
+ if @replay_mode
31
+ replay_line(line)
32
+ else
31
33
  run_line(line.rstrip)
32
34
  end
33
- Logger.put_output("EOF")
34
35
  end
36
+
37
+ Logger.put_eof unless @replay_mode
35
38
  end
39
+ end
36
40
 
37
- def replay_log(log)
38
- around_run_lines do
39
- start_time = File.basename(log).match(/timmy-(?<time>\d+)\+\d+.log/)[:time].to_i
40
- MasterTimer.start(start_time)
41
-
42
- File.readlines(log).each do |line|
43
- if match = line.match(/^(?<m>\d+):(?<s>\d+(\.\d+)?) \| (?<content>.*)/)
44
- line_time = match[:m].to_i * 60 + match[:s].to_f
45
- MasterTimer.set(line_time)
46
- run_line(match[:content])
47
- elsif match = line.match(/^(?<s>\d+(\.\d+)?) (?<content>.*)/)
48
- line_time = match[:s].to_f
49
- MasterTimer.set(line_time)
50
- run_line(match[:content])
51
- end
52
- end
41
+ private
42
+
43
+ def init_replay_mode(line)
44
+ if @replay_mode == nil
45
+ if (match = line.match(/^TIMMY-SESSION:v1:(?<s>\d+\.\d{9})$/))
46
+ MasterTimer.start(match[:s].to_f)
47
+ @replay_mode = true
48
+ else
49
+ @replay_mode = false
53
50
  end
54
51
  end
52
+ end
53
+
54
+ def around_run_lines
55
+ MasterTimer.start
55
56
 
56
- private
57
+ yield
57
58
 
58
- def around_run_lines
59
- MasterTimer.start
59
+ TargetedTimerManager.stop_all
60
+ Logger.finalize
61
+ end
60
62
 
61
- yield
63
+ def replay_line(line)
64
+ line_match = line.match(/^(?<s>\d+(\.\d+)?) (?<content>.*)/)
65
+ line_time = line_match[:s].to_f
62
66
 
63
- TargetedTimerManager.stop_all
64
- Logger.finalize
65
- end
67
+ duration = line_time - @last_replay_time
68
+ sleep duration / @replay_speed if @replay_speed
69
+ @last_replay_time = line_time
66
70
 
67
- def run_line(line)
68
- TargetedTimerManager.start_for_line(line)
69
- Logger.put_output(line)
70
- TargetedTimerManager.stop_for_line(line)
71
- end
71
+ MasterTimer.set(line_time)
72
+
73
+ run_line(line_match[:content])
74
+ end
75
+
76
+ def run_line(line)
77
+ TargetedTimerManager.start_for_line(line)
78
+ Logger.put_output(line)
79
+ TargetedTimerManager.stop_for_line(line)
72
80
  end
73
81
  end
74
82
  end
data/lib/timmy/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Timmy
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
data/lib/timmy.rb CHANGED
@@ -7,3 +7,11 @@ require "timmy/targeted_timer"
7
7
  require "timmy/targeted_timer_definition"
8
8
  require "timmy/targeted_timer_manager"
9
9
  require "timmy/version"
10
+
11
+ module Timmy
12
+ module_function
13
+
14
+ def configure
15
+ yield(ConfigLoader.new)
16
+ end
17
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timmy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Karol Słuszniak
@@ -52,9 +52,7 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '5.0'
55
- description: A simple command line tool that allows to measure how much time an arbitrary
56
- command spends on each stage of execution by annotating the command output with
57
- timestamps as well as running command-specific targeted timers.
55
+ description:
58
56
  email:
59
57
  - ksluszniak@gmail.com
60
58
  executables: