Log4j Properties VS XML IDE autocompletion and code assistance

Here’s why I prefer Log4j configured via an XML rather than a properties file:

I love my IDEs and a good reason for that is their autocompletion capabilities. XML structured configuration files tend to give you their grammar/syntax/doc and rules on an XSD or DTD file that are publicly available to help IDEs (and patient humans) autocomplete while editing the XML file.

I personally highly value this convenience.

Now for some reason everywhere in the Internet when I query “log4j xml file” I get back lots of sample config files that they all start by:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

This simply doesn’t work and doesn’t help the IDE (let it be IntelliJ or Eclipse) that is looking in vain for guidance and instructions out of a missing log4j.dtd file (found under org.apache.log4j.xml) or a meaningful http://jakarta.apache.org/log4j/ url.

To keep the IDE happy replace with the url of the DTD and remove the latter url (log4j:configuration is defined in the DTD file anyway therefore keeping happy the IDEs autocompletion system).

<?xml version="1.0" encoding="UTF-8" ?>
                <!DOCTYPE log4j:configuration SYSTEM "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">

Log4j Cheet Sheet

A gather-up of Appenders, Layout information and other Configuration concerning Log4j:

# =========
# =========
# Appender | Description
# ------------------------------------------
# ConsoleAppender | Logs to the console
# FileAppender | Logs to a file
# RollingFileAppender | Logs to a file and creates a backup when the file reaches a specified size
# DailyRollingFileAppender | Logs to a file, which is rolled over to a backup file at a specified time
# JDBCAppender | Logs to a database
# NTEventLogAppender | Logs to the Windows event log (available only on Windows)
# SMTPAppender | Logs using the SMTP mail server (sends email)
# SocketAppender | Logs to a TCP socket

# ======
# ======

# Specifier | Description
# ----------------------------------------------------------
# %c | Name of the logger. (In previous versions of log4j, loggers were called categories; hence the abbreviation.)
# %d | Date and time. The default format is ISO8601.
# %m | Message passed by the logger.
# %n | Platform-dependent new line string. (Depending on the platform, it may be "\r\n", "\n", or "\r".)
# %p | Priority of the message.
# %r | Elapsed time, in milliseconds, since the application was started.
# %t | Name of the thread.
# %% | Percent sign.
# %C | Fully qualified name of the class.
# %F | Filename.
# %l | Location information. Depending on JVM, may include fully qualified name of method, source file
# name and line number. If this is the last specifier before %n in a layout, the
# message will provide a hotlink to the source code in the the Eclipse console view.
# %L | Line number.

# log4j format | SimpleDateFormat style pattern | Sample printout
# -----------------------------------------------------------------------
# ABSOLUTE | hh:mm:ss,SSS | 18:16:10,432
# DATE | dd MMM YYYY hh:mm:ss,SSS | 08 Jan 2003 18:16:10,432
# ISO8601 | YYYY-mm-dd hh:mm:ss,SSS | 2003-01-08 18:16:10,432

# =================
# =================

# log4j.rootLogger=PriorityLevel, Appender1 [, Appender2 [, etc.]]
# log4j.appender.KeyName[.Property[.Property[.etc]]={Class|Value}

# Set root logger to DEBUG and assign two appenders
# log4j.rootLogger=PriorityLevel, Appender1 [, Appender2 [, etc.]]
log4j.rootLogger=DEBUG, myConsole, myLogFile

# log4j.appender.KeyName[.Property[.Property[.etc]]={Class|Value}
# Console appender
log4j.appender.myConsole.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n

# Rolling file appender
# max backups at a time
log4j.appender.myLogFile.layout.ConversionPattern= %d{MMM d, yyyy hh:mm:ss a}: %p [%t] %m%n
# Overriding the default DEBUG per appender