On May 8, 2008, at 7:12 AM, Michael Duerr wrote:

Hallo,

I'm writing a simulation application, that creates and destroys several objects of the same class during the simulation. I want to perform logging for each of these objects to a single file (i.e. I want only the output of one object in the corresponding object's logging file). The application is single threaded.

Can I achieve this behaviour with log4cxx - if so - how? I tried to implement this behaviour by initializing a new logger for each new object. But since there are up to 10000 objects this seems to be inefficient. Furthermore I could not figure out how to delete such a logger in case the associated object gets destroyed (how todo this???) and hence I experienced a lot of memory leaks. To my best knowledge MDC is also no alternative, since it does not allow for the
restricted object->file logging.

Is there any chance to achieve this logging behaviour with log4cxx?

Thank you!

Cheers Michael

I agree with Dale's comments, but want to add some more.

The motivation of having a logger hierarchy is so to allow the user to control the processing of logging requests by discarding some requests and selectively routing others to specific appenders. Having 10000 loggers with dynamic names has little value to someone who is trying to shape logging in the configuration file.

If you really wanted 10000 output files, the best approach would be to use something like the mythical MultiFileAppender that lies unfinished in the log4j sandbox. One appender, but can manage multiple open files. Search log4j-dev for MultiFileAppender for the back story if you are interested.

However, I agree with Dale that you'd be better off writing to a single file and then appropriately sorting or filtering.

If you were using the mythical MFA, you'd need to have something in the logging event to determine what file the event should be routed, some sort of identification of the object. In the single file approach, you could write this identifier out into the log file and then use grep to pull out only the relevant log entries.

The question is then how do you get this object identifier into the logging event. Your options are:

1. Put the object identifier into the message.  Either something like:

LOG4CXX_INFO(logger, this << "Hello, World");

You'd need to provide an insertion operator for your object that works on a log4cxx::helpers::MessageBuffer to insert the id. If advantage of this is that it costs nothing if logging is disabled.

A cleaner solution would be to define your own macro that handled inserting the object ID into the message.

2. Put the object identifier in the NDC on public method entry:

void foo() {
        NDC entry(getID());

}

This will add an entry to the nested diagnostic context on method entry and remove it on method exit. However, this adds a fixed cost to the method call even if logging is disabled.

3. Put the object identifier in the MDC on public method entry:

void foo() {
     MDC entry("objID", getID());

Same disadvantage and likely slower.


Reply via email to