2015-05-31 46 views
10

Chociaż mam przyznało dobrodziejstwa dla użytkowników poniżej, które mają próbowali pomóc, oryginalne pytanie pozostaje bez odpowiedzi. Nie istnieje faktyczne rozwiązanie , które zapewnia, że ​​logback.groovy skonfigurowane rejestrowanie jest honorowane w ramach testów jednoczasowych. Testy załadować config logback i to nie zgłosić odpowiedni poziom, a mimo to rzeczywisty rejestrowanie przetestować (wyłącznie za pośrednictwem slf4j) jest w każdej lub TRACE poziomLogger slf4j nie używa logback skonfigurowanego poziomu

wiem inni napotkał ten sam problem i go jest bardzo denerwujące, gdy testy dużych projektów zabierają dużo więcej czasu ze względu na to, że rejestrowanie konsoli jest zbyt szczegółowe. Nie mogę dalej rzucać nagród pod to pytanie. Mam nadzieję, że ktoś wymyśli dobre rozwiązanie, które pozwoli rejestrowanie testów być odpowiednio skonfigurowane na różnych poziomach za pośrednictwem właściwości systemu. Następnie dla projektu można skonfigurować różne konfiguracje, aby testy mogły być konfigurowane na różnych poziomach progowych rejestrowania.

Moje rejestrowania jest skonfigurowany przez logback poprzez plik logback.groovy

Teraz, kiedy mój projekt Maven POM który agreguje wszystkie inne projekty rozpoczyna się, gdy przechodzi im przez cały właściwość systemu, aby ustawić odpowiedni poziom rejestrowania.

Jednak, gdy testy jednoczęściowe są uruchomione, z jakiegoś powodu program rejestrujący nie pobiera poprawnego poziomu, mimo że klasy testowe static @ beforeClass zapewniają prawidłowe skonfigurowanie dziennika.

To nie są rejestratory w testach, które są problemem, - no - tak, one też -, prawdziwym problemem jest to, że rejestratory w sekcjach kodu, które działają (wszystkie moje programy rejestrujące wszędzie) są ustawione do niewłaściwego poziomu logowania. Nie zbierają tego, co rejestrowane jest po skonfigurowaniu testów programu.

Jednak projekty zgłaszają poprawność, gdy logback inicjuje się za pomocą pliku logback.goovy. Jednak rzeczywisty poziom rejestrowania jest ustawiony na wartość TRACE lub ALL

Z poniższego wyjścia jasno wynika, że ​​funkcja logback skonfigurowała się na INFO. Jednak pierwsza instrukcja zapisywania projektu w TRACE (ostatnia linia) pokazuje, że nie jest ona pobierana.

Pomoc.

------------------------------------------------------- 
T E S T S 
------------------------------------------------------- 
Running groovy.text.StreamingTemplateEngineTest 
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.245 sec 
Running net.abcd.templating.InlinerTest 
01:22:15,265 |-INFO in [email protected] - Added status listener of type [ch.qos.logback.core.status.OnConsoleStatusListener] 
01:22:15,290 |-INFO in [email protected] - Setting ReconfigureOnChangeFilter scanning period to 5 minutes 
01:22:15,290 |-INFO in ReconfigureOnChangeFilter{invocationCounter=0} - Will scan for changes in [[C:\Users\ABDC\Dropbox\workspace\abcd\AbcdTemplating\conf\logback.groovy]] every 300 seconds. 
01:22:15,290 |-INFO in [email protected] - Adding ReconfigureOnChangeFilter as a turbo filter 
01:22:15,312 |-INFO in [email protected] - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender] 
01:22:15,316 |-INFO in [email protected] - Naming appender as [STDOUT] 
*********************************************************** 

LOGGING MODE PROPERTY 'net.abcd.logging.level' SET TO: [info] 
IT CAN BE SET TO: OFF, ERROR, WARN, INFO, DEBUG, TRACE, ALL, INFO 

*********************************************************** 
getLogLevel() returned 'INFO' 
01:22:15,496 |-INFO in [email protected] - Setting level of logger [ROOT] to INFO 
01:22:15,532 |-INFO in [email protected] - Attaching appender named [STDOUT] to Logger[ROOT] 
01:22:15.846 [main] TRACE net.abcd.templating.Inliner - Document: 

Mój plik logback.groovy jest:

displayStatusOnConsole() 
scan('5 minutes') // Scan for changes every 5 minutes. 
setupAppenders() 
setupLoggers() 

def displayStatusOnConsole() { 
    statusListener OnConsoleStatusListener 
} 

def setupAppenders() { 
    appender('STDOUT', ConsoleAppender) { 
     encoder(PatternLayoutEncoder) { 
      pattern = "%d{HH:mm:ss.SSS} [%thread] %-5level %-16logger{50} - %msg%n" 
     } 
    } 
} 


def setupLoggers() {  
    def loglevel = getLogLevel() 
    println("getLogLevel() returned '${loglevel}'") 
    root(loglevel, ['STDOUT']) 
} 

