简体   繁体   English

更改容器运行时的日志级别

[英]Change log level on runtime for containers

im using logrus for logging for out applications which run on K8S we have env variable which we can set the log-level and change it when we restart out application our applications is running with docker containers on k8s Now we want to change the log-level on runtime, ie don't restart the container and change it when it's running and with this we can change it from error to debug , I think this is legitimic request but didn't find any reference or any open source which doing this, any idea? 我使用logrus来注销在K8S上运行的应用程序,我们有一个env变量,我们可以设置log-level并在重启应用程序时更改它,我们的应用程序在k8s上使用docker容器运行现在我们要更改日志级别在运行时,即不要重新启动容器并在运行时更改它,并且我们可以将其从error更改为debug ,我认为这是合法的要求,但没有找到任何引用或开放源代码理念?

package logs

import (
    "fmt"
    "os"

    "github.com/sirupsen/logrus"
)

const (
    AppLogLevel = “APP_LOG_LEVEL"
    DefLvl = "info"
)


var Logger *logrus.Logger


func NewLogger() *logrus.Logger {

    var level logrus.Level
    lvl := getLogLevel()
    // In case level doesn't set will not print any message
    level = logLevel(lvl)
    logger := &logrus.Logger{
        Out:   os.Stdout,
        Level: level,
    }
    Logger = logger
    return Logger
}

// use from env
func getLogLevel() string {
    lvl, _ := os.LookupEnv(AppLogLevel)
    if lvl != "" {
        return lvl
    }
    return DefLvl
}

func logLevel(lvl string) logrus.Level {

    switch lvl {
    case "debug":
        // Used for tracing
        return logrus.DebugLevel
    case "info":
        return logrus.InfoLevel
    case "error":
        return logrus.ErrorLevel
    case "fatal":
        return logrus.FatalLevel
    default:
        panic(fmt.Sprintf("the specified %s log level is not supported", lvl))
    }
}

I know how to change the log level but I need a way to infuance the logger to change the level 我知道如何更改日志级别,但是我需要一种方法来促使记录器更改级别

As a general Un*x statement, you cannot change an environment variable in a process after it has started. 作为一般的Un * x语句,启动后无法在进程中更改环境变量。 (You can setenv (3) your own environment, and you can specify a new process's environment when you execve (2) it, but once it's started, you can't change it again.) (您可以SETENV(3)自己的环境,而当你的execve(2你可以指定一个新的进程的环境),但一旦它开始,就不能再次进行更改。)

This restriction carries through to higher levels. 这种限制会延续到更高的水平。 If you've docker run a container, its -e option to set an environment variable is one of the things you have to delete and recreate a container to change. 如果您已经docker rundocker run ,则其-e选项来设置环境变量是您必须删除并重新创建要更改的容器之一。 The env: is one of the many immutable parts of a Kubernetes Pod specification; env:是Kubernetes Pod规范中许多不变的部分之一; you also can't change it without deleting and recreating the pod. 您也不能在不删除并重新创建广告连播的情况下进行更改。

If you've deployed the pod via a Deployment (and you really should), you can change the environment variable setting in the Deployment spec (edit the YAML file in source control and kubectl apply -f it, or directly kubectl edit ). 如果您确实是通过Deployment部署了Pod,则可以更改Deployment规范中的环境变量设置(在源代码管理中编辑YAML文件,然后kubectl apply -f it或直接kubectl edit )。 This will cause Kubernetes to start new pods with the new log value and shut down old ones, in that order, doing a zero-downtime update. 这将导致Kubernetes使用新的日志值启动新的Pod并按该顺序关闭旧的Pod,进行零停机时间更新。 Deleting and recreating pods like this is totally normal and happens whenever you want to, for example, change the image inside the deployment to have today's build. 像这样删除和重新创建Pod是完全正常的,并且每当您想要更改部署内部的映像以拥有当今的构建时便会发生。

If your application is capable of noticing changes to config files it's loaded (and it would have to be specially coded to do that) one other path that could work for you is to mount a ConfigMap into a container ; 如果您的应用程序能够注意到对配置文件的更改,则它已被加载(并且必须对此进行特殊编码),另一种可能对您有用的路径是将ConfigMap装入容器 if you change the ConfigMap contents, the files the container sees will change but it will not restart. 如果更改ConfigMap内容,则容器看到的文件将更改,但不会重新启动。 I wouldn't go out of my way to write this just to avoid restarting a pod, though. 不过,我不会竭尽全力编写此代码,只是为了避免重新启动Pod。

You can run the command kubectl exec -it <container_name> bash and use the command line inside the container to change the environment variable . 您可以运行命令kubectl exec -it <container_name> bash并使用容器内的命令行更改环境变量。 You can do it by running the command export LOG_LEVEL=debug or export LOG_LEVEL=error inside the container. 您可以通过在容器内运行命令export LOG_LEVEL=debugexport LOG_LEVEL=error来实现。

First off, understand this should happen on the application level. 首先,了解这应该在应用程序级别上发生。 Ie it's not something that Kubernetes is supposed to do for you. 也就是说,Kubernetes应该不会为您做这件事。

That being said, you could have your application checking an environment variable's value (you are already doing this), and depending on what that value is, it can set the application's log-level. 话虽如此,您可以让您的应用程序检查环境变量的值(您已经在执行此操作),并且根据该值是多少,它可以设置应用程序的日志级别。 In other words, let the application code poll an environment variable to see if it has changed. 换句话说,让应用程序代码轮询环境变量以查看其是否已更改。

You can inject environment variables like Shahaf suggests, but that requires you to exec into the pod, which may not always be possible or good practice. 你可以注入环境变量,如Shahaf建议,但是这需要你exec进入吊舱,这可能并不总是可能的或好的做法。

I would suggest you run kubectl set env rs [REPLICASET_NAME] SOME_ENVIRONMENT_VAR=1 . 我建议您运行kubectl set env rs [REPLICASET_NAME] SOME_ENVIRONMENT_VAR=1

All of this being said, you need to consider why this is important. 综上所述,您需要考虑为什么这很重要。 Kubernetes is built under the principle that " pods should be treated like cattle, not pets ". Kubernetes的建立原则是“ 应将豆荚视为牛,而不是宠物 ”。 Meaning when a pod is no longer useful, or out of sync, it should be terminated and a new one, that represents the code's current state, should be booted up in its stead. 这意味着当某个Pod不再有用或不同步时,应终止该Pod,并代替它启动一个代表代码当前状态的新Pod。

Regardless of how you go about doing what you need to do, you REALLY shouldn't be doing this in production, or even in staging. 不管您如何去做自己需要做的事情,您都绝对不应该在生产甚至阶段中做到这一点。

Instead let your app's underlying environment variables set a log-level that is appropriate for that environment. 而是让您的应用程序的基础环境变量设置适合该环境的日志级别。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM