I would like to configure logging appender based on the environment, for example while running in production I would like to configure an appender that would send log to elasticsearch but while on test or development mode this appender would not be enabled.
You can override the default logback config file by using logback.configurationFile
system variable.
java -Dlogback.configurationFile=logback-prod.xml -jar your.jar
But, if what you need is the ability to use an env variable you can do this without to use a third-party library:
Override the logback system variable inside the main micronaut class before call main, like following
@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); } }
create you custom env based logback config file like:
logback-dev.xml
and put in resources dir.then set env var
MICRONAUT_ENVIRONMENTS=dev
according to your deployment logic.enjoy using
logback-dev.xml
,logback-prod.xml
,logback-stagging.xml
, etc
The work around i found was by doing conditional expressions in logback. You will need the following dependency
<!-- https://mvnrepository.com/artifact/org.codehaus.janino/janino -->
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
<version>3.1.2</version>
</dependency>
Then in your logback.xml
file, you can do a conditional statement such as following for selecting the appender you want to you use based on a micronaut profile. In my case, I wanted to activate the STDOUT
appender if i was running the application locally but i did not want to activate the STDOUT
profile if the app was running in any other environment such as dev or prod profiles, instead i wanted the RSYSLOG
appender to be used.
<root level="info">
<if condition='property("MICRONAUT_ENVIRONMENTS").contains("local")'>
<then>
<appender-ref ref="STDOUT"/>
</then>
<else>
<appender-ref ref="RSYSLOG"/>
</else>
</if>
</root>
You can use conditional statements to configure other properties in your logback file.
As far I understand, Micronaut doesn't have similar thing like Spring boot ( ) implemented. I think logback-production.xml (where production is profile ) doesn't work too - only logback.xml and logback-test.xml is suported.
I wasn't crazy about the idea of having multiple logback config files or pulling in another dependency (janino) to support this use-case.
You can also do this using environment variables.
In my logback.xml
I defined 2 appenders, one for "DEV" and one for "PROD".
Then I dynamically select which appender to use via the LOG_TARGET
variable. If the variable is not set then it defaults to "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>
Yet another approach, if it can be useful for someone. Maybe not the best one but I've been building my micronaut application as native-image and for some reason, the environmental variable inside logback.xml or janino setup did not have any effect during runtime.
Hence, I ended up declaring both references at the root logger and then programmatically removing the appenders I do not want and leaving the one I want based on my configuration or environment variables.
Logback.xml would look like this
<?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>
and then at micronaut start (simplified for the example)
@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);
}
}
© 2022 - 2024 — McMap. All rights reserved.
Micronaut
, but to the logging library you are working with, right? – Tolle-Dlogback.configurationFile=logback-dev.xml
as VM Options? – Covetous