Embed logging functionality to DRY code

Signed-off-by: Evans Mungai <mbuevans@gmail.com>
pull/31411/head
Evans Mungai 3 months ago
parent 9c32e34d60
commit 5ab4ca5490
No known key found for this signature in database
GPG Key ID: BBEB812143DD14E1

@ -20,6 +20,7 @@ import (
"context"
"log/slog"
"os"
"sync/atomic"
)
// DebugEnabledFunc is a function type that determines if debug logging is enabled
@ -93,3 +94,28 @@ type LoggerSetterGetter interface {
// Logger returns the logger for the object
Logger() *slog.Logger
}
type LogHolder struct {
// logger is an slog.Logger pointer to use the driver
logger atomic.Pointer[slog.Logger]
}
// Logger returns the logger for the LogHolder. If nil, returns slog.Default().
func (l *LogHolder) Logger() *slog.Logger {
if lg := l.logger.Load(); lg != nil {
return lg
}
return slog.Default() // We rarely get here, just being defensive
}
// SetLogger sets the logger for the LogHolder. If nil, sets the default logger.
func (l *LogHolder) SetLogger(newLogger *slog.Logger) {
if newLogger == nil {
l.logger.Store(slog.New(slog.DiscardHandler)) // Assume nil as discarding logs
return
}
l.logger.Store(newLogger)
}
// Ensure LogHolder implements LoggerSetterGetter
var _ LoggerSetterGetter = &LogHolder{}

