clog

package module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 29, 2024 License: BSD-3-Clause Imports: 6 Imported by: 0

README

clog

Go Reference

A lightweight log/slog.JSONHandler wrapper that adapts the fields to the Google Cloud Logging structured log format.

The intended use case is Cloud Run, but it should work in similar environments where logs are emitted to stdout/stderr and automatically picked up by Cloud Logging (e.g. App Engine, Cloud Functions, GKE).

Features

  • Lightweight. The handler merely reformats/renames the structured JSON log fields. It's still log/slog.JSONHandler under the hood. It does NOT send logs to Cloud Logging directly (e.g. using the Cloud SDK).

  • Tracing. A tracing middleware is provided to automatically extract tracing information from traceparent or X-Cloud-Trace-Context HTTP request header, and attaches it to the request context. The Handler automatically includes any tracing information as log attributes.

  • Custom levels as supported by Google Cloud Logging, e.g. CRITICAL and NOTICE.

Usage

import (
	"log/slog"

	"cloud.google.com/go/compute/metadata"
	"github.com/ronny/clog"
)

func main() {
	projectID, err := metadata.ProjectID()
	if err != nil {
		panic(err)
	}

	logger := slog.New(
		clog.NewHandler(os.Stderr, clog.HandlerOptions{
			Level: clog.LevelInfo,
			GoogleProjectID: projectID,
		}),
	)
	slog.SetDefault(logger)

	mux := http.NewServeMux()
	mux.Handle("POST /warn", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		ctx := r.Context()
		// ⚠️ The log will have tracing attrs since we're using
		// trace.Middleware below (assuming trace header is in the request):
		// "logging.googleapis.com/trace"
		// "logging.googleapis.com/spanId"
		// "logging.googleapis.com/traceSampled"
		slog.WarnContext(ctx, "flux capacitor is too warm",
			"mycount", 42,
		)
	}))
	mux.Handle("POST /critical", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		ctx := r.Context()
		// ⚠️ Custom level CRITICAL
		slog.Log(ctx, clog.LevelCritical, "flux capacitor is on fire")
	}))

	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
	}
	log.Printf("listening on port %s", port)

	// ⚠️ `trace.Middleware` to make tracing information available in ctx in mux
	// handlers.
	if err := http.ListenAndServe(":"+port, trace.Middleware(mux)); err != nil {
		log.Fatal(err)
	}
}

Credits and acknowledgements

Thank you to Remko Tronçon for doing most of the hard work in https://github.com/remko/cloudrun-slog which is the basis for this library.

Documentation

Overview

Package clog provides a Google Cloud Logging "adapter" for log/slog.

Index

Constants

View Source
const (
	TimestampKey   = "timestamp"
	MessageKey     = "message"
	SeverityKey    = "severity"
	HttpRequestKey = "httpRequest"
)

Standard JSON log fields as per https://cloud.google.com/logging/docs/structured-logging#structured_logging_special_fields

View Source
const (
	LabelsKey         = "logging.googleapis.com/labels"
	OperationKey      = "logging.googleapis.com/operation"
	SourceLocationKey = "logging.googleapis.com/sourceLocation"
	TraceKey          = trace.TraceKey
	SpanIDKey         = trace.SpanIDKey
	TraceSampledKey   = trace.TraceSampledKey
)

Extended JSON log fields as per https://cloud.google.com/logging/docs/structured-logging#structured_logging_special_fields

View Source
const (
	LevelDefault   slog.Level = -5
	LevelDebug     slog.Level = slog.LevelDebug // -4
	LevelInfo      slog.Level = slog.LevelInfo  // 0
	LevelNotice    slog.Level = 2
	LevelWarning   slog.Level = slog.LevelWarn  // 4 ⚠️ Warning vs Warn
	LevelError     slog.Level = slog.LevelError // 8
	LevelCritical  slog.Level = 9
	LevelAlert     slog.Level = 10
	LevelEmergency slog.Level = 11
)

The levels' name and order match https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#LogSeverity but the internal int values differ.

The internal int values are changed so that they can be used with log/slog.Log for logging at a custom level, for example:

slog.Log(ctx, clog.LevelCritical, "flux capacitor exploded")

Variables

View Source
var ErrInvalidHandlerOptions = errors.New("invalid HandlerOptions")

Functions

func LevelName

func LevelName(l slog.Level) string

LevelName returns the Google Cloud Logging name (in uppercase) for the level as per https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#LogSeverity

Examples:

LevelName(LevelWarning) => "WARNING"

func ReplaceAttr

func ReplaceAttr(groups []string, attr slog.Attr) slog.Attr

ReplaceAttr replaces attr keys and values to fit Google Cloud Logging's expected structure as per: - https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry - https://cloud.google.com/functions/docs/monitoring/logging - https://cloud.google.com/functions/docs/monitoring/logging

Types

type Handler added in v0.3.0

type Handler struct {
	// contains filtered or unexported fields
}

Handler is a log/slog.JSONHandler preconfigured for Google Cloud Logging.

func NewHandler

func NewHandler(w io.Writer, opts HandlerOptions) (*Handler, error)

func (*Handler) Enabled added in v0.3.0

func (h *Handler) Enabled(ctx context.Context, level slog.Level) bool

Enabled implements log/slog.Handler.

func (*Handler) Handle added in v0.3.0

func (h *Handler) Handle(ctx context.Context, record slog.Record) error

Handle implements log/slog.Handler.

func (*Handler) WithAttrs added in v0.3.0

func (h *Handler) WithAttrs(attrs []slog.Attr) slog.Handler

WithAttrs implements log/slog.Handler.

func (*Handler) WithGroup added in v0.3.0

func (h *Handler) WithGroup(name string) slog.Handler

WithGroup implements log/slog.Handler.

type HandlerOptions

type HandlerOptions struct {
	AddSource       bool
	Level           slog.Leveler
	ReplaceAttr     func(groups []string, a slog.Attr) slog.Attr
	GoogleProjectID string
}

Directories

Path Synopsis
Package trace contains utilities to extract and use Cloud Trace context in logs.
Package trace contains utilities to extract and use Cloud Trace context in logs.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL