Hi, Curt, and Ceki,

Curt - Thanks for the tips.  I fixed the getLogger() typo.  When I get
some time, I'll add links to the extras companion, and copy the page
to the wiki.


Ceki - I'll try and fix up those omissions.  Thanks for reminding me.
This document was written 4 years ago.  I only put it on the web
yesterday when a friend asked me too.  On that note, I intend to
(mildly) recommend SLF4J over commons-logging, but I still prefer to
avoid the generalization if possible, and just use the underlying log
framework directly.

The mild recommendation is mostly due to SLF4J's improved approach to
the isDebugEnabled() situation (the pattern + arguments solution).
All my commons-logging classpath issues mysteriously went away with
commons-logging-1.1, so I don't feel it's fair to punish them any more
for that hilarious problem.

Even though I've never used Logback, it probably makes sense to say
"Use Log4J (or its worthier competitors - e.g. Logback)."


Okay, and now some more thoughts, unrelated to the feedback received so far:

----------------------------

1. Best practice for using grep:  use zgrep!!!  (or bzgrep, but it's
too slow!)  Never unzip the archived logs.  It's a waste of time and
space.

2. Always log to local-disk.  Send to archive using a reliable
transport (e.g. ftp, scp, nfs, smbfs).  Keep a week or two of the
archived files in both places (local-disk and archival server), both
to make trouble shooting easier for sysadmins (since a couple weeks of
files is nearbye... good for quickly asking "did this problem start in
the last few days?"), and to give you some breathing room should your
archival process break down temporarily.

2.b.  Never try to log directly to network with UDP or TCP streaming
appenders.  You can DoS your internal network infrastructure too
easily.  Local disk is much more robust.   TCP can be especially nasty
with Log4J (even with AsyncAppender!) - it can block all your
application threads, completely hanging your application.  It can even
block ALL your application servers (assuming they all log to the same
central log archive that's suddenly decided to stop acking its
incoming TCP packets - these things happen!).  Local disk is your
loyal and trustworthy friend.

So many times people say, "The network is not reliable."  This means
it's unsuitable for direct logging.

(It's probably okay to log-to-network if the network is between
several virtual machines that actually reside on the same physical
box).


3. Best practices should include use of NDC.

4. Exceptions - if the Exception is significant, at the very minimum,
always do this:   log.error(e, e).  If you're sending the stacktraces
to a separate log file, you can do this:

log.error(e);
stacktraceLog.error(e,e);

This way the error is in both files, but the actual stacktrace itself
is only in the "stacktraces" logger.

Wishlist for logging frameworks:  please add the timestamp and level
to each line of the stacktrace to keep it grep-friendly.  I hate doing
"grep -C 15" (e.g. show 15 lines before and after).



5.  A best practice that's currently not possible:

When a log file rotates (either because of size, or daily/hourly), you
should make the first line of the new log file contain important
version information about the running application.

Imagine the file rolls hourly, and it's 8:59:59.999 right now.....
Even if the rotate happens at 9:12:00.000, the log file's first line
should be:

2008-06-06/09:00:00.000 UPTIME=[382 Days, 10:51:11.231] APP=[FooApp
1.2.3] VM=[Java HotSpot(TM) Client VM 1.4.2_16-b05] OS=[Windows XP 5.1
x86] SERVLET=[Apache Tomcat/5.0.30] HEAP=[69MB/281MB 24.6%]


If that appears at the top of every rotated log file it makes certain
kinds of investigations possible.  It doesn't make them easy.  But at
least it makes them possible.... for example, "The application started
getting a lot more of bug X when we upgraded the linux kernel," or
"response time improved by 12% after we upgraded java."

That version line should also print in the middle of the current log
whenever the application restarts.

(This "version line" should be sent to all active log files.  So if
log4j.properties is managing 100 files, then all 100 should get this
line.)

Personally, I would even recommend that during really quiet times
logging frameworks should still create the file, and log the single
version line, even if no other log events occurred during the day or
hour in question.  This way the absence of the file in the log archive
would almost always mean "the application was shut down," rather than
"the application was either shut down, or was not doing anything."

It would also make it really obvious when two JVM's were logging to
the same file.  :-)


yours,

Julius




On Fri, Jun 6, 2008 at 2:16 PM, Ceki Gulcu <[EMAIL PROTECTED]> wrote:
> Julius,
>
> Interesting read and thank you for sharing your experience.
>
> In the section entitled "Use Log4j", you mention various logging
> systems such as j.u.l, commons-logging and even logKit which
> practically no one uses anymore. Curiously enough, you did not mention
> SLF4J and logback. Was it because you were not aware that they
> existed, or was it some other reason?
>
>
> Julius Davies wrote:
>>
>> Here's a page of what I consider log4j best practises:
>>
>> http://juliusdavies.ca/logging.html
>>
>>



-- 
yours,

Julius Davies
250-592-2284 (Home)
250-893-4579 (Mobile)
http://juliusdavies.ca/

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to