feat(GODT-2691): close logrus output file on exit.

This commit is contained in:
Xavier Michelon
2023-06-28 13:34:19 +02:00
parent c267168cb7
commit 7b7c9093ce
5 changed files with 52 additions and 8 deletions

View File

@ -18,6 +18,7 @@
package main package main
import ( import (
"io"
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
@ -81,7 +82,8 @@ func main() { //nolint:funlen
sessionID := logging.NewSessionID() sessionID := logging.NewSessionID()
crashHandler.AddRecoveryAction(logging.DumpStackTrace(logsPath, sessionID, launcherName)) crashHandler.AddRecoveryAction(logging.DumpStackTrace(logsPath, sessionID, launcherName))
if err := logging.Init( var closer io.Closer
if closer, err = logging.Init(
logsPath, logsPath,
sessionID, sessionID,
logging.LauncherShortAppName, logging.LauncherShortAppName,
@ -92,6 +94,10 @@ func main() { //nolint:funlen
l.WithError(err).Fatal("Failed to setup logging") l.WithError(err).Fatal("Failed to setup logging")
} }
defer func() {
_ = logging.Close(closer)
}()
updatesPath, err := locations.ProvideUpdatesPath() updatesPath, err := locations.ProvideUpdatesPath()
if err != nil { if err != nil {
l.WithError(err).Fatal("Failed to get updates path") l.WithError(err).Fatal("Failed to get updates path")

View File

@ -19,6 +19,7 @@ package app
import ( import (
"fmt" "fmt"
"io"
"net/http" "net/http"
"net/http/cookiejar" "net/http/cookiejar"
"net/url" "net/url"
@ -189,6 +190,11 @@ func run(c *cli.Context) error {
exe = os.Args[0] exe = os.Args[0]
} }
var logCloser io.Closer
defer func() {
_ = logging.Close(logCloser)
}()
// Restart the app if requested. // Restart the app if requested.
return withRestarter(exe, func(restarter *restarter.Restarter) error { return withRestarter(exe, func(restarter *restarter.Restarter) error {
// Handle crashes with various actions. // Handle crashes with various actions.
@ -205,7 +211,9 @@ func run(c *cli.Context) error {
} }
// Initialize logging. // Initialize logging.
return withLogging(c, crashHandler, locations, func() error { return withLogging(c, crashHandler, locations, func(closer io.Closer) error {
logCloser = closer
// If there was an error during migration, log it now. // If there was an error during migration, log it now.
if migrationErr != nil { if migrationErr != nil {
logrus.WithError(migrationErr).Error("Failed to migrate old app data") logrus.WithError(migrationErr).Error("Failed to migrate old app data")
@ -304,7 +312,7 @@ func withSingleInstance(settingPath, lockFile string, version *semver.Version, f
} }
// Initialize our logging system. // Initialize our logging system.
func withLogging(c *cli.Context, crashHandler *crash.Handler, locations *locations.Locations, fn func() error) error { func withLogging(c *cli.Context, crashHandler *crash.Handler, locations *locations.Locations, fn func(closer io.Closer) error) error {
logrus.Debug("Initializing logging") logrus.Debug("Initializing logging")
defer logrus.Debug("Logging stopped") defer logrus.Debug("Logging stopped")
@ -318,7 +326,8 @@ func withLogging(c *cli.Context, crashHandler *crash.Handler, locations *locatio
// Initialize logging. // Initialize logging.
sessionID := logging.NewSessionIDFromString(c.String(flagSessionID)) sessionID := logging.NewSessionIDFromString(c.String(flagSessionID))
if err := logging.Init( var closer io.Closer
if closer, err = logging.Init(
logsPath, logsPath,
sessionID, sessionID,
logging.BridgeShortAppName, logging.BridgeShortAppName,
@ -343,7 +352,7 @@ func withLogging(c *cli.Context, crashHandler *crash.Handler, locations *locatio
WithField("SentryID", sentry.GetProtectedHostname()). WithField("SentryID", sentry.GetProtectedHostname()).
Info("Run app") Info("Run app")
return fn() return fn(closer)
} }
// WithLocations provides access to locations where we store our files. // WithLocations provides access to locations where we store our files.

View File

@ -21,6 +21,7 @@ import (
"bytes" "bytes"
"context" "context"
"errors" "errors"
"io"
"os" "os"
"path/filepath" "path/filepath"
"regexp" "regexp"
@ -88,7 +89,7 @@ func (cs *coloredStdOutHook) Fire(entry *logrus.Entry) error {
// Init Initialize logging. Log files are rotated when their size exceeds rotationSize. if pruningSize >= 0, pruning occurs using // Init Initialize logging. Log files are rotated when their size exceeds rotationSize. if pruningSize >= 0, pruning occurs using
// the default pruning algorithm. // the default pruning algorithm.
func Init(logsPath string, sessionID SessionID, appName AppName, rotationSize, pruningSize int64, level string) error { func Init(logsPath string, sessionID SessionID, appName AppName, rotationSize, pruningSize int64, level string) (io.Closer, error) {
logrus.SetFormatter(&logrus.TextFormatter{ logrus.SetFormatter(&logrus.TextFormatter{
DisableColors: true, DisableColors: true,
FullTimestamp: true, FullTimestamp: true,
@ -99,12 +100,22 @@ func Init(logsPath string, sessionID SessionID, appName AppName, rotationSize, p
rotator, err := NewDefaultRotator(logsPath, sessionID, appName, rotationSize, pruningSize) rotator, err := NewDefaultRotator(logsPath, sessionID, appName, rotationSize, pruningSize)
if err != nil { if err != nil {
return err return nil, err
} }
logrus.SetOutput(rotator) logrus.SetOutput(rotator)
return setLevel(level) return rotator, setLevel(level)
}
// Close closes the log file. if closer is nil, no error is reported.
func Close(closer io.Closer) error {
if closer == nil {
return nil
}
logrus.SetOutput(os.Stdout)
return closer.Close()
} }
// ZipLogsForBugReport returns an archive containing the logs for bug report. // ZipLogsForBugReport returns an archive containing the logs for bug report.

View File

@ -23,6 +23,7 @@ import (
"testing" "testing"
"github.com/ProtonMail/proton-bridge/v3/internal/constants" "github.com/ProtonMail/proton-bridge/v3/internal/constants"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -93,3 +94,12 @@ func TestLogging_GetOrderedLogFileListForBugReport(t *testing.T) {
filepath.Join(dir, string(sessionID1)+"_lau_000"+fileSuffix), filepath.Join(dir, string(sessionID1)+"_lau_000"+fileSuffix),
}, filePaths) }, filePaths)
} }
func TestLogging_Close(t *testing.T) {
d := t.TempDir()
closer, err := Init(d, NewSessionID(), constants.AppName, 1, DefaultPruningSize, "debug")
require.NoError(t, err)
logrus.Debug("Test") // because we set max log file size to 1, this will force a rotation of the log file.
require.NotNil(t, closer)
require.NoError(t, closer.Close())
}

View File

@ -86,6 +86,14 @@ func (r *Rotator) Write(p []byte) (int, error) {
return n, nil return n, nil
} }
func (r *Rotator) Close() error {
if r.wc != nil {
return r.wc.Close()
}
return nil
}
func (r *Rotator) rotate() error { func (r *Rotator) rotate() error {
if r.wc != nil { if r.wc != nil {
_ = r.wc.Close() _ = r.wc.Close()