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

IT小君   2021-12-11T07:25:06

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

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

我试过设置 env vars 之类的,LOGGING_LEVEL_ORG_SPRINGFRAMEWORK=TRACE但这没有效果。logging.level.org.springframework: TRACEapplication.properties做的工作,虽然。

评论(10)
IT小君

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

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

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

2021-12-11T07:25:06   回复
IT小君

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

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

TL; 博士

设置的日志级别有效

LOGGING_LEVEL_COM_ACME_PACKAGE=DEBUG

为特定设置日志级别无效

LOGGING_LEVEL_COM_ACME_PACKAGE_CLASS=DEBUG

怎么可能?

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

这与 Spring 的Relaxed Binding 相关,它提出了环境变量的大写表示法。因此,对于 LoggingApplicationListener 而言,类的典型驼峰式大小写符号是不可见的:必须将 for 的环境变量MyClass定义为MYCLASS并且将myclass在 Spring 的环境中可用(此示例忽略类的完全限定名称)

一旦类的驼峰命名法丢失,在运行时就没有机会恢复原始类名。因此,环境变量中的日志定义不适用于类,而仅适用于包。

2021-12-11T07:25:07   回复
IT小君

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

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

在 spring boot 1.5.3 上测试

2021-12-11T07:25:07   回复
IT小君

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

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

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

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

    应用:
    - 名称:我的应用程序名称
      内存:2048
      环境:
        APP_LOGGING_LEVEL:调试

我希望这将有所帮助。

2021-12-11T07:25:07   回复
IT小君

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

LOGGING_LEVEL_COM_ZAXXER=DEBUG java -jar myApp.jar

或 Spring 框架调试日志:

LOGGING_LEVEL_ORG_SPRINGFRAMEWORK=DEBUG java -jar myApp.jar

或两者:

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

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

2021-12-11T07:25:07   回复
IT小君

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

$ cf set-env <app name> LOGGING_LEVEL_ROOT DEBUG

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

$ cf set-env <app name> LOGGING_LEVEL_ORG_SPRINGFRAMEWORK INFO

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

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

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

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

2021-12-11T07:25:07   回复
IT小君

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

  1. 创建 2 个属性文件:

    application-local.propertiesapplication-remote.properties

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

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

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

2021-12-11T07:25:08   回复
IT小君

在 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

2021-12-11T07:25:08   回复
IT小君

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


登录文件


<?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>

开发文件

<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>

配置文件

<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>
2021-12-11T07:25:08   回复
IT小君

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

$ 出口LOGGING_LEVEL_COM_ACME=错误

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

$ export EUREKA_CLIENT_ENABLED=false

谢谢。

2021-12-11T07:25:08   回复