From 89edfbf257b888d2d3fcc428b7216cdbe883d516 Mon Sep 17 00:00:00 2001 From: Jarek Kowalski Date: Sat, 6 Nov 2021 23:08:00 -0700 Subject: [PATCH] maintenance: send logs to content log as well (#1496) --- cli/command_logs_test.go | 8 ++++---- repo/content/committed_read_manager.go | 9 ++++++--- repo/logging/ctx.go | 19 +++++++++++++++++++ repo/maintenance/maintenance_run.go | 6 ++++-- repo/repository.go | 9 ++++----- .../snapshotmaintenance.go | 2 +- 6 files changed, 38 insertions(+), 15 deletions(-) diff --git a/cli/command_logs_test.go b/cli/command_logs_test.go index 9f6fc20db..837b6278e 100644 --- a/cli/command_logs_test.go +++ b/cli/command_logs_test.go @@ -91,13 +91,13 @@ func TestLogsMaintenance(t *testing.T) { e.RunAndVerifyOutputLineCount(t, 5, "logs", "list") e.RunAndExpectSuccess(t, "maintenance", "run") - e.RunAndVerifyOutputLineCount(t, 2, "logs", "list") - - e.RunAndExpectSuccess(t, "maintenance", "set", "--max-retained-log-age=1ms") e.RunAndVerifyOutputLineCount(t, 3, "logs", "list") + e.RunAndExpectSuccess(t, "maintenance", "set", "--max-retained-log-age=1ms") + e.RunAndVerifyOutputLineCount(t, 4, "logs", "list") + e.RunAndExpectSuccess(t, "maintenance", "run") - e.RunAndVerifyOutputLineCount(t, 0, "logs", "list") + e.RunAndVerifyOutputLineCount(t, 1, "logs", "list") e.RunAndExpectSuccess(t, "maintenance", "set", "--max-retained-log-age=22h", diff --git a/repo/content/committed_read_manager.go b/repo/content/committed_read_manager.go index c9bf3f0dc..ee539b5a4 100644 --- a/repo/content/committed_read_manager.go +++ b/repo/content/committed_read_manager.go @@ -491,9 +491,12 @@ func (sm *SharedManager) release(ctx context.Context) error { return errors.Wrap(sm.st.Close(ctx), "error closing storage") } -// InternalLogger returns the internal logger. -func (sm *SharedManager) InternalLogger() logging.Logger { - return sm.internalLogger +// AlsoLogToContentLog wraps the provided content so that all logs are also sent to +// internal content log. +func (sm *SharedManager) AlsoLogToContentLog(ctx context.Context) context.Context { + sm.internalLogManager.enable() + + return logging.AlsoLogTo(ctx, sm.log) } func (sm *SharedManager) shouldRefreshIndexes() bool { diff --git a/repo/logging/ctx.go b/repo/logging/ctx.go index 7ff503f26..c47bf3756 100644 --- a/repo/logging/ctx.go +++ b/repo/logging/ctx.go @@ -33,3 +33,22 @@ func WithLogger(ctx context.Context, l LoggerFactory) context.Context { createLoggerForModule: l, }) } + +// loggerFactoryFromContext returns a LoggerFactory associated with current context. +func loggerFactoryFromContext(ctx context.Context) LoggerFactory { + v := ctx.Value(loggerCacheKey) + if v == nil { + return getNullLogger + } + + return v.(*loggerCache).getLogger +} + +// AlsoLogTo returns a context where all logging is emitted the the original output plus the provided loggers. +func AlsoLogTo(ctx context.Context, loggers ...Logger) context.Context { + originalLogFactory := loggerFactoryFromContext(ctx) + + return WithLogger(ctx, func(module string) Logger { + return append(Broadcast{originalLogFactory(module)}, loggers...) + }) +} diff --git a/repo/maintenance/maintenance_run.go b/repo/maintenance/maintenance_run.go index 69e8cd81e..cf5e6dd78 100644 --- a/repo/maintenance/maintenance_run.go +++ b/repo/maintenance/maintenance_run.go @@ -140,9 +140,11 @@ func (e NotOwnedError) Error() string { // RunExclusive runs the provided callback if the maintenance is owned by local user and // lock can be acquired. Lock is passed to the function, which ensures that every call to Run() // is within the exclusive context. -func RunExclusive(ctx context.Context, rep repo.DirectRepositoryWriter, mode Mode, force bool, cb func(runParams RunParameters) error) error { +func RunExclusive(ctx context.Context, rep repo.DirectRepositoryWriter, mode Mode, force bool, cb func(ctx context.Context, runParams RunParameters) error) error { rep.DisableIndexRefresh() + ctx = rep.AlsoLogToContentLog(ctx) + p, err := GetParams(ctx, rep) if err != nil { return errors.Wrap(err, "unable to get maintenance params") @@ -208,7 +210,7 @@ func RunExclusive(ctx context.Context, rep repo.DirectRepositoryWriter, mode Mod return errors.Wrap(err, "error refreshing indexes before maintenance") } - return cb(runParams) + return cb(ctx, runParams) } func ensureNoClockSkew(rp RunParameters) error { diff --git a/repo/repository.go b/repo/repository.go index 9336cbde5..480ce5ebf 100644 --- a/repo/repository.go +++ b/repo/repository.go @@ -11,7 +11,6 @@ "github.com/kopia/kopia/internal/clock" "github.com/kopia/kopia/repo/blob" "github.com/kopia/kopia/repo/content" - "github.com/kopia/kopia/repo/logging" "github.com/kopia/kopia/repo/manifest" "github.com/kopia/kopia/repo/object" ) @@ -57,7 +56,7 @@ type DirectRepository interface { Crypter() *content.Crypter NewDirectWriter(ctx context.Context, opt WriteSessionOptions) (context.Context, DirectRepositoryWriter, error) - InternalLogger() logging.Logger + AlsoLogToContentLog(ctx context.Context) context.Context // misc UniqueID() []byte @@ -197,9 +196,9 @@ func (r *directRepository) UpdateDescription(d string) { r.cliOpts.Description = d } -// Logger returns the internal logger for the repository. -func (r *directRepository) InternalLogger() logging.Logger { - return r.sm.InternalLogger() +// AlsoLogToContentLog returns a context that causes all logs to also be sent to content log. +func (r *directRepository) AlsoLogToContentLog(ctx context.Context) context.Context { + return r.sm.AlsoLogToContentLog(ctx) } // NewWriter returns new RepositoryWriter session for repository. diff --git a/snapshot/snapshotmaintenance/snapshotmaintenance.go b/snapshot/snapshotmaintenance/snapshotmaintenance.go index d86579894..e48deb577 100644 --- a/snapshot/snapshotmaintenance/snapshotmaintenance.go +++ b/snapshot/snapshotmaintenance/snapshotmaintenance.go @@ -15,7 +15,7 @@ func Run(ctx context.Context, dr repo.DirectRepositoryWriter, mode maintenance.Mode, force bool, safety maintenance.SafetyParameters) error { // nolint:wrapcheck return maintenance.RunExclusive(ctx, dr, mode, force, - func(runParams maintenance.RunParameters) error { + func(ctx context.Context, runParams maintenance.RunParameters) error { // run snapshot GC before full maintenance if runParams.Mode == maintenance.ModeFull { if _, err := snapshotgc.Run(ctx, dr, true, safety); err != nil {