From 80ce17a57f9990c64a79ca07e136600234b23b47 Mon Sep 17 00:00:00 2001 From: rabbitstack Date: Wed, 27 Nov 2024 18:58:45 +0100 Subject: [PATCH] fix(log): Panic redirection to logs Firstly, make sure the file exists before we try to get the handle to it. Secondly, duplicate the file handle and pass it to SetStdHandle. --- internal/bootstrap/bootstrap.go | 2 +- pkg/util/log/logger.go | 20 +++++++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/internal/bootstrap/bootstrap.go b/internal/bootstrap/bootstrap.go index 3505071c3..d00bd5b64 100644 --- a/internal/bootstrap/bootstrap.go +++ b/internal/bootstrap/bootstrap.go @@ -180,7 +180,7 @@ func (f *App) Run(args []string) error { } log.Infof("bootstrapping with pid %d. Version: %s", os.Getpid(), version.Get()) - log.Infof("rendering config flags... %s", cfg.Print()) + log.Infof("configuration options: %s", cfg.Print()) // build the filter from the CLI argument. If we got // a valid expression the filter is attached to the diff --git a/pkg/util/log/logger.go b/pkg/util/log/logger.go index adee912fe..e02e6989e 100644 --- a/pkg/util/log/logger.go +++ b/pkg/util/log/logger.go @@ -122,16 +122,30 @@ func InitFromConfig(c Config, filename string) error { return nil } +// redirectStderrToFile redirects the standard output stream to a log file. +// Helpful to capture panics and send them to the file. func redirectStderrToFile(file string) error { - f, err := os.OpenFile(file, os.O_WRONLY|os.O_SYNC|os.O_APPEND, 0644) + f, err := os.OpenFile(file, os.O_WRONLY|os.O_CREATE|os.O_SYNC|os.O_APPEND, 0644) if err != nil { return fmt.Errorf("unable to open %s for stderr redirection: %v", file, err) } defer f.Close() - err = windows.SetStdHandle(windows.STD_ERROR_HANDLE, windows.Handle(f.Fd())) + + fd, err := dupFD(f.Fd()) + if err != nil { + return fmt.Errorf("failed to duplicate file handle: %v", err) + } + + err = windows.SetStdHandle(windows.STD_ERROR_HANDLE, fd) if err != nil { return fmt.Errorf("failed to redirect stderr to file: %v", err) } - os.Stderr = f + return nil } + +func dupFD(fd uintptr) (windows.Handle, error) { + proc := windows.CurrentProcess() + var h windows.Handle + return h, windows.DuplicateHandle(proc, windows.Handle(fd), proc, &h, 0, true, windows.DUPLICATE_SAME_ACCESS) +}