Class: Mimi::Logger
- Inherits:
-
Object
- Object
- Mimi::Logger
- Extended by:
- Forwardable
- Includes:
- Core::Module
- Defined in:
- lib/mimi/logger.rb,
lib/mimi/logger/version.rb,
lib/mimi/logger/instance.rb,
lib/mimi/logger/null_logger.rb
Overview
Mimi::Logger is a preconfigured logger which outputs log messages to STDOUT.
Defined Under Namespace
Modules: Instance Classes: NullLogger
Constant Summary collapse
- CONTEXT_ID_SIZE =
bytes
8
- CONTEXT_ID_THREAD_VARIABLE =
'mimi_logger_context_id'
- VERSION =
'1.0.1'.freeze
Instance Attribute Summary collapse
-
#logger_instance ⇒ Object
readonly
Returns the value of attribute logger_instance.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
Class Method Summary collapse
-
.context_id ⇒ String
Returns current context ID if set, otherwise generates and sets a new context ID and returns it.
-
.context_id=(id) ⇒ String
Sets the new context ID to the given value.
-
.formatter(local_options) ⇒ Proc
Returns formatter Proc object depending on configured format.
-
.formatter_json(local_options) ⇒ Proc
Returns formatter for ‘json’ format.
-
.formatter_message_args_to_hash(message_args) ⇒ Hash
Converts logger methods arguments passed in various forms to a message hash.
-
.formatter_string(local_options) ⇒ Proc
Returns formatter for ‘string’ format.
-
.level_from_any(value) ⇒ Object
Returns the log level inferred from value.
-
.manifest ⇒ Object
Mimi::logger module manifest.
-
.new_context! ⇒ String
Starts a new logging context, generates a new random context ID and sets it as current.
-
.with_new_context(&_block) ⇒ Object
Executes a given block in a new context and restores the context afterwards.
-
.with_preserved_context(&_block) ⇒ Object
Executes a given block and ensures the context is restored afterwards.
Instance Method Summary collapse
-
#debug(*args, &block) ⇒ Object
Logs a new message at the corresponding logging level.
-
#error(*args, &block) ⇒ Object
Logs a new message at the corresponding logging level.
-
#fatal(*args, &block) ⇒ Object
Logs a new message at the corresponding logging level.
-
#info(*args, &block) ⇒ Object
Logs a new message at the corresponding logging level.
-
#initialize(*args) ⇒ Logger
constructor
Creates a new Logger instance.
-
#level ⇒ Integer
Returns the current log level.
-
#level=(value) ⇒ Object
Sets the log level.
-
#unknown(*args, &block) ⇒ Object
Logs a new message at the corresponding logging level.
-
#warn(*args, &block) ⇒ Object
Logs a new message at the corresponding logging level.
Constructor Details
#initialize(*args) ⇒ Logger
Creates a new Logger instance
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/mimi/logger.rb', line 68 def initialize(*args) io = args.shift if args.first.is_a?(IO) || args.first.is_a?(StringIO) io ||= STDOUT opts = args.shift if args.first.is_a?(Hash) opts ||= {} raise ArgumentError, '(io, opts) are expected as parameters' unless args.empty? # module configured? self.class.configure() if self.class..empty? @options = self.class..deep_merge(opts) @logger_instance = ::Logger.new(io) @logger_instance.level = self.class.level_from_any([:logger_level]) io.sync = true if io.respond_to?(:sync=) @logger_instance.formatter = self.class.formatter() end |
Instance Attribute Details
#logger_instance ⇒ Object (readonly)
Returns the value of attribute logger_instance.
21 22 23 |
# File 'lib/mimi/logger.rb', line 21 def logger_instance @logger_instance end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
21 22 23 |
# File 'lib/mimi/logger.rb', line 21 def @options end |
Class Method Details
.context_id ⇒ String
Returns current context ID if set, otherwise generates and sets a new context ID and returns it.
Context ID is local to the current thread. It identifies a group of instructions happening within same logical context, as a single operation. For example, processing an incoming request may be seen as a single context.
Context ID is logged with every message.
266 267 268 |
# File 'lib/mimi/logger.rb', line 266 def self.context_id Thread.current[CONTEXT_ID_THREAD_VARIABLE] || new_context! end |
.context_id=(id) ⇒ String
Sets the new context ID to the given value
275 276 277 |
# File 'lib/mimi/logger.rb', line 275 def self.context_id=(id) Thread.current[CONTEXT_ID_THREAD_VARIABLE] = id end |
.formatter(local_options) ⇒ Proc
Returns formatter Proc object depending on configured format
167 168 169 170 171 172 173 174 175 176 |
# File 'lib/mimi/logger.rb', line 167 def self.formatter() case [:logger_format].to_s when 'json' formatter_json() when 'string' formatter_string() else raise "Invalid format specified for Mimi::Logger: '#{[:logger_format]}'" end end |
.formatter_json(local_options) ⇒ Proc
Returns formatter for ‘json’ format
184 185 186 187 188 189 190 191 |
# File 'lib/mimi/logger.rb', line 184 def self.formatter_json() proc do |severity, _datetime, _progname, | h = () h[:c] = context_id if [:logger_context] h[:s] = severity.to_s[0] JSON.dump(h) + "\n" end end |
.formatter_message_args_to_hash(message_args) ⇒ Hash
Converts logger methods arguments passed in various forms to a message hash.
Arguments to a logger may be passed in 6 different ways: This helper method converts all possible variations into one Hash, where key m: refers to the message and the rest are optional parameters passed in a Hash argument.
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
# File 'lib/mimi/logger.rb', line 228 def self.() = .is_a?(String) || .is_a?(Hash) ? [] : if !.is_a?(Array) || .size > 2 raise ArgumentError, "Mimi::Logger arguments expected to be Array of up to 2 elements: #{.inspect}" end h = {} arg1 = .shift arg2 = .shift if arg1.is_a?(String) if arg2 && !arg2.is_a?(Hash) raise ArgumentError, 'Mimi::Logger arguments are expected to be one of (<String>, <Hash>, [<String>, <Hash>])' end h = arg2.dup || {} h[:m] = arg1 elsif arg1.is_a?(Hash) if arg2 raise ArgumentError, 'Mimi::Logger arguments are expected to be one of (<String>, <Hash>, [<String>, <Hash>])' end h = arg1.dup else raise ArgumentError, 'Mimi::Logger arguments are expected to be one of (<String>, <Hash>, [<String>, <Hash>])' end h end |
.formatter_string(local_options) ⇒ Proc
Returns formatter for ‘string’ format
199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/mimi/logger.rb', line 199 def self.formatter_string() proc do |severity, _datetime, _progname, | h = () parts = [] parts << severity.to_s[0] parts << context_id if [:logger_context] parts << h[:m].to_s.tr("\n", [:logger_cr_character]) parts << '...' unless h.except(:m).empty? parts.join(', ') + "\n" end end |
.level_from_any(value) ⇒ Object
Returns the log level inferred from value
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/mimi/logger.rb', line 142 def self.level_from_any(value) return value if value.is_a?(Integer) case value.to_s.downcase.to_sym when :debug ::Logger::DEBUG when :info ::Logger::INFO when :warn ::Logger::WARN when :error ::Logger::ERROR when :fatal ::Logger::FATAL when :unknown ::Logger::UNKNOWN else raise ArgumentError, "Invalid value for the log level: '#{value}'" end end |
.manifest ⇒ Object
Mimi::logger module manifest
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/mimi/logger.rb', line 28 def self.manifest { logger_format: { desc: 'String or JSON', default: 'json', hidden: true }, logger_context: { desc: 'Logger will log context', type: :boolean, default: true, hidden: true }, logger_level: { desc: 'Logger severity level threshold', default: 'info', type: ['debug', 'info', 'warn', 'error', 'fatal'] }, logger_cr_character: { desc: 'Logger replaces new line with alternative CR character', default: '↲', # alternative CR: ↵ ↲ ⏎ type: :string, hidden: true } } end |
.new_context! ⇒ String
Starts a new logging context, generates a new random context ID and sets it as current
283 284 285 |
# File 'lib/mimi/logger.rb', line 283 def self.new_context! self.context_id = SecureRandom.hex(CONTEXT_ID_SIZE) end |
.with_new_context(&_block) ⇒ Object
Executes a given block in a new context and restores the context afterwards
313 314 315 316 317 318 |
# File 'lib/mimi/logger.rb', line 313 def self.with_new_context(&_block) with_preserved_context do new_context! yield end end |
.with_preserved_context(&_block) ⇒ Object
Executes a given block and ensures the context is restored afterwards
297 298 299 300 301 302 |
# File 'lib/mimi/logger.rb', line 297 def self.with_preserved_context(&_block) preserved_context_id = context_id yield ensure self.context_id = preserved_context_id end |
Instance Method Details
#debug(*args, &block) ⇒ Object
Logs a new message at the corresponding logging level
104 105 106 |
# File 'lib/mimi/logger.rb', line 104 def debug(*args, &block) logger_instance.debug(args, &block) end |
#error(*args, &block) ⇒ Object
Logs a new message at the corresponding logging level
122 123 124 |
# File 'lib/mimi/logger.rb', line 122 def error(*args, &block) logger_instance.error(args, &block) end |
#fatal(*args, &block) ⇒ Object
Logs a new message at the corresponding logging level
128 129 130 |
# File 'lib/mimi/logger.rb', line 128 def fatal(*args, &block) logger_instance.fatal(args, &block) end |
#info(*args, &block) ⇒ Object
Logs a new message at the corresponding logging level
110 111 112 |
# File 'lib/mimi/logger.rb', line 110 def info(*args, &block) logger_instance.info(args, &block) end |
#level ⇒ Integer
Returns the current log level
89 90 91 |
# File 'lib/mimi/logger.rb', line 89 def level logger_instance.level end |
#level=(value) ⇒ Object
Sets the log level. Allows setting the log level from a String or a Symbol, in addition to the standard ::Logger::INFO etc.
98 99 100 |
# File 'lib/mimi/logger.rb', line 98 def level=(value) logger_instance.level = self.class.level_from_any(value) end |
#unknown(*args, &block) ⇒ Object
Logs a new message at the corresponding logging level
134 135 136 |
# File 'lib/mimi/logger.rb', line 134 def unknown(*args, &block) logger_instance.unknown(args, &block) end |
#warn(*args, &block) ⇒ Object
Logs a new message at the corresponding logging level
116 117 118 |
# File 'lib/mimi/logger.rb', line 116 def warn(*args, &block) logger_instance.warn(args, &block) end |