2017-09-18 4 views
0

Ich möchte Systemprotokolle von Benutzerprotokollen trennen. Systemlogs werden von Entwicklern und Betreuern betrachtet. Benutzerprotokolle stellen Benutzern Systeminformationen ohne alle technischen Details zur Verfügung. Ich möchte die verschiedenen Protokollnachrichten in verschiedenen Dateien speichern, eine für Techniker, eine für Benutzer.Mehrere log4j2 Logger konfigurieren

Ich habe eine Reihe von Optionen einschließlich benutzerdefinierten Ebenen und Filter angeschaut. Ich könnte dem Anfang der Nachricht ein Schlüsselwort hinzufügen, das ein Filter verwenden könnte, um Benutzernachrichten zu identifizieren. Ich experimentiere mit dem Hinzufügen einer separaten Protokollfunktion nur für Benutzermeldungen, die die Standardfehlerstufen verwenden.

Ich habe ein einfaches Demo-Programm zum Testen geschrieben. Es erstellt 2 Logger und generiert dann einige Fehlermeldungen.

package demo; 
import java.io.IOException; 
import org.apache.logging.log4j.Level; 
import org.apache.logging.log4j.LogManager; 
import org.apache.logging.log4j.Logger; 

public class Logdemo { 
private final static Logger logger = LogManager.getLogger(); 
private final static Logger userLog = LogManager.getLogger("demo.userMsg"); 

public static void main(String[] args) throws IOException { 
    try { 
     ((Object) null).toString(); 
    } catch (Exception e) { 
     logger.error("error message", e); 
    } 
    try { 
     ((Object) null).toString(); 
    } catch (Exception e) { 
     logger.fatal("User level Red message" ,e); 
    } 
    try { 
     ((Object) null).toString(); 
    } catch (Exception e) { 
     userLog.error("User level Amber message" ,e); 
    } 
    logger.info("Errors Logged"); 
    userLog.info("Lunch is served."); 
    } 
} 

In der Konfigurationsdatei habe ich:

<Loggers> 
     <Root level="all"> 
      <AppenderRef ref="RollingFile" level="ALL"/> 
      <AppenderRef ref="Console" level="ALL"/> 
     </Root> 
     <userMsg name="demo.userMsg" level = "all"> 
      <AppenderRef ref="UserMsgFile" level="ALL"/> 
     </userMsg> 
    </Loggers> 
</Configuration> 

Daraus erhalte ich folgende Fehlermeldungen von NetBeans:

run: 
2017-09-18 22:20:13,933 main ERROR Error processing element UserMsgFile [Appenders: null]): CLASS_NOT_FOUND 
2017-09-18 22:20:13,936 main ERROR Error processing element userMsg ([Loggers: null]): CLASS_NOT_FOUND 
22:20:14.038 [main] INFO demo.Logdemo - logger starting... 
22:20:14.040 [main] ERROR demo.Logdemo - error message 

Alle der Ausnahmemeldungen an die Konsole geschrieben werden, einschließlich der Nachrichten für das userLog. Ich weiß also, dass beide Logger arbeiten. Der Logger Appender schreibt in eine Datei OK. Vom userLog-Logger, der einen fast identischen Appender verwendet, wird keine Datei erstellt.

Es scheint, dass ich etwas nicht richtig benannt habe, damit log4j2 den Logger findet. Ich habe verschiedene Namenskombinationen ausprobiert, um es richtig zu machen, aber ich kann nicht herausfinden, was das Problem ist.

Die andere Sache, die ich noch nicht habe, ist mit dem UserLog Logger über verschiedene Klassen. Ich muss nicht wissen, in welcher Klasse eine Benutzerprotokollnachricht erzeugt wurde, daher möchte ich den gleichen Protokollierernamen ohne Klassenbezeichner in allen Klassen verwenden. Ich vermute, dass ich das nicht tun kann.

Also meine Fragen sind: Welchen Fehler habe ich in der Konfigurationsdatei gemacht?
Edit: Der folgende Konfigurationseintrag funktioniert. Dies ergibt zwei Logger. Es gab zwei Probleme. Einer war, dass der Name des Loggers der Paketname ist. Der andere war, dass ich das Wort Logger nicht korrekt benutzt habe.

