2016-07-01 19 views
0

Ich habe ein Tool, das in mehreren JVMs ausgeführt wird, aber in demselben %t (temp) Verzeichnis protokolliert. Ich verwende die Mustervariable %u (einmalig) in der Datei logging.properties, damit sich jede Instanz in einer anderen Protokolldatei anmeldet.Wie kann ich den Namen des aktuellen java.util.logging.Logger-Protokolldateinamens ausgeben?

Wenn der Prozess einen Fehler erkennt (dies ist ein Überwachungstool), sendet er eine E-Mail und ich möchte die Protokolldatei der bestimmten Instanz anfügen, die den Fehler festgestellt hat. Aber wie bekomme ich den Protokolldateipfad? Auch gerne angenommen wäre ein besserer Ansatz, wenn das nicht gut ist.

+0

Wäre es nicht viel besser organisiert, wenn sich jedes Programm in einem anderen Protokollordner anmeldet oder einen anderen Protokolldateinamen/Präfix verwendet? – Andreas

+0

Danke für den Kommentar. Es ist mir egal, da die Log-Dateien "Einmal" sind, sobald sie per E-Mail verschickt werden. Niemand wird jemals die Protokolldateien durchsuchen. Auf jeden Fall sieht es so aus, als müsste ich das programmatisch und nicht einfach über die Protokollkonfiguration durchführen, damit sie am Ende vielleicht organisiert werden. – AndyJ

Antwort

0

Es gibt ein RFE-Archiv mit Oracle unter JDK-4798814 getFiles() needed for java.util.logging.FileHandler, das dies abdeckt.

Sie können zur Reflexion greifen, wenn Sie keinen Sicherheitsmanager verwenden.

public class GetFileHandler extends FileHandler { 

    public GetFileHandler() throws IOException { 
     super(); 
    } 

    /** 
    * Gets the files used by this handler. Index zero is the file that is 
    * in use. 
    * 
    * @return a array of files. 
    * @throws IOException if there is an error. 
    * @throws SecurityException if not allowed. 
    */ 
    public File[] getFiles() throws IOException { 
     return GetFileHandler.getFiles(this); 
    } 

    private static File[] getFiles(FileHandler h) throws IOException { 
     try { 
      Field f = FileHandler.class.getDeclaredField("files"); 
      f.setAccessible(true); 
      synchronized (h) { 
       return ((File[]) f.get(h)).clone(); 
      } 
     } catch (ReflectiveOperationException roe) { 
      throw new IOException(roe); 
     } 
    } 
} 

Beachten Sie, dass diese Lösung möglicherweise gegen die Dateirotation läuft. Es kann auch brechen, wenn der FileHandler-Quellcode geändert wird.

Wenn Sie keine Rotation benötigen, können Sie die Datei StreamHandler immer erweitern und eine bekannte Dateiposition angeben.

public class KnownFileHandler extends StreamHandler { 

    private final File file; 

    public KnownFileHandler() throws IOException { 
     String v = LogManager.getLogManager().getProperty(getClass().getName() +".name"); 
     if(v == null) { 
      v = "knownfilehandler.log"; 
     } 
     file = new File(v); 
     this.setOutputStream(new FileOutputStream(file)); 
    } 


    public File getFile() { 
     return this.file; 
    } 
} 

Wenn das Monitoring-Tool eingehende TCP-Verbindungen unterstützt dann die java.util.logging.SocketHandler wäre ein Weg, um alle Log-Informationen an das Monitoring-Tool zu senden und dann könnten Sie das Monitoring-Tool haben entscheiden, wo die Log-Daten zu speichern oder senden .

+0

Sehr hilfreich, danke für die zahlreichen Anregungen! – AndyJ