Curt: 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. Cheers, Gerard 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 310/812-8544 [EMAIL PROTECTED] -----Original Message----- From: Curt Arnold [mailto:[EMAIL PROTECTED] 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 performance. 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 log4cxx. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
BEGIN:VCARD VERSION:2.1 N:Dion;Gerard FN:Dion, Gerard (Space Technology) ORG:ST-ENGR;D620 TEL;WORK;VOICE:(310) 812-8544 ADR;WORK:;Redondo Beach (ST);One Space Park;Redondo Beach;CA;90278;US LABEL;WORK;ENCODING=QUOTED-PRINTABLE:Redondo Beach (ST)=0D=0AOne Space Park=0D=0ARedondo Beach, CA 90278=0D=0AUS EMAIL;PREF;INTERNET:[EMAIL PROTECTED] REV:20041101T201105Z END:VCARD
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
