slogcp

package module
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Feb 27, 2026 License: Apache-2.0 Imports: 25 Imported by: 1

README

slogcp

slogcp logo

A "batteries included" slog.Handler for Google Cloud Platform with built-in HTTP, gRPC, and Pub/Sub integrations. slogcp turns application events into observability-ready telemetry by aligning logs, traces, and error data for Cloud Logging, Cloud Trace, and Error Reporting. It writes structured JSON to stdout/stderr so GCP's logging agent handles ingestion without the overhead of managing gRPC streams, retries, or batching. Its middleware is OpenTelemetry-aware by default, automatically propagating trace context and attaching request-scoped metadata across service boundaries, while the handler auto-detects your GCP runtime and adapts its defaults so you get end-to-end visibility with minimal configuration.

Installation

go get github.com/pjscruggs/slogcp

Quick Start

package main

import (
    "log"
    "log/slog"
    "os"

    "github.com/pjscruggs/slogcp"
)

func main() {
    // Create a handler with default settings
    handler, err := slogcp.NewHandler(os.Stdout)
    if err != nil {
        log.Fatalf("Failed to create handler: %v", err)
    }

    // No need to manually Close() when targeting stdout/stderr
    // For other targets (e.g., WithRedirectToFile),
    // `defer handler.Close()` to flush and release resources

    logger := slog.New(handler)
    // Log a simple message
    logger.Info("Application started")
}

Why Would I Use This?

Who is this for?

slogcp will be useful to you if you're using:

  1. these Google Cloud services:
  • Cloud Run Services
  • Cloud Run Jobs
  • Cloud Functions
  • App Engine
  • Google Kubernetes Engine
  1. Google Cloud's native observability stack
    You rely on Cloud Logging, Cloud Trace, and Error Reporting to understand your services. So, you want logs, traces, and errors to line up cleanly in those UIs with correct severities, structured fields, trace IDs, and stack traces, without wiring all of that by hand in every service.

  2. You want to reduce the boilerplate

In a typical Go service, you'd otherwise need to hand-roll a custom slog.Handler (or replacer) to rename level to severity, plumb OpenTelemetry span IDs into logging.googleapis.com/trace / spanId / trace_sampled, detect the current GCP runtime and project ID to populate serviceContext.service / .version, write HTTP and gRPC middleware to derive request-scoped loggers and attach method/route/status/latency/size fields, handle proxy-derived scheme/client IP metadata (for example X-Forwarded-Proto/X-Forwarded-For) on managed runtimes, and capture Go stack traces with context.reportLocation so Error Reporting can group crashes. slogcp packages all of that into one handler and a small set of middlewares, so each service just wires slogcp.NewHandler, slogcphttp.Middleware, and/or slogcpgrpc.ServerOptions and the client interceptors instead of re-implementing the same JSON shapes and trace/error wiring over and over again.

Why not just use the official logging library?
Using cloud.google.com/go/logging is more expensive than logging to stdout

[!NOTE] The official GCP documentation for the various services that support automatic ingestion of logs written to stdout/stderr doesn't have a consistent term for this feature. Lacking an official term, we'll be referring to this service as the "logging ingester."

CPU time is money. When you use a Cloud Logging client library and let it send logs to the Cloud Logging API, your billable service is responsible for marshaling every record into protobuf, maintaining gRPC streams, retrying transient failures, and batching writes across worker goroutines. If you don't configure the client correctly, this can kill your performance. When you log to stdout, GCP's backend logging ingester handles all of that for you, free of charge.

If it determines that it is running in a GCP environment, slogcp further reduces the billable CPU cycles spent on JSON marshalling by:

  • suppressing log/slog's automatic timestamping for stdout/stderr handlers since the logging ingester will automatically timestamp those entries (file targets keep timestamps so rotated/shipped logs stay annotated)
  • using shorter, aliases for severity, which the logging ingester will recognize and convert to their standard values
Why not just use cloud.google.com/go/logging with logging.RedirectAsJSON(os.Stdout)?

cloud.google.com/go/logging has a built-in ability to JSONs to stdout rather than sending logs over the API, so why don't we just use that?

Because, cloud.google.com/go/logging is not logging-pattern agnostic. It ships its own Logger type and never implements the slog.Handler interface. That means, even if you're just logging to stdout, you cannot hand the client to slog.SetDefault for a global pattern, you cannot derive child loggers with logger.With for a dependency-injected pattern, and you cannot swap in request-scoped loggers harvested for a request-scoped pattern. You could build an adapter that translates slog.Record into the client's Entry struct, but then you're re-creating a handler just to regain native slog ergonomics, and having to add the boilerplate to do so to each of your services.

Features

Severity fields

log/slog emits a vendor-neutral level field and leaves severity naming up to you, but Cloud Logging expects a severity field using its own enum. slogcp maps slog levels (including GCP-specific levels like NOTICE, CRITICAL, and EMERGENCY) onto the correct Cloud Logging severities and can emit single-letter aliases on managed GCP runtimes, so you don't need a custom JSON handler or ReplaceAttr function in every service.

Trace correlation

Cloud Logging and Cloud Trace correlate logs via logging.googleapis.com/trace, logging.googleapis.com/spanId, and logging.googleapis.com/trace_sampled. slogcp reads the current OpenTelemetry span from context (covering W3C traceparent, grpc-trace-bin, and X-Cloud-Trace-Context) and populates these fields automatically. The HTTP and gRPC helpers also handle trace header extraction and injection for you, so logs come with clickable trace links in Logs Explorer without hand-rolled middleware.

Error Reporting

Error Reporting groups errors by service and stack trace, but getting the JSON shape right (serviceContext, stack_trace, and context.reportLocation) is tedious. slogcp can capture Go stack traces, infer service metadata from Cloud Run/Functions/App Engine, and attach Error Reporting-friendly fields either automatically (based on level and configuration) or via helpers like ErrorReportingAttrs and ReportError, so plain ERROR logs become rich Error Reporting events without a separate client library.

HTTP and gRPC Interceptors

HTTP and gRPC usually require bespoke middleware/interceptors just to get request-scoped loggers, consistent request/RPC attributes (method/route/status/duration/sizes), and trace context propagation. slogcp ships slogcphttp and slogcpgrpc helpers that do that wiring for you, so each service adds one middleware or ServerOptions call instead of re-implementing instrumentation.

Pub/Sub Integration

Pub/Sub workflows usually require extra glue code: copy trace context into message attributes, recover it on the subscriber, derive a per-message logger, and remember to attach consistent subscription/topic/message fields so Logs Explorer stays queryable. slogcp’s slogcppubsub package (github.com/pjscruggs/slogcp/slogcppubsub) collapses that to a couple helpers (Inject and WrapReceiveHandler), giving you message-scoped loggers (slogcp.Logger(ctx)), Cloud Logging trace correlation, and OpenTelemetry messaging semantic-convention fields by default. It also supports optional consumer spans, googclient_ trace attribute interop, and a “public endpoint” trust-boundary mode (new root + link) so you can keep end-to-end observability without blindly trusting producer trace IDs.

Async Logging

slogcp writes synchronously to stdout/stderr by default. When slogcp writes to a file target (SLOGCP_TARGET=file:... or slogcp.WithRedirectToFile), it buffers writes by default so disk I/O doesn't sit on hot paths. See docs/CONFIGURATION.md#async-logging-slogcpasync to tune or disable buffering (or to opt into async for other targets).

[!TIP] Async wrappers on stdout/stderr usually add overhead without improving throughput.

Tested Out The Wazoo

slogcp has 100% local test coverage. Each of our examples is its own Go module with its own tests. Some of those tests verify compatibility with popular third-party libraries like masq for redaction and timberjack for log rotation. We also run a series of E2E tests in Google Cloud that spin up real Cloud Run services wired together with slogcp’s HTTP and gRPC interceptors. Those tests drive HTTP requests and both unary and streaming gRPC calls through chains of downstream services, then query Cloud Logging and Cloud Trace to verify severities, resource labels/serviceContext, log names (run.googleapis.com/stdout), and that trace IDs/span IDs propagate correctly so logs and spans from every service correlate into a single end-to-end trace in Google Cloud's UIs.

Easy compatibility with other slog libraries

Because slogcp is "just" a slog.Handler that writes JSON to an io.Writer, it slots into existing slog setups instead of replacing them. You still use slog.New, slog.SetDefault, logger.With, and request-scoped loggers, and you can compose slogcp with other slog-based tools like masq for redaction or timberjack (the maintained lumberjack fork) for file rotation without special adapters. When you do write logs to files, the built-in SwitchableWriter and Handler.ReopenLogFile helpers let you cooperate with external rotation tools without rebuilding handlers or changing how the rest of your code logs.

Core Configuration Options

If you don't want to read any more documentation right now, these are the configurations you're the most likely to care about. See .examples/configuration/main.go for a runnable demonstration that applies custom levels, source location, and default attributes.

slogcp.Handler also supports attribute rewriting via slogcp.WithReplaceAttr(func(groups []string, attr slog.Attr) slog.Attr), which runs on every non-group attribute (including attributes added via With/WithAttrs and nested groups) before slogcp adds any of its own fields. Auto-added fields such as severity, time, trace, serviceContext, and stack_trace are appended after the replacer runs and therefore do not flow through this hook.

handler, err := slogcp.NewHandler(os.Stdout,
    slogcp.WithReplaceAttr(func(groups []string, attr slog.Attr) slog.Attr {
        if attr.Key == "token" {
            return slog.String(attr.Key, "[redacted]")
        }
        return attr
    }),
)
Environment Variables

Core environment variables for configuring slogcp:

Variable Description Default
SLOGCP_TARGET stdout, stderr, or file:/path stdout
SLOGCP_LEVEL (fallback: LOG_LEVEL) Minimum log level (debug, info, warn, error, etc.) info
SLOGCP_SOURCE_LOCATION Include source file/line (true, false) false
SLOGCP_STACK_TRACES Enable stack traces (true, false) false
SLOGCP_TRACE_DIAGNOSTICS Controls trace-correlation diagnostics: off, warn/warn_once, or strict warn_once

When the handler encounters attributes whose value is an error, it detects the first such attribute, records an error_type, and appends the error text to the log message so Error Reporting payloads remain informative. A stack_trace field is added when the error already carries a stack, or when stack traces are enabled via SLOGCP_STACK_TRACES or slogcp.WithStackTraceEnabled and the record's level meets the configured threshold.

If slogcp determines at runtime that it is running in a GCP environment such as Cloud Run, Cloud Functions, or App Engine and discovers service metadata, it will automatically populate serviceContext when it is missing so Error Reporting can group errors correctly without additional configuration.

Dynamic Level Control

slogcp.Handler exposes runtime level tuning so you can raise or lower verbosity without redeploying. See .examples/dynamic-level/main.go for a runnable example.

By default, each call to slogcp.NewHandler initializes its minimum level from SLOGCP_LEVEL (falling back to LOG_LEVEL). Override that programmatically with slogcp.WithLevel.

To change levels at runtime, call handler.SetLevel(...) for a single handler. If multiple handlers (or libraries) need to move together, share a single *slog.LevelVar via slogcp.WithLevelVar and update it once:

levelVar := new(slog.LevelVar)

appHandler, err := slogcp.NewHandler(os.Stdout, slogcp.WithLevelVar(levelVar))
if err != nil {
	panic(err)
}

auditHandler, err := slogcp.NewHandler(nil, slogcp.WithRedirectToFile("audit.json"), slogcp.WithLevelVar(levelVar))
if err != nil {
	panic(err)
}
defer auditHandler.Close()

levelVar.Set(slog.LevelDebug) // app + audit now allow debug
Error Reporting helpers

When you need fully Error Reporting-optimized entries, slogcp exposes helpers such as slogcp.ErrorReportingAttrs(err) and slogcp.ReportError(...). These always attach Error Reporting-friendly fields like serviceContext, a Go-formatted stack_trace, and reportLocation, and accept overrides via slogcp.WithErrorServiceContext(...) and slogcp.WithErrorMessage(...).

logger.ErrorContext(ctx, "failed operation",
    append(
        []slog.Attr{slog.Any("error", err)},
        slogcp.ErrorReportingAttrs(err)...,
    )...,
)

Examples

In Google Cloud

See .examples/basic/main.go for a minimal bootstrap that writes to stdout with slogcp.

HTTP and gRPC Middleware

slogcp provides ready-to-use middleware for HTTP servers and gRPC services. The HTTP helpers live in the slogcphttp package (github.com/pjscruggs/slogcp/slogcphttp) and the gRPC interceptors live in the slogcpgrpc package (github.com/pjscruggs/slogcp/slogcpgrpc).

Trace correlation reads the current OpenTelemetry span from the request context: the handler uses trace.SpanContextFromContext to obtain trace and span IDs and emits them as Cloud Logging-compatible fields. The HTTP middleware will either reuse an existing span, extract remote context via otel.GetTextMapPropagator (W3C traceparent/tracestate), or fall back to X-Cloud-Trace-Context if no span or W3C context is present, and by default wraps otelhttp.NewHandler, which uses the global tracer provider unless you override it. With a standard OpenTelemetry setup (global tracer provider and propagator), the logger automatically follows whatever span is active on the context.

HTTP Example (Server)

See .examples/http-server/main.go for a runnable HTTP server that composes slogcp middleware with trace context injection.

HTTP Example (Client propagation)

See .examples/http-client/main.go to watch the HTTP transport forward W3C trace context to downstream services.

gRPC
  • Client interceptors inject W3C traceparent (and optionally X-Cloud-Trace-Context) into outgoing metadata; server interceptors extract context for correlation.
  • ServerOptions bundles slogcp interceptors with OpenTelemetry instrumentation for streamlined server registration; client code can use the provided interceptors directly.
  • See .examples/grpc/main.go for a Greeter service that uses the interceptors end-to-end.
  • If you're already invested in the gRPC Ecosystem ecosystem framework, slogcp still fits: use the ready-made slogcp-grpc-adapter module to have its logging interceptors emit slogcp/Cloud Logging–friendly JSON.
Pub/Sub

See .examples/pubsub/main.go for a runnable Pub/Sub example that injects trace context and derives message-scoped loggers.

Integration with other libraries

Since slogcp is just a slog.Handler, it can easily be integrated with other popular slog libraries.

go-grpc-middleware

Using github.com/grpc-ecosystem/go-grpc-middleware for gRPC logging doesn’t block you from adopting slogcp. There’s a ready-made adapter, slogcp-grpc-adapter, that plugs slogcp into its logging interceptors so you keep your existing interceptor chains while getting Cloud Logging–native JSON, trace correlation, and Error Reporting behavior.

masq

Run an HTTP server that redacts sensitive request fields with github.com/m-mizutani/masq before logging via slogcp. See .examples/masq/main.go.

timberjack

Redirect slogcp output to a timberjack rotating writer with WithRedirectWriter and optional reopen support. See .examples/timberjack/main.go.

Advanced configuration

For more advanced middleware options, see the Configuration Documentation.

License

Apache 2.0

Contributing

Contributions are welcome! Feel free to submit issues for bugs or feature requests. For code contributions, please fork the repository, create a feature branch, and submit a pull request with your changes.

Documentation

Overview

Package slogcp provides a structured logging solution for Go applications that need to integrate cleanly with Google Cloud Logging. It builds on the standard library's log/slog package and emits JSON payloads that follow Cloud Logging conventions while writing to any io.Writer. The default destination is stdout, keeping the library container- and developer-friendly.

The primary entry point is NewHandler, which returns an slog.Handler configured with sensible defaults:

  • Structured JSON output that emits Cloud Logging fields such as `severity`, `logging.googleapis.com/trace`, `httpRequest`, and runtime metadata discovered from Cloud Run, Cloud Functions, Cloud Run Jobs, App Engine, GKE, and Compute Engine environments.
  • Optional source locations, explicit RFC3339 timestamps, and automatic stack traces triggered at or above a configurable level.
  • Seamless trace correlation helpers that leverage the extended Level definitions (`DEBUG` through `EMERGENCY`) plus the ability to emit single-letter severity aliases when desired, defaulting to full names outside Cloud Run, Cloud Run Jobs, Cloud Functions, and App Engine.
  • Timestamp emission that mirrors Cloud Logging expectations: omit the field on those managed runtimes and otherwise leave log/slog's JSONHandler default `time` field (a time.RFC3339Nano value) untouched so local and on-premise logs keep the native precision unless you override it.
  • Middleware hooks that allow additional slog.Handler layers to enrich or filter records before they are encoded.

Handlers can be redirected to stderr, a file managed by slogcp, or a custom writer. When slogcp opens the file it also provides Handler.ReopenLogFile to cooperate with external rotation tools. The handler exposes Handler.LevelVar and Handler.SetLevel for dynamic severity adjustments and honours many environment variables (for example `SLOGCP_LEVEL` with a `LOG_LEVEL` fallback, `SLOGCP_STACK_TRACES`, or `SLOGCP_TARGET`) so the same binary can run locally and in production without code changes. ContextWithLogger and Logger store and retrieve request-scoped loggers so integrations can pass loggers through call stacks.

Subpackages

  • github.com/pjscruggs/slogcp/slogcphttp offers net/http middleware and client transports that derive request-scoped loggers, propagate trace context, record latency/size metadata, and expose Cloud Logging friendly helpers such as [slogcphttp.HTTPRequestAttr] and [slogcphttp.ScopeFromContext]. Legacy `X-Cloud-Trace-Context` handling is available when required.
  • github.com/pjscruggs/slogcp/slogcpgrpc provides client and server interceptors that capture RPC metadata, surface errors with stack traces, and propagate trace context. Helper functions such as [slogcpgrpc.ServerOptions], [slogcpgrpc.DialOptions], and [slogcpgrpc.InfoFromContext] simplify wiring in both directions.
  • github.com/pjscruggs/slogcp/slogcppubsub provides Pub/Sub helpers for injecting and extracting OpenTelemetry trace context via `pubsub.Message.Attributes`, deriving per-message loggers (so `slogcp.Logger(ctx)` works inside handlers), and optionally starting an application-level consumer span. It supports interoperability with the Go Pub/Sub client's `googclient_`-prefixed attribute keys when enabled.

Quick Start

A basic logger only needs a handler and slog:

handler, err := slogcp.NewHandler(os.Stdout)
if err != nil {
    log.Fatalf("create slogcp handler: %v", err)
}
defer handler.Close() // flushes buffered logs and owned writers

logger := slog.New(handler)
logger.Info("application started")

Configuration

Use functional options such as WithLevel, WithSourceLocationEnabled, WithStackTraceEnabled, WithRedirectToFile, WithRedirectWriter, WithAdditionalHandlers, WithSeverityAliases, and WithTraceProjectID to adjust behaviour programmatically. Refer to the package documentation and configuration guide in docs/CONFIGURATION.md for the complete list of options, environment variables, and integration helpers. For trace propagation, applications can install slogcp's recommended composite propagator globally via EnsurePropagation, or construct it directly with NewCompositePropagator and pass it where needed.

