Spring 使用每个租户的自定义配置实现 Logback 多租户
Spring Logback multitenancy implementation with custom config per tenant
我正在尝试实现一个多租户兼容的日志记录,它将每个租户登录到不同的文件中并且可以为每个租户单独配置。
我正在使用 Spring 使用 SLF4j 和 Logback 在 Maven 构建中启动。
为了为每个租户实现不同的文件,我使用 MCP 为每个请求设置租户标识符。
MDC.put("tenant", "tenant-" + tenant_id);
现在可以像这样轻松注销租户
<encoder>
<pattern>%X{tenant} %d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n</pattern>
</encoder>
但是,我无法将它们放在不同的文件中。此外,我对如何为每个租户定义 logback xml 没有任何概念。
我找不到任何超越基础知识的好例子 - 你有什么建议吗?
你真不走运,你将不得不实现自己的 appender。不过应该不会太难。界面非常简单:
public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachable<E> {
/**
* Get the name of this appender. The name uniquely identifies the appender.
*/
String getName();
/**
* This is where an appender accomplishes its work. Note that the argument
* is of type Object.
* @param event
*/
void doAppend(E event) throws LogbackException;
/**
* Set the name of this appender. The name is used by other components to
* identify this appender.
*
*/
void setName(String name);
}
您将在 doAppend
中得到一个 LoggingEvent
,它具有此方法:getMDCPropertyMap
,您可以从中区分要追加到哪个文件。
如果我是你,我可能不会了解处理文件的细节,而实际上会有一张常规 RollingFileAppender
的地图。所以您的 doAppend 方法可能如下所示:
private Map<String, Appender> appenders = new ConcurrentHashMap<>();
void doAppend(LoggingEvent event) {
String tenant = event.getMDCPropertyMap().get("tenant");
Appender appender = appenders.get(tenant);
if(appender == null) { //may need to synchronize, careful
appender = initTenantAppender(tenant);
appenders.put(tenant, appender);
}
appender.doAppend(event);
}
我正在尝试实现一个多租户兼容的日志记录,它将每个租户登录到不同的文件中并且可以为每个租户单独配置。
我正在使用 Spring 使用 SLF4j 和 Logback 在 Maven 构建中启动。
为了为每个租户实现不同的文件,我使用 MCP 为每个请求设置租户标识符。
MDC.put("tenant", "tenant-" + tenant_id);
现在可以像这样轻松注销租户
<encoder>
<pattern>%X{tenant} %d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n</pattern>
</encoder>
但是,我无法将它们放在不同的文件中。此外,我对如何为每个租户定义 logback xml 没有任何概念。
我找不到任何超越基础知识的好例子 - 你有什么建议吗?
你真不走运,你将不得不实现自己的 appender。不过应该不会太难。界面非常简单:
public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachable<E> {
/**
* Get the name of this appender. The name uniquely identifies the appender.
*/
String getName();
/**
* This is where an appender accomplishes its work. Note that the argument
* is of type Object.
* @param event
*/
void doAppend(E event) throws LogbackException;
/**
* Set the name of this appender. The name is used by other components to
* identify this appender.
*
*/
void setName(String name);
}
您将在 doAppend
中得到一个 LoggingEvent
,它具有此方法:getMDCPropertyMap
,您可以从中区分要追加到哪个文件。
如果我是你,我可能不会了解处理文件的细节,而实际上会有一张常规 RollingFileAppender
的地图。所以您的 doAppend 方法可能如下所示:
private Map<String, Appender> appenders = new ConcurrentHashMap<>();
void doAppend(LoggingEvent event) {
String tenant = event.getMDCPropertyMap().get("tenant");
Appender appender = appenders.get(tenant);
if(appender == null) { //may need to synchronize, careful
appender = initTenantAppender(tenant);
appenders.put(tenant, appender);
}
appender.doAppend(event);
}