Logging in Logo

Here’s the translation of the Go logging example to Java:

Our first example demonstrates logging in Java using the built-in java.util.logging package and the more advanced org.slf4j with logback for structured logging.

import java.io.ByteArrayOutputStream;
import java.util.logging.*;
import org.slf4j.LoggerFactory;

public class LoggingExample {
    public static void main(String[] args) {
        // Get the root logger
        Logger logger = Logger.getLogger("");

        // Simply using the logger
        logger.info("standard logger");

        // Configure the logger to show microseconds
        System.setProperty("java.util.logging.SimpleFormatter.format",
                "%1$tF %1$tT.%1$tL %4$s %2$s %5$s%6$s%n");
        logger.info("with micro");

        // Configure the logger to show the source of the log message
        System.setProperty("java.util.logging.SimpleFormatter.format",
                "%1$tF %1$tT %4$s %2$s %5$s%6$s%n");
        logger.info("with file/line");

        // Create a custom logger
        Logger myLogger = Logger.getLogger("MyLogger");
        myLogger.setLevel(Level.ALL);
        ConsoleHandler handler = new ConsoleHandler();
        handler.setFormatter(new SimpleFormatter() {
            private static final String format = "[%1$tF %1$tT] [%2$-7s] %3$s %n";

            @Override
            public synchronized String format(LogRecord lr) {
                return String.format(format,
                        new java.util.Date(lr.getMillis()),
                        lr.getLevel().getLocalizedName(),
                        lr.getMessage()
                );
            }
        });
        myLogger.addHandler(handler);
        myLogger.info("from myLogger");

        // Logging to a custom output
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Handler bufHandler = new StreamHandler(baos, new SimpleFormatter());
        Logger bufLogger = Logger.getLogger("BufferLogger");
        bufLogger.addHandler(bufHandler);
        bufLogger.info("hello");
        bufHandler.flush();
        System.out.print("from bufLogger: " + baos.toString());

        // Using SLF4J with Logback for structured logging
        org.slf4j.Logger structLogger = LoggerFactory.getLogger(LoggingExample.class);
        structLogger.info("hi there");
        structLogger.info("hello again", "key", "val", "age", 25);
    }
}

To run this example, you’ll need to include the SLF4J and Logback libraries in your classpath. You can do this by adding the following dependencies to your project:

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.32</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.6</version>
</dependency>

You’ll also need to create a logback.xml configuration file in your src/main/resources directory:

<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="ch.qos.logback.classic.layout.JSONLayout">
                <timestampFormat>yyyy-MM-dd'T'HH:mm:ss.SSSX</timestampFormat>
                <appendLineSeparator>true</appendLineSeparator>
            </layout>
        </encoder>
    </appender>

    <root level="info">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

This example demonstrates various logging techniques in Java:

  1. Using the built-in java.util.logging package for basic logging.
  2. Configuring log formatters to include microseconds and source information.
  3. Creating custom loggers with specific formats.
  4. Logging to a custom output (ByteArrayOutputStream in this case).
  5. Using SLF4J with Logback for structured logging in JSON format.

The output will vary depending on when you run the program, but it will look something like this:

2023-08-22 10:45:16 INFO  LoggingExample standard logger
2023-08-22 10:45:16.904 INFO  LoggingExample with micro
2023-08-22 10:45:16 INFO  LoggingExample with file/line
[2023-08-22 10:45:16] [INFO   ] from myLogger 
from bufLogger: Aug 22, 2023 10:45:16 AM BufferLogger info
INFO: hello

{"timestamp":"2023-08-22T10:45:16.904+01:00","level":"INFO","logger_name":"LoggingExample","message":"hi there"}
{"timestamp":"2023-08-22T10:45:16.904+01:00","level":"INFO","logger_name":"LoggingExample","message":"hello again","key":"val","age":25}

This example provides a comprehensive overview of logging in Java, from basic usage to more advanced structured logging.