Index

Constants

View Source
const (
	// TraceKey is the field name for the formatted trace name.
	// The value must be "projects/PROJECT_ID/traces/TRACE_ID".
	TraceKey = "logging.googleapis.com/trace"
	// SpanKey is the field name for the hex span ID.
	SpanKey = "logging.googleapis.com/spanId"
	// SampledKey is the field name for the boolean sampling decision.
	SampledKey = "logging.googleapis.com/trace_sampled"
)

Constants for trace-related keys used when adding trace information as attributes to structured log payloads. These specific keys are recognized by Google Cloud Logging for automatic correlation with Cloud Trace.

View Source
const (
	// LabelsGroup is the Cloud Logging attribute group used for structured labels.
	LabelsGroup = "logging.googleapis.com/labels"
)

Variables

View Source
var (
	// ErrInvalidRedirectTarget indicates an unsupported value for SLOGCP_TARGET or redirect options.
	ErrInvalidRedirectTarget = errors.New("slogcp: invalid redirect target")
)
View Source
var UserAgent string

UserAgent identifies this library when helper components need to report a version string. It is initialized from Version and can be overridden at build time.

View Source
var Version = "v1.2.0"

Version is the current version of the slogcp library. Follows semantic versioning (https://semver.org/). It can be overridden at build time via -ldflags.

Functions

func AlertContext

func AlertContext(ctx context.Context, logger *slog.Logger, msg string, args ...any)

AlertContext logs at alert severity to integrate with on-call workflows for non-recoverable issues.

func BuildXCloudTraceContext

func BuildXCloudTraceContext(rawTraceID, spanIDHex string, sampled bool) string

BuildXCloudTraceContext builds the value for the legacy X-Cloud-Trace-Context header from raw hex IDs and a sampled flag. The format is:

TRACE_ID[/SPAN_ID][;o=TRACE_TRUE]

where SPAN_ID is decimal and TRACE_TRUE is "1" when sampled, "0" otherwise.

If spanIDHex is empty or invalid, the "/SPAN_ID" portion is omitted.

func CaptureStack

func CaptureStack(skipFn func(string) bool) (string, runtime.Frame)

CaptureStack captures the current goroutine stack, trimming internal frames using skipFn (or SkipInternalStackFrame when nil). It returns the formatted stack trace string and the first remaining frame for use in report locations.

func ContextWithLogger

func ContextWithLogger(ctx context.Context, logger *slog.Logger) context.Context

ContextWithLogger returns a child context that stores logger so handlers can retrieve a request-scoped logger later in the call chain.

func ContextWithTraceProjectID added in v1.2.0

func ContextWithTraceProjectID(ctx context.Context, projectID string) context.Context

ContextWithTraceProjectID stores a normalized trace project ID on ctx so TraceAttributes can resolve project IDs without relying on process-global environment caching.

func CriticalContext

func CriticalContext(ctx context.Context, logger *slog.Logger, msg string, args ...any)

CriticalContext logs a message at critical severity indicating immediate attention is required.

func Debug

func Debug(logger *slog.Logger, msg string, args ...any)

Debug logs a structured message at LevelDebug severity without requiring a context. It mirrors slog.Logger.Debug while guaranteeing Cloud Logging severity alignment.

func DebugContext

func DebugContext(ctx context.Context, logger *slog.Logger, msg string, args ...any)

DebugContext logs a message at LevelDebug severity while attaching contextual attributes from ctx.

func Default

func Default(logger *slog.Logger, msg string, args ...any)

Default logs a structured message at LevelDefault severity without requiring a context value.

func DefaultContext

func DefaultContext(ctx context.Context, logger *slog.Logger, msg string, args ...any)

DefaultContext logs a structured message at LevelDefault severity while attaching contextual attributes from ctx. It is suitable for routing application level events through Cloud Logging.

func EmergencyContext

func EmergencyContext(ctx context.Context, logger *slog.Logger, msg string, args ...any)

EmergencyContext logs at emergency severity highlighting application-wide failures that demand instant response.

func EnsurePropagation

func EnsurePropagation()

EnsurePropagation configures a composite OpenTelemetry text map propagator that prefers the W3C Trace Context headers while accepting Google Cloud's legacy X-Cloud-Trace-Context header on ingress. The configuration is applied exactly once per process.

The installed propagator order is:

  1. CloudTraceOneWayPropagator (extracts X-Cloud-Trace-Context only)
  2. TraceContext (W3C traceparent/tracestate)
  3. Baggage

Applications remain free to override the global propagator afterwards by calling otel.SetTextMapPropagator with their own implementation.

func Error

func Error(logger *slog.Logger, msg string, args ...any)

Error logs a structured message at LevelError severity without requiring a context, mirroring slog.Logger.Error.

func ErrorContext

func ErrorContext(ctx context.Context, logger *slog.Logger, msg string, args ...any)

ErrorContext logs a message at LevelError severity while attaching contextual attributes from ctx.

func ErrorReportingAttrs

func ErrorReportingAttrs(err error, opts ...ErrorReportingOption) []slog.Attr

ErrorReportingAttrs returns structured attributes that align with the Cloud Error Reporting ingestion format. The caller can append the returned attrs to any slog logging call.

func ExtractTraceSpan

func ExtractTraceSpan(ctx context.Context, projectID string) (formattedTraceID, rawTraceID, rawSpanID string, sampled bool, otelCtx trace.SpanContext)

ExtractTraceSpan extracts OpenTelemetry trace details from ctx and, if a non-empty projectID is provided, formats a fully-qualified Cloud Trace name using "projects/{projectID}/traces/{traceID}".

It returns:

  • formattedTraceID: "projects/<projectID>/traces/<traceID>" if projectID != "", else "".
  • rawTraceID: 32-char lowercase hex trace ID.
  • rawSpanID: 16-char lowercase hex span ID.
  • sampled: whether the span context is sampled.
  • otelCtx: the original span context (valid==true iff trace present).

This function is intentionally light-weight: it does not create spans, does not parse headers, and does not mutate context. Upstream middleware should populate the OTel span context (e.g., via OTel propagators or an X-Cloud-Trace-Context injector) before calling this helper.

For cross-project linking, pass the desired project that owns the trace as projectID. If empty, only raw IDs are returned.

func FormatTraceResource

func FormatTraceResource(projectID, rawTraceID string) string

FormatTraceResource returns a fully-qualified Cloud Trace resource name:

projects/<projectID>/traces/<traceID>

Callers should pass a 32-char lowercase hex traceID (e.g., from OTel).

func GetVersion

func GetVersion() string

GetVersion returns the current library version string.

func HTTPRequestValue

func HTTPRequestValue(builder func() *HTTPRequest) slog.Value

HTTPRequestValue constructs a slog.Value that lazily builds an HTTPRequest.

func Info

func Info(logger *slog.Logger, msg string, args ...any)

Info logs a structured message at LevelInfo severity without requiring a context, mirroring slog.Logger.Info.

func InfoContext

func InfoContext(ctx context.Context, logger *slog.Logger, msg string, args ...any)

InfoContext logs a message at LevelInfo severity while attaching contextual attributes from ctx.

func Logger

func Logger(ctx context.Context) *slog.Logger

Logger retrieves a logger stored in ctx via ContextWithLogger. If no logger is found, slog.Default() is returned to ensure callers always receive a usable logger.

func NoticeContext

func NoticeContext(ctx context.Context, logger *slog.Logger, msg string, args ...any)

NoticeContext logs a message at notice severity for operational events that should page responders but do not indicate an outage.

func PrepareHTTPRequest

func PrepareHTTPRequest(req *HTTPRequest)

PrepareHTTPRequest normalizes an HTTPRequest for logging by ensuring derived fields are populated and by detaching the original *http.Request to avoid repeated expansion during JSON serialization. The function is safe to call multiple times.

func ReportError

func ReportError(ctx context.Context, logger *slog.Logger, err error, msg string, opts ...ErrorReportingOption)

ReportError logs err using logger at error level, automatically attaching Cloud Error Reporting metadata. Additional attributes can be provided via opts.

func SkipInternalStackFrame

func SkipInternalStackFrame(funcName string) bool

SkipInternalStackFrame reports whether funcName refers to a frame that belongs to slogcp or runtime internals and should be hidden from user-facing stack traces.

func SpanIDHexToDecimal

func SpanIDHexToDecimal(spanIDHex string) (string, bool)

SpanIDHexToDecimal converts a 16-char hex span ID to its unsigned decimal representation as required by the legacy X-Cloud-Trace-Context header's SPAN_ID field.

It returns ("", false) if the value cannot be parsed.

func TraceAttributes

func TraceAttributes(ctx context.Context, projectID string) ([]slog.Attr, bool)

TraceAttributes extracts Cloud Trace aware attributes from ctx. The returned slice can be supplied to logger.With to correlate logs with traces when emitting per-request loggers. When a project ID is known this helper emits the Cloud Logging correlation fields (`logging.googleapis.com/trace`, `logging.googleapis.com/spanId`, and `logging.googleapis.com/trace_sampled`). When no project ID can be determined it falls back to OpenTelemetry-style keys (`otel.trace_id`, `otel.span_id`, and `otel.trace_sampled`).

When projectID is empty, the helper resolves project IDs in this order: explicit argument, context override, then environment variables in the following order: SLOGCP_TRACE_PROJECT_ID, SLOGCP_PROJECT_ID, SLOGCP_GCP_PROJECT, GOOGLE_CLOUD_PROJECT, GCLOUD_PROJECT, and GCP_PROJECT.

func TraceProjectIDFromContext added in v1.2.0

func TraceProjectIDFromContext(ctx context.Context) (string, bool)

TraceProjectIDFromContext returns the normalized trace project ID override stored in ctx, when present.

func Warn

func Warn(logger *slog.Logger, msg string, args ...any)

Warn logs a structured message at LevelWarn severity without requiring a context, mirroring slog.Logger.Warn.

func WarnContext

func WarnContext(ctx context.Context, logger *slog.Logger, msg string, args ...any)

WarnContext logs a message at LevelWarn severity while attaching contextual attributes from ctx.

Types

type CloseTimeoutPolicy added in v1.2.0

type CloseTimeoutPolicy int

CloseTimeoutPolicy controls what Handler.Close does when async graceful shutdown reaches its flush timeout.

const (
	// CloseTimeoutAutoAbort keeps backward-compatible Close behavior: if
	// graceful async close times out, Close escalates to forceful abort before
	// closing owned resources.
	CloseTimeoutAutoAbort CloseTimeoutPolicy = iota
	// CloseTimeoutReturn keeps Close in graceful-only mode on timeout. Close
	// returns the timeout error and leaves owned resources open so in-flight
	// async workers are not interrupted by a concurrent sink close.
	CloseTimeoutReturn
)

type CompositePropagator added in v1.2.0

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

CompositePropagator wraps slogcp's recommended OpenTelemetry text map propagator composition.

func NewCompositePropagator added in v1.2.0

func NewCompositePropagator() CompositePropagator

NewCompositePropagator returns slogcp's recommended composite propagator.

The returned propagator:

  1. Extracts the legacy X-Cloud-Trace-Context header (read-only).
  2. Extracts and injects W3C Trace Context headers.
  3. Extracts and injects baggage.

This helper does not mutate process-wide OpenTelemetry globals.

func (CompositePropagator) Extract added in v1.2.0

Extract reads propagation fields from the supplied carrier into context.

func (CompositePropagator) Fields added in v1.2.0

func (p CompositePropagator) Fields() []string

Fields returns the set of headers this propagator reads or writes.

func (CompositePropagator) Inject added in v1.2.0

Inject writes propagation fields into the supplied carrier.

type ErrorReportingOption

type ErrorReportingOption func(*errorReportingConfig)

ErrorReportingOption configures ErrorReportingAttrs and ReportError.

func WithErrorMessage

func WithErrorMessage(msg string) ErrorReportingOption

WithErrorMessage overrides the message field embedded in the structured payload.

func WithErrorServiceContext

func WithErrorServiceContext(service, version string) ErrorReportingOption

WithErrorServiceContext sets the service.name and version used for Cloud Error Reporting. When omitted slogcp attempts to infer these values from the execution environment (Cloud Run, Cloud Functions, etc).

type HTTPRequest

type HTTPRequest struct {
	// Request is the original HTTP request. It is used for extracting
	// high-level details such as method, URL, headers, and protocol. The
	// request body is not logged.
	Request *http.Request

	// RequestMethod is the HTTP method, if known. When Request is non-nil this
	// is populated automatically.
	RequestMethod string

	// RequestURL is the full request URL string. When Request is non-nil this
	// is derived from Request.URL.
	RequestURL string

	// RequestSize is the size of the request in bytes. When unknown, it may be
	// set to -1.
	RequestSize int64

	// Status is the HTTP response status code.
	Status int

	// ResponseSize is the size of the response in bytes. When unknown, it may
	// be set to -1.
	ResponseSize int64

	// Latency is the time between when the request was received and when the
	// response was sent.
	Latency time.Duration

	// RemoteIP is the IP address of the client that sent the request.
	RemoteIP string

	// LocalIP is the IP address of the server that handled the request.
	LocalIP string

	// UserAgent is the user agent string of the client, if known.
	UserAgent string

	// Referer is the HTTP referer header of the request, if any.
	Referer string

	// Protocol is the protocol used for the request, such as "HTTP/1.1".
	Protocol string

	// CacheHit reports whether the response was served from cache.
	CacheHit bool

	// CacheValidatedWithOriginServer reports whether the cache entry was
	// validated with the origin server before being served.
	CacheValidatedWithOriginServer bool

	// CacheFillBytes is the number of bytes inserted into cache as a result of
	// the request.
	CacheFillBytes int64

	// CacheLookup reports whether the request was a cache lookup.
	CacheLookup bool
}

HTTPRequest mirrors the Cloud Logging HTTP request payload stored in LogEntry.http_request / httpRequest. It is shaped after the google.logging.type.HttpRequest proto message (see Cloud Logging RPC) and matches the JSON schema described at Cloud Logging REST. The corresponding Go proto type is google.golang.org/genproto/googleapis/logging/type.HttpRequest.

func HTTPRequestFromRequest

func HTTPRequestFromRequest(r *http.Request) *HTTPRequest

HTTPRequestFromRequest constructs an HTTPRequest from a standard library *http.Request, normalizing it via PrepareHTTPRequest. It is useful when you need to emit Cloud Logging-compatible httpRequest payloads without using the slogcphttp middleware helpers.

func (*HTTPRequest) LogValue

func (req *HTTPRequest) LogValue() slog.Value

LogValue implements slog.LogValuer so HTTPRequest payloads render using the Cloud Logging httpRequest schema even when emitted through generic slog handlers.

type Handler

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

Handler routes slog records to Google Cloud Logging with optional middlewares, stack traces and trace correlation.

JSON payload emission is best-effort. If a field value cannot be encoded by encoding/json, slogcp replaces the failing top-level field with a stable "!ERROR:<cause>" placeholder and retries once so one unsupported value does not drop the entire entry.

func NewHandler

func NewHandler(defaultWriter io.Writer, opts ...Option) (*Handler, error)

NewHandler builds a Google Cloud aware slog Handler. It inspects the environment for configuration overrides and then applies any provided Option values. The handler writes to defaultWriter unless a redirect option or environment override is provided. Encoding failures are handled with a single sanitize-and-retry pass described in Handler.

Example:

h, err := slogcp.NewHandler(os.Stdout,
	slogcp.WithLevel(slog.LevelInfo),
)
if err != nil {
	log.Fatal(err)
}
logger := slog.New(h)
logger.Info("ready")

func (*Handler) Abort added in v1.2.0

func (h *Handler) Abort(ctx context.Context) error

Abort performs forceful async shutdown (bounded by ctx) and then closes owned resources. When ctx expires first, Abort returns promptly while the underlying async abort may still be finishing in the background.

func (*Handler) Close

func (h *Handler) Close() error

Close releases any resources owned by the handler such as log files or writer implementations created by options. It first runs async shutdown via the configured flush timeout.

On timeout, behavior depends on CloseTimeoutPolicy:

func (*Handler) Level

func (h *Handler) Level() slog.Level

Level reports the handler's current minimum slog level.

func (*Handler) LevelVar

func (h *Handler) LevelVar() *slog.LevelVar

LevelVar returns the underlying slog.LevelVar used to gate records. It can be integrated with external configuration systems for dynamic level control.

func (*Handler) ReopenLogFile

func (h *Handler) ReopenLogFile() error

ReopenLogFile rotates the handler's file writer when logging to a file. If the handler is not writing to a file the method is a no-op.

func (*Handler) SetLevel

func (h *Handler) SetLevel(level slog.Level)

SetLevel updates the minimum slog level accepted by the handler at runtime. Calls are safe for concurrent use.

func (*Handler) Shutdown added in v1.2.0

func (h *Handler) Shutdown(ctx context.Context) error

Shutdown performs graceful async drain bounded by ctx. On timeout it returns without tearing down owned resources so callers can decide whether to abort.

type Level

type Level slog.Level

Level represents the severity of a log event, extending slog.Level to include all Google Cloud Logging severity levels. It maintains the underlying integer representation compatible with slog.Level.

Google Cloud Logging has 9 severity levels (DEFAULT, DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY) while standard slog has only 4 (DEBUG, INFO, WARN, ERROR). This type bridges that gap by defining additional levels that map directly to GCP severities, allowing applications to use the full range of GCP logging levels while remaining compatible with slog.

The integer values are chosen to maintain ordering and compatibility with the standard slog levels, allowing natural comparison operations.

const (

	// LevelDebug maps to GCP DEBUG (100) severity, directly corresponding to
	// the standard slog.LevelDebug (-4). This level is used for detailed debugging
	// information that would be excessive at higher levels.
	LevelDebug Level = Level(slog.LevelDebug) // -4

	// LevelInfo maps to GCP INFO (200) severity, directly corresponding to
	// the standard slog.LevelInfo (0). This is the default level for routine
	// operational messages confirming normal operation.
	LevelInfo Level = Level(slog.LevelInfo) // 0

	// LevelNotice maps to GCP NOTICE (300) severity. This sits between Info and
	// Warn, used for significant but expected events worth highlighting.
	LevelNotice Level = 2

	// LevelWarn maps to GCP WARNING (400) severity, directly corresponding to
	// the standard slog.LevelWarn (4). Used for potentially harmful situations
	// or unexpected states that might indicate a problem.
	LevelWarn Level = Level(slog.LevelWarn) // 4

	// LevelError maps to GCP ERROR (500) severity, directly corresponding to
	// the standard slog.LevelError (8). Used for runtime errors that require
	// attention but don't necessarily impact overall application function.
	LevelError Level = Level(slog.LevelError) // 8

	// LevelCritical maps to GCP CRITICAL (600) severity. This is more severe
	// than Error, used for severe runtime errors that prevent some function.
	LevelCritical Level = 12

	// LevelAlert maps to GCP ALERT (700) severity. This indicates that action
	// must be taken immediately, such as when a component becomes unavailable.
	LevelAlert Level = 16

	// LevelEmergency maps to GCP EMERGENCY (800) severity. The highest severity
	// level, used when the system is unusable or in a catastrophic failure.
	LevelEmergency Level = 20

	// LevelDefault maps to GCP DEFAULT (0) severity. This is used for unspecified
	// or unknown severity and intentionally sorts above the other levels so that
	// default-severity entries are never filtered out by minimum level settings.
	LevelDefault Level = 30
)

Constants for GCP severity levels, mapped onto slog.Level integer values. The values are chosen to maintain order and provide some spacing, aligning with the slog philosophy while covering all GCP levels.

func (Level) Level

func (l Level) Level() slog.Level

Level returns the underlying slog.Level value. This method allows slogcp.Level to satisfy the slog.Leveler interface, enabling its use in places like slog.HandlerOptions.Level and the standard slog.Logger methods.

The slog.Leveler interface requires a Level() method that returns slog.Level. By implementing this method, Level can be used anywhere a standard slog level is expected. This seamless integration means you can pass a slogcp.Level to functions expecting a slog.Leveler, such as:

  • As the Level field in slog.HandlerOptions
  • When creating a new slog.LevelVar via Set()
  • In comparison operations with standard slog levels

func (Level) String

func (l Level) String() string

String returns the canonical string representation of the Level, matching Google Cloud Logging severity names where applicable (e.g., "DEBUG", "NOTICE", "ERROR"). For levels between defined constants, it returns the name of the nearest lower defined level plus the offset (e.g., "DEFAULT+1", "INFO+1", "NOTICE+1").

This representation is used by the JSON handler for the "severity" field and provides a human-readable form of the level for debugging and display. Note that when logging to GCP, the String representation is not used directly; the numeric value is mapped to the appropriate GCP severity.

type Middleware

type Middleware func(slog.Handler) slog.Handler

Middleware adapts a slog.Handler before it is exposed by Handler. Middleware functions run in the order they are supplied, wrapping the core handler pipeline from last to first to mirror idiomatic HTTP middleware composition.

type Option

type Option func(*options)

Option mutates Handler construction behaviour when supplied to NewHandler.

Options follow the functional options pattern and are applied in the order they are provided by the caller.

func WithAdditionalHandlers added in v1.2.0

func WithAdditionalHandlers(handlers ...slog.Handler) Option

WithAdditionalHandlers fans out accepted records to additional handlers using slog.NewMultiHandler. Nil handlers are ignored.

Additional handlers are not owned by slogcp. If they require shutdown (for example, async wrappers), close them explicitly. Additional sinks are wrapped with sharedLevelHandler so they use slogcp's shared level threshold. When a sink fails, the wrapped error remains unwrappable (errors.Is/errors.As) and MultiHandler aggregates sink failures.

func WithAsync

func WithAsync(opts ...slogcpasync.Option) Option

WithAsync wraps the constructed handler in slogcpasync using tuned per-mode defaults. Supply slogcpasync options to override queue, workers, drop mode, or batch size.

func WithAsyncOnFile added in v1.1.0

func WithAsyncOnFile(opts ...slogcpasync.Option) Option

WithAsyncOnFile applies slogcpasync only when logging to a file target. It keeps stdout/stderr handlers synchronous while letting callers tune (or disable) file buffering.

func WithAttrs

func WithAttrs(attrs []slog.Attr) Option

WithAttrs preloads static attributes to be attached to every record emitted by the handler.

func WithCloseTimeoutPolicy added in v1.2.0

func WithCloseTimeoutPolicy(policy CloseTimeoutPolicy) Option

WithCloseTimeoutPolicy configures how Handler.Close behaves when async graceful shutdown reaches its flush timeout.

The default is CloseTimeoutAutoAbort. Use CloseTimeoutReturn to make Close return timeout errors without aborting or closing owned resources.

func WithGroup

func WithGroup(name string) Option

WithGroup nests subsequent attributes under the supplied group name.

func WithInternalLogger

func WithInternalLogger(logger *slog.Logger) Option

WithInternalLogger injects an internal logger used for diagnostics during handler setup and lifecycle operations.

func WithLevel

func WithLevel(level slog.Level) Option

WithLevel sets the minimum slog level accepted by the handler.

func WithLevelVar

func WithLevelVar(levelVar *slog.LevelVar) Option

WithLevelVar shares the provided slog.LevelVar with the handler, allowing external code to adjust log levels at runtime while keeping slogcp's internal state in sync. When supplied, slogcp initialises the LevelVar to the resolved minimum level (defaults, environment, then WithLevel) during handler construction.

func WithMiddleware

func WithMiddleware(mw Middleware) Option

WithMiddleware appends a middleware that can modify or short-circuit record handling.

func WithRedirectToFile

func WithRedirectToFile(path string) Option

WithRedirectToFile directs handler output to the file at path, creating it if necessary. The path is trimmed of surrounding whitespace and then passed verbatim to os.OpenFile in append mode; parent directories must already exist. When configuring the same behaviour via SLOGCP_TARGET use "file:<path>" with an OS-specific path string (for example, "file:/var/log/app.log" or "file:C:\\logs\\app.log").

func WithRedirectToStderr

func WithRedirectToStderr() Option

WithRedirectToStderr forces the handler to emit logs to stderr.

func WithRedirectToStdout

func WithRedirectToStdout() Option

WithRedirectToStdout forces the handler to emit logs to stdout.

func WithRedirectWriter

func WithRedirectWriter(writer io.Writer) Option

WithRedirectWriter uses writer for log output without taking ownership of its lifecycle. Any file paths configured on the writer itself are interpreted by that writer; slogcp does not parse "file:" targets when this option is used.

func WithReplaceAttr

func WithReplaceAttr(fn func([]string, slog.Attr) slog.Attr) Option

WithReplaceAttr installs a slog attribute replacer mirroring slog.HandlerOptions.ReplaceAttr.

func WithSeverityAliases

func WithSeverityAliases(enabled bool) Option

WithSeverityAliases configures whether the handler emits Cloud Logging severity aliases (for example, "I" for INFO) instead of the full severity names. Using the aliases trims roughly a nanosecond from JSON marshaling, and Cloud Logging still displays the canonical severity names after ingestion. On a detected GCP runtime the aliases remain enabled by default; otherwise they must be explicitly enabled through options or environment variables.

func WithSourceLocationEnabled

func WithSourceLocationEnabled(enabled bool) Option

WithSourceLocationEnabled toggles source location enrichment on emitted records when true.

func WithStackTraceEnabled

func WithStackTraceEnabled(enabled bool) Option

WithStackTraceEnabled toggles automatic stack trace capture for error logs when enabled.

func WithStackTraceLevel

func WithStackTraceLevel(level slog.Level) Option

WithStackTraceLevel captures stack traces for records at or above level. The handler defaults to slog.LevelError when this option is omitted.

func WithTime

func WithTime(enabled bool) Option

WithTime toggles emission of the top-level "time" field. By default slogcp omits timestamps on managed GCP runtimes such as Cloud Run or App Engine when writing to stdout/stderr, since Cloud Logging stamps entries automatically. File targets keep timestamps by default so rotated or shipped logs retain them. Enabling this option stops slogcp from suppressing `log/slog`'s default timestamp behavior.

func WithTraceDiagnostics

func WithTraceDiagnostics(mode TraceDiagnosticsMode) Option

WithTraceDiagnostics adjusts how slogcp reports trace correlation issues.

func WithTraceProjectID

func WithTraceProjectID(id string) Option

WithTraceProjectID overrides the Cloud Trace project identifier used to format logging.googleapis.com/trace URLs.

type RuntimeEnvironment

type RuntimeEnvironment int

RuntimeEnvironment describes the runtime platform detected for slogcp.

const (
	// RuntimeEnvUnknown indicates slogcp could not detect a known hosting environment.
	RuntimeEnvUnknown RuntimeEnvironment = iota
	// RuntimeEnvCloudRunService indicates execution on Cloud Run fully managed.
	RuntimeEnvCloudRunService
	// RuntimeEnvCloudRunJob indicates execution on Cloud Run jobs.
	RuntimeEnvCloudRunJob
	// RuntimeEnvCloudFunctions indicates execution on Cloud Functions.
	RuntimeEnvCloudFunctions
	// RuntimeEnvAppEngineStandard indicates execution on App Engine standard.
	RuntimeEnvAppEngineStandard
	// RuntimeEnvAppEngineFlexible indicates execution on App Engine flexible.
	RuntimeEnvAppEngineFlexible
	// RuntimeEnvKubernetes indicates execution on Kubernetes (including Google Kubernetes Engine).
	RuntimeEnvKubernetes
	// RuntimeEnvComputeEngine indicates execution on Compute Engine.
	RuntimeEnvComputeEngine
)

type RuntimeInfo

type RuntimeInfo struct {
	ProjectID      string
	Labels         map[string]string
	ServiceContext map[string]string
	Environment    RuntimeEnvironment
}

RuntimeInfo captures metadata about the current cloud environment.

func DetectRuntimeInfo

func DetectRuntimeInfo() RuntimeInfo

DetectRuntimeInfo inspects well-known environment variables to infer platform-specific labels and service context. Results are cached for reuse.

type SwitchableWriter

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

SwitchableWriter is an io.Writer that allows its underlying writer to be changed atomically. It is used internally when slogcp is configured to log to a specific file path (for example, via WithRedirectToFile) so that Handler.ReopenLogFile can update the output destination without rebuilding the entire handler chain.

SwitchableWriter also implements io.Closer. Its Close method attempts to close the underlying writer if it implements io.Closer and then sets the internal writer to io.Discard to prevent further writes. The actual closing of file resources managed by slogcp is handled by the Handler itself.

func NewSwitchableWriter

func NewSwitchableWriter(initialWriter io.Writer) *SwitchableWriter

NewSwitchableWriter creates a new SwitchableWriter, initializing it with the provided initialWriter. If initialWriter is nil, the SwitchableWriter defaults to using io.Discard.

func (*SwitchableWriter) Close

func (sw *SwitchableWriter) Close() error

Close attempts to close the current underlying writer if it implements io.Closer. After attempting to close the writer (or if it is not closable), the SwitchableWriter's internal writer is set to io.Discard to prevent further writes. This method is safe for concurrent use and idempotent.

func (*SwitchableWriter) GetCurrentWriter

func (sw *SwitchableWriter) GetCurrentWriter() io.Writer

GetCurrentWriter returns the current underlying io.Writer that this SwitchableWriter is directing writes to. This method is safe for concurrent use but callers should avoid holding on to the returned writer across calls to SetWriter.

func (*SwitchableWriter) SetWriter

func (sw *SwitchableWriter) SetWriter(newWriter io.Writer)

SetWriter atomically updates the underlying writer for this SwitchableWriter. The previously configured writer is not closed by this method; managing its lifecycle is the caller's responsibility. If newWriter is nil, the SwitchableWriter will subsequently direct writes to io.Discard.

func (*SwitchableWriter) Write

func (sw *SwitchableWriter) Write(p []byte) (n int, err error)

Write directs the given bytes to the current underlying writer. It is safe for concurrent use. If the SwitchableWriter has been closed or its writer set to nil, Write may return an error (such as os.ErrClosed).

type TraceDiagnosticsMode

type TraceDiagnosticsMode int

TraceDiagnosticsMode controls how slogcp surfaces trace correlation issues.

const (
	// TraceDiagnosticsOff disables trace correlation diagnostics.
	TraceDiagnosticsOff TraceDiagnosticsMode = iota
	// TraceDiagnosticsWarnOnce emits a single warning when trace correlation cannot be established.
	TraceDiagnosticsWarnOnce
	// TraceDiagnosticsStrict fails handler construction when trace correlation cannot be established.
	TraceDiagnosticsStrict
)

Directories

Path Synopsis
Package slogcpasync adds an opt-in async wrapper around slogcp's synchronous handler.
Package slogcpasync adds an opt-in async wrapper around slogcp's synchronous handler.
Package slogcpgrpc provides gRPC interceptors that integrate slogcp with Google Cloud Logging and OpenTelemetry.
Package slogcpgrpc provides gRPC interceptors that integrate slogcp with Google Cloud Logging and OpenTelemetry.
Package slogcphttp provides net/http integration for slogcp.
Package slogcphttp provides net/http integration for slogcp.
Package slogcppubsub provides Pub/Sub helpers for slogcp.
Package slogcppubsub provides Pub/Sub helpers for slogcp.

Jump to

Keyboard shortcuts

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