WIP: Logging

This commit is contained in:
binwiederhier 2023-02-03 22:21:50 -05:00
parent af4175a5bc
commit a6641980c2
15 changed files with 631 additions and 168 deletions

View file

@ -2,10 +2,12 @@
package cmd
import (
"fmt"
"github.com/urfave/cli/v2"
"github.com/urfave/cli/v2/altsrc"
"heckel.io/ntfy/log"
"os"
"regexp"
)
const (
@ -20,8 +22,14 @@ var flagsDefault = []cli.Flag{
&cli.BoolFlag{Name: "trace", EnvVars: []string{"NTFY_TRACE"}, Usage: "enable tracing (very verbose, be careful)"},
&cli.BoolFlag{Name: "no-log-dates", Aliases: []string{"no_log_dates"}, EnvVars: []string{"NTFY_NO_LOG_DATES"}, Usage: "disable the date/time prefix"},
altsrc.NewStringFlag(&cli.StringFlag{Name: "log-level", Aliases: []string{"log_level"}, Value: log.InfoLevel.String(), EnvVars: []string{"NTFY_LOG_LEVEL"}, Usage: "set log level"}),
altsrc.NewStringSliceFlag(&cli.StringSliceFlag{Name: "log-level-overrides", Aliases: []string{"log_level_overrides"}, EnvVars: []string{"NTFY_LOG_LEVEL_OVERRIDES"}, Usage: "set log level overrides"}),
altsrc.NewStringFlag(&cli.StringFlag{Name: "log-format", Aliases: []string{"log_format"}, Value: log.TextFormat.String(), EnvVars: []string{"NTFY_LOG_FORMAT"}, Usage: "set log level"}),
}
var (
logLevelOverrideRegex = regexp.MustCompile(`(?i)^([^=]+)\s*=\s*(\S+)\s*->\s*(TRACE|DEBUG|INFO|WARN|ERROR)$`)
)
// New creates a new CLI application
func New() *cli.App {
return &cli.App{
@ -40,15 +48,30 @@ func New() *cli.App {
}
func initLogFunc(c *cli.Context) error {
log.SetLevel(log.ToLevel(c.String("log-level")))
log.SetFormat(log.ToFormat(c.String("log-format")))
if c.Bool("trace") {
log.SetLevel(log.TraceLevel)
} else if c.Bool("debug") {
log.SetLevel(log.DebugLevel)
} else {
log.SetLevel(log.ToLevel(c.String("log-level")))
}
if c.Bool("no-log-dates") {
log.DisableDates()
}
if err := applyLogLevelOverrides(c.StringSlice("log-level-overrides")); err != nil {
return err
}
return nil
}
func applyLogLevelOverrides(rawOverrides []string) error {
for _, override := range rawOverrides {
m := logLevelOverrideRegex.FindStringSubmatch(override)
if len(m) != 4 {
return fmt.Errorf(`invalid log level override "%s", must be "field=value -> loglevel", e.g. "user_id=u_123 -> DEBUG"`, override)
}
field, value, level := m[1], m[2], m[3]
log.SetLevelOverride(field, value, log.ToLevel(level))
}
return nil
}

View file

@ -309,9 +309,9 @@ func execServe(c *cli.Context) error {
// Run server
s, err := server.New(conf)
if err != nil {
log.Fatal(err)
log.Fatal(err.Error())
} else if err := s.Run(); err != nil {
log.Fatal(err)
log.Fatal(err.Error())
}
log.Info("Exiting.")
return nil
@ -338,7 +338,9 @@ func sigHandlerConfigReload(config string) {
log.Warn("Hot reload failed: %s", err.Error())
continue
}
reloadLogLevel(inputSource)
if err := reloadLogLevel(inputSource); err != nil {
log.Warn("Reloading log level failed: %s", err.Error())
}
}
}
@ -367,13 +369,24 @@ func parseIPHostPrefix(host string) (prefixes []netip.Prefix, err error) {
return
}
func reloadLogLevel(inputSource altsrc.InputSourceContext) {
func reloadLogLevel(inputSource altsrc.InputSourceContext) error {
newLevelStr, err := inputSource.String("log-level")
if err != nil {
log.Warn("Cannot load log level: %s", err.Error())
return
return fmt.Errorf("cannot load log level: %s", err.Error())
}
newLevel := log.ToLevel(newLevelStr)
log.SetLevel(newLevel)
log.Info("Log level is %s", newLevel.String())
overrides, err := inputSource.StringSlice("log-level-overrides")
if err != nil {
return fmt.Errorf("cannot load log level overrides (1): %s", err.Error())
}
log.ResetLevelOverride()
if err := applyLogLevelOverrides(overrides); err != nil {
return fmt.Errorf("cannot load log level overrides (2): %s", err.Error())
}
log.SetLevel(log.ToLevel(newLevelStr))
if len(overrides) > 0 {
log.Info("Log level is %v, %d override(s) in place", strings.ToUpper(newLevelStr), len(overrides))
} else {
log.Info("Log level is %v", strings.ToUpper(newLevelStr))
}
return nil
}