Hallo Mir ist grad nur aufgefallen, das wenn mein Programm mehrere Exceptions bekommt, und jedes mal mein Catch-Block durchgeführt wird:
FileHandler fh = null;
String userHome = System.getProperty("user.home");
Path home = Paths.get(userHome);
Path syserr = home.resolve(Paths.get("Documents", "NetBeansProjects", "MusikPlayerGUIBuilder_New", "syserr"));
String syserrString = syserr.toString();
try {
if (!Files.exists(syserr)) {
Files.createDirectory(syserr);
}
fh = new FileHandler(syserrString + "\\syserr.log", 1_073_741_824, 1, true);
} catch (IOException ex1) {
System.err.println("Filehandler bei " + MusikThread.class.getName() + " kaputt");
}
Logger log = Logger.getLogger(MusikThread.class.getName());
log.addHandler(fh);
log.log(Level.SEVERE, "Exception " + ex.getClass().getName() + " bei " + MusikThread.class.getName(), ex);```
(Den Pfad hab ich nur zu Testzwecken so geändert, damit ich einen eigenen syserr-Ordner habe, der die log enthält)
So und jedesmal wenn das aufgerufen wird, benennt er die alte in "syserr.xml.log.1" bzw. "XXX.2" usw. um und erstellt eine neue, die dann alle Exceptions beinhält. So, da ich aber gerne will, das er alle Exceptions in die oben genannte Datei schreibt, was er ja auch macht, aber er soll eben nicht die alten einfach umbenennen, sonder die vorhandene wiederverwenden. Gibts dafür ne Möglichkeit das umzusetzen? Meine momentan einzige Idee wäre das hier:
```FileHandler fh = null;
String userHome = System.getProperty("user.home");
Path home = Paths.get(userHome);
Path syserr = home.resolve(Paths.get("Documents", "NetBeansProjects", "Tests", "syserr.xml.log"));
Path syserr2 = home.resolve(Paths.get("Documents", "NetBeansProjects", "Tests", "syserr.xml.log.1"));
String syserrString = syserr.toString();
System.out.println(syserrString);
try {
fh = new FileHandler(syserrString, 1_073_741_824, 1, true);
Logger log = Logger.getLogger(LoggingTest.class.getName());
log.addHandler(fh);
log.log(Level.SEVERE, "Exception " + ex.getClass().getName() + " bei " + LoggingTest.class.getName(), ex);
Files.deleteIfExists(syserr2);
} catch (IOException ex1) {
System.err.println("Filehandler bei LoggingTest kaputt");
}```
Funzt aber auch nicht. Jemand ne Idee? Würde das nur ungerne so lassen, da ich die syserr schon gerne im Hauptordner habe, sie allerdings auch den Ordner nicht füllen sollte, in dem sie x Dateien erstelle :) Google half btw nicht
getLogger() liefert nur beim ersten Mal ein neues Logger-Objekt, bei wiederholten Aufrufen mit dem gleichen Namen wird die Instanz wiederverwendet. Dadurch hängst Du bei jeder Exception wieder einen neuen (= einen weiteren) FileHandler an den Logger. Das könnte evtl. solche Probleme verursachen.
Der Fehler ist, ständig Logger- und vor allem FileHandler-Objekte in lokalen Variablen neu zu speichern. Speicher die Referenz auf das Logger-Objekt in einem static final Feld. Initialisiere es genau einmal (öfter geht ja bei final auch nicht ) und verwende dann nur noch diese Referenz für log-Aufrufe.
OT:
Das stimmt nur mit Einschränkungen. Der Cache für bereits instanzierte Logger-Objekte ist nämlich eine Weak-Reference Implementierung. D.h. sobald keine Referenz mehr auf das Logger-Objekt im Code ist (so wie hier) ist die Instanz ein Kandidat für Garbage Collection. Sollte diese zwischendurch zuschlagen, muss eine neue Instanz erzeugt werden. Nur, wenn zwischendurch nicht garbage collected wurde, wird die Neuerzeugung vermieden.
private static FileHandler fh = null;
private static final Logger log = Logger.getLogger(LoggingTest.class.getName());
public LoggingTest() {
createFileHandler();
}
Du hast den FileHandler fh static (also eine Referenz für alles), überschreibst ihn aber bei jeder Neuerzeugung. Das macht so keinen Sinn. Trenne klar zwischen dem, was Du nur einmal brauchst und dem, was Du je Instanz haben willst. Auch Dein Konstrukt, mitten im Code noch den Logger zu konfigurieren ist unübersichtlich und fehleranfällig. Z.B. der Teil hier:
if (log.getHandlers() == null) {
log.addHandler(fh);
}
Was macht Dich so sicher, dass getHandlers() null zurück liefert und nicht vielleicht eher ein leeres Array? In dem Fall würde nämlich Dein Handler überhaupt nicht zum Logger hinzugefügt und folglich auch nichts ins Logfile geschrieben. Dieses Konstrukt hast Du nur drinnen, weil Du nicht -wie schon geraten- im Vorherein Deinen Logger vernünftig konfigurierst und ihn dann einfach nur noch nutzt.
Prüfen müssen tu ich es nicht, mach es nur aus Sicherheit, das wirklich nur einmal einer erstellt wird, mit final funzt das ganze ja nicht wirklich. Wenn ichs weglasse, funktioniert es genauso.