Logging/Tracing in GLOs

Hello, SGS Community,

I’m experimenting with SGS, and have put together a boot GLO and am trying to make it work. Following the SworldWorld code for the most part. I can start up the server with my game, and I have a client which connects to the server fine. However, the problem I am having is that, even though the boot GLO is registering as a SimUserListener, I am not seeing my userJoined method being called when my client logs in.

I base this on the fact that I am using a java.util.logging.Logger in the boot GLO to log info to a file. I create the Logger in the boot() method, and store a reference to it in a member of the boot GLO. I have logging calls in both the boot() method and the userJoined() method. I see the logging from the boot() method in the log file, but I don’t see the logging from the userJoined() method.

The Logger class is not serializable, so I have to declare the ‘Logger logger’ boot GLO member transient. I was wondering if this works for persistent objects. If the Boot GLO is serialized to the Store and later de-serialized from the Store, then the transient member would be uninitialized. I suppose I really need to address this at some point, but I’m wondering right now if this is the source of the problem I have with the userJoined() method apparently not getting called. Maybe it is getting called, but the logging is not working because of serialization.

The real problem is gaining visibility into what the Server is doing. Does anybody have any advice on how to address the subject of logging in GLOs?

Thanks…BJN

Hi

I’ve done similar things. I used apache commons logging instead, but it’s the same principle. You can take a look at the subversion repository here. Take a look at the DVSFBoot and DVSFUserListener classes.

HTH

Endolf

Endolf,

Thanks for the reply. I notice that you declare your Logger member as 'transient final". I’m not sure of the consequences of doing that. That is not what I tried to finally make it work. Here’s my solution.

Original boot GLO was something like:
public class BootGLO implements BLAH… {
private transient Logger logger;

public void boot(blah) {
logger = Logger.getLogger(blah);
logger.fine(“boot”);
blah…
}

public void userJoined(blah) {
logger.fine(“userJoined”);
blah…
}
}

I was seeing the “boot” log message but not the “userJoined”. And I was not seeing any null pointer exceptions.

Changed this as follows:
public class BootGLO implements BLAH… {

public void boot(blah) {
Logger logger = MyLogManager.getLogger(blah);
logger.fine(“boot”);
blah…
}

public void userJoined(blah) {
Logger logger = MyLogManager.getLogger(blah);
logger.fine(“userJoined”);
blah…
}
}

public class MyLogManager {
static HashMap<String, Logger> logMap = new HashMap(blah);
public static Logger getLogger(String name) {
Logger logger = logMap.get(name);
if (logger == null) {
logger = create and configure new Logger
logMap.put(name, logger);
}
return logger;
}
}

The lesson I’ve learned is to avoid using transient members in GLOs. Instead, pass the job off to components that can recreate the transient service when and if required. Again, not sure if doing your “final transient” solution would have worked as well. Obviously, it works for you. I’ll give it a try when I get a chance. Again, thanks.

I think the important bit is that it’s a static member.

Endolf

err, just use the deserialise method to get a logger?

I use private static final loggers in my normal classes, so it makes sense to me to use static loggers in my GLOs. It’s worked so far by just making them transient.

Endolf