Skip to content

Blank Transport ​

Go ReferenceVersionSourceChangelog

The blank transport delegates SendToLogger to a function you supply inline. Use it for:

  • Prototyping a new transport without creating a full package.
  • One-off integrations (forward to a metrics system, push to a queue, post to an HTTP endpoint) that don't justify their own transport package.
  • Tests that want to inspect raw TransportParams without setting up the testing transport.

If you find yourself repeating the same blank.Config across the codebase, promote it to its own transport package using the Creating Transports template.

sh
go get go.loglayer.dev/transports/blank/v3

Basic Usage ​

go
import (
    "go.loglayer.dev/v3"
    "go.loglayer.dev/v3/transport"
    "go.loglayer.dev/transports/blank/v3"
)

log := loglayer.New(loglayer.Config{
    Transport: blank.New(blank.Config{
        BaseConfig: transport.BaseConfig{ID: "metrics"},
        ShipToLogger: func(p loglayer.TransportParams) {
            if p.LogLevel >= loglayer.LogLevelError {
                metricsClient.Increment("app.errors", 1)
            }
        },
    }),
})

log.Error("payment failed")

Config ​

go
type Config struct {
    transport.BaseConfig

    // ShipToLogger is invoked for every entry that passes the level filter.
    // If nil, entries are silently discarded.
    ShipToLogger func(params loglayer.TransportParams)
}

Behavior ​

  • The transport's BaseConfig.Level filter still applies. Set Level: loglayer.LogLevelError to receive only error+ entries.
  • If ShipToLogger is nil, the transport silently drops everything that passes the filter. This makes a no-op blank transport useful as a placeholder during development.
  • GetLoggerInstance returns nil; there is no underlying library.
  • The wrapper itself is safe under concurrent emission. If your ShipToLogger mutates shared state, you are responsible for synchronizing it.

Patterns ​

Forward to multiple sinks ​

Pair with multi-transport fan-out so the blank transport sees every entry alongside your real transports:

go
loglayer.New(loglayer.Config{
    Transports: []loglayer.Transport{
        structured.New(structured.Config{ /* JSON to stdout */ }),
        blank.New(blank.Config{
            BaseConfig: transport.BaseConfig{ID: "audit"},
            ShipToLogger: func(p loglayer.TransportParams) {
                if p.LogLevel >= loglayer.LogLevelWarn {
                    auditChan <- formatAudit(p)
                }
            },
        }),
    },
})

Inspect entries in a test ​

When you don't need the typed LogLine capture of the testing transport, this is shorter:

go
var captured []loglayer.TransportParams
log := loglayer.New(loglayer.Config{
    Transport: blank.New(blank.Config{
        BaseConfig: transport.BaseConfig{ID: "spy"},
        ShipToLogger: func(p loglayer.TransportParams) {
            captured = append(captured, p)
        },
    }),
    DisableFatalExit: true,
})

When to Promote ​

Once you've used the same blank.Config in two places, it's time to write a real transport. The Creating Transports page shows the minimal template.

Fatal Behavior ​

This transport writes fatal entries normally; whether the process actually exits is the core's decision via Config.DisableFatalExit (default: exit). See Fatal Exits the Process.