Logging in Chapel

Here’s the translation of the Go logging example to Chapel, formatted in Markdown suitable for Hugo:

Chapel provides several ways to output logs from programs. We’ll explore different logging methods and configurations in this example.

use IO;
use Time;
use Logging;

proc main() {
    // Simply writing to stdout is a basic form of logging
    writeln("standard output");

    // Chapel doesn't have a built-in logging module like Go's log package,
    // but we can create a simple logging function with timestamps
    proc log(msg: string) {
        const now = getCurrentTime();
        writef("%s %s\n", now.isoformat(), msg);
    }

    log("with timestamp");

    // We can modify our logging function to include file and line information
    proc logWithLocation(msg: string) {
        const now = getCurrentTime();
        const (filename, line, _) = here.getLineAndFile();
        writef("%s %s:%d: %s\n", now.isoformat(), filename, line, msg);
    }

    logWithLocation("with file/line");

    // Chapel doesn't have a built-in way to create custom loggers,
    // but we can create a simple logger class
    class MyLogger {
        var prefix: string;

        proc init(prefix: string) {
            this.prefix = prefix;
        }

        proc log(msg: string) {
            const now = getCurrentTime();
            writef("%s%s %s\n", prefix, now.isoformat(), msg);
        }
    }

    var mylog = new MyLogger("my:");
    mylog.log("from mylog");

    // We can change the prefix of our logger
    mylog.prefix = "ohmy:";
    mylog.log("from mylog");

    // Chapel doesn't have a direct equivalent to Go's bytes.Buffer,
    // but we can use a string to accumulate log messages
    var buflog: string;
    proc bufLogger(msg: string) {
        const now = getCurrentTime();
        buflog += "buf:" + now.isoformat() + " " + msg + "\n";
    }

    bufLogger("hello");
    writef("from buflog:%s", buflog);

    // Chapel doesn't have a built-in structured logging system like Go's slog,
    // but we can create a simple JSON-like output
    proc structuredLog(msg: string, args: tuple) {
        const now = getCurrentTime();
        var logEntry = "{'time':'" + now.isoformat() + "','msg':'" + msg + "'";
        for param i in 0..#args.size by 2 {
            logEntry += ",'" + args[i]:string + "':'" + args[i+1]:string + "'";
        }
        logEntry += "}";
        writeln(logEntry);
    }

    structuredLog("hi there", ());
    structuredLog("hello again", ("key", "val", "age", "25"));
}

This Chapel code demonstrates various logging techniques, attempting to replicate the functionality shown in the Go example. Here’s a breakdown of the differences and adaptations:

  1. Chapel doesn’t have a standard logging library like Go’s log package, so we’ve created custom logging functions.

  2. The Time module is used for timestamp functionality.

  3. We’ve created a simple MyLogger class to mimic Go’s custom logger behavior.

  4. Instead of using a bytes.Buffer, we use a string to accumulate log messages.

  5. Chapel doesn’t have built-in JSON logging like Go’s slog, so we’ve created a simple structuredLog function that outputs JSON-like strings.

  6. File and line information is obtained using Chapel’s here.getLineAndFile() method.

The output of this program will be similar to the Go version, but with some differences due to the adaptations made for Chapel. The exact timestamps will depend on when the program is run.

Chapel, being a different language, doesn’t have exact equivalents for all of Go’s logging features. However, this example demonstrates how similar functionality can be achieved using Chapel’s capabilities.