Logging - FreeMarker Manual

- Home
- Manual
- Java API

- Contribute
- Report a Bug
- Download

Manual
Previous Next

# Logging

## Logging library selection

Is short, the recommended setup in contemporary application (as of 2015) is using SLF4J API for logging everywhere. To get FreeMarker 2.3.x. to use SLF4J, simply add the `org.slf4j:log4j-over-slf4j` dependency to your project, and ensure that `log4j:log4j` isn't present. (Starting from FreeMarker 2.4.x you don't need `log4j-over-slf4j` anymore, though it does no harm either.)

Read on if you are curious about the details, or if you can't use SLF4J...

FreeMarker integrates with the following logging libraries: SLF4J, Apache Commons Logging, Log4J 1.x, Avalon LogKit, and `java.util.logging`. By default, FreeMarker will look for the these logging libraries in the following order, and will automatically use the first one it finds (in 2.3.x): Log4J (will use SLF4J instead if it's a properly installed `log4j-over-slf4j`, since 2.3.22), Apache Avalon LogKit, `java.util.logging`. As you can see, Log4j has the highest priority. The presence of Log4j is simply detected from the presence of the `org.apache.log4j.Logger` class, which means that Log4j redirections like `log4j-over-slf4j` or `log4j-1.2-api` will also get the highest priority.

Prior to FreeMarker 2.4, SLF4J and Apache Commons Logging aren't searched automatically due to backward compatibility constraints. But if you have `org.slf4j:log4j-over-slf4j` properly installed (means, you have no real Log4j in your class path, and SLF4J has a backing implementation like `logback-classic`), then FreeMarker will use the SLF4J API directly instead of the Log4j API (since FreeMarker 2.3.22).

Note that a similar trick can be applied for logging into Log4j2: If `org.apache.logging.log4j:log4j-1.2-api` is present, FreeMarker 2.3.x will pick that as it looks like Log4j, but all the messages will actually go to Log4j2.

If the auto detection doesn't give you the result that you want, you can set the `org.freemarker.loggerLibrary` system property to select a logger library explicitly (since 2.3.22), like:

    java ... -Dorg.freemarker.loggerLibrary=SLF4J

The supported system property values are: `SLF4J`, `CommonsLogging`, `JUL` (for `java.util.logging`), `Avalon`, `auto` (the default behavior), `none` (disables logging).

Note that for reliable operation, the system property should be set when the JVM starts (like above), not later from Java code.

Using SLF4J is recommended, as it works best with FreeMarker, and also because it will be the highest priority auto detected logger starting from FreeMarker 2.4.

## Logging categories

All log messages produced by FreeMarker are logged with a logger category that starts with `freemarker.`. The currently used logger categories are:

Log category name | Purpose
--- | ---
`freemarker.beans` | Logs messages of the Beans wrapper module.
`freemarker.cache` | Logs messages related to template loading and caching.
`freemarker.runtime` | Logs messages related to template execution that doesn't fit any of the more specific categories. Most importantly, it logs template exceptions thrown during template processing (however that should be disabled in modern application; see later).
`freemarker.runtime.attempt` | Logs template exceptions thrown during template processing and caught by `attempt`/`recover` directives, with DEBUG severity. Note that such exceptions will be still also logged with their normal logger (like `freemarker.runtime`).
`freemarker.servlet` | Logs messages of the `FreemarkerServlet` class.
`freemarker.jsp` | Logs messages of the FreeMarker JSP support.

One quirk relating this is that FreeMarker will log exceptions during template execution under the `freemarker.runtime` category even if the exception continues propagating and so eventually will be thrown by `Template.process` or `Environment.process` anyway. (Those are the API calls with which the template was invoked from the application or the application framework.) Well behaving applications log the exceptions thrown at them, or rarely, handle them and deliberately don't want to log them. But as FreeMarker has already logged that exception, you will end up one more log entry than expected. To fix that (since 2.3.22), set the `log_template_exceptions` (`Configurable.setLogTemplateExceptions(boolean)`) setting to `false`.

Previous Next