I don't like debuggers. Debuggers are scary, filled with memory addresses, break points and what-have-yous (I'll just disregard that I never bothered to properly learn their ways for a moment here). I much prefer the simple and straightforward way of logging everything. Logging instead of debugging also has a bunch of advantages, such as offering a wealth of information for when something breaks on a machine you don't control, giving you a direct and nice overview of the program flow, lets you archive the information in server applications, and so on. Essentially you should do lots of logging anyway, so you might as well do it well and forget the debugger entirely.
Since I care a lot about formatting and how things look in general, I like to have a system that makes the logs sufficiently extensible and nice-looking. I also like to employ a level-and-category based system, which many logging frameworks don't seem to offer for whatever reason. Most only support either levels or categories, or a weird combination of both where levels are also categories. The reason why I want levels and categories is because they dictate two rather different, but equally important pieces of information that help immensely in sorting out the problems and scanning through the logfiles.
Logging levels indicate how important the message is. An unrecoverable error for example would be deemed really important, but a progress message could be quite unimportant. So, you want levels to be able to filter out noise that doesn't interest you at the moment. When running a production server, you probably only want to hear about errors, not about whatever detail work the server is currently undergoing.
Categories on the other hand allow you to sort out information depending on subsystems. Especially in large and extensive programs such as Radiance, this additional step of separation is really important. I want to be able to know at a glance in what part of the system something happens, so I can quickly identify the source of a potential issue or oddity. This separation also helps to figure out the current program state and flow, as it allows you to roughly estimate the call stack and history.
Putting both into one would greatly reduce the amount of information the logs carry and I want to avoid this. Now, previously I was using Log4CL. The problems I have with it are follows: the documentation is confusing and hard to figure out. The default log output format is really noisy and I don't like it. I'm sure I could change that somehow, but I couldn't figure out how and didn't want to bother. Otherwise it seems to do a lot of extra stuff that I don't really deem necessary.
Not finding any suitable alternative that offered what I want, I naturally set out to create my own. After a bit of thinking on how to set this up, I then decided to launch yet another sub-project to abstract away the main way messages are being passed around. This lead me to create piping. Piping provides a rather simple (and still a bit rough around the edges) framework for creating message passing systems. As the name implies, it uses a model similar to a pipeline. There's different kinds of pipe parts, splitters, valves, filters, faucets, etc. that either manipulate the flow or the message itself.
Once that was complete I got to work on Verbose, my new logging system. Out of the box, verbose provides a multi-threading ready simple, but extensible logging solution. It starts out with a small pipeline setup for the different logging levels and adds a rather simple faucet (endpoint) to print to the repl/standard-output. To log a message, it provides either the log function or a separate function for each level directly. It also currently provides a rotating log faucet, that allows you to set up a rotating file log, for longer sessions or archives.
Given that it has piping in its background you can also set up very complex logging systems that manipulate log messages or log to multiple faucets depending on category, message, thread, time or whatever your heart might desire. Currently though, creating pipelines is a bit of a pain and can take a lot more code than I think is necessary, so there's still some work to be done there, before I want to release it as a 1.0.0 . Currently both projects are available for download over my public GIT repositories. I won't ask to put them on Quicklisp until I get sufficient testing and a version 1 out for each of them though.
I already switched all of Radiance's logging over to Verbose and I'm liking it quite a bit. It's still lacking a lot of verbosity, so I'll probably go around and add logging statements all over the place so I can get a nice… well, let's say less painful debugging experience.
I'm a bit concerned though that this will eat up too much of my time again. Already I've been working on my projects way more than I feel comfortable with in the past few weeks. Top priority right now is to get back into studying and catch up on things I never sufficiently revised or practised. Hopefully I'll be able to do this and, well, development on this will slow down.
So, as weird as this might sound, hopefully I won't be updating this blog any soon. Next time: Probably something different? ?? ???
Written by shinmera