Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A way to tell authelia to reopen its logfile #4964

Open
2 tasks done
electrofloat opened this issue Feb 19, 2023 · 2 comments · May be fixed by #7140
Open
2 tasks done

A way to tell authelia to reopen its logfile #4964

electrofloat opened this issue Feb 19, 2023 · 2 comments · May be fixed by #7140
Labels
area/logs Logging related features/bugs priority/5/low Low priority items status/needs-design Requires thoughtful design type/feature Request for adding a new feature

Comments

@electrofloat
Copy link
Contributor

Description

In #3210 (comment) I can see that is is recommended to use logrotate to rotate authelia's own logfile, which is fair enough.

But, unfortunately there is no way currently (not that I know of) to tell authelia to reopen its logfile after it has been rotated.
That means only the copytruncate option can be used instead of create in logrotate, which has the downside of possibly losing some logs.

So I'd like to see an option to tell authelia to reopen its logfile to be able to use the create option in logrotate. (either by handling -HUP/-USR1/-USR2 signals, or any other method)

Use Case

When using authelia's own mechanism to log to a file, that file grows forever.
It is recommended to use linux's logrotate tool to rotate it, but needs a bit more support from authelia's side.

Details

No response

Documentation

https://linux.die.net/man/8/logrotate

Pre-Submission Checklist

  • I agree to follow the Code of Conduct
  • I have checked for related issues and checked the documentation
@electrofloat electrofloat added priority/4/normal Normal priority items status/needs-design Requires thoughtful design type/feature Request for adding a new feature labels Feb 19, 2023
@james-d-elliott james-d-elliott added priority/5/low Low priority items area/logs Logging related features/bugs and removed priority/4/normal Normal priority items labels Feb 20, 2023
@james-d-elliott
Copy link
Member

james-d-elliott commented Feb 20, 2023

As we support injecting the process start time into the log file name I am inclined to say use that or use copytruncate. If someone wishes to contribute this and can prove it works reliably via integration testing then we'd welcome the PR however.

@james-d-elliott
Copy link
Member

james-d-elliott commented Mar 15, 2024

Rough Signal Service in line with our current services that could be fairly easily added. We just need to figure out the reopen logic to avoid causing panics and not losing logs.

// NewSignalService creates a new SignalService with the appropriate logger etc.
func NewSignalService(name string, log *logrus.Logger, action func() (err error), signals ...os.Signal) (service *SignalService, err error) {
	entry := log.WithFields(map[string]any{logFieldService: serviceTypeSignals, serviceTypeSignals: name})
	event := make(chan os.Signal, 1)
	done := make(chan struct{}, 1)

	signal.Notify(event, signals...)

	return &SignalService{
		name:   name,
		log:    entry,
		event:  event,
		done:   done,
		action: action,
	}, nil
}


// SignalService is a Service that listens to operating system signals.
type SignalService struct {
	name string
	log  *logrus.Entry

	event  chan os.Signal
	done   chan struct{}
	action func() (err error)
}

// ServiceType returns the service type for this service, which is always 'watcher'.
func (service *SignalService) ServiceType() string {
	return serviceTypeSignals
}

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

// Run the FileWatcherService.
func (service *SignalService) Run() (err error) {
	defer func() {
		if r := recover(); r != nil {
			service.log.WithError(recoverErr(r)).Error("Critical error caught (recovered)")
		}
	}()

	service.log.Debug("Signals Service Started")

	for {
		select {
		case <-service.event:
			if err := service.action(); err != nil {
				return err
			}
		case <-service.done:
			return nil
		}
	}
}

// Shutdown the FileWatcherService.
func (service *SignalService) Shutdown() {
	service.done <- struct{}{}

	close(service.event)
	close(service.done)
}

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

func svcSignalLogRotateFunc(ctx *CmdCtx) (service Service) {
	action := func() (err error) {
		// TODO: Add logging logic here.

		return nil
	}

	var err error

	if service, err = NewSignalService("log rotate", ctx.log, action, syscall.SIGUSR1); err != nil {
		ctx.log.WithError(err).Fatal("Create Signal Service (log rotate) returned error")
	}

	return service
}

@james-d-elliott james-d-elliott linked a pull request Apr 11, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/logs Logging related features/bugs priority/5/low Low priority items status/needs-design Requires thoughtful design type/feature Request for adding a new feature
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants