Java 通过环境变量在 Spring Boot 中设置日志级别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34181094/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 15:23:05  来源:igfitidea点击:

Set Logging Level in Spring Boot via Environment Variable

javaspringspring-boot

提问by EngineerBetter_DJ

Should it be possible to set logging levels through environment variables alone in a Spring Boot application?

是否可以在 Spring Boot 应用程序中单独通过环境变量设置日志记录级别?

I don't want to use application.propertiesas I'm running on Cloud Foundry and want to pick up changes without a deploy (but after the app has restarted, or restaged to be more precise).

我不想使用,application.properties因为我在 Cloud Foundry 上运行并且想在没有部署的情况下获取更改(但在应用程序重新启动后,或者更精确地重新部署之后)。

I've tried setting env vars like LOGGING_LEVEL_ORG_SPRINGFRAMEWORK=TRACEbut that has no effect. Putting logging.level.org.springframework: TRACEin application.propertiesdoes work though.

我试过像这样设置环境变量,LOGGING_LEVEL_ORG_SPRINGFRAMEWORK=TRACE但这没有效果。把logging.level.org.springframework: TRACEapplication.properties做的工作,虽然。

采纳答案by Timekiller

This is just an idea, but did you try setting

这只是一个想法,但你有没有尝试设置

_JAVA_OPTIONS=-Dlogging.level.org.springframework=TRACE?

_JAVA_OPTIONS=-Dlogging.level.org.springframework=TRACE?

Theoretically, this way -Dlogging.level.org.springframework=TRACEwill be passed as default JVM argument and should affect every JVM instance in your environment.

从理论上讲,这种方式-Dlogging.level.org.springframework=TRACE将作为默认 JVM 参数传递,并且应该会影响您环境中的每个 JVM 实例。

回答by Micha? Urbaniak

I would anyway suggest you to use Spring profiles:

无论如何,我建议您使用 Spring 配置文件:

  1. Create 2 properties files:

    application-local.propertiesand application-remote.properties

    (profile names can be different obviously)

  2. Set the logging level in each file accordingly (logging.level.org.springframework)

  3. Run your application with -Dspring.profiles.active=locallocally and -Dspring.profiles.active=remotefor CF.

  1. 创建 2 个属性文件:

    application-local.propertiesapplication-remote.properties

    (配置文件名称可以明显不同)

  2. 相应地在每个文件中设置日志记录级别 ( logging.level.org.springframework)

  3. 使用-Dspring.profiles.active=local本地和-Dspring.profiles.active=remoteCF运行您的应用程序。

回答by Sparkle8

Yes, you can control logging level using environment variable. Here is how I have implemented for my Spring Boot application, deployed on Cloud Foundry platform.

是的,您可以使用环境变量控制日志记录级别。以下是我为部署在 Cloud Foundry 平台上的 Spring Boot 应用程序实现的方式。

In you log configuration file provide placeholder for logging level to read value from environment variable. Default is INFO.

在您的日志配置文件中,为日志级别提供占位符以从环境变量中读取值。默认为信息。

    <logger name="com.mycompany.apps.cf" level="${APP_LOGGING_LEVEL:-INFO}">
      <appender-ref ref="CONSOLE"/>
    </logger>

And then, in CF deployment manifest file provide environment variable.

然后,在 CF 部署清单文件中提供环境变量。

    applications:
    - name: my-app-name
      memory: 2048
      env:
        APP_LOGGING_LEVEL: DEBUG

I hope this will help.

我希望这将有所帮助。

回答by Eddie B

Here's an example using Logbackwith Janinoto conditionally include different logging configs via properties or environmental variables... The base config, logback.xml is using conditionals for development console logging or production file logging... just drop the following files in /resources/

这是使用带有Janino 的Logback通过属性或环境变量有条件地包含不同日志配置的示例......基本配置 logback.xml 使用条件进行开发控制台日志记录或生产文件日志记录......只需将以下文件放入/resources/



logback.xml

日志文件



<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true">
    <if condition='property("spring.profiles.active").contains("dev")'>
        <then>
            <include resource="org/springframework/boot/logging/logback/base.xml"/>
            <include resource="dev.xml" optional="true"/>
        </then>
    </if>
    <if condition='property("spring.profiles.active").contains("pro")'>
        <then>
            <include resource="org/springframework/boot/logging/logback/base.xml"/>
            <include resource="pro.xml" optional="true"/>
        </then>
    </if>