def getLogLevel() { 
    def mode = System.getProperty('net.abcd.logging.level', '') 
    println("***********************************************************") 
    println("") 
    println("LOGGING MODE PROPERTY 'net.abcd.logging.level' SET TO: [${mode}]") 
    println("IT CAN BE SET TO: OFF, ERROR, WARN, INFO, DEBUG, TRACE, ALL, INFO") 
    println("") 
    println("***********************************************************") 
    switch(mode.toLowerCase()){ 
    case 'off': 
     return OFF 
    case 'error': 
     return ERROR 
    case 'warn': 
     return WARN 
    case 'info': 
     return INFO 
    case 'debug': 
     return DEBUG 
    case 'trace': 
     return TRACE 
    case 'all': 
     return ALL 
    default: 
     return INFO 
    } 
} 
+1

Nie wiem, czy to pomaga, ale JUnit instaluje własny program ładujący klasy, o którym wiadomo, że koliduje z ramami logowania. – llogiq

+0

@llogiq Wiem. .... Więc dlaczego konfiguracja uruchomiona przez raport junit jest poprawna, mimo że poszczególne testy tego nie robią. I jak to naprawić? –

Odpowiedz

3

spotkałem podobnego problemu na moich testów JUnit, jak również. Nie mogłem znaleźć dobrego rozwiązania. Użyłem poniżej prac wokół:

import ch.qos.logback.classic.Level; 
import ch.qos.logback.classic.Logger; 
import org.slf4j.LoggerFactory; 
... 
static Logger logger; 
static{ 
    // Logger.ROOT_LOGGER_NAME == "ROOT" 
    logger = ((Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME)); 
    logger.setLevel(Level.INFO); 
} 

...

Myślę, że w twoim przypadku, jakoś biblioteka wykorzystuje swój własny przykład ConsoleAppender którego imię nie jest „STDOUT”. Mam nadzieję, że ustawienie poziomu logu root powinno rozwiązać problem.

root(loglevel, ['ROOT']); 
+0

To jest pomocne. Nie jestem pewien, czy rozwiązuje problem, ponieważ loguję testy na różnych poziomach w zależności od właściwości dostarczanej przez kompilator Reactor. Ale dzięki za bicie. –

+0

próbowałem. nie działa. –

1

Zazwyczaj przesyłamy każde logowanie za pomocą slf4j, a następnie konfigurujemy rejestrowanie za pomocą funkcji logback. Więc nasze zależnościami Maven wyglądać następująco:

<dependency> 
     <groupId>org.slf4j</groupId> 
     <artifactId>slf4j-api</artifactId> 
     <version>${slf4j.version}</version> 
    </dependency> 
    <dependency> 
     <groupId>org.slf4j</groupId> 
     <artifactId>jcl-over-slf4j</artifactId> 
     <version>${slf4j.version}</version> 
    </dependency> 
    <dependency> 
     <groupId>org.slf4j</groupId> 
     <artifactId>log4j-over-slf4j</artifactId> 
     <version>${slf4j.version}</version> 
    </dependency> 
    <dependency> 
     <groupId>org.slf4j</groupId> 
     <artifactId>jul-to-slf4j</artifactId> 
     <version>${slf4j.version}</version> 
    </dependency> 
    <dependency> 
     <groupId>ch.qos.logback</groupId> 
     <artifactId>logback-core</artifactId> 
     <version>${logback.version}</version> 
    </dependency> 
    <dependency> 
     <groupId>ch.qos.logback</groupId> 
     <artifactId>logback-classic</artifactId> 
     <version>${logback.version}</version> 
    </dependency> 

więc jeśli jakiś zależność używa java-commons-logging (JCL), log4j lub java.util.logging (lip) niż jego rejestrowanie zostanie zmostkowany do slf4j. Rejestrowanie aplikacji używa również slf4j i to jest skonfigurowane niż logback.

Może być konieczne użycie jednego z mostów (np. Jcl-over-slf4j) w celu uzyskania kontroli zewnętrznych zależności.

Edytuj: Pavel Horal, dzięki za jul i tak, masz rację. Trzeba zrobić coś więcej niż tylko dodać zależności. Mamy również konfigurator logback, który jawnie wywołuje SLF4JBridgeHandler.install(). Nasz konfigurator ładuje również plik konfiguracji logback i zapomniałem o tym połączeniu. Ale przede wszystkim chciałem wskazać kierunek problemu z wieloma bibliotekami logującymi używanymi przez zewnętrzne zależności i tymi mostami, które mogą umieścić różne biblioteki rejestrowania pod dachem logback.

+0

* "Nie wiem nawet" * -> ['java.util.logging'] (http://docs.oracle.com/javase/7/docs/api/java/util/logging/package-summary .html) ... i to nie jest takie proste, jak * używanie tylko właściwej zależności * - http://stackoverflow.com/questions/9117030/jul-to-slf4j-bridge –

+0

Wszystko używa SLF4J. Właśnie dlatego jest dla mnie zagadką, dlaczego rejestr rejestracyjny jest poprawny, ale wszystkie testy logują się tak, jakby poziom był TRACE lub DOWOLNY. –

+0

Dzięki za grę. Dałem ci nagrodę, mimo że to nie rozwiązuje problemu. To cenny dodatek. –