[英]Logback - can you define appender name and class from env variables?
我想要动态 logback appender 属性,可以轻松地将其添加到 logback 配置文件中,但是尝试设置 appender 的类和名称(它们位于 xml 属性中,而不是 appender 元素下的元素中)。
所以这是我的 application.yml(对示例的值进行硬编码,但在实际用例中,在部署到 K8s 集群期间,这些值将作为来自 Helm 的环境变量传递):
log:
config:
appender:
name: CONSOLE
class: ch.qos.logback.core.ConsoleAppender
这是我尝试访问 logback-spring.xml(spring boot version - 2.2.4.RELEASE
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- use Spring default values like patterns -->
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<!-- declaration of ENV properties: -->
<springProperty name="LOG_CONFIG_APPENDER_NAME" source="log.config.appender.name"/>
<springProperty name="LOG_CONFIG_APPENDER_CLASS" source="log.config.appender.class"/>
<appender name="${LOG_CONFIG_APPENDER_NAME}" class="${LOG_CONFIG_APPENDER_CLASS}">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="${LOG_CONFIG_APPENDER_NAME}"/>
</root>
</configuration>
这会导致以下异常:
ERROR in ch.qos.logback.core.joran.action.AppenderAction - Could not create an Appender of type [${LOG_CONFIG_APPENDER_CLASS}]. ch.qos.logback.core.util.DynamicClassLoadingException: Failed to instantiate type ${LOG_CONFIG_APPENDER_CLASS}
所以我的问题是:是否可以动态定义附加程序名称和类?
对于本地环境,我想要简单的控制台日志附加程序。 对于其他任何事情,我将使用
LayoutWrappingEncoder
和JacksonJsonFormatter
为我们的 ELK 堆栈添加自定义字段。
所以你想在你的logback-spring.xml
使用<springProfile>
标签:
<springProfile>
标记允许您根据活动的 Spring 配置文件选择性地包含或排除配置部分。<configuration>
元素中的任何地方都支持<configuration>
文件部分。 使用name
属性指定哪个配置文件接受配置。<springProfile>
标签可以包含一个简单的配置文件名称(例如staging
)或配置文件表达式。 配置文件表达式允许表达更复杂的配置文件逻辑,例如production & (eu-central | eu-west)
。 查看参考指南了解更多详情。
请参阅下面的示例:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<springProfile name="staging">
<!-- configuration to be enabled when the "staging" profile is active -->
</springProfile>
<springProfile name="dev | staging">
<!-- configuration to be enabled when the "dev" or "staging" profiles are active -->
</springProfile>
<springProfile name="!production">
<!-- configuration to be enabled when the "production" profile is not active -->
</springProfile>
</configuration>
我最终在 Groovy 中完成了这项工作,因为将配置映射到 Spring 配置文件对我和我的团队不起作用,因为我们将开发配置文件用于本地和共享开发环境(托管在 K8s 集群上)。
我并不为此感到自豪,但以一个简单的 if 结束了它:
def loggingType = System.getenv('LOGGING_TYPE')
def loggingLevelEnvVar = System.getenv('CUSTOM_LOGGING_LEVEL')
def loggingLevel = loggingLevelEnvVar == null ? INFO : Level.valueOf(loggingLevelEnvVar)
// please do not use a coloured pattern for consoles that will be scrapped
def loggingPattern = System.getenv('LOGGING_LEVEL_PATTERN')
...
if ('JSON'.equalsIgnoreCase(loggingType)) {
appender('CONSOLE', ConsoleAppender) {
encoder(LayoutWrappingEncoder) {
layout(JsonLayout) {
timestampFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS"
timestampFormatTimezoneId = 'Etc/UTC'
appendLineSeparator = true
jsonFormatter(JacksonJsonFormatter) {
prettyPrint = false
}
}
}
}
} else {
appender('CONSOLE', ConsoleAppender) {
encoder(PatternLayoutEncoder) {
pattern = loggingPattern
}
}
}
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.