2016-02-01 26 views
6

Mam następujący problem: Chcę użyć java.util.logging.Logger. Nie znalazłem różnych zasobów 1, 2, 3, jak można modyfikować zachowanie rejestratora.Jak poprawnie zainicjować rejestratory?

Szczególnie w kwestii 2 (w mojej opinii) podano dobrą strukturę do zainicjowania rejestratorów zgodnie z nazwą klasy. Umożliwia to również modyfikowanie gadatliwości na poziomie pakietu w celu debugowania w razie potrzeby.

Po drobnym wykopaniu problemu dowiedziałem się, że globalny program rejestrujący i "pusty" rejestrator (o nazwie "") to nie to samo. Zobacz także poniższy przykład. Właśnie utworzyłem program rejestrujący foo.Bar, który jest zakotwiczony w pustym rejestratorze zamiast w rejestratorze o nazwie foo. Tylko jeśli najpierw utworzę rejestrator bar, rejestrator bar.Baz jest zakotwiczony do niego poprawnie.

To sprawia, że ​​podejście w this question jest głównie bezużyteczne, ponieważ nie można założyć, że rejestratory nadrzędne mają zostać utworzone wcześniej. Trzeba przeanalizować nazwę klasy i utworzyć rejestratory w miarę potrzeb, o ile widzę.

Czy mam rację, że muszę dodać kod static {...}, aby zainicjować rejestratory w sposób rekursywny przed zainicjowaniem własnego rejestratora? Czy ma to jakiś negatywny wpływ, jeśli wiele klas wywołuje metodę Logger.getLogger(String) dla rejestratorów pakietów (co powoduje ogólne połączenia, np. bar.Baz i bar.FooBaz uzyskać rejestrator bar)?

import java.util.Enumeration; 
import java.util.logging.LogManager; 
import java.util.logging.Logger; 
public class TestLogger 
{ 
    public static void main(String[] args) 
    { 
     // Create the logger directly 
     Logger.getLogger("foo.Bar"); 
     // Create the logger objects step-by-step 
     Logger.getLogger("bar"); 
     Logger.getLogger("bar.Baz"); 
     // Put the available loggers to output 
     Enumeration<String> e = LogManager.getLogManager().getLoggerNames(); 
     while(e.hasMoreElements()) 
     { 
      String s = e.nextElement(); 
      Logger l = Logger.getLogger(s); 
      String p = (l.getParent() == null ? "none" : "'" + l.getParent().getName() + "'"); 
      System.out.println("'" + s + "': " + p); 
     } 
    } 
} 

Wyjście programu jest

'bar': '' 
'global': '' 
'foo.bar': '' 
'bar.baz': 'bar' 
'': none 
+0

'java.utils.Logger's może być trudny. Chociaż nie w pełni rozumiem, jakie jest aktualne pytanie, (prawdopodobnie) ważna informacja dodatkowa: osoby rejestrujące mogą być zbiorem śmieci. Kiedy piszesz 'Logger.getLogger (" foo ") setLevel (x)' w swojej metodzie 'main', a następnie uzyskaj logger z' Logger.getLogger ("foo") 'gdzie indziej, to ** może ** być innym przykładem! Logger uzyskany w 'main' może już być śmieciem zebranym, a drugie wywołanie' getLogger ("foo") 'następnie utworzy nowe wystąpienie. – Marco13

Odpowiedz

1

Negatywnym efektem konieczności Logger.getLogger(String) w każdej klasie jest to, że nie będzie w stanie go wyśmiewać (lub zdać specjalny rejestrator) dla testów.

Przykład: Załóżmy, że trzeba przetestować następujące klasy C:

package a.b; 
class C { 
    private Logger logger; 
    private int capacity; 
    private int size; 
    C(int capacity) { 
    this.logger = Logger.getLogger("a.b.C"); 
    this.capacity = capacity; 
    size = 0; 
    } 
    void add(int item) { 
    if (size >= capacity) { 
     logger.log("You already reached the capacity: " + capacity); 
    } 
    //... 
    } 
} 

Jest to wymóg, aby dodać logi jeśli zostanie osiągnięta pojemność. Teraz musisz to przetestować. To jest bardzo trudne i hacky zrobić test, który sprawdza to:

public void testCapacityReachedLogs() { 
    C c = new C(2); 
    c.add(1); 
    c.add(2); 
    // verify that c logged the exact string: "You already reached the capacity: 2" 
} 

Jednak jeśli masz:

package a.b; 
class D { 
    private Logger logger; 
    private int capacity; 
    private int size; 
    D(Logger logger, int capacity) { 
    this.logger = logger; 
    this.capacity = capacity; 
    size = 0; 
    } 
    void add(int item) { 
    if (size >= capacity) { 
     logger.log("You already reached the capacity: " + capacity); 
    } 
    //... 
    } 
} 

Teraz można drwić Rejestrator:

public void testCapacityReachedLogs() { 
    Logger logger = getMock(Logger.class); 
    D d = new D(logger, 2); 
    d.add(1); 
    d.add(2); 
    verify(logger).log("You already reached the capacity: 2"); 
} 

Uwaga „mock "powiązany kod niekoniecznie podąża za składnią frameworka, to tylko na przykład.

+0

Co masz na myśli mówiąc "naśmiewać się"? Czy możesz wyjaśnić to nieco? –

+0

@ChristianWolf Dodałem przykład z "mock" – Gavriel

+0

Ahh, widzę. Dzięki za wyjaśnienie. –