Micronaut 根据环境配置记录器附加程序

问题描述 投票:0回答:5

我想根据环境配置日志附加程序,例如,在生产中运行时,我想配置一个将日志发送到elasticsearch的附加程序,但在测试或开发模式下,此附加程序将不会启用。

logback micronaut
5个回答
9
投票

您可以使用“logback.configurationFile”系统变量覆盖默认的 logback 配置文件。

java -Dlogback.configurationFile=logback-prod.xml -jar your.jar

但是,如果您需要的是使用环境变量的能力,您可以这样做 无需使用第三方库:

  1. 在调用 main 之前覆盖主 micronaut 类中的 logback 系统变量,如下所示

     @Singleton
     public class MyMicronautApplication  {
    
         public static void main(String[] args) {
             var env = System.getenv("MICRONAUT_ENVIRONMENTS");
    
             if (env != null && !env.isEmpty()) {
                 System.setProperty(ContextInitializer.CONFIG_FILE_PROPERTY, "logback-" + env + ".xml");
             }
    
             Micronaut.run(MyMicronautApplication.class);
    
         }
     }
    
  2. 创建基于自定义环境的 logback 配置文件,例如:logback-dev.xml 并放入资源目录中。

  3. 然后根据您的部署逻辑设置环境变量 MICRONAUT_ENVIRONMENTS=dev 。

  4. 享受使用 logback-dev.xml、logback-prod.xml、logback-stagging.xml 等


8
投票

我发现的解决方法是在 logback 中执行条件表达式。您将需要以下依赖项

<!-- https://mvnrepository.com/artifact/org.codehaus.janino/janino -->
<dependency>
    <groupId>org.codehaus.janino</groupId>
    <artifactId>janino</artifactId>
    <version>3.1.2</version>
</dependency>

然后在您的

logback.xml
文件中,您可以执行如下条件语句,用于根据 micronaut 配置文件选择您想要使用的附加程序。就我而言,如果我在本地运行应用程序,我想激活
STDOUT
附加程序,但如果应用程序在任何其他环境(例如 dev 或 prod 配置文件)中运行,我不想激活
STDOUT
配置文件,而是我希望使用
RSYSLOG
附加器。

    <root level="info">
        <if condition='property("MICRONAUT_ENVIRONMENTS").contains("local")'>
            <then>
                <appender-ref ref="STDOUT"/>
            </then>
            <else>
                <appender-ref ref="RSYSLOG"/>
            </else>
        </if>
    </root>

您可以使用条件语句来配置 logback 文件中的其他属性。


1
投票

据我了解,Micronaut 没有实现类似 Spring boot ( ) 的东西。 我认为 logback-production.xml (其中生产是配置文件 )也不起作用 - 仅支持 logback.xml 和 logback-test.xml。


1
投票

我并不热衷于拥有多个 logback 配置文件或引入另一个依赖项(janino)来支持此用例。

您也可以使用环境变量来执行此操作。

在我的

logback.xml
中,我定义了 2 个附加程序,一个用于“DEV”,一个用于“PROD”。

然后我通过

LOG_TARGET
变量动态选择要使用的附加程序。如果未设置该变量,则默认为“DEV”。

<configuration>

    <appender name="DEV" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%date{ISO8601} %-5level [%X{trace_id},%X{span_id}] [%thread] %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="PROD" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="net.logstash.logback.encoder.LogstashEncoder" />
    </appender>

    <appender name="OTEL" class="io.opentelemetry.instrumentation.logback.v1_0.OpenTelemetryAppender">
        <appender-ref ref="${LOG_TARGET:-DEV}"/>
    </appender>

    <root level="info">
        <appender-ref ref="OTEL"/>
    </root>
</configuration>

0
投票

另一种方法,如果它对某人有用的话。也许不是最好的,但我一直在将 micronaut 应用程序构建为本机映像,并且由于某种原因,logback.xml 或 janino 设置中的环境变量在运行时没有任何效果。

因此,我最终在根记录器中声明了这两个引用,然后以编程方式删除我不需要的附加程序,并根据我的配置或环境变量留下我想要的附加程序。

Logback.xml 看起来像这样

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <appender name="PLAIN" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} - %msg%n</pattern>
    </encoder>
  </appender>
  <appender name="LOGSTASH" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="net.logstash.logback.encoder.LogstashEncoder" />
  </appender>
  <root level="error">
    <appender-ref ref="PLAIN"/>
    <appender-ref ref="LOGSTASH"/>
  </root>
</configuration>

然后在 micronaut 启动(示例中已简化)

@Singleton
public class MyMicronautApplication  {

  public static void main(String[] args) {

    List<String> appenders = new ArrayList<>();
    appenders.add("PLAIN");
    appenders.add("LOGSTASH");

    String appender = System.getenv("LOG_APPENDER");

    LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
    Logger root = loggerContext.getLogger("ROOT");

    appenders.filter(value -> !value.equals(appender))
        .forEach(filtered -> root.detachAppender(filtered));

    Micronaut.run(MyMicronautApplication.class);

  }
}
© www.soinside.com 2019 - 2024. All rights reserved.