Title here
Summary here
Here’s the translation of the Go logging example to Java, with explanations in Markdown format suitable for Hugo:
The Java standard library provides various tools for outputting logs from Java programs. We'll use the `java.util.logging` package for free-form output and the `org.json.JSONObject` for structured output (simulating the `slog` package in Go).
```java
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 {
// Simply invoking methods like info() from the Logger class uses
// the default logger, which is already pre-configured for reasonable
// logging output to the console.
Logger.getGlobal().info("standard logger");
// Loggers can be configured with properties to set their output format.
// We can change its format to emit time with microsecond accuracy.
System.setProperty("java.util.logging.SimpleFormatter.format",
"%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%1$tL %4$s %2$s %5$s%6$s%n");
Logger.getGlobal().info("with micro");
// It also supports emitting the class name and
// line from which the log function is called.
Logger logger = Logger.getLogger(LoggingExample.class.getName());
logger.info("with class/line");
// It may be useful to create a custom logger and
// pass it around. When creating a new logger, we
// can set a handler to customize its output.
Logger mylog = Logger.getLogger("MyLogger");
ConsoleHandler handler = new ConsoleHandler();
handler.setFormatter(new SimpleFormatter() {
private static final String format = "my: %1$tF %1$tT %2$s %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()
);
}
});
mylog.setUseParentHandlers(false);
mylog.addHandler(handler);
mylog.info("from mylog");
// We can change the format of existing loggers
handler.setFormatter(new SimpleFormatter() {
private static final String format = "ohmy: %1$tF %1$tT %2$s %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()
);
}
});
mylog.info("from mylog");
// Loggers can have custom output targets;
// any OutputStream works.
ByteArrayOutputStream out = new ByteArrayOutputStream();
Logger buflog = Logger.getLogger("BufferLogger");
StreamHandler streamHandler = new StreamHandler(out, new SimpleFormatter() {
private static final String format = "buf: %1$tF %1$tT %2$s %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()
);
}
});
buflog.setUseParentHandlers(false);
buflog.addHandler(streamHandler);
// This call writes the log output into out.
buflog.info("hello");
streamHandler.flush();
// This will actually show it on standard output.
System.out.print("from buflog:" + out.toString());
// For structured log output, we can use JSONObject.
// This simulates the slog package's JSON output.
JSONObject jsonLog = new JSONObject();
jsonLog.put("time", Instant.now().toString());
jsonLog.put("level", "INFO");
jsonLog.put("msg", "hi there");
System.out.println(jsonLog.toString());
// In addition to the message, we can include
// an arbitrary number of 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());
}
}
Sample output; the date and time emitted will depend on when the example ran:
May 30, 2023 3:45:16 PM LoggingExample main
INFO: standard logger
2023-05-30 15:45:16.904 INFO LoggingExample main with micro
May 30, 2023 3:45:16 PM LoggingExample main
INFO: with class/line
my: 2023-05-30 15:45:16 INFO from mylog
ohmy: 2023-05-30 15:45:16 INFO from mylog
from buflog:buf: 2023-05-30 15:45:16 INFO hello
{"level":"INFO","msg":"hi there","time":"2023-05-30T15:45:16.904166391Z"}
{"level":"INFO","msg":"hello again","time":"2023-05-30T15:45:16.904178985Z","key":"val","age":25}
These are wrapped for clarity of presentation; in reality, they are emitted on a single line.
Note: This example uses the org.json.JSONObject
class for JSON formatting, which may require adding an external dependency to your project.