logging.go 1.64 KB
Newer Older
1
// Package logging provides shared logger configuration for snapshot binaries.
2
3
4
5
6
7
8
9
10
11
12
13
14
package logging

import (
	"fmt"
	"os"
	"strings"

	"github.com/go-logr/logr"
	"github.com/go-logr/zapr"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

15
// ConfigureLogger creates a logr.Logger from the SNAPSHOT_LOG_LEVEL environment variable.
16
17
18
// output controls where log lines are written ("stdout" or "stderr").
// Supported levels: trace, debug, info, warn, error. Defaults to info.
func ConfigureLogger(output string) logr.Logger {
19
	level := strings.TrimSpace(strings.ToLower(os.Getenv("SNAPSHOT_LOG_LEVEL")))
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
	if level == "" {
		level = "info"
	}

	zapLevel := zapcore.InfoLevel
	var parseErr error
	switch level {
	case "trace", "debug":
		zapLevel = zapcore.DebugLevel
	case "info":
		zapLevel = zapcore.InfoLevel
	case "warn", "warning":
		zapLevel = zapcore.WarnLevel
	case "error":
		zapLevel = zapcore.ErrorLevel
	default:
		parseErr = fmt.Errorf("invalid level %q", level)
	}

	if output == "" {
		output = "stdout"
	}

	zapCfg := zap.Config{
		Level:            zap.NewAtomicLevelAt(zapLevel),
		Development:      false,
		Encoding:         "console",
		EncoderConfig:    zap.NewProductionEncoderConfig(),
		OutputPaths:      []string{output},
		ErrorOutputPaths: []string{"stderr"},
	}
	zapCfg.EncoderConfig.EncodeTime = zapcore.RFC3339NanoTimeEncoder
	zapCfg.EncoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
	zapLog, err := zapCfg.Build()
	if err != nil {
		zapLog, _ = zap.NewDevelopment()
	}

	log := zapr.NewLogger(zapLog)
	if parseErr != nil {
60
		log.WithName("setup").Info("Invalid SNAPSHOT_LOG_LEVEL, falling back to info", "value", level, "error", parseErr)
61
62
63
	}
	return log
}