簡體   English   中英

在多租戶架構中為每個租戶在單獨的文件中記錄異常

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM