Apache Software Foundation > Apache POI
 

Apache POI - Logging Framework

Introduction

Logging in POI is used primarily as a debugging mechanism, not a normal runtime logging system. Logging at levels noisier than WARN is ONLY for autopsy type debugging, and should NEVER be enabled on a production system.

POI 5.1.0 and above

Since version 5.1.0 Apache POI uses Apache Log4j v2 directly.

Apache POI only depends on log4j-api and allows choosing which logging framework to use. log4j-core is just one of many options. If you want to continue to use another SLF4J compatible logging framework, you can deploy the log4j-to-slf4j jar to facilitate this.

POI tries to name loggers after the canonical name of the containing class. For example, org.apache.poi.poifs.filesystem.POIFSFileSystem. Use your logging framework's typical mechanisms for activating and deactivating logging for specific loggers.

All loggers are named com.apache.poi.*, so rules applied to com.apache.poi will affect all POI loggers.

Logging with Log4j 2 Core

Capturing POI logs using Log4j 2 Core is as simple as including the log4j-core JAR in your project. POI also has dependencies on libraries that make use of the SLF4J and Apache Commons Logging APIs. Gather logs from these dependencies by adding the Commons Logging Bridge and the the SLF4J Binding to your project.

The simplest configuration is to capture all POI logs at the same level as your application. You might want to collect all messages INFO and higher, and are OK with capturing POI messages as well.

<Configuration ...>
<Loggers>
<Root level="INFO">
...
</Root>
</Loggers>
</Configuration>

A more recommended configuration is to capture only messages from loggers you opt in to. For example, you might want to capture all messages from com.example.myapplication at INFO but only POI messages at WARN or more severe.

<Configuration ...>
<Loggers>
<Logger name="com.example.myapplication" level="INFO" />
<Logger name="org.apache.poi" level="WARN" />
<Root level="OFF">
...
</Root>
</Loggers>
</Configuration>

Another strategy you may decide to use is to capture all messages except those coming from POI.

<Configuration ...>
<Loggers>
<Logger name="org.apache.poi" level="OFF" />
<Root level="INFO">
...
</Root>
</Loggers>
</Configuration>

Log4J SimpleLogger

If your main aim is just to get rid of the scary logging log message from Log4J that says 'ERROR StatusLogger Log4j2 could not find a logging implementation.', then one option is to enable the SimpleLogger using a system property.

-Dlog4j2.loggerContextFactory=org.apache.logging.log4j.simple.SimpleLoggerContextFactory

Logging with SLF4J

If you want to continue to use another SLF4J compatible logging framework, you can deploy the log4j-to-slf4j jar and the intended slf4j-bridges to facilitate this.

See https://www.slf4j.org/ for more details about using SLF4J.

Logging with Logback

Capturing POI logs using Logback requires adding the Log4j to SLF4J Adapter to your project, along with the standard Logback dependencies. POI also has dependencies on libraries that make use of the SLF4J and Apache Commons Logging APIs. Gather logs from these dependencies by adding the Commons Logging Bridge to your project.

The simplest configuration is to capture all POI logs at the same level as your application. You might want to collect all messages INFO and higher, and are OK with capturing POI messages as well.

<configuration ...>
<root level="INFO">
...
</root>
</configuration>

A more recommended configuration is to capture only messages from loggers you opt in to. For example, you might want to capture all messages from com.example.myapplication at INFO but only POI messages at WARN or more severe.

<configuration ...>
<logger name="com.example.myapplication" level="INFO" />
<logger name="org.apache.poi" level="WARN" />
<root level="OFF">
...
</root>
</configuration>

Another strategy you may decide to use is to capture all messages except those coming from POI.

<configuration ...>
<logger name="org.apache.poi" level="OFF" />
<root level="INFO">
...
</root>
</configuration>

POI 5.0.0

POI 5.0.0 switched to using SLF4J for logging. If you want to enable logging, please read up on the various SLF4J compatible logging frameworks. Apache Log4j v2 is a good choice. Logback is also widely used.

Legacy POI Logging Framework (no longer supported in POI 5.0.0 and above)

Prior to POI 5.0.0, POI used a custom logging framework which allows to configure where logs are sent to.

Logging in POI 3 and 4 is used only as a debugging mechanism, not as a normal runtime logging system. Logging at level debug/info is ONLY for debugging, and should NEVER be enabled on a production system.

The framework is extensible so that you can send log messages to any logging framework that your application uses.

A number of default logging implementations are supported by POI out-of-the-box and can be selected via a system property.

POI 4.x and before: Enable Legacy POI Logging Framework

By default, logging is disabled in POI 3 and 4. Sometimes, it might be useful to enable logging to see some debug messages printed out which can help in analyzing problems.

You can select the logging framework by setting the system property org.apache.poi.util.POILogger during application startup or by calling System.setProperty():

System.setProperty("org.apache.poi.util.POILogger", "org.apache.poi.util.CommonsLogger" );

Note: You need to call setProperty() before any POI functionality is invoked as the logger is only initialized during startup.

POI 4.x and before: Available Legacy POI Logging Framework implementations

The following logger implementations are provided by POI 3 and 4:

Class Type
org.apache.poi.util.SystemOutLogger Sends log output to the system console
org.apache.poi.util.NullLogger Default logger, does not log anything
org.apache.poi.util.CommonsLogger Allows to use Apache Commons Logging for logging. This can use JDK1.4 logging, log4j, logkit, etc. The log4j dependency was removed in POI 5.0.0, so you will need to include this dependency yourself if you need it.
org.apache.poi.util.DummyPOILogger Simple logger which will keep all log-lines in memory for later analysis (this class is not in the jar, just in the test source). Used primarily for testing. Note: this may cause a memory leak if used in production application!

POI 4.x and before: Sending logs to a different log framework

You can send logs to other logging frameworks by implementing the interface org.apache.poi.util.POILogger.

POI 4.x and before: Implementation details

Every class uses a POILogger to log, and gets it using a static method of the POILogFactory .

Each class in POI can log using a POILogger, which is an abstract class. We decided to make our own logging facade because:

  1. we need to log many values and we put many methods in this class to facilitate the programmer, without having him write string concatenations;
  2. we need to be able to use POI without any logger package present.

by Dominik Stadler, Marius Volkhart