From f3866b728366d2f631193da5684505d1ced1b28a Mon Sep 17 00:00:00 2001 From: Keepers <104464746+ryanfkeepers@users.noreply.github.com> Date: Thu, 9 Jun 2022 13:17:01 -0600 Subject: [PATCH] add pkg/log with zap log library (#155) Adds a logger pkg using the zap log library. Generally straight- forward, though we'll have to watch out for gotchas with the flush requirements. --- src/cli/cli.go | 7 ++++- src/cli/repo/s3.go | 35 +++++++++++++------------ src/pkg/logger/logger.go | 55 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 17 deletions(-) create mode 100644 src/pkg/logger/logger.go diff --git a/src/cli/cli.go b/src/cli/cli.go index 8f00c52a5..f6fabb848 100644 --- a/src/cli/cli.go +++ b/src/cli/cli.go @@ -1,6 +1,7 @@ package cli import ( + "context" "fmt" "os" @@ -10,6 +11,7 @@ import ( "github.com/alcionai/corso/cli/backup" "github.com/alcionai/corso/cli/config" "github.com/alcionai/corso/cli/repo" + "github.com/alcionai/corso/pkg/logger" ) // The root-level command. @@ -58,7 +60,10 @@ func Handle() { repo.AddCommands(corsoCmd) backup.AddCommands(corsoCmd) - if err := corsoCmd.Execute(); err != nil { + ctx, log := logger.Seed(context.Background()) + defer log.Sync() // flush all logs in the buffer + + if err := corsoCmd.ExecuteContext(ctx); err != nil { fmt.Println(err) os.Exit(1) } diff --git a/src/cli/repo/s3.go b/src/cli/repo/s3.go index 251ac9b13..5d5a75aba 100644 --- a/src/cli/repo/s3.go +++ b/src/cli/repo/s3.go @@ -10,6 +10,7 @@ import ( "github.com/alcionai/corso/cli/config" "github.com/alcionai/corso/cli/utils" "github.com/alcionai/corso/pkg/credentials" + "github.com/alcionai/corso/pkg/logger" "github.com/alcionai/corso/pkg/repository" "github.com/alcionai/corso/pkg/storage" ) @@ -52,20 +53,21 @@ var s3InitCmd = &cobra.Command{ // initializes a s3 repo. func initS3Cmd(cmd *cobra.Command, args []string) error { + log := logger.Ctx(cmd.Context()) + m365 := credentials.GetM365() s3Cfg, commonCfg, err := makeS3Config() if err != nil { return err } - fmt.Printf( - "Called - %s\n\tbucket:\t%s\n\tkey:\t%s\n\t356Client:\t%s\n\tfound 356Secret:\t%v\n\tfound awsSecret:\t%v\n", - cmd.CommandPath(), - s3Cfg.Bucket, - s3Cfg.AccessKey, - m365.ClientID, - len(m365.ClientSecret) > 0, - len(s3Cfg.SecretKey) > 0) + log.Debugw( + "Called - "+cmd.CommandPath(), + "bucket", s3Cfg.Bucket, + "clientID", m365.ClientID, + "hasClientSecret", len(m365.ClientSecret) > 0, + "accessKey", s3Cfg.AccessKey, + "hasSecretKey", len(s3Cfg.SecretKey) > 0) a := repository.Account{ TenantID: m365.TenantID, @@ -102,20 +104,21 @@ var s3ConnectCmd = &cobra.Command{ // connects to an existing s3 repo. func connectS3Cmd(cmd *cobra.Command, args []string) error { + log := logger.Ctx(cmd.Context()) + m365 := credentials.GetM365() s3Cfg, commonCfg, err := makeS3Config() if err != nil { return err } - fmt.Printf( - "Called - %s\n\tbucket:\t%s\n\tkey:\t%s\n\t356Client:\t%s\n\tfound 356Secret:\t%v\n\tfound awsSecret:\t%v\n", - cmd.CommandPath(), - s3Cfg.Bucket, - s3Cfg.AccessKey, - m365.ClientID, - len(m365.ClientSecret) > 0, - len(s3Cfg.SecretKey) > 0) + log.Debugw( + "Called - "+cmd.CommandPath(), + "bucket", s3Cfg.Bucket, + "clientID", m365.ClientID, + "hasClientSecret", len(m365.ClientSecret) > 0, + "accessKey", s3Cfg.AccessKey, + "hasSecretKey", len(s3Cfg.SecretKey) > 0) // TODO: Merge/Validate any local configuration here to make sure there are no conflicts // For now - just reading/logging the local config here (a successful repo connect will overwrite) diff --git a/src/pkg/logger/logger.go b/src/pkg/logger/logger.go new file mode 100644 index 000000000..7c8660228 --- /dev/null +++ b/src/pkg/logger/logger.go @@ -0,0 +1,55 @@ +package logger + +import ( + "context" + "os" + + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +var logCore *zapcore.Core + +func coreSingleton() *zapcore.Core { + if logCore == nil { + // level handling + highPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool { + return lvl >= zapcore.ErrorLevel + }) + lowPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool { + return lvl < zapcore.ErrorLevel + }) + // level-based output + consoleDebugging := zapcore.Lock(os.Stdout) + consoleErrors := zapcore.Lock(os.Stderr) + // encoder type + consoleEncoder := zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig()) + // combine into a logger core + core := zapcore.NewTee( + zapcore.NewCore(consoleEncoder, consoleErrors, highPriority), + zapcore.NewCore(consoleEncoder, consoleDebugging, lowPriority), + ) + logCore = &core + } + return logCore +} + +type loggingKey string + +const ctxKey loggingKey = "corsoLogger" + +// Seed embeds a logger into the context for later retrieval. +func Seed(ctx context.Context) (context.Context, *zap.SugaredLogger) { + l := zap.New(*coreSingleton()) + s := l.Sugar() + return context.WithValue(ctx, ctxKey, s), s +} + +// Ctx retrieves the logger embedded in the context. +func Ctx(ctx context.Context) *zap.SugaredLogger { + l := ctx.Value(ctxKey) + if l == nil { + return zap.New(*coreSingleton()).Sugar() + } + return l.(*zap.SugaredLogger) +}