phuslu/log Transport
Wraps an existing *phuslu/log.Logger. Metadata nests under a single configurable key.
go get go.loglayer.dev/transports/phuslu/v3
go get github.com/phuslu/logBasic Usage
import (
"os"
plog "github.com/phuslu/log"
"go.loglayer.dev/v3"
llphuslu "go.loglayer.dev/transports/phuslu/v3"
)
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
type Config struct {
transport.BaseConfig
Logger *phuslu/log.Logger // wrap an existing logger
Writer io.Writer // used only when Logger is nil
}Fatal Behavior
phuslu always exits on Fatal
phuslu calls os.Exit(255) 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
The core nests the entry's metadata under MetadataFieldName (default "metadata"; set Config.FlattenMetadata: true to restore per-transport v2 placement). This transport honors that key.
Metadata nests under the metadata key
log.WithMetadata(loglayer.Metadata{"requestId": "xyz", "n": 42}).Info("served")
// {"time":"...","level":"info","message":"served","metadata":{"requestId":"xyz","n":42}}
log.WithMetadata(User{ID: 7, Name: "Alice"}).Info("user")
// {"time":"...","level":"info","metadata":{"id":7,"name":"Alice"},"message":"user"}The nested value is written with Entry.Any(k, v). With Config.FlattenMetadata: true, each map entry instead becomes its own Entry.Any(k, v) call at the root.
Or globally via the core's MetadataFieldName (which also nests map metadata under the same key):
loglayer.New(loglayer.Config{
Transport: llphuslu.New(llphuslu.Config{Logger: p}),
MetadataFieldName: "payload",
})Reaching the Underlying Logger
GetLoggerInstance returns the wrapped *phuslu/log.Logger:
p := log.GetLoggerInstance("phuslu").(*plog.Logger)
p.SetLevel(plog.DebugLevel)("phuslu" is whatever you set as BaseConfig.ID; defaults to an auto-generated ID when unset.)
Level Mapping
| LogLayer Level | phuslu Level |
|---|---|
LogLevelTrace | TraceLevel |
LogLevelDebug | DebugLevel |
LogLevelInfo | InfoLevel |
LogLevelWarn | WarnLevel |
LogLevelError | ErrorLevel |
LogLevelFatal | FatalLevel |
LogLevelPanic | PanicLevel |
