Logging in Karel
Here’s the translation of the Go logging example to Java, formatted in Markdown suitable for Hugo:
Our logging example demonstrates how to use Java’s built-in logging capabilities, primarily focusing on the java.util.logging
package for free-form output and the org.json.JSONObject
for structured output (simulating the slog
package’s JSON functionality).
import java.util.logging.*;
import java.io.*;
import org.json.JSONObject;
import java.time.Instant;
public class LoggingExample {
public static void main(String[] args) throws IOException {
// The default logger is already pre-configured for reasonable logging
// output to System.err.
Logger logger = Logger.getLogger(LoggingExample.class.getName());
logger.info("standard logger");
// We can configure the logger's output format
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 microseconds");
// To include the class name and line number, we need to use a custom formatter
class MyFormatter extends Formatter {
@Override
public String format(LogRecord record) {
return String.format("%1$tF %1$tT %2$s:%3$s: %4$s\n",
new java.util.Date(record.getMillis()),
record.getSourceClassName(),
record.getSourceMethodName(),
record.getMessage());
}
}
ConsoleHandler handler = new ConsoleHandler();
handler.setFormatter(new MyFormatter());
logger.setUseParentHandlers(false);
logger.addHandler(handler);
logger.info("with class/method");
// We can create a custom logger with a specific name
Logger mylog = Logger.getLogger("MyLogger");
mylog.info("from mylog");
// We can change the logger's name
mylog.setLevel(Level.INFO);
mylog.info("from renamed mylog");
// Loggers can have custom output targets
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Handler bufHandler = new StreamHandler(baos, new SimpleFormatter());
Logger buflog = Logger.getLogger("BufferLogger");
buflog.setUseParentHandlers(false);
buflog.addHandler(bufHandler);
// This call writes the log output into baos
buflog.info("hello");
bufHandler.flush();
// This will actually show it on standard output
System.out.print("from buflog:" + baos.toString());
// For structured logging, we can use JSON
JSONObject jsonLog = new JSONObject();
jsonLog.put("time", Instant.now().toString());
jsonLog.put("level", "INFO");
jsonLog.put("msg", "hi there");
System.out.println(jsonLog.toString());
// We can add arbitrary key-value pairs
jsonLog = new JSONObject();
jsonLog.put("time", Instant.now().toString());
jsonLog.put("level", "INFO");
jsonLog.put("msg", "hello again");
jsonLog.put("key", "val");
jsonLog.put("age", 25);
System.out.println(jsonLog.toString());
}
}
To run this program, you’ll need to include the org.json
library in your classpath. You can download it from JSON-java or use a dependency management tool like Maven or Gradle.
Sample output; the date and time emitted will depend on when the example ran:
2023-08-22 10:45:16 INFO LoggingExample main standard logger
2023-08-22 10:45:16.904 INFO LoggingExample main with microseconds
2023-08-22 10:45:16 LoggingExample:main: with class/method
Aug 22, 2023 10:45:16 AM LoggingExample main
INFO: from mylog
Aug 22, 2023 10:45:16 AM LoggingExample main
INFO: from renamed mylog
from buflog:Aug 22, 2023 10:45:16 AM LoggingExample main
INFO: hello
{"level":"INFO","msg":"hi there","time":"2023-08-22T10:45:16.904166391Z"}
{"level":"INFO","msg":"hello again","time":"2023-08-22T10:45:16.904178985Z","key":"val","age":25}
This Java example demonstrates various logging techniques, including:
- Using the standard logger
- Configuring log output format
- Creating custom loggers
- Writing logs to different outputs
- Structured logging using JSON
Note that Java’s built-in logging is not as feature-rich as Go’s slog
package, so we’ve used a JSON library to simulate structured logging. In a real-world application, you might want to consider using a more robust logging framework like SLF4J with Logback or Log4j2, which offer more advanced features and better performance.