@ -29,7 +29,6 @@ import (
"slices"
"strings"
"sync"
"sync/atomic"
"text/template"
"time"
@ -41,6 +40,7 @@ import (
"sigs.k8s.io/kustomize/kyaml/kio"
kyaml "sigs.k8s.io/kustomize/kyaml/yaml"
"helm.sh/helm/v4/internal/logging"
"helm.sh/helm/v4/pkg/chart/common"
chart "helm.sh/helm/v4/pkg/chart/v2"
chartutil "helm.sh/helm/v4/pkg/chart/v2/util"
@ -110,11 +110,11 @@ type Configuration struct {
// HookOutputFunc called with container name and returns and expects writer that will receive the log output.
HookOutputFunc func(namespace, pod, container string) io.Writer
// logger is an slog.Logger pointer to use with the Configuration instance
logger atomic.Pointer[slog.Logger]
// Mutex is an exclusive lock for concurrent access to the action
mutex sync.Mutex
// Embed a LogHolder to provide logger functionality
logging.LogHolder
}
func NewConfiguration() *Configuration {
@ -554,23 +554,6 @@ func (cfg *Configuration) SetHookOutputFunc(hookOutputFunc func(_, _, _ string)
cfg.HookOutputFunc = hookOutputFunc
}
// Logger returns the logger for the Configuration. If nil, returns slog.Default().
func (cfg *Configuration) Logger() *slog.Logger {
if lg := cfg.logger.Load(); lg != nil {
return lg
}
return slog.Default() // We rarely get here, just be defensive
}
// SetLogger sets the logger for the Configuration. If nil, sets the default logger.
func (cfg *Configuration) SetLogger(newLogger *slog.Logger) {
if newLogger == nil {
cfg.logger.Store(slog.New(slog.DiscardHandler)) // Assume nil as discarding logs
return
}
cfg.logger.Store(newLogger)
}
func determineReleaseSSApplyMethod(serverSideApply bool) release.ApplyMethod {
if serverSideApply {
return release.ApplyMethodServerSideApply

@ -30,7 +30,6 @@ import (
"reflect"
"strings"
"sync"
"sync/atomic"
jsonpatch "github.com/evanphx/json-patch/v5"
v1 "k8s.io/api/core/v1"
@ -40,6 +39,8 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
"helm.sh/helm/v4/internal/logging"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
@ -82,11 +83,12 @@ type Client struct {
Factory Factory
// Namespace allows to bypass the kubeconfig file for the choice of the namespace
Namespace string
// logger is an slog.Logger pointer to use with the kube client
logger atomic.Pointer[slog.Logger]
Waiter
kubeClient kubernetes.Interface
// Embed a LogHolder to provide logger functionality
logging.LogHolder
}
var _ Interface = (*Client)(nil)
@ -1198,19 +1200,3 @@ func (e *joinedErrors) Error() string {
func (e *joinedErrors) Unwrap() []error {
return e.errs
}
// logger returns the logger for the Client. If nil, returns slog.Default().
func (c *Client) Logger() *slog.Logger {
if lg := c.logger.Load(); lg != nil {
return lg
}
return slog.Default() // We rarely get here, just being defensive
}
func (c *Client) SetLogger(newLogger *slog.Logger) {
if newLogger == nil {
c.logger.Store(slog.New(slog.DiscardHandler)) // Assume nil as discarding logs
return
}
c.logger.Store(newLogger)
}

@ -22,7 +22,6 @@ import (
"log/slog"
"strconv"
"strings"
"sync/atomic"
"time"
v1 "k8s.io/api/core/v1"
@ -32,6 +31,7 @@ import (
"k8s.io/apimachinery/pkg/util/validation"
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
"helm.sh/helm/v4/internal/logging"
"helm.sh/helm/v4/pkg/release"
rspb "helm.sh/helm/v4/pkg/release/v1"
)
@ -45,8 +45,9 @@ const ConfigMapsDriverName = "ConfigMap"
// ConfigMapsInterface.
type ConfigMaps struct {
impl corev1.ConfigMapInterface
// logger is an slog.Logger pointer to use the driver
logger atomic.Pointer[slog.Logger]
// Embed a LogHolder to provide logger functionality
logging.LogHolder
}
// NewConfigMaps initializes a new ConfigMaps wrapping an implementation of
@ -281,19 +282,3 @@ func newConfigMapsObject(key string, rls *rspb.Release, lbs labels) (*v1.ConfigM
Data: map[string]string{"release": s},
}, nil
}
// logger returns the logger for the ConfigMaps driver. If nil, returns slog.Default().
func (cfgmaps *ConfigMaps) Logger() *slog.Logger {
if lg := cfgmaps.logger.Load(); lg != nil {
return lg
}
return slog.Default() // We rarely get here, just being defensive
}
func (cfgmaps *ConfigMaps) SetLogger(newLogger *slog.Logger) {
if newLogger == nil {
cfgmaps.logger.Store(slog.New(slog.DiscardHandler)) // Assume nil as discarding logs
return
}
cfgmaps.logger.Store(newLogger)
}

@ -21,8 +21,8 @@ import (
"strconv"
"strings"
"sync"
"sync/atomic"
"helm.sh/helm/v4/internal/logging"
"helm.sh/helm/v4/pkg/release"
)
@ -44,8 +44,8 @@ type Memory struct {
namespace string
// A map of namespaces to releases
cache map[string]memReleases
// logger is an slog.Logger pointer to use the driver
logger atomic.Pointer[slog.Logger]
// Embed a LogHolder to provide logger functionality
logging.LogHolder
}
// NewMemory initializes a new memory driver.
@ -253,18 +253,3 @@ func (mem *Memory) rlock() func() {
// ```defer unlock(mem.rlock())```, locks mem for reading at the
// call point of defer and unlocks upon exiting the block.
func unlock(fn func()) { fn() }
func (mem *Memory) Logger() *slog.Logger {
if lg := mem.logger.Load(); lg != nil {
return lg
}
return slog.Default() // We rarely get here, just being defensive
}
func (mem *Memory) SetLogger(newLogger *slog.Logger) {
if newLogger == nil {
mem.logger.Store(slog.New(slog.DiscardHandler)) // Assume nil as discarding logs
return
}
mem.logger.Store(newLogger)
}

@ -22,7 +22,6 @@ import (
"log/slog"
"strconv"
"strings"
"sync/atomic"
"time"
v1 "k8s.io/api/core/v1"
@ -32,6 +31,7 @@ import (
"k8s.io/apimachinery/pkg/util/validation"
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
"helm.sh/helm/v4/internal/logging"
"helm.sh/helm/v4/pkg/release"
rspb "helm.sh/helm/v4/pkg/release/v1"
)
@ -45,8 +45,8 @@ const SecretsDriverName = "Secret"
// SecretsInterface.
type Secrets struct {
impl corev1.SecretInterface
// logger is an slog.Logger pointer to use the driver
logger atomic.Pointer[slog.Logger]
// Embed a LogHolder to provide logger functionality
logging.LogHolder
}
// NewSecrets initializes a new Secrets wrapping an implementation of
@ -278,19 +278,3 @@ func newSecretsObject(key string, rls *rspb.Release, lbs labels) (*v1.Secret, er
Data: map[string][]byte{"release": []byte(s)},
}, nil
}
// logger returns the logger for the Secrets driver. If nil, returns slog.Default().
func (secrets *Secrets) Logger() *slog.Logger {
if lg := secrets.logger.Load(); lg != nil {
return lg
}
return slog.Default() // We rarely get here, just being defensive
}
func (secrets *Secrets) SetLogger(newLogger *slog.Logger) {
if newLogger == nil {
secrets.logger.Store(slog.New(slog.DiscardHandler)) // Assume nil as discarding logs
return
}
secrets.logger.Store(newLogger)
}

@ -22,7 +22,6 @@ import (
"maps"
"sort"
"strconv"
"sync/atomic"
"time"
"github.com/jmoiron/sqlx"
@ -33,6 +32,7 @@ import (
// Import pq for postgres dialect
_ "github.com/lib/pq"
"helm.sh/helm/v4/internal/logging"
"helm.sh/helm/v4/pkg/release"
rspb "helm.sh/helm/v4/pkg/release/v1"
)
@ -90,8 +90,8 @@ type SQL struct {
db *sqlx.DB
namespace string
statementBuilder sq.StatementBuilderType
// logger is an slog.Logger pointer to use the driver
logger atomic.Pointer[slog.Logger]
// Embed a LogHolder to provide logger functionality
logging.LogHolder
}
// Name returns the name of the driver.
@ -706,19 +706,3 @@ func getReleaseSystemLabels(rls *rspb.Release) map[string]string {
"version": strconv.Itoa(rls.Version),
}
}
// logger returns the logger for the SQL driver. If nil, returns slog.Default().
func (s *SQL) Logger() *slog.Logger {
if lg := s.logger.Load(); lg != nil {
return lg
}
return slog.Default() // We rarely get here, just being defensive
}
func (s *SQL) SetLogger(newLogger *slog.Logger) {
if newLogger == nil {
s.logger.Store(slog.New(slog.DiscardHandler)) // Assume nil as discarding logs
return
}
s.logger.Store(newLogger)
}

@ -21,7 +21,6 @@ import (
"fmt"
"log/slog"
"strings"
"sync/atomic"
"helm.sh/helm/v4/internal/logging"
"helm.sh/helm/v4/pkg/release"
@ -47,8 +46,8 @@ type Storage struct {
// ignored (meaning no limits are imposed).
MaxHistory int
// logger is an slog.Logger pointer to use the storage engine
logger atomic.Pointer[slog.Logger]
// Embed a LogHolder to provide logger functionality
logging.LogHolder
}
// Get retrieves the release from storage. An error is returned
@ -349,19 +348,3 @@ func Init(d driver.Driver) *Storage {
}
return s
}
// logger returns the logger for the Storage. If nil, returns slog.Default().
func (s *Storage) Logger() *slog.Logger {
if lg := s.logger.Load(); lg != nil {
return lg
}
return slog.Default() // We rarely get here, just being defensive
}
func (s *Storage) SetLogger(newLogger *slog.Logger) {
if newLogger == nil {
s.logger.Store(slog.New(slog.DiscardHandler)) // Assume nil as discarding logs
return
}
s.logger.Store(newLogger)
}

Loading…
Cancel
Save