slog based logging library optimized for Cloud Logging. This packaged inspired by Zapdriver and zerodriver.
This package provides simple structured logger optimized for Cloud Logging based on slog.
Go 1.21 or above
Initialize a logger.
logger := slogdriver.New(os.Stdout, slogdriver.HandlerOptions{})
This logger
is *slog.Logger. Then, write by using slog API.
logger.Info("Hello World!", slog.String("key", "value"))
If your log follows LogEntry format, you can query logs or create metrics alert easier and efficiently on GCP Cloud Logging console.
You can use slog.Level(Debug, Info, Warn, Error). And this library prepare all severities for Cloud Logging.
- DEFAULT
- DEBUG
- INFO
- NOTICE
- WARNING
- ERROR
- CRITICAL
- ALERT
- EMERGENCY
logger := slogdriver.New(os.Stdout, slogdriver.HandlerOptions{
Level: slogdriver.LevelDefault,
})
logger.Log(context.Background(), slogdriver.LevelEmergency, "emergency msg")
To log HTTP related metrics and information, you can create slog.Attr with the following function.
var req *http.Request
var res *http.Response
logger.Info("Http Request finished", slogdriver.MakeHTTPAttr(req, res))
The following fields needs to be set manually:
- ServerIP
- Latency
- CacheLookup
- CacheHit
- CacheValidatedWithOriginServer
- CacheFillBytes
Using these feature, you can log HTTP related information as follows,
p := slogdriver.MakeHTTPPayload(req, res)
p.Latency = time.Since(start)
logger.Info("http finished", slogdriver.MakeHTTPAttrFromHTTPPayload(p))
// Or, you can create attr manually
logger.Info("http finished", slog.Any(slogdriver.HTTPKey, p))
import "go.opentelemetry.io/otel"
// Set projectId or, you can set environment GOOGLE_CLOUD_PROJECT
logger := slogdriver.New(os.Stdout, slogdriver.HandlerOptions{ProjectID: "YOUR_PROJECT_ID"})
ctx, span := otel.Tracer(traceName).Start(context.Background(), "span")
defer span.End()
logger.InfoContext(ctx, "Hello World")
// got:
// {"severity":"INFO","message":"Hello World","logging.googleapis.com/trace":"projects/YOUR_PROJECT_ID/traces/00000000000000000000000000000000","logging.googleapis.com/spanId":"0000000000000000","logging.googleapis.com/trace_sampled":true}
If you use go.opentelemetry.io/otel, it is able to set traceId with request context like the below:
import (
gcppropagator "github.com/GoogleCloudPlatform/opentelemetry-operations-go/propagator"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"go.opentelemetry.io/otel/propagation"
)
otel.SetTextMapPropagator(
propagation.NewCompositeTextMapPropagator(
gcppropagator.CloudTraceOneWayPropagator{},
propagation.TraceContext{},
),
)
handler := NewServeMux()
handler.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
logger.InfoContext(r.Context(), "Hello World") // This log should include trace information.
})
handler := otelhttp.NewHandler(handler, traceName)
You can see example for Cloud Run.
You can add any "labels" to your log as following:
logger.Info("", slog.Group(slogdriver.LabelKey, slog.String("label", "hoge")))
You can set common label like the follow:
logger = logger.With(slog.Group(slogdriver.LabelKey, slog.String("commonLabel", "hoge")))
logger.Info("Hello World", slog.Group(slogdriver.LabelKey, slog.String("label1", "fuga")))
// got:
// {"severity":"INFO","message":"Hello World","logging.googleapis.com/labels":{"commonLabel":"hoge","label1":"fuga"}}
logger.Warn("Hello World", slog.Group(slogdriver.LabelKey, slog.String("label2", "fuga")))
// got:
// {"severity":"WARNING","message":"Hello World","logging.googleapis.com/labels":{"commonLabel":"hoge","label2":"fuga"}}
logger := slogdriver.New(os.Stdout, slogdriver.HandlerOptions{AddSource: true})
logger.Info("Hello World")
// {"severity":"INFO","message":"Hello World","logging.googleapis.com/sourceLocation":{"file":"/path/to/source.go","line":"12","function":"yourFunction"}}
- severity
- message
- httpRequest
- time, timestamp
- insertId
- labels
- operation
- sourceLocation
- spanId
- trace
- traceSampled
https://cloud.google.com/logging/docs/structured-logging#special-payload-fields