Joern Huxhorn wrote:
Ceki Gulcu wrote:
Hello Joern,

Did you know that NDC can be implemented on top of MDC? I just added
such an implementation into slf4j-ext. You can view it at:

http://svn.slf4j.org/viewvc?view=rev&revision=1268

I'd implement NDC by using MDC the same way but it's obviously much less
efficient than using a dedicated Stack (or ArrayList ) like in the log4j
NDC.

It is indeed less efficient, and increasingly so as the stack size grows. In the tests I have performed, for a stack size of 3, I got the following results:

3.9 microseconds on average for direct calls to log4j's NDC with 3 pushes followed 3 pops 9.4 microseconds on average for NDC implemented via lMDC for 3 pushes followed 3 pops

For a stack size of 4,
direct log4j NDC: 5.6 microseconds on average for 4 push followed by 4 pop
indirectly via MDC: 17 microseconds on average for 4 push followed by 4 pops

Under logback, the performance is very similar, 17 microseconds for 4 pushes followed by 4 pops.

So, the cost is clearly higher but not appalling so.

Moreover, it kind of "pollutes" the MDC by mixing MDC and NDC together.

Indeed. For example, MDC.clear() would also affect NDC.

Well, I don't use NDC but I'd really like to :)
It's not about which one is better but about which one is more suitable
for a certain use case.

OK.

They supplement each other. The NDC is something like a contextual stack
trace while the MDC is a snapshot of some of the application data.

In our application, for example, we use the MDC to store the username,
thee URL, the request-parameters and some other state information.

We write a proprietary CMS system where content can include other
content and each of these have certain dynamic parts which need to be
resolved. Therefore one use case for NDC would be to keep the nesting of
the contents as well as informations about the various dynamic resolvers
that could, again, load other contents..

An actual NDC would look something like this:
Loading content A
Loading content B
Resolving dynamic values for X
Loading content C

which would be of great use for us. Really. ;)

Thank you for clarifying this point.

Let me respond by observing that if you print the whole NDC stack on each log, they will take a lot of space (on each line), eventually causing eye sore.

If you think of it, NDC is just a thread local stack accessible by a conversion pattern of the underlying logging system. In logback, it is quite easy to register your own conversion pattern and conversion words. Search for "Creating a custom conversion specifier" in http://logback.qos.ch/manual/layouts.html

Given that you are using logback, you could create your own NDC implementation and associated conversion specifier. Once you have done that, you could print (log) NDC data at convenient times, for example every time the NDC data changes. (Your NDC code would use its own logger.)

Come to think of it, you don't even need your own conversion specifier. Your NDC implementation would simply convert the NDC stack into a string and log that as a message at appropriate times, for example when NDC changes.

For example, if the loading of C failed we'd have the additional
information that it could be related to the resolving of X that was done
before.
Using the NDC like this would also mean that we would push and pop quite
often. Therefore the implementation of size(), which is called both in
push and pop, would have a significant performance impact und would
certainly perform *much* worse than just adding/removing to/from a
thread-local List.

Although, it is true that there is a significant impact on performance, depends on what you mean by *much* worse. Anyway, I tend to agree with you.

[snip]
I also suggested an NDC with lazy message formatting similar to logback
logging messages. This would make a big difference if there was a place
to globally disable NDC evaluation altogether or if NDC wasn't disabled
but isn't used in any appender.

I think that writing your own NDC implementation would be the way to go in the use case you describe.

Joern.

--
Ceki Gülcü
Logback: The reliable, generic, fast and flexible logging framework for Java.
http://logback.qos.ch
_______________________________________________
user mailing list
user@slf4j.org
http://www.slf4j.org/mailman/listinfo/user

Reply via email to