zatonovo / futile.logger

A logging package in R similar to log4j
151 stars 34 forks source link

Can't figure out proper configuration #86

Open kenahoo opened 5 years ago

kenahoo commented 5 years ago

I can't figure out how to configure the logger setup I'm trying to achieve.

I would like all messages INFO and above to go to the console (stdout), and all messages WARN and above to also be logged to a file warnlogger.log.

Here's my example code:

library('futile.logger')

flog.threshold('INFO')
flog.logger('ROOT', threshold=WARN, appender=appender.file('warnlogger.log'))
flog.logger('ROOT', threshold=INFO, appender=appender.console())

flog.debug("debug message")
flog.info("info message")
flog.warn("warn message")
flog.error("error message")

The output is:

% Rscript logs.R
NULL
NULL
NULL
INFO [2018-12-10 18:25:10] info message
WARN [2018-12-10 18:25:10] warn message
ERROR [2018-12-10 18:25:10] error message

But the warnlogger.log file is never created.

The README for the package says "Typically only one appender is used per logger, but multiple can be assigned." How can I assign more than one appender, if that's what I need to do to achieve what I'm trying to do?

Thanks.

muxspace commented 5 years ago

I think that statement is incorrect. The code shows that the appender will be overwritten. I thought there was an example of this use case, but I can't find it. I'll look for it today.

kenahoo commented 5 years ago

Thanks, that will be helpful.

muxspace commented 5 years ago

I looked at this a bit more, and it doesn't appear to be supported, which surprises me. I'm collecting a number of feature requests for an update, so let me think about this and see how difficult it is to support.

kenahoo commented 5 years ago

Thanks. In the meantime, would it be reasonable to create my own logger/appender that multiplexes its messages out to two backend appenders?

muxspace commented 5 years ago

Not sure. The appender doesn't take the log level, so it would be hard to do that. Unfortunately, there doesn't seem to be an easy solution. Congratulations, you stumped the chump!

muxspace commented 5 years ago

I think the easiest way to support this is to enable multiple appenders to a given logger and then also pass the log level to the appender. I prefer this over mucking with the logger hierarchy, because it's meant to be simple. Matching multiple loggers for a given log level introduces some subtle edge cases that I don't want to deal with.

In essence, you would do something like:

flog.appender(list(appender.console(), appender.tee('file.log', WARN))

Then log as you normally would:

flog.info("Only print to console")
flog.warn("Prints to console and file")

Does that work for you?

kenahoo commented 5 years ago

I think that works - as long as the logging code just keeps doing flog.info & flog.warn, etc., we can tolerate pretty much whatever config is necessary in the setup code.

Is there a precedent in log4j or Python's logging for this kind of multi-dispatch setup that's worth emulating? I haven't looked into it myself.