TwP / logging

A flexible logging library for use in Ruby programs based on the design of Java's log4j library.
https://rubygems.org/gems/logging
MIT License
529 stars 100 forks source link

::Logging.num_level is not working for me #226

Closed rful011 closed 2 years ago

rful011 commented 3 years ago

Hi

First off Thanks for a great gem! I am converting a lot of my stuff to using it.

I recently tried out filters on a new appender I have written using the supplied "levels" filter and found that the filter were not have any effect.

I already had my own wrapper around Logging so I overrode some of levels' methods so I could see what was going on. After a lot of fiddling I established that doing something like

filter = Logging::Filters::Level.new( 'error', 'alert' )
Logging.init :trace, :debug, :info, :warn, :error, :alert
$logger = Logging.logger 'XXXX', level: 'debug'

$logger.add_appenders Logging::Appenders::ES.new( 'test_es', connection: es, filters: [filter])
pp $logger.appenders[1].filters

gives output:

[#<Logging::Filters::Level:0x00000001733bc8 @levels=#<Set: {}>>]

I.e @levels is an empty Set

The problem is that Logging::Filters::Levels.new is called before Logging.init to set up the logging levels!

May be an extra line in levels.new to make sure that LEVELS is initialised!

Having fixed that and moved the filter definition I spent more time debugging my custom appender and the with the filter. Almost all the problems were with getting parameters to various call right. I like hash parameters but if you get the keys wrong things fail silently.

Would you please add a example for setting up a filter, I suspect it would have saved me a lot of trial and error. On the up side I learned a bit more ruby from my hours peering at your code!

Lastly is there a way of instantiating a logging instance with just my custom appender? Logging.logger needs a dev which it maps to one of the preconfigured appenders.

I have tried "removing" the appender I created first but it does not work:

$logger = Logging.logger('default', {level: 'debug'})
 Logging::Appenders.remove 'default'
filter = Logging::Filters::Level.new( 'error', 'alert' )
$logger.add_appenders Logging::Appenders::ES.new( 'test_es', connection: es, filters: [filter])
puts $logger.appenders

tools@secmgrprd02:~/src/common-library$ ruby test/my_logger_es.rb
<Appenders::RollingFile name="default">
<Appenders::ES name="test_es">

not sure if this is a bug or a feature.

This isn't critical as I will normally have a default of syslog which gets everything and have the high priority stuff logged to elasicsearch where I have stuff set up to log calls into ServiceNow.

TwP commented 2 years ago

The problem is that Logging::Filters::Levels.new is called before Logging.init to set up the logging levels! May be an extra line in levels.new to make sure that LEVELS is initialised!

Good point - I added a check during Filter initialization to ensure that the Logging framework has been configured properly #238

Would you please add a example for setting up a filter, I suspect it would have saved me a lot of trial and error. On the up side I learned a bit more ruby from my hours peering at your code!

I'll add that to the list of examples to create.

Lastly is there a way of instantiating a logging instance with just my custom appender? Logging.logger needs a dev which it maps to one of the preconfigured appenders.

Yes! The Logging.logger() method is designed to return a Logger that is configured as closely as possible to the core Ruby logger class.

You can get a plain Logger via Logging::Logger['example'].