Newer
Older
EnvoyControlPlane / internal / log / log.go
package internal

import (
	"context"

	"k8s.io/klog/v2"
)

// Logger defines the interface for logging operations.
// The DefaultLogger must satisfy this interface.
// This is necessary so we can store and retrieve the interface type in the context.
type Logger interface {
	Debugf(format string, args ...interface{})
	Infof(format string, args ...interface{})
	Warnf(format string, args ...interface{})
	Errorf(format string, args ...interface{})
}

// Ensure DefaultLogger satisfies the Logger interface.
var _ Logger = (*DefaultLogger)(nil)

// DefaultLogger is enabled when no consuming clients provide
// a logger to the server/cache subsystem.
type DefaultLogger struct {
}

// NewDefaultLogger creates a DefaultLogger.
func NewDefaultLogger() *DefaultLogger {
	// klog is globally initialized. You might call klog.InitFlags(nil)
	// and flag.Parse() earlier in your main function to configure it.
	// We don't do it here as it would conflict with other flag parsing.
	return &DefaultLogger{}
}

// Debugf logs a message at level debug.
// klog's standard Verbosity (V) is used for debugging/info levels.
// V(0) is typically equivalent to Infof, V(1) or higher is for debugging.
func (l *DefaultLogger) Debugf(format string, args ...interface{}) {
	// Using V(2) for typical debug output
	klog.V(2).Infof(format, args...)
}

// Infof logs a message at level info.
func (l *DefaultLogger) Infof(format string, args ...interface{}) {
	klog.Infof(format, args...)
}

// Warnf logs a message at level warn.
func (l *DefaultLogger) Warnf(format string, args ...interface{}) {
	klog.Warningf(format, args...)
}

// Errorf logs a message at level error.
func (l *DefaultLogger) Errorf(format string, args ...interface{}) {
	klog.Errorf(format, args...)
}

// -----------------------------------------------------------------------------
// Context Key and Functions
// -----------------------------------------------------------------------------

// loggerKey is an unexported type for context keys.
// Using an unexported, unique type prevents collisions with other packages' keys.
type loggerKey struct{}

var (
	// defaultLog is a singleton instance of the default logger
	defaultLog = NewDefaultLogger()
)

// WithLogger returns a new context derived from ctx with the provided Logger
// injected into it.
func WithLogger(ctx context.Context, log Logger) context.Context {
	return context.WithValue(ctx, loggerKey{}, log)
}

// LogFromContext extracts the Logger from the context.
// If no Logger is present, it returns the default Logger.
func LogFromContext(ctx context.Context) Logger {
	if ctx == nil {
		return defaultLog
	}

	// Retrieve the value stored with loggerKey{}
	if log, ok := ctx.Value(loggerKey{}).(Logger); ok {
		return log
	}

	// If no logger is found in the context, return the default logger
	return defaultLog
}