1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
package logging
import (
"fmt"
"github.com/lxc/incus/v6/internal/server/events"
"github.com/lxc/incus/v6/internal/server/state"
"github.com/lxc/incus/v6/shared/logger"
)
// Controller is responsible for managing a set of loggers.
type Controller struct {
listener *events.InternalListener
loggers map[string]Logger
}
// NewLoggingController instantiates a new LoggerController object.
func NewLoggingController(listener *events.InternalListener) *Controller {
return &Controller{
listener: listener,
loggers: map[string]Logger{},
}
}
// AddLogger adds a new logger to the controller.
func (c *Controller) AddLogger(s *state.State, name string, loggerType string) error {
loggerClient, err := LoggerFromType(s, name, loggerType)
if err != nil {
return err
}
c.loggers[name] = loggerClient
c.listener.AddHandler(name, loggerClient.HandleEvent)
return nil
}
// RemoveLogger removes a logger from the controller.
func (c *Controller) RemoveLogger(name string) {
loggerClient, ok := c.loggers[name]
if ok {
loggerClient.Stop()
delete(c.loggers, name)
c.listener.RemoveHandler(name)
}
}
// Setup is responsible for preparing a new set of loggers.
func (c *Controller) Setup(s *state.State) error {
loggingConfig, err := s.GlobalConfig.Loggers()
if err != nil {
return err
}
for loggerName, loggerType := range loggingConfig {
err = c.AddLogger(s, loggerName, loggerType)
if err != nil {
logger.Error("Error creating a logger", logger.Ctx{"err": err})
}
}
return nil
}
// Reconfigure handles the reinitialization of loggers after configuration changes.
func (c *Controller) Reconfigure(s *state.State, config map[string]struct{}) error {
loggingConfig, err := s.GlobalConfig.Loggers()
if err != nil {
return err
}
for loggerName := range config {
c.RemoveLogger(loggerName)
loggerType, ok := loggingConfig[loggerName]
if !ok {
continue
}
err = c.AddLogger(s, loggerName, loggerType)
if err != nil {
logger.Error("Error creating logger", logger.Ctx{"err": err})
}
}
return nil
}
// Shutdown cleans up loggers.
func (c *Controller) Shutdown() {
for _, loggerClient := range c.loggers {
loggerClient.Stop()
}
}
// LoggerFromType returns a new logger based on its type.
func LoggerFromType(s *state.State, loggerName string, loggerType string) (Logger, error) {
if loggerType == "" {
return nil, fmt.Errorf("No type definition for logger %s", loggerName)
}
var loggerClient Logger
var err error
switch loggerType {
case "syslog":
loggerClient, err = NewSyslogLogger(s, loggerName)
case "loki":
loggerClient, err = NewLokiLogger(s, loggerName)
case "webhook":
loggerClient, err = NewWebhookLogger(s, loggerName)
default:
return nil, fmt.Errorf("%s is not supported logger type", loggerType)
}
if err != nil {
return nil, err
}
err = loggerClient.Validate()
if err != nil {
return nil, err
}
err = loggerClient.Start()
if err != nil {
return nil, err
}
return loggerClient, nil
}
|