From 1600f7342fcb4133493672b67b5a971387c709da Mon Sep 17 00:00:00 2001 From: a Date: Wed, 12 Oct 2022 18:37:23 -0500 Subject: [PATCH] add feature --- go.mod | 1 - go.sum | 13 ------- log.go | 117 ++++++++++++++++++++++++++++++++------------------------- 3 files changed, 66 insertions(+), 65 deletions(-) diff --git a/go.mod b/go.mod index 1f42e4b..1c42667 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,6 @@ go 1.15 require ( github.com/coreos/go-systemd/v22 v22.4.0 github.com/mattn/go-colorable v0.1.13 - github.com/mattn/go-isatty v0.0.16 // indirect github.com/pkg/errors v0.9.1 github.com/rs/xid v1.4.0 golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41 // indirect diff --git a/go.sum b/go.sum index 2ab4d1d..8cd353d 100644 --- a/go.sum +++ b/go.sum @@ -1,27 +1,14 @@ -github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534 h1:rtAn27wIbmOGUs7RIbVgPEjb31ehTVniDwPGXyMxm5U= -github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.4.0 h1:y9YHcjnjynCd/DVbg5j9L/33jQM3MxJlbj/zWskzfGU= github.com/coreos/go-systemd/v22 v22.4.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/rs/xid v1.3.0 h1:6NjYksEUlhurdVehpc7S7dk6DAmcKv8V9gG0FsVN2U4= -github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 h1:foEbQz/B0Oz6YIqu/69kfXPYeFQAuuMYFkjaqXzl5Wo= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41 h1:ohgcoMbSofXygzo6AD2I1kz3BFmW1QArPYTtwEM3UXc= golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/log.go b/log.go index fa1c75d..5830e9e 100644 --- a/log.go +++ b/log.go @@ -2,103 +2,103 @@ // // A global Logger can be use for simple logging: // -// import "git.tuxpa.in/a/zlog/log" +// import "git.tuxpa.in/a/zlog/log" // -// log.Info().Msg("hello world") -// // Output: {"time":1494567715,"level":"info","message":"hello world"} +// log.Info().Msg("hello world") +// // Output: {"time":1494567715,"level":"info","message":"hello world"} // // NOTE: To import the global logger, import the "log" subpackage "git.tuxpa.in/a/zlog/log". // // Fields can be added to log messages: // -// log.Info().Str("foo", "bar").Msg("hello world") -// // Output: {"time":1494567715,"level":"info","message":"hello world","foo":"bar"} +// log.Info().Str("foo", "bar").Msg("hello world") +// // Output: {"time":1494567715,"level":"info","message":"hello world","foo":"bar"} // // Create logger instance to manage different outputs: // -// logger := zlog.New(os.Stderr).With().Timestamp().Logger() -// logger.Info(). -// Str("foo", "bar"). -// Msg("hello world") -// // Output: {"time":1494567715,"level":"info","message":"hello world","foo":"bar"} +// logger := zlog.New(os.Stderr).With().Timestamp().Logger() +// logger.Info(). +// Str("foo", "bar"). +// Msg("hello world") +// // Output: {"time":1494567715,"level":"info","message":"hello world","foo":"bar"} // // Sub-loggers let you chain loggers with additional context: // -// sublogger := log.With().Str("component": "foo").Logger() -// sublogger.Info().Msg("hello world") -// // Output: {"time":1494567715,"level":"info","message":"hello world","component":"foo"} +// sublogger := log.With().Str("component": "foo").Logger() +// sublogger.Info().Msg("hello world") +// // Output: {"time":1494567715,"level":"info","message":"hello world","component":"foo"} // // Level logging // -// zlog.SetGlobalLevel(zlog.InfoLevel) +// zlog.SetGlobalLevel(zlog.InfoLevel) // -// log.Debug().Msg("filtered out message") -// log.Info().Msg("routed message") +// log.Debug().Msg("filtered out message") +// log.Info().Msg("routed message") // -// if e := log.Debug(); e.Enabled() { -// // Compute log output only if enabled. -// value := compute() -// e.Str("foo": value).Msg("some debug message") -// } -// // Output: {"level":"info","time":1494567715,"routed message"} +// if e := log.Debug(); e.Enabled() { +// // Compute log output only if enabled. +// value := compute() +// e.Str("foo": value).Msg("some debug message") +// } +// // Output: {"level":"info","time":1494567715,"routed message"} // // Customize automatic field names: // -// log.TimestampFieldName = "t" -// log.LevelFieldName = "p" -// log.MessageFieldName = "m" +// log.TimestampFieldName = "t" +// log.LevelFieldName = "p" +// log.MessageFieldName = "m" // -// log.Info().Msg("hello world") -// // Output: {"t":1494567715,"p":"info","m":"hello world"} +// log.Info().Msg("hello world") +// // Output: {"t":1494567715,"p":"info","m":"hello world"} // // Log with no level and message: // -// log.Log().Str("foo","bar").Msg("") -// // Output: {"time":1494567715,"foo":"bar"} +// log.Log().Str("foo","bar").Msg("") +// // Output: {"time":1494567715,"foo":"bar"} // // Add contextual fields to global Logger: // -// log.Logger = log.With().Str("foo", "bar").Logger() +// log.Logger = log.With().Str("foo", "bar").Logger() // // Sample logs: // -// sampled := log.Sample(&zlog.BasicSampler{N: 10}) -// sampled.Info().Msg("will be logged every 10 messages") +// sampled := log.Sample(&zlog.BasicSampler{N: 10}) +// sampled.Info().Msg("will be logged every 10 messages") // // Log with contextual hooks: // -// // Create the hook: -// type SeverityHook struct{} +// // Create the hook: +// type SeverityHook struct{} // -// func (h SeverityHook) Run(e *zlog.Event, level zlog.Level, msg string) { -// if level != zlog.NoLevel { -// e.Str("severity", level.String()) -// } -// } +// func (h SeverityHook) Run(e *zlog.Event, level zlog.Level, msg string) { +// if level != zlog.NoLevel { +// e.Str("severity", level.String()) +// } +// } // -// // And use it: -// var h SeverityHook -// log := zlog.New(os.Stdout).Hook(h) -// log.Warn().Msg("") -// // Output: {"level":"warn","severity":"warn"} +// // And use it: +// var h SeverityHook +// log := zlog.New(os.Stdout).Hook(h) +// log.Warn().Msg("") +// // Output: {"level":"warn","severity":"warn"} // -// -// Caveats +// # Caveats // // There is no fields deduplication out-of-the-box. // Using the same key multiple times creates new key in final JSON each time. // -// logger := zlog.New(os.Stderr).With().Timestamp().Logger() -// logger.Info(). -// Timestamp(). -// Msg("dup") -// // Output: {"level":"info","time":1494567715,"time":1494567715,"message":"dup"} +// logger := zlog.New(os.Stderr).With().Timestamp().Logger() +// logger.Info(). +// Timestamp(). +// Msg("dup") +// // Output: {"level":"info","time":1494567715,"time":1494567715,"message":"dup"} // // In this case, many consumers will take the last value, // but this is not guaranteed; check yours if in doubt. package zlog import ( + "errors" "fmt" "io" "io/ioutil" @@ -189,6 +189,21 @@ func ParseLevel(levelStr string) (Level, error) { return Level(i), nil } +// UnmarshalText implements encoding.TextUnmarshaler to allow for easy reading from toml/yaml/json formats +func (l *Level) UnmarshalText(text []byte) error { + if l == nil { + return errors.New("can't unmarshal a nil *Level") + } + var err error + *l, err = ParseLevel(string(text)) + return err +} + +// MarshalText implements encoding.TextMarshaler to allow for easy writing into toml/yaml/json formats +func (l Level) MarshalText() ([]byte, error) { + return []byte(LevelFieldMarshalFunc(l)), nil +} + // A Logger represents an active logging object that generates lines // of JSON output to an io.Writer. Each logging operation makes a single // call to the Writer's Write method. There is no guarantee on access