Title here
Summary here
Our first program will demonstrate logging in Java. Here’s the full source code with explanations:
import java.util.logging.*;
import java.io.*;
public class LoggingExample {
public static void main(String[] args) throws IOException {
// Simply invoking methods like info() from the Logger class uses the
// standard logger, which is already pre-configured for reasonable
// logging output to the console.
Logger.getGlobal().info("standard logger");
// Loggers can be configured with handlers and formatters to set
// their output format. We can change its format to emit time with
// millisecond accuracy, for example.
Logger logger = Logger.getLogger("MyLogger");
ConsoleHandler handler = new ConsoleHandler();
handler.setFormatter(new SimpleFormatter() {
private static final String format = "[%1$tF %1$tT.%1$tL] %2$s %3$s%n";
@Override
public synchronized String format(LogRecord lr) {
return String.format(format,
lr.getMillis(),
lr.getLevel().getLocalizedName(),
lr.getMessage()
);
}
});
logger.setUseParentHandlers(false);
logger.addHandler(handler);
logger.info("with milliseconds");
// It also supports emitting the class name and
// line from which the log method is called.
logger.logp(Level.INFO, "LoggingExample", "main", "with class/method");
// It may be useful to create a custom logger and
// pass it around. When creating a new logger, we
// can set a name to distinguish its output
// from other loggers.
Logger mylog = Logger.getLogger("MyCustomLogger");
mylog.info("from mylog");
// We can set the level on existing loggers
mylog.setLevel(Level.FINE);
mylog.fine("fine message from mylog");
// Loggers can have custom output targets;
// any OutputStream works.
ByteArrayOutputStream buf = new ByteArrayOutputStream();
Handler bufHandler = new StreamHandler(buf, new SimpleFormatter());
Logger buflog = Logger.getLogger("BufferLogger");
buflog.setUseParentHandlers(false);
buflog.addHandler(bufHandler);
// This call writes the log output into buf.
buflog.info("hello");
bufHandler.flush();
// This will actually show it on standard output.
System.out.print("from buflog:" + buf.toString());
// For structured logging, we can use a third-party library like SLF4J
// with Logback. Here's a basic example using java.util.logging:
Logger structLog = Logger.getLogger("StructuredLogger");
structLog.info("hi there");
structLog.log(Level.INFO, "hello again", new Object[]{"key", "val", "age", 25});
}
}
To run the program, compile and execute it:
$ javac LoggingExample.java
$ java LoggingExample
Sample output; the date and time emitted will depend on when the example ran:
Aug 22, 2023 10:45:16 AM LoggingExample main
INFO: standard logger
[2023-08-22 10:45:16.904] INFO with milliseconds
[2023-08-22 10:45:16.905] INFO with class/method
Aug 22, 2023 10:45:16 AM LoggingExample main
INFO: from mylog
Aug 22, 2023 10:45:16 AM LoggingExample main
FINE: fine message from mylog
from buflog:Aug 22, 2023 10:45:16 AM BufferLogger info
INFO: hello
Aug 22, 2023 10:45:16 AM LoggingExample main
INFO: hi there
Aug 22, 2023 10:45:16 AM LoggingExample main
INFO: hello again
Note that Java’s built-in logging framework doesn’t have native support for structured logging like Go’s slog
. For more advanced logging features, including structured logging, consider using third-party libraries like SLF4J with Logback or Log4j2.