- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Meanwhile, and directed at myself -- Whoosh!!!
I wonder if there's a smiley for that?
Admin
Nah, The OP said that their inhouse guy architected the thing and that he logged a whole lot. Knocking off the debug loggin in production was a good first step, but as the OP said, much work remains.
Admin
Where walter really got in trouble was when he added logging to the logging methods.
Admin
Ahem... AOP anyone? TRWTF is about the choice of polluting the code with that crap instead of using AOP as it's supposed to be... management requiring a log with every method call (start and end) is insane but not unheard of.
Admin
One word: profiler.
Admin
It's nothing to do with "teh Kodez not B Trust, Respeck!"
It's to do with cleaning up afterwards. Fact(ish):
20% of programmer effort is deployed on the original system.
80% of (maintenance) programmer effort is deployed on correcting Teh Codez. Often, for problems that could not possibly have been detected when implementing the original product.
This is why, on the happy occasions that I get near the early stages of a product, I fight tooth and nail over logging.
Do you want to be woken up at two in the morning to solve a problem, only to see a log message that says "This should never happen!" If you're lucky. At least you can troll through the code to find it on line 22,461 in some obscure library you've never seen before.
It's happened to me. Several times, over five years.
Get another job, mate. How are you with lipstick? Alternatively, pig farmers are always on the lookout for suitable carcasses.
Admin
Don't you mean, "whoever AUTHORED the dictionary"?
Admin
The OP (IIRC) did not indicate the type of application, i.e., if it was a long-running process, or a short transactional thing. The last two decades have muddied the distinction.
For short transactions (and this is why the old slow obsolete mainframes could still process airline reservations blindingly fast -- much faster than your typical contemporary ajax-enabled ATM application) the amount of processing is ruthlessly kept to a minimum.
A proper database pends the updates for a very short time, then writes them to the roll-forward log in one short burst. Variations exist, including roll-back vs. roll-forward, but the point is, one transaction should equal one IO. Two, if the base data isn't already in database cache, but often it is. Actual page updates don't go to disk during the transaction, they wait until later.
Now. Insert logging. Depending upon the file system, you /may/ end up writing the entire log output in one burst, if the entire output will fit in one file system allocation unit. But this is at least two writes as well... metadata, and data. Also consider that you have many of these happening concurrently -- which the database is designed to handle expeditiously, and which the filesystem is designed not to screw up, if at all possible.
In that environment, I would not be surprised to see a greater than 50% improvement in disabling the logging.
Captcha: appellatio... For some reason, the name Steve Jobs comes to mind. I have no idea why.
2nd try.
Admin
I'm working on a system now that does huge amounts of logging. And about 90% of it is useless. Which means that every time you have to track down a problem, you have to hack your way through megabytes worth of useless drivel.
Logging every query before you execute it: Very useful. It lets us see exactly what the query was that blew up.
Logging every time we get a database connection from the pool or return it to the pool: Major useless. If we discover that there's a problem with pool management, it will be time to put something like this in. Otherwise, this adds tons of junk to the log files.
Admin
FTFY
Admin
Please don't log to the database.
Please don't log to the database.
Keeping your hilarious interpretations of a captcha to yourself would be a welcome benefit ... although admittedly not on the lines of unrolling a TPF loop.
Please don't log to the database.
I don't know how many times I have to tell you this.
Please don't log to the database.
The performance sucks, it isn't what logging is for, and furthermore it is almost impossible to retrieve useful log information from a database.
Please don't log to the database.
Admin
There is a fine balance between too much and too little logging.
With a sufficient amount of logging you are able to resolve bugs a lot faster but too much is obviously slowing down the system.
But logging every method entry/exit without regard to call frequency or how critical it is is just stupid.
Admin
Admin
On the other hand, if your running time is dominated by a pure log term, you know your algorithm will scale well. :-)
Admin
Umm, was that Log4J code?
Admin
Oh god, I'm in an algorithm analysis class right now!
Admin
Now what did Einstein (or was is Arthur C Clarke?) say about human stupidity?
Trust me, there are people who do that...
Admin
What a Java newbie...
That should be:
void meth( String arg ) { logger.entering( this.getClass().getName(), "meth", arg ); // ... logger.exiting( this.getClass().getName(), "meth", arg ); }
Admin
Oh, I see.....
Admin
Don't you mean "To verb a noun" ?
Admin
Must... restrain... fist... of... death..
Admin
FTW !!!
Admin
It could be worse. He could have written a custom logger system that went like this:
void log(Level logLevel, Object message){ if(isDebugEnabled()) { log(debug, "Attempting to log " + message); } javaLogger.log(logLevel, message); if(isDebugEnabled()) { log(debug, "Finished logging " + message); } }
I've seen that code get to system testing, and I ended up discovering it when, trying to solve a problem, I set the global log level to debug.
The poor former trainee still gets crap for this, 10 years later.
Admin
Exactly my point. I conclude from the debug code, that either the developer didn't trust their work, or they never got around to cleaning up from unit testing.
If you think nothing could be done, you're mistaken. Many things in retrospect ASK for trouble. If you're in maintenance, try playing code pathologist. Why did they do that?
Logging is good, when it's useful. But giving tickets when someone enters a tunnel, and collecting it when you leave is not particularly useful. You know thoughtful logging when you see it... I hope (hint: 02:05.03.003 - All is well .004 - All is well .005 - This shouldn't happen. There's a difference between info and noise. There's also a difference between real problems (i.e. the problem the program is trying to solve), and artificial problems (the bug that crashes the logging system, which the customer doesn't see, but takes 40% of the system resources... Do you think the System Architect factored that into their system specs? Or are you one of those arrogant idiots that sees the 50% overspec, and thinks it's for them, and not for when they double the users, or the database size?)
I know, you know everything. You've been in the biz a whopping 5 years. Met a customer once, did you? (Year 23 for me - started in test, developer/PM now)
Admin
Sorry, "architect" is now a verb. This issue is now officially wordsmithed.
CAPTCHA: minim - truly minimalist?
Admin
It's hard to know how much logging you're going to need, so I usually log with a priority level. Things that happen at the lowest levels are logged at priority 0, so you never see those unless you ask for them. With a default clipping level of 2 or 3, a good 90% of the log messages are surpressed, leaving you with a manageable subset of messages.
Admin
cough #ifdef DEBUG ... #else ... #endif
Admin
You only need error logging when you have errors in your program.
The l33t among us write programs without errors, so writing code to log errors is a waste of everybodies time. It's called robust code.
Admin
A) they probably didn't measure, some bright spark just said 'Wow - that must be 40% faster' ("42% of people know all statistics are made up" - Homer J Simpson (roughly) B) 40% of what? C) Other things that I have now forgotted D) Yawn!!!
Admin
Edit: Beaten to the punch. Darn.
Admin
I'd like to comment on this WTF. Here is the first sentence of my comment. Yes, logging is good, but I've never found it necessary to log absolutely every method call. I'm done with the first part of my comment so here is my next sentence. You end up with overly verbose logs that just make it difficult to find an issue when someone has a real error. That's all I wanted to say in the second part of my comment and that's it for my comment on this WTF.
Admin
Admin
I've seen developers who log in time senitive paths without thhought to the time implications of logging. I work with them today, every day, they are everywhere.
I've seen developers who wont log in time insensitive, function critial, paths "because it's a performance drain". I work with them today, wvery day, they are everywhere.
I've seen developers who way lyrical about wrapping time insensitive log.debug in if (log.isDebugEnabled()) and 99% of the time get it right, but 1% of the time mess up the flow control, and in so ding self invalidate. I work with them today, every day, they are everywhere.
In the end of the day, what most of all I've seeb, is developer output log to discover how the code mught behave. This becomes the product, and the support crew are understandably dum-founded. There is always a background project (support driven), never resourced (not sales driven), to "clean up the logging".
Admin
alternatively you could have something like
then you wouldn't need the try/finally, but you would still see the logs in the face of exceptions
it seems that this may be a case of applying a coding style designed for one type of coding paradigm to code written under a different paradigm. I used to see a lot of this kind of logging when normal debugging facilities were either unavailable or unusable.
one advantage i can see is that you have a record of the complete call tree, not just the current stack trace you would get with a debugger.
one major problem with this kind of logging is that ones logs can get very large, to the point that they may become useless.
Admin
My turn to get on a soapbox....
There are two types of logging to consider: Error Logging Debug Logging
Error Logging logs Errors (wow!). This means ONLY error conditions should appear in an error log. If the log is filled with noise from errors that we ignore, it becomes very difficult to find real errors. If we plan to ignore errors in the log (especially long term), then the logging of these errors should be removed (no point noting that something we don't care about just happened).
Debug logging should have variable level and log information about where in the code we are, how we are going and perhaps what the values of some key variables in that function are (depending on the set level). The twats that suggest "#ifdef DEBUG" should first realise that (in this case) we are talking Java (which I don't think has these compiler directives) and secondly this is the WRONG approach anyway. Why? The biggest use for debug is incident/problem investigation and resolution. This should not be a compiled option (ie there shouldn't be two separate binaries on a system that do roughly the same thing (but different). How do you know if the debug is up to date with the non-debug? Rather, debug should be able to be turned on (eg restart a daemon with a flag indicating debug level or something). In this way, the debug is available to some poor person on support duties, and is definitely the current version. Debug should not be permanently on - aside from implying you don't trust your system (and won't be able to recreate problems) it causes overhead and increases the likelihood of unrelated errors - eg debug log fills disk or exceeds max file size etc).
The real trick (which is by no means easy, if even possible) is to create debug which doesn't affect the running of the system. Too often, debug mode behaviour is (unintentionally) different from non-debug (especially, it seems, when the problem lies in memory management - although this would not be as much a problem Java).
Logging for the sake of logging is stupid, and rather than logging "Entered myMethod", etc, why not set a variable to hold the method name at the beginning of the method, and display this at every debug/Error print (this way you can see which method you are in and where you came from without having to scroll back to see). An example of debug logging might be:
Oct 12 12:13:12 2009: processFile: readFromFile [temp.txt] Oct 12 12:13:12 2009: readFromFile: opening [temp.txt] Oct 12 12:13:12 2009: processFile: read 156752 Bytes Oct 12 12:13:12 2009: callingProcess: read from [temp.txt] buffer begins [It was a cold and fr]
(this might be excessive and slow, however we would have options to reduce the debug level, and let's not forget that debug is only on in the case that a developer is currently looking into a problem - ie, generally short term).
Admin
Admin
Not read all the comments so this has probably been pointed out already, but TRWTF is that debug level logging was turned on in production code.
Admin
Admin
Admin
The real problem with this sort of logging happens when you grep for 'This should never happen', and you find that it occurs 1,386 times over the 52,964 lines of the file - making it the second most common line in the file (the most common, of course, being a lone closing curly bracket, as the programmer felt that vertical whitespace is for losers.)
I've not experienced anything quite that bad, mind you - the worst I've personally encountered was a program where that error output could originate from about 200-300 different lines across 20 files.
On another note: please, never log directly to a database. Please correct any code that logs directly to a database to log to a regular file. (Note: it is acceptable to log to a flat file and a database (for example, something like Splunk); the problem is where one must utilize a database access protocol to get to the logs. An exceptionally gratuitous case of this issue is the error message 'cannot connect to database', which should never be sent directly to the database. I hope the reasons for this are obvious.)
Admin
Explain? What do you think is the purpose of 'Debug' level logging? Ok maybe logging getters and setters is excessive, but i'd rather have plenty of logging information available (for example if you aren't doing the testing and a fault is raised by the testing team), thats better than having no clue as to where the error occured and having to start from scratch with a debugger. With regard to the pattern (checking for level first), that's common if the logging parameter is more expensive than the check, and really should not impact performance. Are you suggesting that debug level logging code should be removed from production code altogether? If your just saying logging getters and setters is overkill then fair enough but I still say the RTWTF is that debug level logging was left on in production code - note he got a 40% increase in performance when it was turned off.
P.S. my career is doing fine and dandy thank you very much
Admin
Most profilers I've encountered do not report problems with code which is spread across every single routine (aka function, subroutine, or method) - they only report how much time is spent within each routine.
Some of the profilers I've encountered will also only report the processor time spent, not the I/O time; such a profiler could miss this entirely.
My point is not that profilers won't work, but you need a good profiler for this.
Admin
Admin
I have seen a system brought to its knee's due to the fact that the idiot who configured log4j did not have circular logging set up. 90% of available disk space was consumed with logs, so the 40% performance degradation mentioned is very believable.
Admin
While I like AOP and lots of examples use logging as a typical scenario, AOP is not without it's disadvantages.
Introduces extra wrapper classes that have to be generated and compiled on the fly ( aspectJ at least, when u weave your aspect ).
When developing in eclispe, I find AOP a real drag as it seems to slow things down significantly, while log4J does not.
Still AOP would have worked here.
Nice suggestion.
Admin
Admin
public static function isDebugEnabled() { // query database for xml file name ... // parse the xml file ... // return debug boolean return bDebug; }
Admin
The real WTF is he wasn't using aspects.
Admin
There will be a savings anytime you use that pattern, even if it is just writing a plain string (creating the String object, and either garbage collecting it or storing it in the string pool). I just did a quick test using a logger that does nothing more than log a string literal appended with an integer and the version that had the guard outside of the log block was consistently well over 10 times faster (though that's a small fraction of the savings you get compared when logging is actually enabled and it has to actually write those messages). Now normally its not going to be worth the effort to do this (in my test, even logging a million times the unguarded version took less than half a second), unless you happen to have a macro of some sort in your IDE to do this. Which in this case if they have this many logging statements, they probably did.
Oh, and when in a method that gets called often, reallyComplexMethod doesn't have to be that complex to make a noticeable difference. A very common log message would be something like logger.log(Level.FINE, "received object "+myObject). That could have a significant performance hit if the implicit myObject.toString() is slow.
Admin
I guess I do now know why ATMs can run very slow, but not for the reason you think. If your code is so complex that adding entry and exit logs add 5 minutes to the running time, I don't think the problem is in your logging requirements...