Module: Log
Overview
Singleton logger for use with both console and gtk+ apps. Logs to both a file and the console/queue for shell/UI apps. Uses Mutex.synchronize where required to provide thread safety.
Constant Summary collapse
- @@level =
3
- @@path =
nil
- @@_queue =
nil
- @@_stdout =
true
- @@_monitor =
Monitor.new
Instance Method Summary collapse
-
#call_details ⇒ Object
Get timestamp and location of call.
- #debug(*args) ⇒ Object
-
#die(msg) ⇒ Object
Log the given message in red and exit.
-
#empty? ⇒ Boolean
Check if the log queue is empty.
- #error(*args) ⇒ Object
- #info(*args) ⇒ Object
-
#init(path: nil, level: LogLevel.debug, queue: false, stdout: true) ⇒ Object
Singleton’s init method can be called multiple times to reset.
-
#pop ⇒ Object
Remove an item from the queue, block until one exists.
- #print(*args) ⇒ Object
- #puts(*args) ⇒ Object
- #warn(*args) ⇒ Object
Instance Method Details
#call_details ⇒ Object
Get timestamp and location of call
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/nub/log.rb', line 73 def call_details @@_monitor.synchronize{ # Skip first 3 on stack (i.e. 0 = block in call_details, 1 = synchronize, 2 = call_detail) stack = caller_locations(3, 20) # Skip past any calls in 'log.rb' or 'monitor.rb' i = -1 while i += 1 do mod = File.basename(stack[i].path, '.rb') break if !['log', 'monitor'].include?(mod) end # Save lineno from original location lineno = stack[i].lineno # Skip over block type functions to use method. # Note: there may not be a non block method e.g. in thread case regexps = [Regexp.new('^rescue\s.*in\s'), Regexp.new('^block\s.*in\s'), Regexp.new('^each$')] while regexps.any?{|regexp| stack[i].label =~ regexp} do break if i + 1 == stack.size i += 1 end # Set label, clean up for block case label = stack[i].label regexps.each{|x| label = label.gsub(label[x], "") if stack[i].label =~ x} label = stack[i].label if label.empty? # Construct stamp location = ":#{File.basename(stack[i].path, '.rb')}:#{label}:#{lineno}" return Time.now.utc.iso8601(3), location } end |
#debug(*args) ⇒ Object
200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/nub/log.rb', line 200 def debug(*args) @@_monitor.synchronize{ if LogLevel.debug <= self.level opts = args.find{|x| x.is_a?(Hash)} opts[:type] = 'D' if opts args << {:type => 'D'} if !opts newline = (opts && opts.key?(:newline)) ? opts[:newline] : true return newline ? self.puts(*args) : self.print(*args) end return true } end |
#die(msg) ⇒ Object
Log the given message in red and exit
215 216 217 218 219 220 |
# File 'lib/nub/log.rb', line 215 def die(msg) @@_monitor.synchronize{ msg += "!" if msg.is_a?(String) && msg[-1] != "!" self.puts("Error: #{msg}".colorize(:red), stamp: false) and exit } end |
#empty? ⇒ Boolean
Check if the log queue is empty
228 229 230 |
# File 'lib/nub/log.rb', line 228 def empty? return @@_queue ? @@_queue.empty? : true end |
#error(*args) ⇒ Object
164 165 166 167 168 169 170 171 172 |
# File 'lib/nub/log.rb', line 164 def error(*args) @@_monitor.synchronize{ opts = args.find{|x| x.is_a?(Hash)} opts[:loc] = true and opts[:type] = 'E' if opts args << {:loc => true, :type => 'E'} if !opts newline = (opts && opts.key?(:newline)) ? opts[:newline] : true return newline ? self.puts(*args) : self.print(*args) } end |
#info(*args) ⇒ Object
187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/nub/log.rb', line 187 def info(*args) @@_monitor.synchronize{ if LogLevel.info <= self.level opts = args.find{|x| x.is_a?(Hash)} opts[:type] = 'I' if opts args << {:type => 'I'} if !opts newline = (opts && opts.key?(:newline)) ? opts[:newline] : true return newline ? self.puts(*args) : self.print(*args) end return true } end |
#init(path: nil, level: LogLevel.debug, queue: false, stdout: true) ⇒ Object
Singleton’s init method can be called multiple times to reset.
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/nub/log.rb', line 55 def init(path:nil, level:LogLevel.debug, queue:false, stdout:true) self.id ||= 'singleton'.object_id self.path = path ? File.(path) : nil self.level = level @@_queue = queue ? Queue.new : nil @@_stdout = stdout $stdout.sync = true # Open log file creating as needed if self.path FileUtils.mkdir_p(File.dirname(self.path)) if !File.exist?(File.dirname(self.path)) @file = File.open(self.path, 'a') @file.sync = true end end |
#pop ⇒ Object
Remove an item from the queue, block until one exists
223 224 225 |
# File 'lib/nub/log.rb', line 223 def pop return @@_queue ? @@_queue.pop : nil end |
#print(*args) ⇒ Object
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/nub/log.rb', line 108 def print(*args) @@_monitor.synchronize{ str = !args.first.is_a?(Hash) ? args.first.to_s : '' # Format message opts = args.find{|x| x.is_a?(Hash)} loc = (opts && opts.key?(:loc)) ? opts[:loc] : false type = (opts && opts.key?(:type)) ? opts[:type] : "" stamp = (opts && opts.key?(:stamp)) ? opts[:stamp] : true if stamp or loc , location = self.call_details location = loc ? location : "" type = ":#{type}" if !type.empty? str = "#{}#{location}#{type}:: #{str}" end # Handle output if !str.empty? @file << str.strip_color if self.path @@_queue << str if @@_queue $stdout.print(str) if @@_stdout end return true } end |
#puts(*args) ⇒ Object
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/nub/log.rb', line 135 def puts(*args) @@_monitor.synchronize{ str = !args.first.is_a?(Hash) ? args.first.to_s : '' # Format message opts = args.find{|x| x.is_a?(Hash)} loc = (opts && opts.key?(:loc)) ? opts[:loc] : false type = (opts && opts.key?(:type)) ? opts[:type] : "" stamp = (opts && opts.key?(:stamp)) ? opts[:stamp] : true str = str.colorize(:red) if type == 'E' str = str.colorize(:light_yellow) if type == 'W' if stamp or loc , location = self.call_details location = loc ? location : "" type = ":#{type}" if !type.empty? str = "#{}#{location}#{type}:: #{str}" end # Handle output @file.puts(str.strip_color) if self.path @@_queue << "#{str}\n" if @@_queue $stdout.puts(str) if @@_stdout return true } end |
#warn(*args) ⇒ Object
174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/nub/log.rb', line 174 def warn(*args) @@_monitor.synchronize{ if LogLevel.warn <= self.level opts = args.find{|x| x.is_a?(Hash)} opts[:type] = 'W' if opts args << {:type => 'W'} if !opts newline = (opts && opts.key?(:newline)) ? opts[:newline] : true return newline ? self.puts(*args) : self.print(*args) end return true } end |