Make log level configurable, remove custom log message handler

This commit is contained in:
Brian Picciano 2024-11-09 17:08:39 +01:00
parent 032bdb9e43
commit 06d85ca961
5 changed files with 48 additions and 83 deletions

View File

@ -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.

View File

@ -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 "string" }

View File

@ -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
}

View File

@ -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,

View File

@ -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,17 +71,25 @@ 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(
&fs.network, "network", "", "Which network to perform the command against, if more than one is joined. Can be ID, name, or domain", &fs.network, "network", "", "Which network to perform the command against, if more than one is joined. Can be an ID, name, or domain.",
) )
} }
fs.FlagSet.VarP(
&fs.logLevel,
"log-level", "l",
"Maximum log level to output. Can be DEBUG, CHILD, INFO, WARN, ERROR, or FATAL.",
)
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),