File: controller.go

package info (click to toggle)
incus 6.0.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 24,392 kB
  • sloc: sh: 16,313; ansic: 3,121; python: 457; makefile: 337; ruby: 51; sql: 50; lisp: 6
file content (131 lines) | stat: -rw-r--r-- 3,006 bytes parent folder | download | duplicates (3)
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
}