Skip to content

phuslu/log Transport

Go ReferenceVersionSourceChangelog

Wraps an existing *phuslu/log.Logger. Map metadata flattens to fields via Entry.Any(k, v); struct metadata lands under a configurable key.

sh
go get go.loglayer.dev/transports/phuslu

Basic Usage

go
import (
    "os"

    plog "github.com/phuslu/log"

    "go.loglayer.dev"
    llphuslu "go.loglayer.dev/transports/phuslu"
)

p := &plog.Logger{
    Level:  plog.InfoLevel,
    Writer: &plog.IOWriter{Writer: os.Stderr},
}

log := loglayer.New(loglayer.Config{
    Transport: llphuslu.New(llphuslu.Config{Logger: p}),
})

log.Info("hello")
// {"time":"...","level":"info","message":"hello"}

If you don't pass a Logger, the transport constructs one writing to Writer (default os.Stderr).

Config

go
type Config struct {
    transport.BaseConfig

    Logger            *phuslu/log.Logger // wrap an existing logger
    Writer            io.Writer          // used only when Logger is nil
    MetadataFieldName string             // key for non-map metadata; default "metadata"
}

Fatal Behavior

phuslu always exits on Fatal

phuslu calls os.Exit(1) from every fatal-level dispatch path, including Logger.WithLevel(FatalLevel).Msg(...). This wrapper cannot suppress that behavior. A log.Fatal(...) through the phuslu transport WILL terminate the process even when Config.DisableFatalExit is set to true.

If you need fatal paths to not exit (tests, library code, integration scenarios), use a different transport for those scenarios. The structured, zerolog, and zap transports all honor DisableFatalExit.

For non-fatal levels, the wrapper dispatches via Logger.WithLevel(level).Msg(...), preserving phuslu's full pipeline (formatters, hooks, async writers).

Metadata Handling

Map metadata → individual fields

go
log.WithMetadata(loglayer.Metadata{"requestId": "xyz", "n": 42}).Info("served")
// {"time":"...","level":"info","message":"served","requestId":"xyz","n":42}

Each map entry becomes an Entry.Any(k, v) call.

Struct metadata → nested under MetadataFieldName

go
type User struct {
    ID   int    `json:"id"`
    Name string `json:"name"`
}

log.WithMetadata(User{ID: 7, Name: "Alice"}).Info("user")
// {"time":"...","level":"info","message":"user","metadata":{"id":7,"name":"Alice"}}

To use a different key per call, wrap in a map:

go
log.WithMetadata(loglayer.Metadata{"user": User{ID: 7, Name: "Alice"}}).Info("user")

Or globally via MetadataFieldName:

go
llphuslu.New(llphuslu.Config{
    Logger:            p,
    MetadataFieldName: "payload",
})

Reaching the Underlying Logger

GetLoggerInstance returns the wrapped *phuslu/log.Logger:

go
p := log.GetLoggerInstance("phuslu").(*plog.Logger)
p.SetLevel(plog.DebugLevel)

Level Mapping

LogLayer Levelphuslu Level
LogLevelDebugDebugLevel
LogLevelInfoInfoLevel
LogLevelWarnWarnLevel
LogLevelErrorErrorLevel
LogLevelFatalFatalLevel