No, it's not a typo. The title has a deliberate play on words that implies that incorrect strategies can end up in tragedy. While the word "tragedy" may be a bit strong, the thought process does have a ring of truth to it. In this chapter we attempt to give you helpful hints and tips to boost the performance of your code and your development team. We will break the discussion into logging strategies, development strategies, component strategies, testing strategies, and finally some notes on security strategies.
Logging is a necessary function in any system. The problem arises when the logging is not implemented in an efficient manner. Before we get into the nuts and bolts of how to create an efficient logging implementation, we have to identify what logging efficiency is.
In the spirit of the Separation of Concerns pattern, there are two problem domains to consider: log organization and log writing. Log organization is primarily concerned with how the log categories are organized, and how the log files are organized. Log writing has to do with the mechanics of writing log entries.
The Avalon framework and team advocate a category based approach to organizing loggers as opposed to a class name based approach. There is a very good reason for this. First is that categorization allows you to put information of like kind in one location. Second, it allows you to turn on and off an entire category of log messages.
The arguments for the class name based logging usually fall under these assumptions:
While these arguments have their point, so does a strict category based logging approach:
I would argue that it is a mistake to use only one category for all logging. The reason is that you will inevitably need to turn on and off a whole class of messages. Another reason is that you will need at least one category for each log file you have. One effective approach is to separate your logging needs into roles and classifications.
If you have already decomposed your system into Components, then you have one set of categories defined. I would use a shorthand name for the category names for simple reference (e.g. "resource" instead of "org.apache.avalon.excalibur.resource.ResourceManager"). The simplified names can be used for a broad set of classes. Using the same example, the name "resource" implies the Resource class, its manager, and anything that is directly associated with the concept of a "resource".
You can also use classifications as a specialization of the main role classification. For example, all ComponentManager code would have a category name of "component". This would allow you to have a Category manager for the aforementioned "resource" infrastructure. Typically classifications are sub-categories. In this case, the full name of the "component" category would be "resource.component". This means that we are referring to the "component" classification for the "resource" role.
Most of your logging needs can be organized into this two dimensional cross-section of Role and Classification. Roles are best for main categories due to their logical separation. Typical classifications are "component", "security", and "pool". These same classifications can be used as standard sub-categories of the different roles. This way your log entries can have fine-grained control that is logically organized.
The mechanics of log writing can vastly affect the
performance of your code. For instance, if you concatenate several
strings together in your log messages, the Java Virtual Machine
converts the concatenation to a StringBuffer, and performs the
toString operation on the result. The
Logger interface provides a mechanism to optimize away
these conversions when they are not needed.