summaryrefslogtreecommitdiff
path: root/internal/service/signal.go
blob: b6445a792d065978a55e76329b9a8cefa2ad0938 (plain)
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
package service

import (
	"os"
	"os/signal"
	"syscall"

	"github.com/sirupsen/logrus"

	"github.com/authelia/authelia/v4/internal/logging"
)

func ProvisionLoggingSignal(ctx Context) (service Provider, err error) {
	config := ctx.GetConfiguration()

	if config == nil || len(config.Log.FilePath) == 0 {
		return nil, nil
	}

	return &Signal{
		name:    "log-reload",
		signals: []os.Signal{syscall.SIGHUP},
		action:  logging.Reopen,
		log:     ctx.GetLogger().WithFields(map[string]any{logFieldService: serviceTypeSignal, serviceTypeSignal: "log-reload"}),
	}, nil
}

// Signal is a Service which performs actions on signals.
type Signal struct {
	name    string
	signals []os.Signal
	action  func() (err error)
	log     *logrus.Entry

	notify chan os.Signal
	quit   chan struct{}
}

// ServiceType returns the service type for this service, which is always 'server'.
func (service *Signal) ServiceType() string {
	return serviceTypeSignal
}

// ServiceName returns the individual name for this service.
func (service *Signal) ServiceName() string {
	return service.name
}

// Run the ServerService.
func (service *Signal) Run() (err error) {
	service.quit = make(chan struct{})

	service.notify = make(chan os.Signal, 1)

	signal.Notify(service.notify, service.signals...)

	for {
		select {
		case s := <-service.notify:
			if err = service.action(); err != nil {
				service.log.WithError(err).Error("Error occurred executing service action.")
			} else {
				service.log.WithFields(map[string]any{"signal-received": s.String()}).Debug("Successfully executed service action.")
			}
		case <-service.quit:
			return
		}
	}
}

// Shutdown the ServerService.
func (service *Signal) Shutdown() {
	signal.Stop(service.notify)

	service.quit <- struct{}{}
}

// Log returns the *logrus.Entry of the ServerService.
func (service *Signal) Log() *logrus.Entry {
	return service.log
}