As we hopefully all agree good logging is a great asset. Yet I come across aweful styles of logging (and sometimes produce them myself). So I guess it is time for a small Antipattern collection.
- No Logging at All
- Exception Handler without any code are an obvious example of this, but reading a configuration file without giving a hint which whan you are reading and what you found in it also belongs in this category
- Wrong Log Level
- logging the discovery that you can’t connect to the database of the application in DEBUG level, or logging entry and exit points of method with ERROR level are typical examples. Always remember: Once in production the log level will probably risen to WARN or ERROR and you gonna still want to see the important messages, don’t you?
- Catch Log Throw
- In a catch block the exception gets logged and then thrown again, possibly wrapped in a new exception. When this anti pattern is used in many places the result is a log file that contains every stacktrace in a dozen repetitions and variations. A nightmare when you try to understand what is going on.
- Logging to stderr or stdout
- System.out.println and ex.printStacktrace() are easy and fast to write, but their result will probably disappear in /dev/null once your application is running on a production server.
- Complex Logging Statements
- When the message for logging gets constructed in a convoluted way with lots of function calls, there is a serious risk that you end up with a NullPointerException instead of a proper logging entry. This is especially true when we try to log inside a catch block. After all something went wrong in the first place, so NULL values a everywhere
Lego is such a great thing because it is made of simple components. When you build something out of it you can take it apart and build something different out of it. It is fun. If a piece breaks you can take the model apart, replace the broken piece and reassemble the whole thing. Great.
Of course this modularity comes at a price. Building the model of a fighter jet from Lego is much more difficult then building it from a plastic construction kit. Also the result of any Lego based attempt will look a little ‘bricky’. On the other hand, try to build a ship out of your fighter jet construction kit.
So there are benefits to modularity and there are benefits to sacrificing this modularity.
This is pretty obvious, isn’t it?
Yet in software development modularity is required almost every time, without considering the cost of modularity.
Also in software development modularity is sacrificed to budget and time pressure immediately, often before testing and documentation, also without considering modularity.
I got varying reactions on my last post. Some thought the story about making coffee using an extremely detailed plan was funny. For example Fabio Akita wrote:
“Planning is the death of any project” http://bit.ly/bFYkAW Just an entertainment story, but fun nonetheless
I’m certainly proud to produce something that is considered fun. Yet my little story actually has some serious background. Of course the simple task of making coffee doesn’t justify elaborate project planning. But which task does? As we have seen, simple tasks don’t.
So how about complex tasks? Tasks that depend on circumstances in many ways, like e.g. balancing a stick on a finger, or playing table tennis. It would surely simplify the task, if we knew exactly when to make which movement. But we can’t plan this kind of thing, because the tiniest deviation from the intendend movement at some point in time will greatly change the required action some time later.
The coach teaching me project management had a great example of a project needing very accurate planning: When you build a nuclear reactor, the core will get encapsulated in a huge steel chamber. There are only very few cranes huge enough to move this thing. And they need a rail track to get to the building site, as well as a foundation for the crane to stand on. Rent of this crane is expensive as hell and you have to fix the dates years in advance. Everything that was needed for this crane and the needed structure, was planned with great care, to make sure everything was in place.
Few of us build nuclear reactors. For all others check these rules as a guide for the amount of planning justified:
- How plannable is it anyway? Don’t try to plan the unplannable. Get it out of the way instead. This is what many agile approaches do, when they implement the most risky stuff first.
- Do you have fixed dependencies between tasks? A plan becomes more helpfull, when you have many dependencies between tasks, possible with long ramp up or preperation time. As with the crane: The task of moving the steel shell wasn’t very long, but the preperation had to start years ahead. Without a plan it gets easy to kill a deadline long before it comes into sight.
- What is the damage done, when you don’t stick to the plan. In some projects, the only damage done is that somebody has to adjust all the plans. In that case, you might just as well scrap the plan.