Class: RGFA::Logger Private

Inherits:
Object show all
Defined in:
lib/rgfa/logger.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

This class allows to output a message to the log file or STDERR and to keep track of the progress of a method which takes long time to complete.

Defined Under Namespace

Classes: ProgressData

Instance Method Summary collapse

Constructor Details

#initialize(verbose_level: 1, channel: STDERR, prefix: "#") ⇒ RGFA::Logger

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Create a Logger instance

Parameters:

  • channel (#puts) (defaults to: STDERR)

    where to output (default: STDERR)

  • prefix (String) (defaults to: "#")

    output prefix (default: “#”)

  • verbose_level (Integer) (defaults to: 1)

    0: no logging; >0: the higher, the more logging



23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/rgfa/logger.rb', line 23

def initialize(verbose_level: 1, channel: STDERR, prefix: "#")
  @progress = false
  if !verbose_level.kind_of?(Integer)
    raise ArgumentError, "verbose_level must be an Integer"
  end
  if !channel.respond_to?(:puts)
    raise TypeError, "channel must provide a puts method"
  end
  @channel = channel
  @pfx = prefix
  @verbose_level = verbose_level
  @data = {}
end

Instance Method Details

#disable_progressvoid

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Disable progress logging



67
68
69
70
71
# File 'lib/rgfa/logger.rb', line 67

def disable_progress
  @progress = false
  @channel.puts "#@pfx Progress logging disabled" if @verbose_level > 0
  return nil
end

#enable_progress(part: 0.1) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Enable output from the Logger instance

Parameters:

  • part (Float) (defaults to: 0.1)
    • part = 0 => output at every call of progress_log

    • 0 < part < 1 => output once per part of the total progress

      (e.g. 0.001 = log every 0.1% progress)
      
    • part = 1 => output only total elapsed time



55
56
57
58
59
60
61
62
63
# File 'lib/rgfa/logger.rb', line 55

def enable_progress(part: 0.1)
  if part < 0 or part > 1
    raise ArgumentError, "part must be in range [0..1]"
  end
  @progress = true
  @part = part
  @channel.puts "#@pfx Progress logging enabled" if @verbose_level > 0
  return nil
end

#log(msg, min_verbose_level = 1) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Output a message

Parameters:

  • msg (String)

    message to output

  • min_verbose_level (Integer) (defaults to: 1)


42
43
44
45
# File 'lib/rgfa/logger.rb', line 42

def log(msg, min_verbose_level=1)
  @channel.puts "#@pfx #{msg}" if @verbose_level >= min_verbose_level
  return nil
end

#progress_end(symbol, **keyargs) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Completes progress logging for a computation

Parameters:

  • symbol (Symbol)

    the symbol assigned to the computation at init time

  • keyargs (Hash)

    additional units to display, with their current value (e.g. segments_processed: 10000)



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/rgfa/logger.rb', line 137

def progress_end(symbol, **keyargs)
  return if !@progress
  data = @data[symbol]
  return if data.nil?
  t = Time.now - data.starttime
  tstr= ("Elapsed time: %02dh %02dmin %02ds" % [t/3600, t/60%60, t%60])
  quantity = @part == 1 ? data.total.to_s : "100.0%"
  keystr = ""
  keyargs.each {|k,v| keystr << "; #{k}: #{v}"}
  str = "#@pfx #{quantity} #{data.units} processed [#{tstr}#{keystr}]"
  spacediff = " "*([data.strlen - str.size,0].max)
  @channel.print "\r" if @part != 1
  @channel.puts "#{str}#{spacediff}"
  @channel.flush
  @data.delete(symbol)
  return nil
end

#progress_init(symbol, units, total, initmsg = nil) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Initialize progress logging for a computation

Parameters:

  • symbol (Symbol)

    a symbol assigned to the computation

  • units (String)

    a string with the name of the units, in plural

  • total (Integer)

    total number of units

  • initmsg (String) (defaults to: nil)

    an optional message to output at the beginning



80
81
82
83
84
85
86
87
88
# File 'lib/rgfa/logger.rb', line 80

def progress_init(symbol, units, total, initmsg = nil)
  return nil if !@progress or total == 0
  str = "#@pfx 0.0% #{units} processed"
  @data[symbol] = ProgressData.new(0, units, (@part*total).to_i, 1, total,
                                   Time.now, str.size)
  @channel.puts "#@pfx #{initmsg}" if initmsg
  @channel.print str if @part != 1
  return nil
end

#progress_log(symbol, progress = 1, **keyargs) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Updates progress logging for a computation

Parameters:

  • symbol (Symbol)

    the symbol assigned to the computation at init time

  • keyargs (Hash)

    additional units to display, with their current value (e.g. segments_processed: 10000)

  • progress (Integer) (defaults to: 1)

    how many units were processed



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/rgfa/logger.rb', line 99

def progress_log(symbol, progress=1, **keyargs)
  return nil if !@progress or @part == 1
  data = @data[symbol]
  return nil if data.nil?
  data.counter += progress
  if data.counter == data.total
    progress_end(symbol)
  elsif data.partsize == 0 or
      (data.counter / data.partsize).to_i > data.lastpart
    return nil if data.partsize == 0 and @part > 0
      # this means total is very small
    data.lastpart = data.counter / data.partsize if data.partsize > 0
    done = data.counter.to_f / data.total
    t = Time.now - data.starttime
    eta = (t / done) - t
    tstr= ("Elapsed: %02dh %02dmin %02ds" % [t/3600, t/60%60, t%60])
    etastr = ("ETA: %02dh %02dmin %02ds" % [eta/3600, eta/60%60, eta%60])
    donestr = "%.1f" % (done*100)
    keystr = ""
    keyargs.each {|k,v| keystr << "; #{k}: #{v}"}
    str = "#@pfx #{donestr}% #{data.units} processed "+
            "[#{tstr}; #{etastr}#{keystr}]"
    if str.size > data.strlen
      data.strlen = str.size
      spacediff = ""
    else
      spacediff = " "*(data.strlen-str.size)
    end
    @channel.print "\r#{str}#{spacediff}"
    @channel.flush
  end
  return nil
end