logging.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package config
  2. import (
  3. "errors"
  4. "fmt"
  5. "log/slog"
  6. )
  7. var (
  8. ErrMissingLoggingFileConfig = errors.New("config.Logging: missing value parameters in logging block")
  9. ErrInvalidLoggingSink = errors.New("config.Logging: invalid sink")
  10. ErrInvalidLoggingFileConfig = errors.New("config.LoggingFileConfig: invalid parameters")
  11. ErrOutOfRange = errors.New("config: error out of range")
  12. )
  13. type Logging struct {
  14. Sink string `json:"sink"` // Logging sink, either "stdio" or "file"
  15. Level *slog.Level `json:"level"` // Log level, if set supersedes the level in flags
  16. Parameters *LoggingFileConfig `json:"parameters"` // Logging parameters, to be dynamic in the future
  17. }
  18. const (
  19. LogSinkStdio = "stdio"
  20. LogSinkFile = "file"
  21. )
  22. func (l *Logging) Valid() error {
  23. var errs []error
  24. switch l.Sink {
  25. case LogSinkStdio:
  26. // no validation needed
  27. case LogSinkFile:
  28. if l.Parameters == nil {
  29. errs = append(errs, ErrMissingLoggingFileConfig)
  30. }
  31. if err := l.Parameters.Valid(); err != nil {
  32. errs = append(errs, err)
  33. }
  34. default:
  35. errs = append(errs, fmt.Errorf("%w: sink %s is unknown to me", ErrInvalidLoggingSink, l.Sink))
  36. }
  37. if len(errs) != 0 {
  38. return errors.Join(errs...)
  39. }
  40. return nil
  41. }
  42. func (Logging) Default() *Logging {
  43. return &Logging{
  44. Sink: "stdio",
  45. }
  46. }
  47. type LoggingFileConfig struct {
  48. Filename string `json:"file"`
  49. MaxBackups int `json:"maxBackups"`
  50. MaxBytes int64 `json:"maxBytes"`
  51. MaxAge int `json:"maxAge"`
  52. Compress bool `json:"compress"`
  53. UseLocalTime bool `json:"useLocalTime"`
  54. }
  55. func (lfc *LoggingFileConfig) Valid() error {
  56. if lfc == nil {
  57. return fmt.Errorf("logging file config is nil, why are you calling this?")
  58. }
  59. var errs []error
  60. if lfc.Zero() {
  61. errs = append(errs, ErrMissingValue)
  62. }
  63. if lfc.Filename == "" {
  64. errs = append(errs, fmt.Errorf("%w: filename", ErrMissingValue))
  65. }
  66. if lfc.MaxBackups < 0 {
  67. errs = append(errs, fmt.Errorf("%w: max backup count %d is not greater than or equal to zero", ErrOutOfRange, lfc.MaxBackups))
  68. }
  69. if lfc.MaxAge < 0 {
  70. errs = append(errs, fmt.Errorf("%w: max backup count %d is not greater than or equal to zero", ErrOutOfRange, lfc.MaxAge))
  71. }
  72. if len(errs) != 0 {
  73. errs = append([]error{ErrInvalidLoggingFileConfig}, errs...)
  74. return errors.Join(errs...)
  75. }
  76. return nil
  77. }
  78. func (lfc LoggingFileConfig) Zero() bool {
  79. for _, cond := range []bool{
  80. lfc.Filename != "",
  81. lfc.MaxBackups != 0,
  82. lfc.MaxBytes != 0,
  83. lfc.MaxAge != 0,
  84. lfc.Compress,
  85. lfc.UseLocalTime,
  86. } {
  87. if cond {
  88. return false
  89. }
  90. }
  91. return true
  92. }
  93. func (LoggingFileConfig) Default() *LoggingFileConfig {
  94. return &LoggingFileConfig{
  95. Filename: "./var/anubis.log",
  96. MaxBackups: 3,
  97. MaxBytes: 104857600, // 100 Mi
  98. MaxAge: 7, // 7 days
  99. Compress: true,
  100. UseLocalTime: false,
  101. }
  102. }