logging-log4j-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Dion, Gerard \(Space Technology\)" <gerard.d...@ngc.com>
Subject RE: Anyone Interested in a New C++ Log4J?
Date Wed, 07 Feb 2007 05:08:57 GMT

My C++ log4j JNI project is 250 file lines and 1.5 days old, and it does
90% of what I need it to do right now.  That doesn't mean it's ready for
prime time, but I'm surprised that I don't need to do anything more
right now for myself at least. I think it's a statement about Log4J
actually.  Log4j has hundreds of public methods (mostly Appender and
Appender related classes that you don't need use to work with log4j if
you don't want to). But really, you only need 10 methods or so to use
Log4J, as one will find perusing Ceki Gulcu's book.  I don't know if he
ever shows you these other methods.  A few Log4J methods and the
considerable rules one can put in a configuration file allow you to
exercise the vast log4j's capabilities.  And this is one of the main
reasons I believe Log4j is a great project to wrap a JNI C++ library.
But to be complete would be expose all the methods not in the book, but
allowable in the Log4J interface, which might require another 1,000 to
2,000 file lines, for things like the hundreds of Appender and Appender
related class methods, and the list for a Release 1.0.  But there's
another reason why this is a good thing to do.  Compare that 1-2,000
lines of C++ wrapper code The Log4J is 32,000 file lines.  Suppose on
the average, any of the ported C++ Log4J's are also 32,000 file lines.
Would you rather maintain 1-2,000 lines of C++ wrapper code that does
everything Log4J does, or 32,000 file lines?  I'll tell you this.  The
current C++ log4j port out on the Log4 website is called log4cxx-0.9.7.
It's published at http://archive.apache.org/dist/logging/log4cxx/. with
a date of 21-May-2004.  Have a go at trying to compile and link it; it's
not easy. I gave up.  I haven't had any luck with any of the others, and
so I started this project of my own.

Now that's the good news, on why you might want to go with a JNI
version, but I agree with you there might be some lurking bad reasons
you might not want to ever call a C++ JNI method to log something, and
you've given me one, but there are probably more.   Oh, here's one of
own: it's a hassle because you have to deal with the JDK.  You have to
go through the hoops of making sure the JDK is installed and on your
path, and you have built using the right jni.h header and compiled and
linked with the right jdk.lib/jdk.dll.  Really, it's a pain. And then
your CLASSPATH get's passed into the runtime of your program, and you
need to be sure that you've added the Log4j jar file to this.  So that's
where good documentation needs to come in.  

Now you are concerned about the performance and you make some good
points, but I think there are some ways to deal with the issues you
brought up. Now when the Log4J logger doesn't need to make the method
call, perhaps because LEVEL is as high as WARN say, it may be checking
for the LEVEL, or perhaps it uses (I'm guessing here) the Abstract
Factory pattern to make the method a stubbed out one, so the call will
be optimized out at run time.  That's a cute one, I've used it before
and the stubbed out method calls really don't get called.  The thing is
however, it seems to me that we can re-create this kind of behavior on
the C++ side.  First, if it's a parameter test issue, say if (LEVEL ==
DEBUG)...., we can get that parameter through the JNI interface and
store it in a private field of the wrapper class, and don't call the JNI
method if the test doesn't pass.  Or, if it's more like the Abstract
Factory pattern kind of thing, though I doubt it is cause this would be
so fancy, but just for grins, we could pull those classes across through
JNI calls, and either make the JNI calls on the C++ side, and test for
speed of such a call to see if the call is optimized out, or add code to
do something like a fancier Abstract Factory "Wrapper", which would
optimize out on the C++ side, or simply create a new instance variable
and don't make the call.  Now for the JNI calls that are going to do
some work, the majority are going to be Logging calls.  These calls send
message to Appender's, which spend most of their time talking across
some kind of a connection until the message is delivered.   For example,
when sending a message to a RollingFileAppender, the Appender (really,
the process) is waiting for the disk to come back and say "done, I wrote
the message, and you can have control back".  And the time from the JNI
call, to the Appender talking to the disk, and the disk returning, and
the JNI method returning, is a lot longer than the time taken up just by
the JNI call across the interface and the JNI return across the
interface.  That's probably true regardless of the Appender type.  The
connection time to send the message always hogs the time.

If we did pursue word on this, here are some tasks that could be added
to a 1 st release:

*	Expose the interface to its fullest.  There are hundred of
public methods that I found related to the Appender classes, etcetera.
You javap them to get the JNI signature and just write the JNI stuff.
Pretty chug-work.  Not time consuming.  Perhaps some portion of these
need do not need to be exposed.  
*	Support exceptions for Methods through the interface.  
*	Support the instantiation of all JDK versions, and test the
CLASSPATH handling.  
*	Port to other other compilers.  Currently supported as
"nearly-POSIX-C++" on Visual Studio 2005  
*	Port to other machine types, and platforms, including CYGWIN.  
*	Write install and interface documentation.  


Gerard Dion, Ph.D.
Senior Project Engineer
Simulation and Modeling Group, D621
Northrop Grumman Space Technology
Mail Stop: R4/1023, One Space Park
Redondo Beach, CA, 90278

-----Original Message-----
From: Curt Arnold [mailto:carnold@apache.org] 
Sent: Monday, February 05, 2007 9:33 PM
To: Log4J Developers List
Subject: Re: Anyone Interested in a New C++ Log4J?

On Feb 5, 2007, at 6:39 PM, Dion, Gerard (Space Technology) wrote:

> Log4J Users:
> I exposed the Java Log4J in C++ by Wrapping it with JNI.  The  
> interface is C++-ish, not JNI-ish; all JNI jobjects and such  
> returned on JNI calls and such, like the org.apache.log4j.Logger,  
> are wrapped and saved inside my own C++ class instances.  So one  
> gets instead an org::apache::log4j::Logger instance for each new  
> call to the Logger interface.  Example:
> static org::apache::log4j::Logger * newLogger =  
> org::apache::Logger::getLogger(std::string loggerName);
> How do I publish this new C++ Log4J Wrapper?  It's only 250 lines  
> of code right now, and yet it handles most of the functionality we  
> need.  To support all the functionality of the underlying 32,000  
> lines of Java log4j code, I believe another 1000 lines of C++ might  
> be required, at most.

 From reading the code, it would appear that you would incur a JNI  
call even when processing log requests that don't satisfy the  
threshold.  Both log4j and log4cxx attempt to make discarded logging  
requests as cheap as possible so you can feel free to place debug()  
calls all over your code without worrying about compromising  

Could you discuss the motivations behind the your effort?

What would be the relative benefits or disadvantages of:

1. Trying to mimic the log4cxx API
2. Provide an adapter that would allow log4j appenders to be used in  

To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org

View raw message