14

I need to add a custom log level like "verbose" or "traffic" to ruby logger, how to do?

7 Answers 7

7

Your own logger just need to overwrite the Logger#format_severity method, something like this :

class MyLogger < Logger

  SEVS = %w(DEBUG INFO WARN ERROR FATAL VERBOSE TRAFFIC)
  def format_severity(severity)
    SEVS[severity] || 'ANY'
  end

  def verbose(progname = nil, &block)
    add(5, nil, progname, &block)
  end
end
Sign up to request clarification or add additional context in comments.

1 Comment

IMO, this is a better answer because it avoids the monkey patching of Ruby core. +
5

You can simply add to the Logger class:

require 'logger'

class Logger
  def self.custom_level(tag)
    SEV_LABEL << tag 
    idx = SEV_LABEL.size - 1 

    define_method(tag.downcase.gsub(/\W+/, '_').to_sym) do |progname, &block|
      add(idx, nil, progname, &block)
    end 
  end 

  # now add levels like this:

  custom_level 'TRAFFIC'
  custom_level 'ANOTHER-TAG'
end


# using it:

log = Logger.new($stdout)
log.traffic('testing')
log.another_tag('another message here.')

2 Comments

results in FrozenError: can't modify frozen Array
Add the unfreeze method via stackoverflow.com/questions/35633367/… then Logger::SEV_LABEL.unfreeze
3

Log levels are nothing but integer constants defined in logger.rb:

# Logging severity.
module Severity
  DEBUG = 0
  INFO = 1
  WARN = 2
  ERROR = 3
  FATAL = 4
  UNKNOWN = 5
end

You can log messages with any level you like using Logger#add method:

l.add 6, 'asd'
#=> A, [2010-02-17T16:25:47.763708 #14962]   ANY -- : asd

1 Comment

This is not going to work well (unless you want to add a level above fatal) because these numbers matter and are used in a comparison return true if @logdev.nil? or severity < level
2

If you start needing a bunch of custom stuff, it may be worth checking out log4r, which is a flexible logging library that lets you do a bunch of interesting/useful stuff easily.

Comments

0

I couldn't get the solution suggested by @Lucas to work as I wanted to insert an extra level - my solution was along the following lines...

class UWS_Logger < Logger
  verb = $VERBOSE
  $VERBOSE = nil
  %w(DEBUG TRACE INFO WARN ERROR FATAL UNKNOWN).each_with_index do |c, i|
    Logger::Severity.const_set(c, i)
  end
  $VERBOSE = verb

end

Comments

-1

This is an old question, but since it comes up so high on google, I figured it'd be useful to have to correct answer. You can actually use the Logging.init method. Here's how you would add a trace log level

require 'logging'
Logging.init %w(trace debug info warn error fatal)
Logging.logger.root.level = :trace
Logging.logger.root.add_appenders Logging.appenders.stdout
Logging.logger['hello'].trace 'TEST'

This is using the 2.0.0 of the logging gem.

1 Comment

But how to use the built-in logger? is using another dependency necessary?
-2

You can create your own logger by overloading the Logger class

1 Comment

@turri not that I know of. It looks like the levels are pretty much coded in ( Logger::INFO and so on). Maybe there's another way but I can't think of it right now

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.