![](/img/trans.png)
[英]Multi-Tenancy with Spring + Hibernate: "SessionFactory configured for multi-tenancy, but no tenant identifier specified"
[英]Log exceptions in separate files for each tenant in multi-tenancy architecture
我有一個支持多租戶的應用程序,即一台服務器和多個數據庫,每個租戶都有單獨的數據庫。 應用程序中拋出的所有異常都將記錄在一個日志中。 租戶ID 將與異常一起打印。
我想在單獨的文件中處理它,即每個租戶都有一個單獨的日志文件。 這將有助於確定此異常是由屬於特定租戶的用戶完成的活動引起的。 是否有可能使用自定義ObjectRenderer
或任何其他技術來實現這一點。 提前致謝。
我的建議是創建自己的Appenders
。 在自定義Appenders
你可以做任何你想做的事情,比如單獨的日志文件等等,
參考: 如何在 log4j 中創建自己的 Appender? http://logging.apache.org/log4j/2.x/manual/extending.html
我建議您將 logback 與 MDC 一起使用。
請參閱文檔
我正在使用請求響應過濾器,在請求過濾器中,我會將tenantId
添加到 MDC 上下文中,讀取請求對象中的值,並在響應過濾器中從 MDC 中刪除它。
在 logback 配置中,將文件名配置為,
<file>${FILE_PATH}/${tenantId}.log</file>
將鑒別器指定為,
<discriminator>
<key>tenantId</key>
<defaultValue>defaultFileName</defaultValue>
</discriminator>
在這里,logback 將tenantId
視為鑒別器並從MDC 上下文中獲取它,如果它不可用,則將其設置為默認值。
以下是我們正在使用的完整配置,
<property name="USER_HOME" value="/home/logs" />
<appender name="FILE-THREAD" class="ch.qos.logback.classic.sift.SiftingAppender">
<!-- This is MDC value -->
<!-- This is being set via request response filter via Java code -->
<discriminator>
<key>tenantId</key>
<defaultValue>applyService</defaultValue>
</discriminator>
<sift>
<!-- A standard RollingFileAppender, the log file is based on 'logFileName' at runtime -->
<appender name="FILE-${tenantId}"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${USER_HOME}/${tenant}.log</file>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>
%d{yyyy-MM-dd HH:mm:ss} [%level] [%logger:%line] [%mdc{tenant}] [%mdc{username}] - %msg%n
</Pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>${USER_HOME}/${tenant}-%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern>
<!-- each file should be at most 10MB, keep 60 days worth of history-->
<maxFileSize>10MB</maxFileSize>
<maxHistory>60</maxHistory>
</rollingPolicy>
</appender>
</sift>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%d{yyyy-MM-dd HH:mm:ss} [%level] [%logger:%line] [%mdc{tenant}] [%mdc{username}] - %msg%n
</Pattern>
</layout>
</appender>
<logger name="com.test.client" level="debug" additivity="false">
<appender-ref ref="FILE-THREAD" />
</logger>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
Java代碼:
@Provider
public class RequestandResponseFilter implements ContainerRequestFilter, ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
throws IOException {
MDC.remove( "tenantId" );
}
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
String reqJsonStr = EMPTY_STRING;
try (BufferedReader buffer = new BufferedReader(new InputStreamReader( requestContext.getEntityStream() ))) {
reqJsonStr = buffer.lines().collect(Collectors.joining("\n"));
}
if( reqJsonStr != null && !reqJsonStr.isEmpty() ) {
JsonObject reqJson = //convertStringtoJson
MDC.put("tenantId", reqJson.get("tenantId"));
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.