<Loggers> 
    <Logger name="demo" level="all"> <!-- name = package name --> 
     <AppenderRef ref="UserLogFile" level="ALL" /> 
    </Logger> 
    <Root level="all"> 
     <AppenderRef ref="Console" level="ALL"/> 
     <AppenderRef ref="SystemLogFile" level="ALL"/> 
    </Root> 
</Loggers> 

Muss ich den Klassennamen in die Loggerinitiierung in jeder Klasse aufnehmen?
Edit: Ich musste den Paketnamen enthalten. Das hat eine Weile gedauert, bis ich es herausgefunden hatte.

Das andere Problem, das ich hatte, war Debug-Meldungen für log4j2 einzuschalten. Dies wird erreicht mit:

<Configuration status="WARN"> <!-- to debug, set status="TRACE" --> 

Antwort

0

Ich habe meinen Ansatz geändert. Ich habe die Marker-Funktion mit einem zusätzlichen Logger verwendet. Das Hinzufügen einer Markierung zu einer Protokollnachricht ermöglicht es mir, einen anderen Appender zu verwenden, um Benutzernachrichten zu verarbeiten. Der Beispielcode sieht wie folgt aus:

import java.io.IOException; 
import org.apache.logging.log4j.LogManager; 
import org.apache.logging.log4j.Logger; 
import org.apache.logging.log4j.MarkerManager; 
import org.apache.logging.log4j.Marker; 

    public class Logdemo { 

    private final static Logger logger = LogManager.getLogger(); 
    static final Marker usrMkr = MarkerManager.getMarker("USR"); 

    public static void main(String[] args) throws IOException { 
     logger.info("logger starting..."); 

     try { 
      ((Object) null).toString(); 
     } catch (Exception e) { 
      logger.fatal(usrMkr,"User message"); 
     } 
     try { 
      ((Object) null).toString(); 
     } catch (Exception e) { 
      logger.debug("Debug error message" ,e); 
     } 
     logger.info("Errors Logged"); 
     } 
    } 

Die relevanten Teile der Konfigurationsdatei wie folgt aussehen:

 <RollingFile 
     name="UserLogFile" 
     fileName="${basePath}/UserMsg.log" 
     immediateFlush="false" 
     filePattern="logs/$${date:yyyy-MM}/user-%d{MM-dd-yyyy}-%i.log"> 
     <MarkerFilter marker="USR" onMatch="ACCEPT" onMismatch="DENY"/> 
    </RollingFile> 
</Appenders> 

<Loggers> 
    <Logger name="demo" level="all"> 
     <AppenderRef ref="UserLogFile" level="ALL"/> 
    </Logger> 
    <Root level="all"> 
     <AppenderRef ref="Console" level="ALL"/> 
     <AppenderRef ref="RollingFile" level="ALL"/> 

    </Root> 

</Loggers> 

ich eine appender erstellt mit dem MarkerFilter Befehl hinzugefügt. Ich richtete den Logger auf den Appender, um markierte Nachrichten in eine separate Datei umzuleiten. Anmerkung aus Gründen der Kürze habe ich große Teile der XML-Datei gehackt.

+0

Hallo Dazz, sollte einer Ihrer Ansätze funktionieren. Ich habe bemerkt, dass Sie gesagt haben: "Durch Hinzufügen eines Markers zu einer Protokollnachricht kann ich einen anderen Appender verwenden, um Benutzermeldungen zu verarbeiten." Dies ist jedoch ohne Marker möglich. Ich denke, dass Sie mit Markern auf dem richtigen Weg sind, denn wenn Sie keine Marker verwenden würden, müssten Sie mehrere Logger erstellen und ich finde das weniger lesbar. –

+0

Eine andere Sache - wenn der "Demo" -Logger der einzige Grund ist, den "UserLogFile" -Appender zuzuweisen, dann brauchen Sie diesen Logger nicht wirklich. Da Ihr Appender einen MarkerFilter hat, können Sie ihn dem Root Logger zuweisen und er sollte genauso funktionieren. –

+0

Hallo # D.B Nach einem steilen Anstieg der Logger Lernkurve (und immer noch ein langer Weg), der Code, den ich geschrieben habe, macht den Job. Ich kann sehen, dass der Demologger nicht benötigt wird, aber ich denke, dass ich ihn dort habe, wird es mir in einigen Jahren leichter machen, den Code zu lesen, wenn ich vergessen habe, was ich getan habe. – dazz

Verwandte Themen