2012-01-30 11 views
6

Mam problem dotyczący projektu logback. Moim wymaganiem jest dynamiczne tworzenie właściwości dziennika. Pozwól mi wyjaśnić to na przykładzie.Programowanie logway logowania programowo

Mój projekt tworzy komunikację gniazda z systemem zewnętrznym i może mieć wiele gniazd. Dla każdego gniazda chcę mieć różne pliki dziennika, które będą zawierać przeczytane i wysłane wiadomości. Aby to osiągnąć, programowo tworzę rejestrator dla gniazd. Problem polega na tym, że chcę ponownie skonfigurować rejestratory w oparciu o logback.xml (dodając scan = "true" lub ponownie zainicjalizując logback), utworzone przeze mnie rejestratory stają się bezużyteczne. Jak mogę to naprawić lub czy możesz mi doradzić inne rozwiązanie?

To jest mój plik konfiguracyjny (logback.xml)

<?xml version="1.0" ?> 
<configuration> 
    <property name="HOME_PATH" value="/data/logs/myapp/" scope="CONTEXT" /> 
    <property name="MYAPP_LOG_FILE" value="myapp.log" /> 
    <property name="MYAPP_ROLLING_TEMPLATE" value="%d{yy-MM-dd}" scope="CONTEXT" /> 
    <property name="MYAPP_OLD_LOG_FILE" value="${MYAPP_LOG_FILE}.%d{yy-MM-dd}" /> 
    <property name="DEFAULT_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%file:%line] [%level] %msg%n" scope="CONTEXT" /> 

    <appender name="myAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> 
     <file>${HOME_PATH}${MYAPP_LOG_FILE}</file> 
     <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> 
      <fileNamePattern>${HOME_PATH}${MYAPP_LOG_FILE}.${MYAPP_ROLLING_TEMPLATE}</fileNamePattern> 
     </rollingPolicy> 

     <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> 
      <pattern>${DEFAULT_PATTERN}</pattern> 
     </encoder> 
    </appender> 

    <logger name="com.myapp" level="DEBUG" additivity="false"> 
     <appender-ref ref="myAppender" /> 
    </logger> 

    <root level="OFF"> 
    </root> 
</configuration> 

i tutaj można zobaczyć, jak utworzyć rejestratory programowo (znów to zrobić tylko dla dzienników gniazdo).

public static Logger createLogger(String name) { 
     ch.qos.logback.classic.Logger templateLogger = (ch.qos.logback.classic.Logger) LogUtil.getLogger("com.myapp"); 
     LoggerContext context = templateLogger.getLoggerContext(); 

     String logDir = context.getProperty("HOME_PATH"); 

     PatternLayoutEncoder encoder = new PatternLayoutEncoder(); 
     encoder.setPattern(context.getProperty("DEFAULT_PATTERN")); 
     encoder.setContext(context); 

     DefaultTimeBasedFileNamingAndTriggeringPolicy<ILoggingEvent> timeBasedTriggeringPolicy = new DefaultTimeBasedFileNamingAndTriggeringPolicy<ILoggingEvent>(); 
     timeBasedTriggeringPolicy.setContext(context); 

     TimeBasedRollingPolicy<ILoggingEvent> timeBasedRollingPolicy = new TimeBasedRollingPolicy<ILoggingEvent>(); 
     timeBasedRollingPolicy.setContext(context); 
     timeBasedRollingPolicy.setFileNamePattern(logDir + name + ".log." + context.getProperty("MYAPP_ROLLING_TEMPLATE")); 
     timeBasedRollingPolicy.setTimeBasedFileNamingAndTriggeringPolicy(timeBasedTriggeringPolicy); 
     timeBasedTriggeringPolicy.setTimeBasedRollingPolicy(timeBasedRollingPolicy); 

     RollingFileAppender<ILoggingEvent> rollingFileAppender = new RollingFileAppender<ILoggingEvent>(); 
     rollingFileAppender.setAppend(true); 
     rollingFileAppender.setContext(context); 
     rollingFileAppender.setEncoder(encoder); 
     rollingFileAppender.setFile(logDir + name + ".log"); 
     rollingFileAppender.setName(name + "Appender"); 
     rollingFileAppender.setPrudent(false); 
     rollingFileAppender.setRollingPolicy(timeBasedRollingPolicy); 
     rollingFileAppender.setTriggeringPolicy(timeBasedTriggeringPolicy); 

     timeBasedRollingPolicy.setParent(rollingFileAppender); 

     encoder.start(); 
     timeBasedRollingPolicy.start(); 

     rollingFileAppender.stop(); 
     rollingFileAppender.start(); 

     ch.qos.logback.classic.Logger logbackLogger = (ch.qos.logback.classic.Logger) LogUtil.getLogger(name); 
     logbackLogger.setLevel(templateLogger.getLevel()); 
     logbackLogger.setAdditive(false); 
     logbackLogger.addAppender(rollingFileAppender); 

     return logbackLogger; 
} 

I to jest jak ja ponownie zainicjować logback

private static void initializeLogback() { 
    File logbackFile = new File(logFilePath); 
    System.setProperty("logback.configurationFile", logbackFile.getAbsolutePath()); 
    StaticLoggerBinder loggerBinder = StaticLoggerBinder.getSingleton(); 
    LoggerContext loggerContext = (LoggerContext) loggerBinder.getLoggerFactory(); 

    loggerContext.reset(); 
    JoranConfigurator configurator = new JoranConfigurator(); 
    configurator.setContext(loggerContext); 
    try { 
     configurator.doConfigure(logbackFile); 
    } catch(JoranException e) { 
     throw new ColumbusRuntimeException(e.getMessage(), e); 
    } 
} 

Odpowiedz

3

Wygląda na to potrzebny jest SiftingAppender gdzie dyskryminator byłaby sama id gniazdo, lub dowolny połączony zmienność. Nie wiem, z jakimi problemami napotkasz (kiedy czytasz MDC itp.), Ale to powinno być dobrym punktem wyjścia i wydaje się podobne do twojego przypadku.

+0

W podręczniku logback http://logback.qos.ch/manual/mdc.html napisano, że "logback-classic zakłada, że ​​wartości są umieszczane w MDC z umiarkowaną częstotliwością". czy może obsłużyć 1000 żądań na sekundę? Jaka jest przerwa TPS, kiedy mówimy o "umiarkowanej częstotliwości"? –

+0

Nie jestem pewien. Możesz skontaktować się z autorem lub opublikować na liście mailingowej. Właśnie przypomniałem sobie o tym czytaniu i pomyślałem, że jest podobny do twojego problemu. –

+1

Umieszczam to pytanie na liście adresowej, a Ceki odpowiedział. Oto ona: "Myślę, że modyfikacja 1000 MDC powinna być OK. Spójrz na LogbackMDCAdapter [1], aby uzyskać szczegółowe informacje: Pozdrawiam, [1] [link] http://logback.qos.ch/xref/ch/qos /logback/classic/util/LogbackMDCAdapter.html " –