2016-09-01 7 views
1

Я пытаюсь реализовать совместимый с многоуровневым протоколированием журнал регистрации каждого арендатора в другом файле И может быть настроен для каждого арендатора индивидуально.Реализация многопользовательского режима Spring Logback с настраиваемой конфигурацией для каждого арендатора

Я использую Spring Boot в сборке Maven с SLF4j и Logback.

Чтобы получить отдельный файл для каждого арендатора, я использую MCP для установки идентификатора арендатора для каждого запроса.

MDC.put("tenant", "tenant-" + tenant_id); 

Это теперь легко можно выйти арендатора как этот

<encoder> 
    <pattern>%X{tenant} %d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n</pattern> 
</encoder> 

Однако, я не могу поместить их в разные файлы. Более того, у меня нет понятия о том, как определить loglog xml для каждого арендатора.

Я не могу найти никаких хороших примеров, чтобы выйти за рамки основ - есть ли у вас какие-либо предложения?

ответ

1

Вам не повезло, вам нужно будет реализовать свой собственный 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); 
} 

Вы получите LoggingEvent в doAppend, который имеет этот метод: 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); 
} 
+0

Спасибо за советы - я только что нашел «SiftingAppender» Как вы думаете, Appender обеспечивает достаточно для моей цели? –

+0

Да, это в основном делает то, что я описываю, вы можете реализовать свой appender, основанный на этом – Ulises

+0

Спасибо! - Последний вопрос: если я хочу иметь еще один уровень журнала для TenantA, чем у TenantB, достаточно ли установить уровень журнала в начале каждого запроса? У меня возникают проблемы с параллельными запросами? –