FancyLog – a proxy for Ruby’s Logger
This is the second post in the toolbox series. FancyLog is basically a proxy for Ruby’s Logger that solves some problems that occurred in my development and enhances slightly the logger API. All original methods should work as expected, so you can use FancyLog as a Logger replacement without any changes to your code.
But lets start from the beginning. In my first project I faced the problem that I did not see errors on the console when they occurred. They were nicely written to the log file or the console, but the log could get really large and I felt not to comfortable searching a large log for possible errors. I wanted an easy way to see the errors on my console, when I was developing, and to log them to the log file when in production mode. Replacing the calls to the logger with
puts seemed a bad idea, managing two logger instances, too. So I decided to factor out the logger to a separate gem and that was the birth of FancyLog.
FancyLog uses the singleton pattern, so you always have only one instance flying around your application, agnostic to where and when it was first invoked. At the first call you can pass options to it, to let it behave the way you want it to, but you can change most of them later. The only thing you can not change at run time are the log devices. Maybe this will be included in a future version.
Want an example? Here it is:
log = FancyLog.instance log.error('An undefined error occurred') log.just_an_information('I like FancyLog!!!') log.information_to_err('This is an information')
What happens here?
- In line 1, we get an instance of FancyLog. Because we do not specify any options, all informational log messages (debug, info, warn) go to STDOUT and all errors (error, fatal) go to STDERR. This is FancyLog’s default behavior, that can be overridden.
- Line 2 sends an error to the logger, that is printed to STDERR – just like Ruby’s Logger would.
- Line 3 gets interesting, because this is no more the standard Logger API. FancyLog uses Ruby’s method_missing to determine what you wanted it to do. It scans the provided method for debug, info, warn, error and fatal and calls the appropriate Logger method – in this case
info– and passes the arguments to it. If it can not find a match it defaults to the default_level specified in the options.
- Line 4 sends – as it explicitly says – an information to the error log. How this is done, you ask? You can always tell FancyLog to log messages to err or out with the appropriate ending of your method (
As you can see, FancyLog enables you to specify log methods that tell you as a programmer what really happens, regardless of the message printed to the user.
If you want to switch from development to production mode, it is just one option, you have to specify in the setup of your logger –
log = FancyLog(:errs_to_err => false).instance and you are done. Of course, FancyLog does not perform as well as the original Ruby Logger, but I do not expect logging to be a performance critical task.
To summarize: FancyLog lets you easily define were your log messages are logged to and it lets you name the log method in a way that your code makes more sense and is better readable.
- Ruby’s Logger
- Singleton pattern