Reputation: 461
I'm seeing a rather odd issue.
I created some standard Java loggers (using Logger.getLogger(), a FileHandle, and a SimpleFormatter.) Those work fine, and output the log file as expected.
Then, I used some classes from the Gigaspaces API (com.gigaspaces.gs-openspaces - included via a Maven dependency), which includes its own logging. After that, all of the output of my loggers ended up inside the Gigaspaces log file (e.g. ~/.m2/repository/com/gigaspaces/logs/2017-03-27~12.46-gigaspaces-service-135.60.146.142-23534.log) instead of in the appropriate log files that they are supposed to be using.
If I then create more loggers after I've initialised Gigaspaces, these new loggers work as expected. Only loggers created before initialising gigaspaces are affected.
I tried poking around in the code for Gigaspaces a little bit, there's a lot of code in there. I didn't see anything immediately obvious.
Am I doing something wrong with setting up my loggers? It doesn't seem right that a library can steal the output from pre-existing loggers that are unrelated to its classes.
The below short test program demonstrates the 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");
Upvotes: 0
Views: 242
Reputation: 461
Overriding the security manager, as suggested by jmehrens, seems to be the way to go. I was able to stop Gigaspaces from stealing the logging by denying it permission to run the reset() methods on the LogManager, thusly:
// 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.");
}
}
}
}
});
}
I this case, I just added the override in a static block of the class that creates my gigaspace instances, but anywhere before initialising them should do.
Upvotes: 0
Reputation: 11065
You have to pin the "testlog" logger or you risk losing all of the changes you apply to it.
Modifying loggers requires permissions. One option might be to use a custom security manager that doesn't let GigaSpaces redirect your logging.
If GigaSpaces is calling LogManager.reset(), then one hacky, smelly, dirty way to get around removing your handler is to extend FileHandler and override equals.
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");
}
}
Upvotes: 0