Applications today are becoming increasingly complex. Part of making them easier to develop/maintain is to do logging. Logging allows you to later see what happened in your application. It can be a great help when debugging and/or testing it. The great thing about logging is that you can use it on systems in production and/or in use - if an error occurs, by examining the log, you can get a picture of where the problem is.
Good logging is mandatory in support projects, you simply can't live without it.
Used properly, logging is a very powerful tool. Besides aiding debugging/ testing, it can also show you how your application is used (which modules, etc.), how time-consuming certain parts of your program are, how much bandwidth your application consumes, etc. - it's up to you how much information you log, and where.
Features
- A simple and clear separation of concepts
- concepts are also easily separated into namespaces
- A very flexible interface
- You don't pay for what you don't use.
- Allows for internationalization (i18n) - can be used with Unicode characters
- Fits a lot of scenarios: from very simple (dumping all to one log) to very complex (multiple logs, some enabled/some not, levels, etc).
- Allows you to choose how you use logs in your code (by defining your own LOG_ macros, suiting your application)
- Allows you to use Log levels (debug, error, fatal, etc). However this is an orthogonal concept - the library will work whether you use levels, categories or whatever , or not.
- Efficient filtering of log messages - that is, if a log is turned off, the message is not processed at all
- Thread-safe - the library allows you several degrees of thread-safety, as you'll see
- Allows for formatters and destinations
- formatters format the message (like, prepending extra information - an index, the time, thread id, etc)
- destinations specify where the message is to be written
- Formatters and Destinations are orthogonal to the rest of the library - if you want you can use them, otherwise you can define your own writing mechanism
- Easy manipulation of the logs (turning on/off, setting formatters, destinations, etc)
- Allows you to use tags (extra information about the context of the log: file/line, function name, thread id, etc.)
- Allows for scoped logs
- Has high precision time formatter
- easy to configure at run-time, if you wish
- cache messages before logs are initialized
- Allows for profiling itself
To get you started, here's the most common usage:
This usage:
- You have multiple levels (in this example: debug < info < error)
- You want to format the message before it's written (in this example: prefix it by time, by index, and append newline to it)
- You have one log, which writes to several log destinations (in this example: the console, the debug output window, and a file)
In this example, all output will be written to the console, debug output window, and "out.txt" file. It will look similar to this one:
21:03.17.243 [1] this is so cool 1
21:03.17.243 [2] first error 2
21:03.17.243 [3] hello, world
21:03.17.243 [4] second error 3
21:03.17.243 [5] good to be back ;) 4
21:03.17.243 [6] third error 5
Click to see the code
To see more examples, check out Usage Scenarios (together with code).
I certainly welcome all feedback. So, be it a suggestion, or criticism, do write to me:
See the changelog.
Copyright John Torjo © 2007
Have a question/ suggestion/ comment? Send me feedback