Skip to content
danfickle edited this page Sep 12, 2021 · 4 revisions

Default logging (java.util.logging)

By default log messages are sent to a java.util.logging.Logger. The Logger instances are configured to output to the stderr console with a format of {1} {2}:: {5} where {1} is the logger name (starting with com.openhtmltopdf), {2} is the log level and {5} is the log message. A typical log message is output below:

com.openhtmltopdf.load INFO:: Loading font(TestFont) from PDFont supplier now.

As of version 1.0.10, the default log format for messages with an associated exception will be {1} {2}:: {5} => {6}:: {7} where {6} is the exception class name and {7} is the exception message.

Changing the log level

You probably don't want to log at the default INFO level as it will be too verbose. To change the log level for all loggers you can use this code:

XRLog.listRegisteredLoggers().forEach(logger -> XRLog.setLevel(logger, java.util.logging.Level.WARNING));

Alternatively, you can use a customised version of the JDKXRLogger adaptor with its constructor:

XRLog.setLoggingImpl(new JDKXRLogger(false, Level.WARNING, new ConsoleHandler(), new XRSimpleLogFormatter());

The third argument is a java.util.logging.Handler and the fourth is a java.util.logging.Formatter so these can be changed too.

SLF4J Logging Adapter

Most frameworks, such as Spring Boot, now include the logging facade SLF4J. If you are using one of these frameworks it is recommended to use the SLF4J 1.x adaptor for this project.

<dependency>
    <groupId>com.openhtmltopdf</groupId>
    <artifactId>openhtmltopdf-slf4j</artifactId>
    <version>${openhtml.version}</version>
</dependency>
XRLog.setLoggerImpl(new Slf4jLogger());

SLF4J 1.x does not allow setting the log level, but the concrete logging implementation used can be configured to do so.

NOTE: In the adaptor SLF4J API 1.x is listed as a provided dependency. This means that it your responsibility to make sure it is on your classpath. Typically, this is already done by the framework.

Per run diagnostic consumer

Users are now able to provide a consumer for Diagnostic objects on a per run basis.

        List<Diagnostic> logs = new ArrayList<>();

        try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
            PdfRendererBuilder builder = new PdfRendererBuilder();

            builder.withDiagnosticConsumer(logs::add);
            builder.useFastMode();
            builder.toStream(os);
            builder.withHtmlContent(html, baseUrl);
            builder.run();
        }


        Assert.assertFalse(
             logs.stream()
                 .anyMatch(diag -> diag.getLogMessageId() == LogMessageId.LogMessageId2Param.CSS_PARSE_GENERIC_MESSAGE));

Use cases for diagnostic consumer

  • Multi tenant - provide log messages for each user.
  • Filter diagnostic messages for particular log messages such as load errors or CSS warnings.
  • Testing - make sure a log message is present or not.

Provide your own logging adaptor

See the XRLogger interface in com.openhtmltopdf.util.