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 }