2017-03-27 1 views
0

Ich sehe ein ziemlich seltsames Problem.Java-Datei-Logger wird entführt und in eine Datei eines anderen Loggers (von Gigaspaces API) nach der Erstellung umgeleitet

Ich habe einige Standard-Java-Logger (mit Logger.getLogger(), einem FileHandle und einem SimpleFormatter) erstellt. Die funktionieren gut, und die Protokolldatei wie erwartet ausgeben.

Dann habe ich einige Klassen aus der Gigaspaces-API (com.gigaspaces.gs-openspaces - enthalten über eine Maven-Abhängigkeit), die eine eigene Protokollierung enthält. Danach endete die gesamte Ausgabe meiner Logger in der Gigaspaces Logdatei (zB ~/.m2/repository/com/gigaspaces/logs/2017-03-27 ~ 12.46-gigaspaces-service-135.60.146.142-23534 .log) statt in den entsprechenden Protokolldateien, die sie verwenden sollen.

Wenn ich dann nach der Initialisierung von Gigaspaces weitere Logger erstelle, funktionieren diese neuen Logger wie erwartet. Es sind nur Logger betroffen, die vor der Initialisierung von Gigaspaces erstellt wurden.

Ich habe versucht, im Code für Gigaspaces ein bisschen herumzustochern, da ist eine Menge Code drin. Ich habe nichts sofort offensichtlich gesehen.

Mache ich etwas falsch mit der Einrichtung meiner Logger? Es scheint nicht richtig zu sein, dass eine Bibliothek die Ausgabe von bereits existierenden Loggern stehlen kann, die nicht mit ihren Klassen zusammenhängen.

Das unten kurze Testprogramm demonstriert das Problem:

Logger testLog = Logger.getLogger("testlog"); 
    try { 
     FileHandler fh = new FileHandler("testlog.log"); 
     fh.setFormatter(new SimpleFormatter()); 
     testLog.addHandler(fh); 
    } 
    catch (Exception e) { 
     // Not important 
     e.printStackTrace(); 
    } 

    testLog.log(Level.INFO, "This appears in the main log file"); 

    // Spin up gigaspaces, even by trying to connect to a space that doesn't exist 
    UrlSpaceConfigurer testSpaceConfigurer = new UrlSpaceConfigurer("jini://*/*/testSpace?locators=127.0.01").lookupTimeout(1); 
    try { 
     GigaSpace g = new GigaSpaceConfigurer(testSpaceConfigurer).gigaSpace(); 
    } 
    catch (Exception e) { 
     // This will throw an exception, just ignore it. 
    } 
    testSpaceConfigurer.close(); 

    testLog.log(Level.INFO, "This appears in the (wrong) gigaspaces log file"); 
+1

Ich denke, dass GigaSpaces ein anderes Logging-Framework (Log4j, Logback, was auch immer) verwendet, das standardmäßig die Logging von anderen Diensten zu seinem Framework umleitet. – john16384

+0

Ich habe überprüft, und es scheint keine Abhängigkeiten zu log4j oder einem anderen Framework zu haben. Es hat eine transitive Abhängigkeit von (Avalon) LogKit. Ich versuchte das durch Maven auszuschließen, und das machte keinen Unterschied. –

Antwort

0

Das Überschreiben des Sicherheitsmanagers, wie von jmehrens vorgeschlagen, scheint der richtige Weg zu sein. konnte ich GigaSpaces um zu verhindern, die Protokollierung zu stehlen, indem sie die Erlaubnis verweigert die reset() Methoden auf dem LogManager, thusly auszuführen:

// Silly hack to keep gigaspaces from STEALING ALL OUR LOGS 
static { 
    System.setSecurityManager(new SecurityManager() { 
     @Override 
     public void checkPermission(Permission p) { 
      if (p instanceof LoggingPermission) { 
       for (StackTraceElement stackTraceElement : new Exception().getStackTrace()) { 
        if (stackTraceElement.getMethodName().equalsIgnoreCase("reset") && stackTraceElement.getClassName().equalsIgnoreCase("java.util.logging.LogManager")) { 
         throw new SecurityException("No resetting the logger! It is forbidden."); 
        } 
       } 
      } 
     } 
    }); 
} 

ich diesen Fall habe ich gerade hinzugefügt haben die Überschreibung in einem statischen Block von der Klasse, die meine Gigaspace-Instanzen erstellt, aber irgendwo vor der Initialisierung sollten sie tun.

0

Sie müssen pin the "testlog" logger oder Sie alle Änderungen riskieren Sie den Verlust für sie gelten.

Das Ändern von Protokollfunktionen erfordert Berechtigungen. Eine Option könnte die Verwendung eines benutzerdefinierten Sicherheits-Managers sein, bei dem GigaSpaces die Protokollierung nicht umleitet.

Wenn GigaSpaces ruft LogManager.reset(), dann ist eine hacky, stinkende, schmutzige Möglichkeit, um Ihre Handler zu entfernen, um FileHandler zu erweitern und zu überschreiben gleich.

public class GigaSpaces { 

    //Pin the logger 
    private static final Logger testLog = Logger.getLogger("testlog"); 
    static { 
     try { 
      FileHandler fh = new FileHandler("testlog.log") { 
       public boolean equals(Object o) { 
        return false; //Pure Evil. 
       } 
      }; 

      fh.setFormatter(new SimpleFormatter()); 
      testLog.addHandler(fh); 
     } 
     catch (Exception e) { 
      // Not important 
      e.printStackTrace(); 
     } 
    } 

    public void foo() throws Throwable { 
     testLog.log(Level.INFO, "This appears in the main log file"); 

     // Spin up gigaspaces, even by trying to connect to a space that doesn't exist 
     UrlSpaceConfigurer testSpaceConfigurer = new UrlSpaceConfigurer("jini://*/*/testSpace?locators=127.0.01").lookupTimeout(1); 
     try { 
      GigaSpace g = new GigaSpaceConfigurer(testSpaceConfigurer).gigaSpace(); 
     } 
     catch (Exception e) { 
      // This will throw an exception, just ignore it. 
     } finally { 
      testSpaceConfigurer.close(); 
     } 

     testLog.log(Level.INFO, "This appears in the (wrong) gigaspaces log file"); 
    } 
} 
Verwandte Themen