app.go 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. // Package cmd provides the ntfy CLI application
  2. package cmd
  3. import (
  4. "fmt"
  5. "github.com/urfave/cli/v2"
  6. "github.com/urfave/cli/v2/altsrc"
  7. "heckel.io/ntfy/log"
  8. "os"
  9. "regexp"
  10. )
  11. const (
  12. categoryClient = "Client commands"
  13. categoryServer = "Server commands"
  14. )
  15. var commands = make([]*cli.Command, 0)
  16. var flagsDefault = []cli.Flag{
  17. &cli.BoolFlag{Name: "debug", Aliases: []string{"d"}, EnvVars: []string{"NTFY_DEBUG"}, Usage: "enable debug logging"},
  18. &cli.BoolFlag{Name: "trace", EnvVars: []string{"NTFY_TRACE"}, Usage: "enable tracing (very verbose, be careful)"},
  19. &cli.BoolFlag{Name: "no-log-dates", Aliases: []string{"no_log_dates"}, EnvVars: []string{"NTFY_NO_LOG_DATES"}, Usage: "disable the date/time prefix"},
  20. altsrc.NewStringFlag(&cli.StringFlag{Name: "log-level", Aliases: []string{"log_level"}, Value: log.InfoLevel.String(), EnvVars: []string{"NTFY_LOG_LEVEL"}, Usage: "set log level"}),
  21. altsrc.NewStringSliceFlag(&cli.StringSliceFlag{Name: "log-level-overrides", Aliases: []string{"log_level_overrides"}, EnvVars: []string{"NTFY_LOG_LEVEL_OVERRIDES"}, Usage: "set log level overrides"}),
  22. altsrc.NewStringFlag(&cli.StringFlag{Name: "log-format", Aliases: []string{"log_format"}, Value: log.TextFormat.String(), EnvVars: []string{"NTFY_LOG_FORMAT"}, Usage: "set log level"}),
  23. }
  24. var (
  25. logLevelOverrideRegex = regexp.MustCompile(`(?i)^([^=]+)\s*=\s*(\S+)\s*->\s*(TRACE|DEBUG|INFO|WARN|ERROR)$`)
  26. )
  27. // New creates a new CLI application
  28. func New() *cli.App {
  29. return &cli.App{
  30. Name: "ntfy",
  31. Usage: "Simple pub-sub notification service",
  32. UsageText: "ntfy [OPTION..]",
  33. HideVersion: true,
  34. UseShortOptionHandling: true,
  35. Reader: os.Stdin,
  36. Writer: os.Stdout,
  37. ErrWriter: os.Stderr,
  38. Commands: commands,
  39. Flags: flagsDefault,
  40. Before: initLogFunc,
  41. }
  42. }
  43. func initLogFunc(c *cli.Context) error {
  44. log.SetLevel(log.ToLevel(c.String("log-level")))
  45. log.SetFormat(log.ToFormat(c.String("log-format")))
  46. if c.Bool("trace") {
  47. log.SetLevel(log.TraceLevel)
  48. } else if c.Bool("debug") {
  49. log.SetLevel(log.DebugLevel)
  50. }
  51. if c.Bool("no-log-dates") {
  52. log.DisableDates()
  53. }
  54. if err := applyLogLevelOverrides(c.StringSlice("log-level-overrides")); err != nil {
  55. return err
  56. }
  57. return nil
  58. }
  59. func applyLogLevelOverrides(rawOverrides []string) error {
  60. for _, override := range rawOverrides {
  61. m := logLevelOverrideRegex.FindStringSubmatch(override)
  62. if len(m) != 4 {
  63. return fmt.Errorf(`invalid log level override "%s", must be "field=value -> loglevel", e.g. "user_id=u_123 -> DEBUG"`, override)
  64. }
  65. field, value, level := m[1], m[2], m[3]
  66. log.SetLevelOverride(field, value, log.ToLevel(level))
  67. }
  68. return nil
  69. }