Skip to content

Commit

Permalink
logger: add logLevel to DSCI devFlags
Browse files Browse the repository at this point in the history
Allow to override global zap log level from DSCI devFlags. Accepts
the same values as to `--zap-log-level` command line switch.

The parsing code is modified version of the one from
controller-runtime/pkg/log/zap/flag.go.

Deprecate DSCI.DevFlags.logmode.

Signed-off-by: Yauheni Kaliuta <ykaliuta@redhat.com>
  • Loading branch information
ykaliuta committed Oct 18, 2024
1 parent 959f84d commit b8d9cde
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 4 deletions.
4 changes: 4 additions & 0 deletions apis/dscinitialization/v1/dscinitialization_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,13 @@ type DevFlags struct {
// Custom manifests uri for odh-manifests
// +optional
ManifestsUri string `json:"manifestsUri,omitempty"`
// ## DEPRECATED ##: Ignored, use LogLevel instead
// +kubebuilder:validation:Enum=devel;development;prod;production;default
// +kubebuilder:default="production"
LogMode string `json:"logmode,omitempty"`
// Override Zap log level. Can be "debug", "info", "error" or a number (more verbose).
// +optional
LogLevel string `json:"logLevel,omitempty"`
}

type TrustedCABundleSpec struct {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,13 @@ spec:
Internal development useful field to test customizations.
This is not recommended to be used in production environment.
properties:
logLevel:
description: Override Zap log level. Can be "debug", "info", "error"
or a number (more verbose).
type: string
logmode:
default: production
description: '## DEPRECATED ##: Ignored, use LogLevel instead'
enum:
- devel
- development
Expand Down
10 changes: 10 additions & 0 deletions controllers/dscinitialization/dscinitialization_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import (
"github.com/opendatahub-io/opendatahub-operator/v2/controllers/status"
"github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster"
"github.com/opendatahub-io/opendatahub-operator/v2/pkg/deploy"
"github.com/opendatahub-io/opendatahub-operator/v2/pkg/logger"
"github.com/opendatahub-io/opendatahub-operator/v2/pkg/trustedcabundle"
"github.com/opendatahub-io/opendatahub-operator/v2/pkg/upgrade"
)
Expand Down Expand Up @@ -101,6 +102,15 @@ func (r *DSCInitializationReconciler) Reconcile(ctx context.Context, req ctrl.Re
instance = &instances.Items[0]
}

if instance.Spec.DevFlags != nil {
level := instance.Spec.DevFlags.LogLevel
log.V(1).Info("Setting log level", "level", level)
err := logger.SetLevel(level)
if err != nil {
log.Error(err, "Failed to set log level", "level", level)
}
}

if instance.ObjectMeta.DeletionTimestamp.IsZero() {
if !controllerutil.ContainsFinalizer(instance, finalizerName) {
log.Info("Adding finalizer for DSCInitialization", "name", instance.Name, "finalizer", finalizerName)
Expand Down
3 changes: 2 additions & 1 deletion docs/api-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,8 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
| `manifestsUri` _string_ | Custom manifests uri for odh-manifests | | |
| `logmode` _string_ | | production | Enum: [devel development prod production default] <br /> |
| `logmode` _string_ | ## DEPRECATED ##: Ignored, use LogLevel instead | production | Enum: [devel development prod production default] <br /> |
| `logLevel` _string_ | Override Zap log level. Can be "debug", "info", "error" or a number (more verbose). | | |


#### Monitoring
Expand Down
62 changes: 59 additions & 3 deletions pkg/logger/logger.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,68 @@
package logger

import (
"errors"
"flag"
"fmt"
"os"
"strconv"
"strings"
"sync/atomic"

"github.com/go-logr/logr"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
ctrlzap "sigs.k8s.io/controller-runtime/pkg/log/zap"
)

var logLevel atomic.Value

// copy from controller-runtime/pkg/log/zap/flag.go.
var levelStrings = map[string]zapcore.Level{
"debug": zap.DebugLevel,
"info": zap.InfoLevel,
"error": zap.ErrorLevel,
}

// adjusted copy from controller-runtime/pkg/log/zap/flag.go, keep the same argument name.
func stringToLevel(flagValue string) (zapcore.Level, error) {
level, validLevel := levelStrings[strings.ToLower(flagValue)]
if validLevel {
return level, nil
}
logLevel, err := strconv.Atoi(flagValue)
if err != nil {
return 0, fmt.Errorf("invalid log level \"%s\"", flagValue)
}
if logLevel > 0 {
intLevel := -1 * logLevel
return zapcore.Level(int8(intLevel)), nil
}

return 0, fmt.Errorf("invalid log level \"%s\"", flagValue)
}

func SetLevel(levelStr string) error {
if levelStr == "" {
return nil
}
levelNum, err := stringToLevel(levelStr)
if err != nil {
return err
}

// ctrlzap.addDefauls() uses a pointer to the AtomicLevel,
// but ctrlzap.(*levelFlag).Set() the structure itsef.
// So use the structure and always set the value in newOptions() to addDefaults() call
level, ok := logLevel.Load().(zap.AtomicLevel)
if !ok {
return errors.New("stored loglevel is not of type *zap.AtomicLevel")
}

level.SetLevel(levelNum)
return nil
}

// NewNamedLogger creates a new logger for a component.
// If the mode is set (so can be different from the default one),
// it will create a new logger with the specified mode's options.
Expand All @@ -22,6 +76,7 @@ func NewNamedLogger(log logr.Logger, name string, mode string) logr.Logger {
func NewLoggerWithOptions(mode string, override *ctrlzap.Options) logr.Logger {
opts := newOptions(mode)
overrideOptions(opts, override)
logLevel.Store(opts.Level)
return newLogger(opts)
}

Expand All @@ -37,19 +92,19 @@ func newLogger(opts *ctrlzap.Options) logr.Logger {

func newOptions(mode string) *ctrlzap.Options {
var opts ctrlzap.Options
level := zap.NewAtomicLevelAt(zapcore.InfoLevel)

switch mode {
case "devel", "development": // the most logging verbosity
opts = ctrlzap.Options{
Development: true,
StacktraceLevel: zapcore.WarnLevel,
Level: zapcore.InfoLevel,
DestWriter: os.Stdout,
}
case "prod", "production": // the least logging verbosity
opts = ctrlzap.Options{
Development: false,
StacktraceLevel: zapcore.ErrorLevel,
Level: zapcore.InfoLevel,
DestWriter: os.Stdout,
EncoderConfigOptions: []ctrlzap.EncoderConfigOption{func(config *zapcore.EncoderConfig) {
config.EncodeTime = zapcore.ISO8601TimeEncoder // human readable not epoch
Expand All @@ -66,10 +121,11 @@ func newOptions(mode string) *ctrlzap.Options {
opts = ctrlzap.Options{
Development: false,
StacktraceLevel: zapcore.ErrorLevel,
Level: zapcore.InfoLevel,
DestWriter: os.Stdout,
}
}

opts.Level = level
return &opts
}

Expand Down

0 comments on commit b8d9cde

Please sign in to comment.