</configuration>


dev.xml

开发文件

<included>
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <charset>utf-8</charset>
            <Pattern>%-30([%p] [%c:%L]) ? %m%n%rEx</Pattern>
        </encoder>
    </appender>

    <!-- CHATTY LOGGERS HERE.-->
    <logger name="org.springframework" level="DEBUG"/>

    <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
        <resetJUL>true</resetJUL>
    </contextListener>

    <root level="${logback.loglevel}">
        <appender-ref ref="CONSOLE"/>
    </root>

</included>


pro.xml

配置文件

<included>
    <conversionRule conversionWord="wex"
                    converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
    <property name="FILE_LOG_PATTERN"
              value="%d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${PID:- } --- [%t] %-40.40logger{39} : %m%n%wex"/>
    <property name="FILE_NAME_PATTERN" value="./logs/%d{yyyy-MM-dd}-exec.log"/>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>FILE_NAME_PATTERN</fileNamePattern>
            <maxHistory>7</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${FILE_LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
        <queueSize>512</queueSize>
        <appender-ref ref="FILE"/>
    </appender>

    <!-- APP SPECIFIC LOGGERS HERE.-->
    <logger name="org.springframework.boot.SpringApplication" level="INFO"/>

    <root level="INFO">
        <appender-ref ref="FILE"/>
    </root>

</included>

回答by Damian O' Neill

Folks can anyone explain why this is not working?

任何人都可以解释为什么这不起作用?

$ export LOGGING_LEVEL_COM_ACME=ERROR

$ 出口LOGGING_LEVEL_COM_ACME=错误

For all other configuration using environment variables as an override seems to work with no issues, for example:

对于使用环境变量作为覆盖的所有其他配置似乎没有问题,例如:

$ export EUREKA_CLIENT_ENABLED=false

$ export EUREKA_CLIENT_ENABLED=false

Thanks.

谢谢。

回答by Allan Lang

Also using Spring Boot (v1.2.3) in Cloud Foundry, I've found that it is possible to adjust the root logging level using an environment variable as follows:

同样在 Cloud Foundry 中使用 Spring Boot (v1.2.3),我发现可以使用环境变量调整根日志记录级别,如下所示:

$ cf set-env <app name> LOGGING_LEVEL_ROOT DEBUG

Unfortunately, it does not appear to be possible to dial-down the logging level for specific packages (at least with the version of Java Buildpack and Spring Boot I am using). For example adding the following in addition to the above does not reduce the log level for Spring framework:

不幸的是,似乎无法调低特定包的日志记录级别(至少在我使用的 Java Buildpack 和 Spring Boot 版本中)。例如,在上述之外添加以下内容不会降低 Spring 框架的日志级别:

$ cf set-env <app name> LOGGING_LEVEL_ORG_SPRINGFRAMEWORK INFO

If you are using something like Splunk to gather your logs, you may be able to filter out the noise, however.

但是,如果您使用 Splunk 之类的工具来收集日志,则可以过滤掉噪音。

Another alternative which looks promising could be based on customisation of the build pack's arguments option (see here):

另一种看起来很有希望的替代方案可能是基于构建包参数选项的自定义(请参阅此处):

$ cf set-env <app name> '{arguments: "-logging.level.root=DEBUG -logging.level.org.springframework=INFO"}'

Sadly, I couldn't get this to actually work. I certainly agree that being able to reconfigure logging levels at package level without changing the application code would be handy to get working.

可悲的是,我无法让它真正起作用。我当然同意能够在不更改应用程序代码的情况下在包级别重新配置日志记录级别对于开始工作会很方便。

回答by pepuch

I also tried to set logging level via environment variable but as already mentioned it is not possible by using environment variable with upper case name, eg. LOGGING_LEVEL_ORG_SPRINGFRAMEWORK=DEBUG. I also didn't want to do it via application.propertiesor _JAVA_OPTIONS.

我还尝试通过环境变量设置日志记录级别,但如前所述,使用大写名称的环境变量是不可能的,例如。LOGGING_LEVEL_ORG_SPRINGFRAMEWORK=DEBUG. 我也不想通过application.properties或来做_JAVA_OPTIONS

After digging into class org.springframework.boot.logging.LoggingApplicationListenerI've checked that spring boot tries to set logging level DEBUGto ORG_SPRINGFRAMEWORKpackage which is not real package name. So conclusion is that you can use environment variable to set logging level but it needs to be in the form: LOGGING_LEVEL_org.springframework=DEBUG or logging.level.org.springframework=DEBUG

挖掘到下课后org.springframework.boot.logging.LoggingApplicationListener,我检查了春天开机尝试设置日志记录级别DEBUG,以ORG_SPRINGFRAMEWORK包是不是真正的软件包名称。所以结论是您可以使用环境变量来设置日志记录级别,但它需要采用以下形式: LOGGING_LEVEL_org.springframework=DEBUG logging.level.org.springframework=DEBUG

Tested on spring boot 1.5.3

在 spring boot 1.5.3 上测试

回答by PetroCliff

In spring-boot 2.0.0, adding --traceworks. For instance java -jar myapp.jar --debugor java -jar myapp.jar --trace

在 spring-boot 2.0.0 中,添加--trace作品。例如java -jar myapp.jar --debugjava -jar myapp.jar --trace

https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-logging.html#boot-features-logging-console-output

https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-logging.html#boot-features-logging-console-output

回答by t0r0X

Starting with Spring Boot 2.0.x this works again. Tested with Spring Boot v2.0.9.RELEASE. E.g. enable connection pool debug log:

从 Spring Boot 2.0.x 开始,这再次起作用。使用 Spring Boot v2.0.9.RELEASE 进行测试。例如启用连接池调试日志:

LOGGING_LEVEL_COM_ZAXXER=DEBUG java -jar myApp.jar

or Spring framework debug log:

或 Spring 框架调试日志:

LOGGING_LEVEL_ORG_SPRINGFRAMEWORK=DEBUG java -jar myApp.jar

or both:

或两者:

LOGGING_LEVEL_ORG_SPRINGFRAMEWORK=DEBUG LOGGING_LEVEL_COM_ZAXXER=DEBUG java -jar myApp.jar

See "Application Poperties" in Spring Boot Reference Documentationfor more application properties.

有关更多应用程序属性,请参阅Spring Boot 参考文档中的“应用程序属性”。

回答by Peter Wippermann

Setting log levels via environment variables can only be done for Packages but not for Classes

通过环境变量设置日志级别只能对包进行,而不能对类进行

I had the same problem as the OP. And I was wondering why some of the users here reported that the proposed solutions worked well while others responded they didn't.
I'm on Spring Boot 2.1and the problem obviously changed a bit over the last years, but the current situation is as follows:

我遇到了与 OP 相同的问题。我想知道为什么这里的一些用户报告提出的解决方案运行良好,而其他用户则表示没有。
我在Spring Boot 2.1 上,问题显然在过去几年有所改变,但目前的情况如下:

TL;DR

TL; 博士

Setting the log level for a package works:

设置的日志级别有效

LOGGING_LEVEL_COM_ACME_PACKAGE=DEBUG

While setting the log level for a specific class has no effect:

为特定设置日志级别无效

LOGGING_LEVEL_COM_ACME_PACKAGE_CLASS=DEBUG

How can that be?

怎么可能?

Have a look at Spring Boot's LoggingApplicationListener.
If you'd debug it and set a breakpoint in the highlighted code block, you'd see that the log level definition for a class com.acme.mypackage.MyClassbecomes com.acme.mypackage.myclass.
So a log level definition for a class looks exactly like a log level definition for a package.

看看 Spring Boot 的LoggingApplicationListener
如果您调试它并在突出显示的代码块中设置断点,您会看到类的日志级别定义com.acme.mypackage.MyClass变为 com.acme.mypackage.myclass.
所以一个类的日志级别定义看起来就像一个包的日志级别定义。

This is related to Spring's Relaxed Binding, which proposes an upper case notation for environment variables. Thus the typical camel case notation of a class is not available for the LoggingApplicationListener. On the other hand, I think one can't check whether the given fully-qualified path matches a class. The classloader won't find anything as long as the notation doesn't match exactly.

这与 Spring 的Relaxed Binding 相关,它提出了环境变量的大写表示法。因此,LoggingApplicationListener 无法使用类的典型驼峰命名法。另一方面,我认为无法检查给定的完全限定路径是否与类匹配。只要符号不完全匹配,类加载器就不会找到任何东西。

Thus log definitions in environment variables don't work for classes but only for packages.

因此,环境变量中的日志定义不适用于类,而仅适用于包。