labkit

module
v2.0.0-...-c02def0 Latest Latest
Warning

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

Go to latest
Published: Apr 14, 2026 License: MIT

README

labkit/v2

LabKit v2 is GitLab's standard platform library for Go services. It provides production-ready building blocks for observability, HTTP serving, database connectivity, and secret management — all wired into a common lifecycle so teams can focus on business logic rather than infrastructure boilerplate.

Packages at a glance

Package What it does
app Application lifecycle: logger, tracer, metrics registry, and pluggable components with ordered start/shutdown
log Structured logger (log/slog) with GitLab field conventions and context enrichment
trace OpenTelemetry tracer with W3C propagation and GitLab-standard sampling
metrics Isolated Prometheus registry with GitLab-standard naming, labels, and bucket sets
httpserver HTTP server component with built-in tracing, logging, and health endpoints
httpclient Instrumented HTTP client with retries and W3C trace propagation
postgres PostgreSQL client component with query tracing via pgx
secret Provider-agnostic secret retrieval with automatic value redaction
fields Canonical log field name constants shared across GitLab services
testing/apptest In-memory app fixture for unit tests
testing/logtest In-memory log recorder for asserting log output
testing/tracetest In-memory span recorder for asserting trace output
testing/metricstest Isolated metrics registry and gather helper for asserting metric values

Typical service wiring

The app package is the entry point. All other components plug into it:

func main() {
    ctx := context.Background()

    a, err := app.New(ctx)
    if err != nil {
        log.Fatal(err)
    }

    // Postgres client — Start opens the pool and pings, Shutdown drains it.
    db, err := postgres.NewWithConfig(&postgres.Config{
        DSN:    os.Getenv("DATABASE_URL"),
        Tracer: a.Tracer(),
    })
    if err != nil {
        log.Fatal(err)
    }

    // HTTP server — built-in tracing and access logging on every route.
    srv := httpserver.NewWithConfig(&httpserver.Config{
        Addr:   ":8080",
        Logger: a.Logger(),
        Tracer: a.Tracer(),
    })
    srv.Router().Get("/api/projects/{id}", handleGetProject(db))
    srv.Router().Get("/-/metrics", a.Metrics().Handler())
    srv.AddReadinessCheck("database", func(ctx context.Context) error {
        return db.DB().PingContext(ctx)
    })

    // Register in dependency order: db starts first, shuts down last.
    a.Register(db)
    a.Register(srv)

    // Run starts all components, waits for SIGTERM/SIGINT, then shuts down.
    if err := a.Run(ctx); err != nil {
        log.Fatal(err)
    }
}

How the packages relate

graph TD
    App["<b>app.App</b><br/>lifecycle orchestrator"]

    App -->|creates| Log["<b>log</b><br/>slog structured logger"]
    App -->|creates| Trace["<b>trace</b><br/>OpenTelemetry tracer"]
    App -->|creates| Metrics["<b>metrics</b><br/>Prometheus registry"]

    Log -->|injected into| Components
    Trace -->|injected into| Components
    Metrics -->|injected into| Components

    subgraph Components["app.Component implementations"]
        HTTP["<b>httpserver.Server</b><br/>HTTP · routing · health checks"]
        PG["<b>postgres.Client</b><br/>connection pool · query tracing"]
        Custom["your own components"]
    end

    App -->|no lifecycle| Secret["<b>secret.Client</b><br/>provider-agnostic secret retrieval"]
    App -->|no lifecycle| HTTPClient["<b>httpclient.Client</b><br/>instrumented outbound HTTP"]
    App -->|no lifecycle| Fields["<b>fields</b><br/>canonical log field name constants"]

    subgraph Testing["testing/ (in-memory replacements)"]
        AppTest["apptest — App fixture"]
        LogTest["logtest — log recorder"]
        TraceTest["tracetest — span recorder"]
        MetricsTest["metricstest — metrics gatherer"]
    end

secret.Client and httpclient.Client are not app.Component implementations — they have no start/shutdown lifecycle. Construct them once and inject them into the handlers or components that need them.

Observability

app.New initialises the logger and tracer from environment variables so services work out of the box with zero configuration:

Variable Controls Default
GITLAB_LOG_LEVEL Minimum log level (DEBUG, INFO, WARN, ERROR) INFO
GITLAB_LOG_FORMAT Log format (json, text) json
GITLAB_TRACING OTLP endpoint, service name, sampling disabled

Pass explicit configuration via app.NewWithConfig to override any of these.

Testing

The testing/ sub-packages provide in-memory replacements for every I/O dependency so unit tests need no live infrastructure:

