Go by Example: Logging

La biblioteca estándar de Go proporciona herramientas sencillas para generar registros desde programas en Go, con el paquete log para salidas de formato libre y el paquete log/slog para salidas estructuradas.

package main
import (
    "bytes"
    "fmt"
    "log"
    "os"
    "log/slog"
)
func main() {

Simplemente invocando funciones como Println del paquete log se utiliza el logger estándar, el cual ya está preconfigurado para una salida de registros razonable a os.Stderr. Métodos adicionales como Fatal* o Panic* terminarán el programa después de registrar.

    log.Println("standard logger")

Los loggers pueden configurarse con flags para establecer su formato de salida. Por defecto, el logger estándar tiene los flags log.Ldate y log.Ltime establecidos, y estos se recogen en log.LstdFlags. Podemos cambiar sus flags para emitir la hora con precisión de microsegundos, por ejemplo.

    log.SetFlags(log.LstdFlags | log.Lmicroseconds)
    log.Println("with micro")

También admite emitir el nombre del archivo y la línea desde la cual se llama a la función log.

    log.SetFlags(log.LstdFlags | log.Lshortfile)
    log.Println("with file/line")

Puede ser útil crear un logger personalizado y pasarlo alrededor. Al crear un nuevo logger, podemos establecer un prefijo para distinguir su salida de otros loggers.

    mylog := log.New(os.Stdout, "my:", log.LstdFlags)
    mylog.Println("from mylog")

Podemos establecer el prefijo en loggers existentes (incluyendo el estándar) con el método SetPrefix.

    mylog.SetPrefix("ohmy:")
    mylog.Println("from mylog")

Los loggers pueden tener objetivos de salida personalizados; cualquier io.Writer funciona.

    var buf bytes.Buffer
    buflog := log.New(&buf, "buf:", log.LstdFlags)

Esta llamada escribe la salida del registro en buf.

    buflog.Println("hello")

Esto en realidad lo mostrará en la salida estándar.

    fmt.Print("from buflog:", buf.String())

El paquete slog proporciona salida de registros estructurada. Por ejemplo, registrar en formato JSON es sencillo.

    jsonHandler := slog.NewJSONHandler(os.Stderr, nil)
    myslog := slog.New(jsonHandler)
    myslog.Info("hi there")

Además del mensaje, la salida de slog puede contener un número arbitrario de pares clave=valor.

    myslog.Info("hello again", "key", "val", "age", 25)
}

Ejemplo de salida; la fecha y hora emitidas dependerán de cuándo se ejecute el ejemplo.

$ go run logging.go
2023/08/22 10:45:16 standard logger
2023/08/22 10:45:16.904141 with micro
2023/08/22 10:45:16 logging.go:40: with file/line
my:2023/08/22 10:45:16 from mylog
ohmy:2023/08/22 10:45:16 from mylog
from buflog:buf:2023/08/22 10:45:16 hello

Estas están envueltas para claridad de presentación en el sitio web; en realidad se emiten en una sola línea.

{"time":"2023-08-22T10:45:16.904166391-07:00",
 "level":"INFO","msg":"hi there"}
{"time":"2023-08-22T10:45:16.904178985-07:00",
    "level":"INFO","msg":"hello again",
    "key":"val","age":25}

Siguiente ejemplo: HTTP Client.