Class: InteractiveLogger

Inherits:
Object
  • Object
show all
Defined in:
lib/interactive-logger.rb,
lib/interactive_logger/step.rb,
lib/interactive_logger/threaded_step_interface.rb

Overview

A logger that shows activity for each step without spamming to stdout.

Defined Under Namespace

Classes: Step, ThreadedStepInterface

Instance Method Summary collapse

Constructor Details

#initialize(debug: false) ⇒ InteractiveLogger

Returns a new instance of InteractiveLogger.



11
12
13
14
15
# File 'lib/interactive-logger.rb', line 11

def initialize(debug: false)
  @debug = debug
  @current_step = nil
  @draw_mutex = Mutex.new
end

Instance Method Details

#debug(str) ⇒ Object

Post a debug message above the current step output, if debugging is enabled.



75
76
77
78
79
80
81
82
83
84
# File 'lib/interactive-logger.rb', line 75

def debug(str)
  return unless debug?

  @draw_mutex.synchronize do
    @current_step.blank if @current_step
    print '--> '.yellow
    puts str
    @current_step.repaint if @current_step
  end
end

#debug?Boolean

Returns:

  • (Boolean)


17
# File 'lib/interactive-logger.rb', line 17

def debug?; @debug == true end

#error(str) ⇒ Object

Post an error message above the current step output.



97
98
99
100
101
102
103
104
# File 'lib/interactive-logger.rb', line 97

def error(str)
  @draw_mutex.synchronize do
    @current_step.blank if @current_step
    print '--> '.red
    puts str
    @current_step.repaint if @current_step
  end
end

#info(str) ⇒ Object

Post an informative message above the current step output.



87
88
89
90
91
92
93
94
# File 'lib/interactive-logger.rb', line 87

def info(str)
  @draw_mutex.synchronize do
    @current_step.blank if @current_step
    print '--> '.green
    puts str
    @current_step.repaint if @current_step
  end
end

#msg(str) ⇒ Object

Post a single message, without any progress tracking.



107
108
109
110
111
# File 'lib/interactive-logger.rb', line 107

def msg(str)
  c = Step.new(str)
  c.success
  print "\n"
end

#start(str) ⇒ Object

Start a step.



20
21
22
23
24
25
26
27
28
29
30
# File 'lib/interactive-logger.rb', line 20

def start(str)
  @current_step = Step.new(str)
  yield @current_step
  print "\n"
rescue => e
  @current_step.failure "Error while performing step: #{str}\n  #{e.class}: #{e.message}"
  print "\n"
  raise
ensure
  @current_step = nil
end

#start_threaded(str) ⇒ Object

Use a threaded interface, to keep the UI updated even on a long-running process.



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/interactive-logger.rb', line 34

def start_threaded(str)
  @current_step = Step.new(str)
  queue = Queue.new

  Thread.abort_on_exception = true
  child = Thread.new do
    yield ThreadedStepInterface.new(queue)
  end

  loop do
    if queue.empty?
      @draw_mutex.synchronize do
        @current_step.continue # Keep the UI updating regardless of actual process.
      end
    else
      until queue.empty?
        msg = queue.pop

        @draw_mutex.synchronize do
          @current_step.send(msg.shift, *msg)
        end
      end
    end

    break unless child.alive?
    sleep 0.5
  end

  puts
  child.join

  @current_step.nil?
rescue => e
  @current_step.failure "Error while performing step: #{str}\n  #{e.class}: #{e.message}"
  print "\n"
  raise
ensure
  @current_step = nil
end