Make log level configurable, remove custom log message handler
This commit is contained in:
parent
032bdb9e43
commit
b31c2fd9d4
@ -7,8 +7,6 @@ import (
|
|||||||
|
|
||||||
"isle/daemon"
|
"isle/daemon"
|
||||||
"isle/daemon/daecommon"
|
"isle/daemon/daecommon"
|
||||||
|
|
||||||
"dev.mediocregopher.com/mediocre-go-lib.git/mlog"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO it would be good to have an `isle daemon config-check` kind of command,
|
// TODO it would be good to have an `isle daemon config-check` kind of command,
|
||||||
@ -30,11 +28,6 @@ var subCmdDaemon = subCmd{
|
|||||||
"Write the default configuration file to stdout and exit.",
|
"Write the default configuration file to stdout and exit.",
|
||||||
)
|
)
|
||||||
|
|
||||||
logLevelStr := ctx.flags.StringP(
|
|
||||||
"log-level", "l", "info",
|
|
||||||
`Maximum log level which should be output. Values can be "debug", "info", "warn", "error", "fatal". Does not apply to sub-processes`,
|
|
||||||
)
|
|
||||||
|
|
||||||
ctx, err := ctx.withParsedFlags()
|
ctx, err := ctx.withParsedFlags()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("parsing flags: %w", err)
|
return fmt.Errorf("parsing flags: %w", err)
|
||||||
@ -44,12 +37,8 @@ var subCmdDaemon = subCmd{
|
|||||||
return daecommon.CopyDefaultConfig(os.Stdout)
|
return daecommon.CopyDefaultConfig(os.Stdout)
|
||||||
}
|
}
|
||||||
|
|
||||||
logLevel := mlog.LevelFromString(*logLevelStr)
|
logger := ctx.logger()
|
||||||
if logLevel == nil {
|
defer logger.Close()
|
||||||
return fmt.Errorf("couldn't parse log level %q", *logLevelStr)
|
|
||||||
}
|
|
||||||
|
|
||||||
logger := ctx.logger.WithMaxLevel(logLevel.Int())
|
|
||||||
|
|
||||||
// TODO check that daemon is either running as root, or that the
|
// TODO check that daemon is either running as root, or that the
|
||||||
// required linux capabilities are set.
|
// required linux capabilities are set.
|
||||||
|
@ -2,9 +2,13 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding"
|
"encoding"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"isle/nebula"
|
"isle/nebula"
|
||||||
|
"isle/toolkit"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
|
||||||
|
"dev.mediocregopher.com/mediocre-go-lib.git/mlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
type textUnmarshaler[T any] interface {
|
type textUnmarshaler[T any] interface {
|
||||||
@ -37,3 +41,24 @@ type (
|
|||||||
ipNetFlag = textUnmarshalerFlag[nebula.IPNet, *nebula.IPNet]
|
ipNetFlag = textUnmarshalerFlag[nebula.IPNet, *nebula.IPNet]
|
||||||
ipFlag = textUnmarshalerFlag[netip.Addr, *netip.Addr]
|
ipFlag = textUnmarshalerFlag[netip.Addr, *netip.Addr]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type logLevelFlag struct {
|
||||||
|
mlog.Level
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *logLevelFlag) Set(v string) error {
|
||||||
|
f.Level = toolkit.LogLevelFromString(v)
|
||||||
|
if f.Level == nil {
|
||||||
|
return errors.New("not a valid log level")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *logLevelFlag) String() string {
|
||||||
|
if f.Level == nil {
|
||||||
|
return "UNKNOWN"
|
||||||
|
}
|
||||||
|
return f.Level.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *logLevelFlag) Type() string { return "log level" }
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"dev.mediocregopher.com/mediocre-go-lib.git/mctx"
|
|
||||||
"dev.mediocregopher.com/mediocre-go-lib.git/mlog"
|
|
||||||
)
|
|
||||||
|
|
||||||
type logMsgHandler struct {
|
|
||||||
stderr *os.File
|
|
||||||
l sync.Mutex
|
|
||||||
}
|
|
||||||
|
|
||||||
func newLogMsgHandler() mlog.MessageHandler {
|
|
||||||
return &logMsgHandler{
|
|
||||||
stderr: os.Stderr,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *logMsgHandler) Sync() error {
|
|
||||||
return h.stderr.Sync()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *logMsgHandler) Handle(msg mlog.FullMessage) error {
|
|
||||||
h.l.Lock()
|
|
||||||
defer h.l.Unlock()
|
|
||||||
|
|
||||||
var namespaceStr string
|
|
||||||
|
|
||||||
if len(msg.Namespace) > 0 {
|
|
||||||
namespaceStr = "[" + path.Join(msg.Namespace...) + "] "
|
|
||||||
}
|
|
||||||
|
|
||||||
var annotationsStr string
|
|
||||||
|
|
||||||
if m := mctx.EvaluateAnnotations(msg.Context, nil).StringMap(); len(m) > 0 {
|
|
||||||
|
|
||||||
for k, v := range m {
|
|
||||||
annotationsStr += fmt.Sprintf(" %q=%q", k, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Fprintf(
|
|
||||||
h.stderr, "%s %s%s%s\n",
|
|
||||||
msg.Level.String(),
|
|
||||||
namespaceStr,
|
|
||||||
msg.Description,
|
|
||||||
annotationsStr,
|
|
||||||
)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -29,11 +29,7 @@ func binPath(name string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
logger := mlog.NewLogger(nil)
|
||||||
logger := mlog.NewLogger(&mlog.LoggerOpts{
|
|
||||||
MessageHandler: newLogMsgHandler(),
|
|
||||||
MaxLevel: mlog.LevelInfo.Int(), // TODO make this configurable
|
|
||||||
})
|
|
||||||
defer logger.Close()
|
defer logger.Close()
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
@ -56,7 +52,6 @@ func main() {
|
|||||||
|
|
||||||
err := subCmdCtx{
|
err := subCmdCtx{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
logger: logger,
|
|
||||||
args: os.Args[1:],
|
args: os.Args[1:],
|
||||||
}.doSubCmd(
|
}.doSubCmd(
|
||||||
subCmdDaemon,
|
subCmdDaemon,
|
||||||
|
@ -14,7 +14,8 @@ import (
|
|||||||
type flagSet struct {
|
type flagSet struct {
|
||||||
*pflag.FlagSet
|
*pflag.FlagSet
|
||||||
|
|
||||||
network string
|
network string
|
||||||
|
logLevel logLevelFlag
|
||||||
}
|
}
|
||||||
|
|
||||||
type subCmd struct {
|
type subCmd struct {
|
||||||
@ -38,18 +39,16 @@ type subCmd struct {
|
|||||||
// subCmdCtx contains all information available to a subCmd's do method.
|
// subCmdCtx contains all information available to a subCmd's do method.
|
||||||
type subCmdCtx struct {
|
type subCmdCtx struct {
|
||||||
context.Context
|
context.Context
|
||||||
logger *mlog.Logger
|
|
||||||
|
|
||||||
subCmd subCmd // the subCmd itself
|
subCmd subCmd // the subCmd itself
|
||||||
args []string // command-line arguments, excluding the subCmd itself.
|
args []string // command-line arguments, excluding the subCmd itself.
|
||||||
subCmdNames []string // names of subCmds so far, including this one
|
subCmdNames []string // names of subCmds so far, including this one
|
||||||
|
|
||||||
flags flagSet
|
flags *flagSet
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSubCmdCtx(
|
func newSubCmdCtx(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
logger *mlog.Logger,
|
|
||||||
subCmd subCmd,
|
subCmd subCmd,
|
||||||
args []string,
|
args []string,
|
||||||
subCmdNames []string,
|
subCmdNames []string,
|
||||||
@ -72,7 +71,10 @@ func newSubCmdCtx(
|
|||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
fs := flagSet{FlagSet: flags}
|
fs := &flagSet{
|
||||||
|
FlagSet: flags,
|
||||||
|
logLevel: logLevelFlag{mlog.LevelInfo},
|
||||||
|
}
|
||||||
|
|
||||||
if !subCmd.noNetwork {
|
if !subCmd.noNetwork {
|
||||||
fs.FlagSet.StringVar(
|
fs.FlagSet.StringVar(
|
||||||
@ -80,9 +82,14 @@ func newSubCmdCtx(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fs.FlagSet.VarP(
|
||||||
|
&fs.logLevel,
|
||||||
|
"log-level", "l",
|
||||||
|
"Maximum log level to output. Can be DEBUG, CHILD, INFO, WARN, ERROR, or FATAL. Default is INFO",
|
||||||
|
)
|
||||||
|
|
||||||
return subCmdCtx{
|
return subCmdCtx{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
logger: logger,
|
|
||||||
subCmd: subCmd,
|
subCmd: subCmd,
|
||||||
args: args,
|
args: args,
|
||||||
subCmdNames: subCmdNames,
|
subCmdNames: subCmdNames,
|
||||||
@ -99,6 +106,12 @@ func usagePrefix(subCmdNames []string) string {
|
|||||||
return fmt.Sprintf("\nUSAGE: %s %s", os.Args[0], subCmdNamesStr)
|
return fmt.Sprintf("\nUSAGE: %s %s", os.Args[0], subCmdNamesStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ctx subCmdCtx) logger() *mlog.Logger {
|
||||||
|
return mlog.NewLogger(&mlog.LoggerOpts{
|
||||||
|
MaxLevel: ctx.flags.logLevel.Int(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (ctx subCmdCtx) withParsedFlags() (subCmdCtx, error) {
|
func (ctx subCmdCtx) withParsedFlags() (subCmdCtx, error) {
|
||||||
ctx.flags.VisitAll(func(f *pflag.Flag) {
|
ctx.flags.VisitAll(func(f *pflag.Flag) {
|
||||||
if f.Shorthand == "h" {
|
if f.Shorthand == "h" {
|
||||||
@ -167,7 +180,6 @@ func (ctx subCmdCtx) doSubCmd(subCmds ...subCmd) error {
|
|||||||
|
|
||||||
nextSubCmdCtx := newSubCmdCtx(
|
nextSubCmdCtx := newSubCmdCtx(
|
||||||
ctx.Context,
|
ctx.Context,
|
||||||
ctx.logger,
|
|
||||||
subCmd,
|
subCmd,
|
||||||
args,
|
args,
|
||||||
append(ctx.subCmdNames, subCmdName),
|
append(ctx.subCmdNames, subCmdName),
|
||||||
|
Loading…
Reference in New Issue
Block a user