Home  >  Article  >  Backend Development  >  Is it possible to update the zap logger's log level at runtime?

Is it possible to update the zap logger's log level at runtime?

王林
王林forward
2024-02-08 23:20:31989browse

是否可以在运行时更新 zap 记录器的日志级别?

It is a common requirement for php editor Xigua to update the log level of the zap recorder at runtime. zap is a powerful logging tool that can help us capture and record application running information. Normally, we need to set zap's log level when the application starts, but sometimes we want to be able to dynamically update the log level at runtime to adjust it according to actual needs. In zap, we can achieve this function by using the methods provided by zap's Logger interface. Specifically, we can use `zap.Info()`, `zap.Debug()`, `zap.Warn()` and other methods to dynamically update the log level. In this way, we can flexibly adjust zap's logging behavior at runtime as needed.

Question content

I created a logger using kubebuilder, which is based on the zap logger:

import (
    "flag"
    "github.com/gin-gonic/gin"
    "net/http"
    "os"
    "go.uber.org/zap/zapcore"
    uzap "go.uber.org/zap"
    // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
    // to ensure that exec-entrypoint and run can make use of them.
    _ "k8s.io/client-go/plugin/pkg/client/auth"

    "k8s.io/apimachinery/pkg/runtime"
    utilruntime "k8s.io/apimachinery/pkg/util/runtime"
    clientgoscheme "k8s.io/client-go/kubernetes/scheme"
    ctrl "sigs.k8s.io/controller-runtime"
    "sigs.k8s.io/controller-runtime/pkg/healthz"
    "sigs.k8s.io/controller-runtime/pkg/log/zap"

)

var (
    scheme   = runtime.NewScheme()
    setupLog = ctrl.Log.WithName("setup")
)

var zapOpts []uzap.Option
    zapOpts = append(zapOpts, uzap.AddCaller())
    zapOpts = append(zapOpts, uzap.AddCallerSkip(1))
    zapOpts = append(zapOpts, uzap.AddStacktrace(uzap.DebugLevel))

    opts := zap.Options{
        Development:     developmentFlag,
        StacktraceLevel: stacktraceLevel,
        Level:           level,
        Encoder:         encoder,
        ZapOpts:  zapOpts,
    }

    opts.BindFlags(flag.CommandLine)
    flag.Parse()

    ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))

Now I want to change the log level to zapcore.infolevel at runtime. I didn't find any setloglevel or similar api.

Do I need to create a new option and then set a new level?

I also need to set up the logger using the sigs.k8s.io/controller-runtime/pkg/log/zap library. The interface of the logger comes from go-logr, which implements the logr.logger interface. If I try to change it to zapcore.newcore I can no longer set the logger using ctrl.setlogger.

I want to keep the option to update all options of zap.options and change the log level and still use sigs.k8s.io/controller-runtime/pkg/log/zap## zap in #.

Is it possible to do this?

sigs.k8s.io/controller-runtime/pkg/log/zap and sigs.k8s.io/controller-runtime?

Solution

Better answer: Follow @oliver dain's suggestion and use zap.atomiclevel. See their answers for details.

Another option is to create the core using a custom

levelenabler function. You can use zap.levelenablerfunc to convert a closure to zapcore.levelenabler.

Related documents:

levelenabler Determines whether the given logging level is enabled when logging messages.

levelenablerfunc is a convenience way to implement zapcore.levelenabler using an anonymous function.

The function may return

true or false depending on other variables that change at runtime:

// will be actually initialized and changed at run time 
    // based on your business logic
    var infoEnabled bool 

    errorUnlessEnabled := zap.LevelEnablerFunc(func(level zapcore.Level) bool {
        // true: log message at this level
        // false: skip message at this level
        return level >= zapcore.ErrorLevel || infoEnabled
    })

    core := zapcore.NewCore(
        zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()),
        os.Stdout,
        errorUnlessEnabled,
    )
    logger := zap.New(core)

    logger.Info("foo") // not logged
    
    infoEnabled = true

    logger.Info("foo again") // logged

ps: This code is artificial. Your program must implement initialization, runtime value changes, and proper synchronization (if required) on

infoenabled variables.

You can run this example in the playground:

https://play.golang.org/p/ot3nvnp1bwc

The above is the detailed content of Is it possible to update the zap logger's log level at runtime?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete