Logging mit log4j2 in verschiedene Dateien?

MiMa

Top Contributor
Ich setze zum logging log4j2 ein und soweit funktioniert es ganz gut.
Jedoch erhalte ich eine ziemlich lange Logdatei und mir ist der Gedanke gekommen diese Logs auf zu teilen, da ich diese an verschiedenen Stellen benötige.

Kennt jemand eine Möglichkeit, das ich ein Log erstellen kann welches den Namen der zu untersuchenden Datei erhält jedoch mit der Endung .log.
Dann würde ich aus einer anderen Klasse die Logs in eine separate Datei Speichern.

Meine Konfigurationsdatei
XML:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="[%t] %-5level %logger{36} - %msg%n" />
        </Console>
        <File name="log" fileName="logs/Logger.log" immediateFlush="false" append="false">
            <PatternLayout pattern="%logger{36} - %msg%n"/>
        </File>
    </Appenders>
    <Loggers>
        <Root level="debug">
            <!-- <AppenderRef ref="Console" /> -->
            <AppenderRef ref="log"/>
        </Root>
    </Loggers>
</Configuration>

Danke
Mi
 

thecain

Top Contributor
Ich würde einen speziellen Appender für diese Klasse konfigurieren.
Vielleicht gibts noch andere Lösungen, aber das wäre mein Ansatz
 

MiMa

Top Contributor
In den Appender sind die Namen und der Speicherort der Logdatei fest eingebunden.
Mich würde interessieren ob und wie man das dynamisch machen kann?
Der Name und Speicherort der Logdatei soll sich ständig ändern damit diese nicht überschrieben werden
 

MiMa

Top Contributor
Danke,
kann ich überhaupt einen Dateipfad die während der Laufzeit erstellt werden an eine LOG-Konfigurationsdatei übergeben?
XML:
fileName="${LOG_DIR}/application.log"
Ich weis nicht wie ich das lösen könnte.
 

MiMa

Top Contributor
Die Logdateien sollen zu den zu Überprüften Dateien geschrieben werden.
Das bedeutet, das die Zielverzeichnisse unterschiedlich sind und der Name sich auch ständig ändert.
 

MiMa

Top Contributor
Meine Konfiguration
XML:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
    <Appenders>
        <File name="LogDatei" fileName="${sys:logDateiName}">
            <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/>
        </File>
    </Appenders>
    <Loggers>
        <Root level="INFO">
            <AppenderRef ref="LogDatei"/>
        </Root>
    </Loggers>
</Configuration>
Java Klasse
Java:
package log4j;

import java.util.Properties;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class Logging {

    public static Properties prop = new Properties(System.getProperties());
    
     // Erstellt ein LoggerObjekt
    private static Logger LOG = LogManager.getLogger(Logging.class);

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        
        prop.setProperty("logDateiName", "B:\\Logging.log");
        LOG = LogManager.getLogger(Logging.class);
        
        LOG.info("Erster Informations Log");
        LOG.warn("Erster Warn Log");
    } // main
} // Logging
Fehlermeldung
Code:
2020-06-14 13:40:26,586 main ERROR FileManager (${sys:logDateiName}) java.io.IOException: Die Syntax für den Dateinamen, Verzeichnisnamen oder die Datenträgerbezeichnung ist falsch java.io.IOException: Die Syntax für den Dateinamen, Verzeichnisnamen oder die Datenträgerbezeichnung ist falsch
    at java.base/java.io.WinNTFileSystem.canonicalize0(Native Method)
 

MiMa

Top Contributor
Habe es geändert, die Fehlermeldung ist aber dennoch die gleiche?
Java:
prop.setProperty("logDateiName", "B:/Logging.log");
Das mit den vier Backslashes habe ich leider auch ohne Erfolgt auch probiert??
 
Zuletzt bearbeitet:
K

kneitzel

Gast
Ähm, du willst ein System Property Setzen? Du erstellst eine Instanz und setzt in der eine Property. Das ändert aber nicht die System Property.

Daher wird die gesetzte Property im Logger nie ankommen. System.setProperty müsste dazu aufgerufen werden.

Und ich bin mir unsicher, ob er das erst danach liest oder ob die config Datei nicht schon früher gelesen wird und ob die statische Initialisierung zu entfernen erwas bringt. Aber das wird dein Test dann ja zeigen.
 

MiMa

Top Contributor
Naja, wirklich funktioniert es nicht.
Ich habe gelesen, das die XML Konfiguration den Dateinamen aus den System Preferenzen holt
Code:
${sys:logDateiName}">
Dann muss die aber vorher dort gespeichert werden und das habe ich setProperty versucht.
Da der die Werte vor dem aufruf drin sein muss, habe ich danach den LogManager nochmal geholt.
Irgendwie scheint es aber nicht zu funktionieren???

Gibt es vielleicht noch eine andere Möglichkeit während der Laufzeit in andere Logdateien zu schreiben mit unterschiedlichen Lognamen?
 
Zuletzt bearbeitet:
K

kneitzel

Gast
Hast Du denn die Initialisierung bei der Deklaration auch raus genommen?

private static Logger LOG = LogManager.getLogger(Logging.class)

Das ist aber ggf. auch nicht ausreichend. Ich weiss nicht sicher, wann Log4j die Datei auswertet. Wenn das direkt beim Laden der Klassen passiert, dann dürfte Dein Vorhaben schwer machbar sein.

Aber ich verstehe den Usecase auch nicht wirklich. Woher kommt der Dateiname? Zur Laufzeit? Dann kannst Du den Appender ja im Config-File weg lassen und komplett in Code hinzu fügen. (https://logging.apache.org/log4j/2.x/manual/customconfig.html könnte da etwas hilfreich sein - wurde ja schon verlinkt! Wichtig ist: Du machst die Configuration dann im vor allem im Code! ).

Wenn es aus einer Konfigurationsdatei kommen soll: Dazu hast Du ja die log4j2.xml. Da kann es dann entsprechend vermerkt sein. Oder Du nutzt eigene Config-Files und machst es damit im Code (Eher schlecht - würde ich von abraten, da Du Dich damit stark einschränkst).

Sorry, wenn ich daher nicht wirklich helfen kann - aber mir war im Code halt das Setzen der Property aufgefallen, was eben keine System-Property setzt...
 

thecain

Top Contributor
Du musst das property vor dem Start setzen mit -DlogDateiName=C:/temp/test.log während der Laufzeit funktioniert es nicht. Habe das eben getestet.

Was ich aber eigentlich gemeint habe, wäre sowas: (de.java.Logging ist meine Testklasse, für die speziell geloggt werden soll)

XML:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
    <Appenders>
        <Console name="STDOUT">
            <PatternLayout pattern="%C{1.} %m %level MDC%X%n"/>
        </Console>
        <File name="LogDatei" fileName="c:/temp/test.log">
            <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/>
        </File>
    </Appenders>
    <Loggers>
        <Logger  name="de.java.Logging" level="DEBUG">
            <AppenderRef ref="LogDatei"/>
        </Logger>
        <Root level="INFO">
            <AppenderRef ref="STDOUT" />
        </Root>
    </Loggers>
</Configuration>
 

MiMa

Top Contributor
Der Dateiname der Logdatei wird während der Laufzeit generiert.
So in etwa sollte es aussehen am Beispiel einer eBook-PDF Datei:
B:\Postfach\Der Java Profi.pdf -> Ursprungsdatei und wird danach verschoben nach B:\Bibliothek\Informatik\Java\DerJavaProfi.pdf
B:\Bibliothek\Informatik\Java\DerJavaProfi.log -> Logdatei
B:\Bibliothek\Informatik\Java\DerJavaProfi.xml -> Metadaten
B:\Fehlermeldungen.log -> alle Problemmeldungen
 

MiMa

Top Contributor
Alternative die mir einfallen würde, wäre das schreibe einer Textdatei an der ich die Meldungen einfach anhänge??
 

MiMa

Top Contributor
Habe das Problem gelöst indem ich mir eine eigene Logging Methode geschrieben habe, die mir je nach Art
eine eigene LOG-Datei zur Laufzeit erzeugt.
 
K

kneitzel

Gast
Ok, ich habe jetzt aber auch ein bisschen gebastelt. Irgendwie wollte er bei mir keinen neuen Logger / Appender einfügen. Aber ich habe problemlos einen existierenden Appender austauschen können.

Wieso ersteres nicht lief kann ich nicht sagen. Aber mein aktueller Zwischenstand ist dies:

Meine log4j2.xml definiert eine LogDatei. Das ist dann erst einmal mein Appender, den ich dann weiter verwenden möchte. "de.kneitzel" ist mein Package, aus dem ich logge ...
Code:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
    <Appenders>
        <Console name="STDOUT">
            <PatternLayout pattern="%C{1.} %level %m%n"/>
        </Console>
        <File name="LogDatei" fileName="./test.log">
            <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/>
        </File>
    </Appenders>
    <Loggers>
        <Logger name="de.kneitzel" level="DEBUG">
            <AppenderRef ref="LogDatei"/>
        </Logger>
        <Root level="INFO">
            <AppenderRef ref="STDOUT" />
        </Root>
    </Loggers>
</Configuration>

Dann meine Klasse / Testprogramm:
Java:
package de.kneitzel.test;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.appender.FileAppender;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;

import java.io.Serializable;

public class Log4jAppenderHandler {

    private static Logger log = LogManager.getLogger(Log4jAppenderHandler.class.getName());

    private String appenderName;
    private String packageName;

    private LoggerContext context;
    private Configuration configuration;
    private Layout<? extends Serializable> layout;

    public Log4jAppenderHandler(final String appenderName, final String packageName) {
        this.appenderName = appenderName;
        this.packageName = packageName;

        context = (LoggerContext) LogManager.getContext(false);
        configuration = context.getConfiguration();
        layout = configuration.getAppender(appenderName).getLayout();
    }


    void updateLogger(final String fileName){

        //delete old appender/logger
        configuration.getAppender(appenderName).stop();
        configuration.removeLogger(packageName);

        //create new appender/logger
        LoggerConfig loggerConfig = new LoggerConfig(packageName, Level.INFO, false);
        FileAppender appender = FileAppender.newBuilder()
                .withFileName(fileName)
                .withAppend(false)
                .withLocking(false)
                .setName(appenderName)
                .withImmediateFlush(true)
                .setIgnoreExceptions(true)
                .withBufferedIo(true)
                .withBufferSize(8192)
                .setLayout(layout)
                .setFilter(null)
                .withAdvertise(false)
                .setConfiguration(configuration)
                .build();
        appender.start();
        loggerConfig.addAppender(appender, Level.INFO, null);
        configuration.addLogger(packageName, loggerConfig);

        context.updateLoggers();
    }

    public static void main(String[] args) {
        // First test message...
        log.warn("Start logging test!");

        // appenderName und packageName kommen aus log4j.xml!
        Log4jAppenderHandler log4jHandler = new Log4jAppenderHandler("LogDatei", "de.kneitzel");

        log4jHandler.updateLogger("./test1.log");
        log.warn ("After updating to test1.log!");

        log4jHandler.updateLogger("./test2.log");
        log.warn ("After updating to test2.log!");
    }

}


Bei meinem Testprogramm wird dann das Logging immer schön weiter umgeleitet.
Erst das ./test.log aus dem Config-File. Da landet dann das erste logging drin.
Dann kommt der switch zu test1.log -> und das nächste log kommt da rein.
Dann switch zu test2.log und das letzte log kommt da in die Datei.

Damit hätte man etwas Code, der zur Laufzeit ein Logfile ändern kann.
 

MiMa

Top Contributor
Danke, das du dich damit beschäftigt hast.
Ich kenne mich nicht gut genug damit aus um es so zu lösen. :)
Habe den ganzen Tag damit verbracht und bin da nicht weiter gekommen. Dann habe ich mit ca 10 Zeilen einen eigenen Logger geschrieben, der mir 3 verschiedene Dateien schreibt und konnte meine log4j Anweisungen sehr einfach ändern.
Auf jeden Fall schaue ich mit Deinen Code an und versuche das mal nach zu verfolgen um eine Wissenslücke zu schließen.
Eine Logdatei loggt die Anwendung, eine weitere Loggt nur die erzeugten Metadaten und die dritte Loggt alle Fehler.
Da ich mich noch nicht mit JUnit beschäftigen konnte kontrolliere ich halt die Logs.
 

MiMa

Top Contributor
@JustNobody
nochmal vielen Dank.
Ich habe deinen Lösungsweg verstanden und werde diesen in meiner Version mit Java-FX und GUI implemetieren.
Der File-Appender hat ja echt viele Parameter ;)
Mi
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
8u3631984 Strukturiertes Logging : Jedes Feld in eine seperate Zeile - aber wie ? Allgemeine Java-Themen 2
T Logging mit org.apache.logging.log4j Allgemeine Java-Themen 1
S Input/Output Jave.utill.logging ohne Default-Locale also in Englisch Allgemeine Java-Themen 3
A Automatisches Methoden Laufzeiten logging? Allgemeine Java-Themen 7
M JVM: Client Software Logging und Profiling aktivieren Allgemeine Java-Themen 1
AssELAss Log4j Logging Ausgabe für jede Klasse in seperates File Allgemeine Java-Themen 2
P Logging levels Allgemeine Java-Themen 2
X Logging Messages - mehr Details? Allgemeine Java-Themen 4
F Error Logging - best practices? Allgemeine Java-Themen 3
L util.logging Log Rotation Allgemeine Java-Themen 3
W Java Logging Problem Allgemeine Java-Themen 3
H java.util.logging Formatter Optionen setzen Allgemeine Java-Themen 2
D Logging XMLFormatter Allgemeine Java-Themen 3
B OOP java.util.logging.Logger: Wie kann ich mehre Klassen in ein Logfile schreiben lassen? Allgemeine Java-Themen 12
D Technologiefragen, logging, JMX Allgemeine Java-Themen 3
S Tomcat java.util.logging - keine Logs Allgemeine Java-Themen 12
J Logging mehrerer Methoden Allgemeine Java-Themen 21
S log4j - doppeltes Logging Allgemeine Java-Themen 4
B Logging von Exceptions Allgemeine Java-Themen 7
S log4j Logging über mehrere Klassen Allgemeine Java-Themen 13
P SLF4J Logging Level einstellen Allgemeine Java-Themen 2
DamienX Google Guice AOP + Logging Allgemeine Java-Themen 3
T CP Problem: Webstart + Logging properties file + eigener Handler Allgemeine Java-Themen 7
A java logging api scheint nicht thread save zu sein Allgemeine Java-Themen 22
T Java Logging API in Multi Threaded API Allgemeine Java-Themen 2
P fehlende Mehrfachvererbung logging.Handler impl. Observable Allgemeine Java-Themen 5
M Verbieten Applets die Nutzung von Commons Logging? Allgemeine Java-Themen 7
F Java logging Allgemeine Java-Themen 4
F Java logging Leerzeile als Standardeinstellung Allgemeine Java-Themen 4
S Java logging konfigurieren? Allgemeine Java-Themen 5
DEvent log4j, commons logging, log4j.properties and co Allgemeine Java-Themen 12
J Logging Allgemeine Java-Themen 10
J Log4j / commons-logging Allgemeine Java-Themen 3
K Logging mit Log4j Allgemeine Java-Themen 2
G Logging Allgemeine Java-Themen 4
S Logging mit log4j Allgemeine Java-Themen 17
S Logging Allgemeine Java-Themen 9
M Rat gesucht: Logging (log4J oder java.util.logging oder .) Allgemeine Java-Themen 5
T Logging Allgemeine Java-Themen 12
T Transaction Logging Allgemeine Java-Themen 2
F Log4j2 SMTP Appender Beispiel Allgemeine Java-Themen 3
izoards log4j2 will nicht.... Allgemeine Java-Themen 15
MarekLanger Filepath in Log4j2 in Docker Container Allgemeine Java-Themen 12
T log4j2 Wo liegt mein Logfile? Allgemeine Java-Themen 3
C Verschiedene Versionen mit Datenbanken Allgemeine Java-Themen 3
Thallius Verschiedene entities für gleichen Code…. Allgemeine Java-Themen 8
OnDemand Zentrale "Drehscheibe" für verschiedene APIs Allgemeine Java-Themen 14
M verschiedene Dokumente auslesen Allgemeine Java-Themen 1
J Verschiedene Runtime Versionen gleichzeitig? Allgemeine Java-Themen 12
H Klassen LibGDX - Verschiedene Klassen als Value in einer Map Allgemeine Java-Themen 8
P mehrer Verschiedene Objekte in einer Klasse erstellen. Allgemeine Java-Themen 4
K Verschiedene Sprachen Allgemeine Java-Themen 1
C -Verschiedene Versionen eines Programms verwalten Allgemeine Java-Themen 7
M Verschiedene Pilzartenerkennung Allgemeine Java-Themen 0
I Verschiedene Arrays auslesen Allgemeine Java-Themen 6
nrg Verschiedene JREs im Browser konfigurieren Allgemeine Java-Themen 6
S Best Practice verschiedene Exceptions fangen und neue Exception erzeugen Allgemeine Java-Themen 11
G DesignPattern Verschiedene Services Allgemeine Java-Themen 4
B Verschiedene Objekte in Abhängigkeit eines Typs instanziieren. Allgemeine Java-Themen 17
M massenhaft verschiedene Date-Pattern Allgemeine Java-Themen 3
R Eclipse Verschiedene Ergebnisse bei Berechnung eines double-Werts Allgemeine Java-Themen 5
R Implementierung eines Interface durch 2 verschiedene Klassen Allgemeine Java-Themen 6
faetzminator verschiedene Beans, verschiedene Felder "koppeln" Allgemeine Java-Themen 3
J Verschiedene Klassen als "Object" in ArrayList und dann in for-Schleife erzeugen!? Allgemeine Java-Themen 2
S Welche Datenstruktur für verschiedene Sprachen sinnvoll? Allgemeine Java-Themen 2
H Zwei verschiedene Dateien mittels einem Binärstream übertragen? Allgemeine Java-Themen 13
M verschiedene Methonden innerhalb des gleichen Threads Allgemeine Java-Themen 7
N verschiedene Klasse laden (Designfrage) Allgemeine Java-Themen 2
S Package in verschiedene Projekten einbinden? Allgemeine Java-Themen 3
D Verschiedene Datein aus einer Zip Datei ins Programm laden Allgemeine Java-Themen 4
D Verschiedene Persistenz Strategien Allgemeine Java-Themen 7
S Konstruktoren, verschiedene Klassen, Methoden. Allgemeine Java-Themen 3
M Verschiedene Modi bei AbstractTableModel Allgemeine Java-Themen 10
J Verschiedene Klassen, verschiedene Ströme? Allgemeine Java-Themen 6
V 1 Methode für viele verschiedene Klassen? Allgemeine Java-Themen 9
L Verschiedene Versionen eines Interfaces Allgemeine Java-Themen 12
J Verschiedene Starteinstellungen Allgemeine Java-Themen 7
J Programm für verschiedene Betriebssystem vertreiben? Allgemeine Java-Themen 10
M 2 verschiedene LookAndFeels in einem Fenster möglich? Allgemeine Java-Themen 6
D Gehts praktischer? Thema:Verschiedene Instanzen einer Klasse Allgemeine Java-Themen 3
C Verschiedene JDKs Allgemeine Java-Themen 6
M Regular Expression - verschiedene Ausdrücke testen (grep | ) Allgemeine Java-Themen 5
C verschiedene Klassenarten Allgemeine Java-Themen 3
G Verschiedene Auflösungen Allgemeine Java-Themen 6
H verschiedene Java Versionen Allgemeine Java-Themen 3
A Textfeld soll verschiedene Datumseingaben akzeptieren Allgemeine Java-Themen 5

Ähnliche Java Themen

Neue Themen


Oben