...

Source file src/edge-infra.dev/pkg/sds/devices/logger/logger.go

Documentation: edge-infra.dev/pkg/sds/devices/logger

     1  package logger
     2  
     3  import (
     4  	"context"
     5  	"log/slog"
     6  	"os"
     7  	"strings"
     8  	"time"
     9  
    10  	"github.com/go-logr/logr"
    11  
    12  	"edge-infra.dev/pkg/lib/fog"
    13  )
    14  
    15  type opts struct {
    16  	logLvl slog.Level
    17  }
    18  
    19  type Option func(*opts)
    20  
    21  const LevelTrace = slog.Level(-8)
    22  
    23  // align with edges log levels and slog log levels
    24  var levels = map[slog.Level]int{
    25  	LevelTrace:      -2,
    26  	slog.LevelDebug: fog.DEBUG,
    27  	slog.LevelInfo:  fog.INFO,
    28  	slog.LevelWarn:  fog.WARN,
    29  	slog.LevelError: fog.ERROR,
    30  }
    31  
    32  // Sets linkerd control plane priority class
    33  func WithLevel(lvl slog.Level) Option {
    34  	return func(o *opts) {
    35  		o.logLvl = lvl
    36  	}
    37  }
    38  
    39  // New returns a new logger with slog
    40  func New(o ...Option) *slog.Logger {
    41  	options := &opts{}
    42  	for _, o := range o {
    43  		o(options)
    44  	}
    45  	return slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: options.logLvl, ReplaceAttr: replaceAttrs()})).With("severity", options.logLvl.String())
    46  }
    47  
    48  // IntoContext will pass the slog into the current context
    49  func IntoContext(ctx context.Context, log *slog.Logger) context.Context {
    50  	return logr.NewContextWithSlogLogger(ctx, log)
    51  }
    52  
    53  // FromContext will return the slog from context. If one does not exist, it will return a new instance.
    54  func FromContext(ctx context.Context) *slog.Logger {
    55  	newLog := logr.FromContextAsSlogLogger(ctx)
    56  	if newLog == nil {
    57  		return New()
    58  	}
    59  	return newLog
    60  }
    61  
    62  // ToLevel converts the log level from string to slog.Level
    63  func ToLevel(logLevel string) slog.Level {
    64  	switch strings.ToLower(logLevel) {
    65  	case "trace":
    66  		return LevelTrace
    67  	case "debug":
    68  		return slog.LevelDebug
    69  	case "error":
    70  		return slog.LevelError
    71  	case "info":
    72  		return slog.LevelInfo
    73  	case "warn":
    74  		return slog.LevelWarn
    75  	default:
    76  		return slog.LevelInfo
    77  	}
    78  }
    79  
    80  // replaceAttrs will replace attributes in the logger
    81  func replaceAttrs() func(groups []string, a slog.Attr) slog.Attr {
    82  	return func(_ []string, attr slog.Attr) slog.Attr {
    83  		if attr.Key == slog.LevelKey {
    84  			level := attr.Value.Any().(slog.Level)
    85  			attr.Value = slog.IntValue(levels[level])
    86  		}
    87  		value := attr.Value
    88  		if value.Kind() != slog.KindTime {
    89  			return attr
    90  		}
    91  		attr.Value = slog.StringValue(value.Time().Format(time.RFC3339))
    92  		return attr
    93  	}
    94  }
    95  

View as plain text