add feature

This commit is contained in:
a 2022-10-12 18:37:23 -05:00
parent 3ec1a83686
commit 1600f7342f
3 changed files with 66 additions and 65 deletions

1
go.mod
View File

@ -5,7 +5,6 @@ go 1.15
require ( require (
github.com/coreos/go-systemd/v22 v22.4.0 github.com/coreos/go-systemd/v22 v22.4.0
github.com/mattn/go-colorable v0.1.13 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/pkg/errors v0.9.1
github.com/rs/xid v1.4.0 github.com/rs/xid v1.4.0
golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41 // indirect golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41 // indirect

13
go.sum
View File

@ -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 h1:y9YHcjnjynCd/DVbg5j9L/33jQM3MxJlbj/zWskzfGU=
github.com/coreos/go-systemd/v22 v22.4.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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/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 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= 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 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 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 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY=
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= 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-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 h1:ohgcoMbSofXygzo6AD2I1kz3BFmW1QArPYTtwEM3UXc=
golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

117
log.go
View File

@ -2,103 +2,103 @@
// //
// A global Logger can be use for simple logging: // 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") // log.Info().Msg("hello world")
// // Output: {"time":1494567715,"level":"info","message":"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". // NOTE: To import the global logger, import the "log" subpackage "git.tuxpa.in/a/zlog/log".
// //
// Fields can be added to log messages: // Fields can be added to log messages:
// //
// log.Info().Str("foo", "bar").Msg("hello world") // log.Info().Str("foo", "bar").Msg("hello world")
// // Output: {"time":1494567715,"level":"info","message":"hello world","foo":"bar"} // // Output: {"time":1494567715,"level":"info","message":"hello world","foo":"bar"}
// //
// Create logger instance to manage different outputs: // Create logger instance to manage different outputs:
// //
// logger := zlog.New(os.Stderr).With().Timestamp().Logger() // logger := zlog.New(os.Stderr).With().Timestamp().Logger()
// logger.Info(). // logger.Info().
// Str("foo", "bar"). // Str("foo", "bar").
// Msg("hello world") // Msg("hello world")
// // Output: {"time":1494567715,"level":"info","message":"hello world","foo":"bar"} // // Output: {"time":1494567715,"level":"info","message":"hello world","foo":"bar"}
// //
// Sub-loggers let you chain loggers with additional context: // Sub-loggers let you chain loggers with additional context:
// //
// sublogger := log.With().Str("component": "foo").Logger() // sublogger := log.With().Str("component": "foo").Logger()
// sublogger.Info().Msg("hello world") // sublogger.Info().Msg("hello world")
// // Output: {"time":1494567715,"level":"info","message":"hello world","component":"foo"} // // Output: {"time":1494567715,"level":"info","message":"hello world","component":"foo"}
// //
// Level logging // Level logging
// //
// zlog.SetGlobalLevel(zlog.InfoLevel) // zlog.SetGlobalLevel(zlog.InfoLevel)
// //
// log.Debug().Msg("filtered out message") // log.Debug().Msg("filtered out message")
// log.Info().Msg("routed message") // log.Info().Msg("routed message")
// //
// if e := log.Debug(); e.Enabled() { // if e := log.Debug(); e.Enabled() {
// // Compute log output only if enabled. // // Compute log output only if enabled.
// value := compute() // value := compute()
// e.Str("foo": value).Msg("some debug message") // e.Str("foo": value).Msg("some debug message")
// } // }
// // Output: {"level":"info","time":1494567715,"routed message"} // // Output: {"level":"info","time":1494567715,"routed message"}
// //
// Customize automatic field names: // Customize automatic field names:
// //
// log.TimestampFieldName = "t" // log.TimestampFieldName = "t"
// log.LevelFieldName = "p" // log.LevelFieldName = "p"
// log.MessageFieldName = "m" // log.MessageFieldName = "m"
// //
// log.Info().Msg("hello world") // log.Info().Msg("hello world")
// // Output: {"t":1494567715,"p":"info","m":"hello world"} // // Output: {"t":1494567715,"p":"info","m":"hello world"}
// //
// Log with no level and message: // Log with no level and message:
// //
// log.Log().Str("foo","bar").Msg("") // log.Log().Str("foo","bar").Msg("")
// // Output: {"time":1494567715,"foo":"bar"} // // Output: {"time":1494567715,"foo":"bar"}
// //
// Add contextual fields to global Logger: // Add contextual fields to global Logger:
// //
// log.Logger = log.With().Str("foo", "bar").Logger() // log.Logger = log.With().Str("foo", "bar").Logger()
// //
// Sample logs: // Sample logs:
// //
// sampled := log.Sample(&zlog.BasicSampler{N: 10}) // sampled := log.Sample(&zlog.BasicSampler{N: 10})
// sampled.Info().Msg("will be logged every 10 messages") // sampled.Info().Msg("will be logged every 10 messages")
// //
// Log with contextual hooks: // Log with contextual hooks:
// //
// // Create the hook: // // Create the hook:
// type SeverityHook struct{} // type SeverityHook struct{}
// //
// func (h SeverityHook) Run(e *zlog.Event, level zlog.Level, msg string) { // func (h SeverityHook) Run(e *zlog.Event, level zlog.Level, msg string) {
// if level != zlog.NoLevel { // if level != zlog.NoLevel {
// e.Str("severity", level.String()) // e.Str("severity", level.String())
// } // }
// } // }
// //
// // And use it: // // And use it:
// var h SeverityHook // var h SeverityHook
// log := zlog.New(os.Stdout).Hook(h) // log := zlog.New(os.Stdout).Hook(h)
// log.Warn().Msg("") // log.Warn().Msg("")
// // Output: {"level":"warn","severity":"warn"} // // Output: {"level":"warn","severity":"warn"}
// //
// // # Caveats
// Caveats
// //
// There is no fields deduplication out-of-the-box. // There is no fields deduplication out-of-the-box.
// Using the same key multiple times creates new key in final JSON each time. // Using the same key multiple times creates new key in final JSON each time.
// //
// logger := zlog.New(os.Stderr).With().Timestamp().Logger() // logger := zlog.New(os.Stderr).With().Timestamp().Logger()
// logger.Info(). // logger.Info().
// Timestamp(). // Timestamp().
// Msg("dup") // Msg("dup")
// // Output: {"level":"info","time":1494567715,"time":1494567715,"message":"dup"} // // Output: {"level":"info","time":1494567715,"time":1494567715,"message":"dup"}
// //
// In this case, many consumers will take the last value, // In this case, many consumers will take the last value,
// but this is not guaranteed; check yours if in doubt. // but this is not guaranteed; check yours if in doubt.
package zlog package zlog
import ( import (
"errors"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
@ -189,6 +189,21 @@ func ParseLevel(levelStr string) (Level, error) {
return Level(i), nil 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 // A Logger represents an active logging object that generates lines
// of JSON output to an io.Writer. Each logging operation makes a single // 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 // call to the Writer's Write method. There is no guarantee on access