func TestMyHandler(t *testing.T) {
    a, logRec, spanRec := apptest.New()

    srv := httpserver.NewWithConfig(&httpserver.Config{
        Logger: a.Logger(),
        Tracer: a.Tracer(),
    })
    srv.Router().Get("/api/projects/{id}", handleGetProject(mockDB))

    req := httptest.NewRequest(http.MethodGet, "/api/projects/42", nil)
    rec := httptest.NewRecorder()
    srv.ServeHTTP(rec, req)

    assert.Equal(t, http.StatusOK, rec.Code)

    // Assert structured log output.
    records := logRec.Records()
    require.Len(t, records, 1)

    // Assert trace spans.
    spans := spanRec.Ended()
    require.Len(t, spans, 1)
    assert.Equal(t, "GET /api/projects/{id}", spans[0].Name)
}

Module path

gitlab.com/gitlab-org/labkit/v2

v2 is a separate Go module from the root gitlab.com/gitlab-org/labkit (v1). The two modules are independent: v2 uses log/slog and OpenTelemetry; v1 uses Logrus and OpenTracing. Services should adopt v2 for all new development.

Directories

Path Synopsis
Package app provides a ready-to-use application context for new GitLab Go services, bundling a structured logger, an OpenTelemetry tracer, and a Prometheus metrics registry with a pluggable component lifecycle.
Package app provides a ready-to-use application context for new GitLab Go services, bundling a structured logger, an OpenTelemetry tracer, and a Prometheus metrics registry with a pluggable component lifecycle.
cmd
validate-log-fields command
Command validate-log-fields scans a Go project for deprecated logging field names and reports offenses.
Command validate-log-fields scans a Go project for deprecated logging field names and reports offenses.
Package config provides protobuf-first configuration management for LabKit v2.
Package config provides protobuf-first configuration management for LabKit v2.
Package correlation provides correlation ID propagation via context.
Package correlation provides correlation ID propagation via context.
events
snowplow
Package snowplow provides a lightweight Snowplow event tracking implementation for Go applications.
Package snowplow provides a lightweight Snowplow event tracking implementation for Go applications.
snowplow/metrics
Package metrics is a module providing observability through Prometheus Metrics for the snowplow events mechanism.
Package metrics is a module providing observability through Prometheus Metrics for the snowplow events mechanism.
snowplow/oidc
Package oidc provides an implementation of the snowplow.TokenSource interface, allowing snowplow.Emitter to authenticate with the collector endpoint using the OIDC flow.
Package oidc provides an implementation of the snowplow.TokenSource interface, allowing snowplow.Emitter to authenticate with the collector endpoint using the OIDC flow.
Package featureflag provides a tracing-aware decorator around the [OpenFeature] Go SDK configured to use [Flipt] as its provider.
Package featureflag provides a tracing-aware decorator around the [OpenFeature] Go SDK configured to use [Flipt] as its provider.
Package fields defines standard log field names used across all GitLab services.
Package fields defines standard log field names used across all GitLab services.
Package httpclient provides an HTTP client that transparently adds distributed tracing and structured logging to every outgoing request.
Package httpclient provides an HTTP client that transparently adds distributed tracing and structured logging to every outgoing request.
Package httpserver provides an HTTP server that implements app.Component, allowing it to be plugged into an app.App and have its lifecycle managed alongside the logger and tracer.
Package httpserver provides an HTTP server that implements app.Component, allowing it to be plugged into an app.App and have its lifecycle managed alongside the logger and tracer.
Package log provides a pre-configured slog.Logger that follows GitLab logging conventions: JSON output to stderr, UTC timestamps in RFC 3339 format, and context-propagated fields.
Package log provides a pre-configured slog.Logger that follows GitLab logging conventions: JSON output to stderr, UTC timestamps in RFC 3339 format, and context-propagated fields.
Package metrics provides an isolated Prometheus registry that integrates with the LabKit v2 component lifecycle.
Package metrics provides an isolated Prometheus registry that integrates with the LabKit v2 component lifecycle.
Package postgres provides an instrumented PostgreSQL client backed by a pgxpool.Pool that implements app.Component.
Package postgres provides an instrumented PostgreSQL client backed by a pgxpool.Pool that implements app.Component.
Package secret provides a simple, provider-agnostic interface for retrieving secrets within GitLab services.
Package secret provides a simple, provider-agnostic interface for retrieving secrets within GitLab services.
testing
apptest
Package apptest provides test helpers for code that depends on the app package.
Package apptest provides test helpers for code that depends on the app package.
metricstest
Package metricstest provides test helpers for asserting that components correctly register and update Prometheus metrics.
Package metricstest provides test helpers for asserting that components correctly register and update Prometheus metrics.
secrettest
Package secrettest provides test helpers for code that depends on the v2/secret package.
Package secrettest provides test helpers for code that depends on the v2/secret package.
tracetest
Package tracetest provides test helpers for code that depends on the v2/trace package.
Package tracetest provides test helpers for code that depends on the v2/trace package.
Package trace provides a thin, ergonomic wrapper around OpenTelemetry distributed tracing for GitLab Go services.
Package trace provides a thin, ergonomic wrapper around OpenTelemetry distributed tracing for GitLab Go services.

Jump to

Keyboard shortcuts

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