Re: NDC
Ceki Gülcü wrote: At 06:58 PM 12/17/2003 -0500, Raymond DeCampo wrote: Before I put any serious effort forward I wanted to make sure that such a change would fit in in terms of the overall vision and that I'm not missing something else that would prevent it being accepted. If one of the committers could confirm that it seems like a good idea, I'll start working on it. Please do. You can take the MDC code as example. (For MDC code, use the latest from CVS not the code from 1.2.8). Test cases would be highly welcome. Will do. I should have some time next week. Ray - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
NDC
All, I was recently thinking about adding some NDC logging to my servlet, but I was concerned (perhaps unnecessarily) by some of the things I read in the docs and the source code. Since I am in a servlet container I am not in control of my threads. So it is difficult to know when to call NDC.remove(). It seemed like it would be safe to call at the end of every request. However, when I was looking over the implementation, I was concerned that it may be a performance issue, especially if there are a lot of requests and threads. I can see that whoever wrote the code was concerned as well. (In particular I am thinking of the comment concerning the synchronization of the ht variable.) I think that the NDC class could be much improved through the use of the ThreadLocal class. I just checked the docs and ThreadLocal has been available since JDK 1.2; if I'm not mistaken that is the threshold we are working for? Before I put any serious effort forward I wanted to make sure that such a change would fit in in terms of the overall vision and that I'm not missing something else that would prevent it being accepted. If one of the committers could confirm that it seems like a good idea, I'll start working on it. Thanks, Ray - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Chainsaw and JDK 1.3
Raymond DeCampo wrote: Paul Smith wrote: On Tue, 2003-12-16 at 10:40, Raymond DeCampo wrote: We've probably been over this before, but what is the current status of Chainsaw relative to JDK 1.3.x? I recently tried to compile the trunk on JDK 1.3.1 but chainsaw did not compile. I think I've addressed all the 1.3.1 issues now. Doesn't look anywhere near as nice, but the Tutorial can run, and all the colouring etc works. Let me know if there is any other 1.3.1 weirdness at runtime. I'll give it a try at work tomorrow and let you know. As promised, I got the latest from the trunk this morning and tried to compile chainsaw again on JDK 1.3.1. Compilation was fine; however, when I ran it I got a NoClassDefError for org/xml/sax/InputSource. When I modified the build.xml to include a copy of xercesImpl.jar and xmlParserAPIs.jar (from Xerces) all was fine. I will keep you inform of any issues I hit that may be related to JDK 1.3.1. BTW, I was going to try the chainsaw-install.xml you posted, however, I did not have a cvs client (is there a command-line cvs client for Windows?) as was required. I did use it partially by running the parts that did not depend on cvs by hand. There is a small error on the web page; the user is instructed to invoke ant with simply ant, I believe you want them to use ant -f chainsaw-install.xml. Finally, a non-chainsaw note if anyone is interested. The JMX examples are compiled even when the JMX jar is not present and the regular log4j JMX classes are not compiled. This causes the build to fail: build.examples: [mkdir] Created dir: T:\test\log4j\jakarta-log4j\examples\classes [javac] Compiling 15 source files to T:\test\log4j\jakarta-log4j\examples\classes [javac] T:\test\log4j\jakarta-log4j\examples\src\jmx\T.java:3: cannot resolve symbol [javac] symbol : class Agent [javac] location: package jmx [javac] import org.apache.log4j.jmx.Agent; [javac] ^ [javac] T:\test\log4j\jakarta-log4j\examples\src\jmx\T.java:18: cannot resolve symbol [javac] symbol : class Agent [javac] location: class jmx.T [javac] Agent agent = new Agent(); [javac] ^ [javac] T:\test\log4j\jakarta-log4j\examples\src\jmx\T.java:18: cannot resolve symbol [javac] symbol : class Agent [javac] location: class jmx.T [javac] Agent agent = new Agent(); [javac] ^ [javac] 3 errors BUILD FAILED Thanks, Ray - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Chainsaw and JDK 1.3
We've probably been over this before, but what is the current status of Chainsaw relative to JDK 1.3.x? I recently tried to compile the trunk on JDK 1.3.1 but chainsaw did not compile. Thanks, Ray - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Chainsaw and JDK 1.3
Paul Smith wrote: On Tue, 2003-12-16 at 10:40, Raymond DeCampo wrote: We've probably been over this before, but what is the current status of Chainsaw relative to JDK 1.3.x? I recently tried to compile the trunk on JDK 1.3.1 but chainsaw did not compile. I think I've addressed all the 1.3.1 issues now. Doesn't look anywhere near as nice, but the Tutorial can run, and all the colouring etc works. Let me know if there is any other 1.3.1 weirdness at runtime. I'll give it a try at work tomorrow and let you know. Thanks, Ray - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [Chainsaw]: Proposed new LogPanel preference saving structure
Paul Smith wrote: Currently we have the SettingsManager and associated event objects which are used to save/load Application wide events. However currently all the LogPanel settings are saved via standard Serialization. This tends to be easy to do, but brittle as we add more information to the savable entity. I propose to extend the SettingsManager stuff so that each entity can still register for saving and loading, but is done so within a 'domain' or namespace. We would have a domain for the Application, and each LogPanel would register to be a SettingsListener, but would register under it's own name space. At load/save time, each SettingsListener would be given the chance to read/write from/to the relevant event, but each logical namespace would be treated separately and have the properties read from a different file and encapsulate in it's own event object. The name of the properties file would just be the namespace + '.properties'. Unless anyone has any thoughts or comments I will use this approach to implement simple property based saving for the LogPanel and associated classes (the ignore list for the logger tree, colour rules etc) Paul, In general, I think that xml based properties files work better in the long run rather than traditional *.properties files. The hierarchical nature of the xml file is definitely a plus. The drawback is it can be more difficult to access and set properties. Perhaps the DOMConfigurator code can help make this just as easy to program? Ray - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: DailyRollingAppender does not roll each period (issue)
Walid Joseph Gedeon wrote: Thank you for your reply, Ceki. First, the rolling appenders have been rewritten. See o.a.l.rolling package in log4j cvs. I will refer to the cvs sources (so far I was based on the sources in the jar). Do the re-written appenders address this issue? I'll probably self-answer that by reading the sources. Second, it is not good practice to hide threads within appenders. What is the reason bahind this? The thread used is a daemon thread, so it will not hang the system... is it because of using up an additional thread per instance? In all situations, a common timer can be used to which this appender would register for events. I can't speak for Ceki, but here's my 2 cents. Some applications try very hard to control the number of threads and other resources for efficiency purposes. For example, application servers are usually written in this way. In fact, the EJB specification prohibits EJB from creating their own threads. So creating hidden threads inside the logging library would not be nice to users working in this environment. Ray - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Sandbox problems
Ceki Gülcü wrote: Given my recent changes to ThrowableInformation the following files no longer compile properly. The method getThrowable() is undefined for the type ThrowableInformation ThrowableClassMatchFilter.java log4j-sandbox/src/java/org/apache/log4j/filter line 170 The method getThrowable() is undefined for the type ThrowableInformation PreparedStatementAppender.java log4j-sandbox/src/java/org/apache/log4j/jdbcline 417 The method getThrowable() is undefined for the type ThrowableInformation PreparedStatementParameter.java log4j-sandbox/src/java/org/apache/log4j/jdbcline 188 The method getThrowable() is undefined for the type ThrowableInformation PreparedStatementParameter.java log4j-sandbox/src/java/org/apache/log4j/jdbcline 189 Ceki, I'll take a look. Ray - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Sandbox problems
Raymond DeCampo wrote: Ceki Gülcü wrote: Given my recent changes to ThrowableInformation the following files no longer compile properly. The method getThrowable() is undefined for the type ThrowableInformation ThrowableClassMatchFilter.java log4j-sandbox/src/java/org/apache/log4j/filter line 170 The method getThrowable() is undefined for the type ThrowableInformation PreparedStatementAppender.java log4j-sandbox/src/java/org/apache/log4j/jdbcline 417 The method getThrowable() is undefined for the type ThrowableInformation PreparedStatementParameter.java log4j-sandbox/src/java/org/apache/log4j/jdbcline 188 The method getThrowable() is undefined for the type ThrowableInformation PreparedStatementParameter.java log4j-sandbox/src/java/org/apache/log4j/jdbcline 189 Ceki, I'll take a look. Ray I've checked in changes for PreparedStatementAppender.java and PreparedStatementParameter.java. I didn't notice the ThrowableClassMatchFilter.java class when I volunteered earlier. I don't have time now, since I'm not familiar with that class, but if nobody has tackled it by this time tomorrow I will take a look. Ray - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: cvs commit: jakarta-log4j/src/java/org/apache/log4j/spi LoggingEvent.java
Paul Smith wrote: The hashcode computation must be fast in itself, at least significantly faster than 'equals' method invocations which return false. I think that String.hashcode computation is kinda slow depending on the JDK because it iterates on ALL the characters of the String. M. Yes, I think you've sold me. Paul I still think that Paul's original point is valid. A millisecond is a long time on a computer these days. What about using the first few characters of the message? Ray - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: JDBC version problems
I think that I will abandon writing a log4j connection pooling class and instead suggest that users use the commons-dbcp package. I looked it over and it does not require anything special from the client code; everything is configured at run-time. Therefore there should be no issue with using the UrlConnectionSource already in the sandbox with the commons-dbcp package to get connection pooling. Then we can let commons-dbcp worry about JDBC versions and such. To be truthful, I was a little reluctant to take on this effort to begin with because I suspected a production worthy implementation might be a significant effort. On the other hand, the wind has been knocked out of my sails a little bit... Ceki Gülcü wrote: Apparently the problem is quiet old: http://www.mail-archive.com/[EMAIL PROTECTED]/msg01282.html It was recently discussed on commons-dev http://marc.theaimsgroup.com/?l=jakarta-commons-devm=101538994027435w=2 My suggestion would be to ask on [EMAIL PROTECTED] to see whether the problem was already adressed. At 08:11 PM 8/9/2003 +0200, you wrote: Ray, Have you considered using jdbc-2.0jar as commons-dbcp has done? At 12:52 PM 8/9/2003 -0400, you wrote: But the problem isn't the methods, but the new classes. For example, one of the new methods on Connection is: Savepoint setSavepoint(); No matter what the implementation of this method is, the 1.2 JRE will not supply a Savepoint class. That will prevent the the Connection implementation from loading (unless the Savepoint class is supplied in another fashion). Ceki Gülcü wrote: Assuming your connection pool implementation encapsulates an underlying connection object, one way to deal with method X that exists in version 1.4 and not in 1.2 of Connection interface is as follows: 1st variant --- Implement method X without actually calling the X method on the underlying connection. MyPooledConnecion implements Connection { void X(...) { throw new Exception(Method X cannot be called.); } The advantage of this approach is that it would compile on all JDK versions. As long as method X is not actually used we are safe. 2nd variant --- Same as the 1st variant for version 1.2 except that method X of the underlying connection object is called using reflection under v. 1.4. HTH, At 11:19 AM 8/9/2003 -0400, Raymond DeCampo wrote: Hello all, As some of you know, I've been working on JDBC-based appenders in the sandbox. I wanted to create a connection pool for environments where no such pool existed so that the JDBC appender would not have to create a new connection for every log message. If you've never thought about JDBC connection pooling, the typical way to implement this is to create an implementation of java.sql.Connection that delegates (almost) all of the calls to another Connection object. When the client requests a Connection object, it gets one of these delegates from the pool. It uses it just like any other Connection object and never needs to know about the pooling. When the client calls close() on the connection, it is not really closed, but returned to the pool. That is all well and good until you try to create an implementation java.sql.Connection that will work for Java 1.2 and up. The Connection interface has new methods on it for 1.3 and 1.4. No big deal, when you compile against 1.2 it won't care because the original interface will be satisfiedexcept that in 1.4 there are new classes (e.g. java.sql.SavePoint) referenced by the new methods. If you try to compile with 1.2, it will say, java.sql.SavePoint? never heard of it... Does anybody have a solution to this? I'm not there is a good one...even if we do a conditional compilation somehow we would need to distribute a version of log4j for each Java version. (Because if you try to run a 1.4 compiled Connection implementation on a 1.2 JRE, there will be no SavePoint class and the class won't load. If you try to load a 1.2 compiled Connection implementation on a 1.4 JRE it will say you don't really implement the Connection I have...) So, unless someone has a brilliant idea I guess I will abandon this idea for now... Ray - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
JDBC version problems
Hello all, As some of you know, I've been working on JDBC-based appenders in the sandbox. I wanted to create a connection pool for environments where no such pool existed so that the JDBC appender would not have to create a new connection for every log message. If you've never thought about JDBC connection pooling, the typical way to implement this is to create an implementation of java.sql.Connection that delegates (almost) all of the calls to another Connection object. When the client requests a Connection object, it gets one of these delegates from the pool. It uses it just like any other Connection object and never needs to know about the pooling. When the client calls close() on the connection, it is not really closed, but returned to the pool. That is all well and good until you try to create an implementation java.sql.Connection that will work for Java 1.2 and up. The Connection interface has new methods on it for 1.3 and 1.4. No big deal, when you compile against 1.2 it won't care because the original interface will be satisfiedexcept that in 1.4 there are new classes (e.g. java.sql.SavePoint) referenced by the new methods. If you try to compile with 1.2, it will say, java.sql.SavePoint? never heard of it... Does anybody have a solution to this? I'm not there is a good one...even if we do a conditional compilation somehow we would need to distribute a version of log4j for each Java version. (Because if you try to run a 1.4 compiled Connection implementation on a 1.2 JRE, there will be no SavePoint class and the class won't load. If you try to load a 1.2 compiled Connection implementation on a 1.4 JRE it will say you don't really implement the Connection I have...) So, unless someone has a brilliant idea I guess I will abandon this idea for now... Ray - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: JDBC version problems
But the problem isn't the methods, but the new classes. For example, one of the new methods on Connection is: Savepoint setSavepoint(); No matter what the implementation of this method is, the 1.2 JRE will not supply a Savepoint class. That will prevent the the Connection implementation from loading (unless the Savepoint class is supplied in another fashion). Ceki Gülcü wrote: Assuming your connection pool implementation encapsulates an underlying connection object, one way to deal with method X that exists in version 1.4 and not in 1.2 of Connection interface is as follows: 1st variant --- Implement method X without actually calling the X method on the underlying connection. MyPooledConnecion implements Connection { void X(...) { throw new Exception(Method X cannot be called.); } The advantage of this approach is that it would compile on all JDK versions. As long as method X is not actually used we are safe. 2nd variant --- Same as the 1st variant for version 1.2 except that method X of the underlying connection object is called using reflection under v. 1.4. HTH, At 11:19 AM 8/9/2003 -0400, Raymond DeCampo wrote: Hello all, As some of you know, I've been working on JDBC-based appenders in the sandbox. I wanted to create a connection pool for environments where no such pool existed so that the JDBC appender would not have to create a new connection for every log message. If you've never thought about JDBC connection pooling, the typical way to implement this is to create an implementation of java.sql.Connection that delegates (almost) all of the calls to another Connection object. When the client requests a Connection object, it gets one of these delegates from the pool. It uses it just like any other Connection object and never needs to know about the pooling. When the client calls close() on the connection, it is not really closed, but returned to the pool. That is all well and good until you try to create an implementation java.sql.Connection that will work for Java 1.2 and up. The Connection interface has new methods on it for 1.3 and 1.4. No big deal, when you compile against 1.2 it won't care because the original interface will be satisfiedexcept that in 1.4 there are new classes (e.g. java.sql.SavePoint) referenced by the new methods. If you try to compile with 1.2, it will say, java.sql.SavePoint? never heard of it... Does anybody have a solution to this? I'm not there is a good one...even if we do a conditional compilation somehow we would need to distribute a version of log4j for each Java version. (Because if you try to run a 1.4 compiled Connection implementation on a 1.2 JRE, there will be no SavePoint class and the class won't load. If you try to load a 1.2 compiled Connection implementation on a 1.4 JRE it will say you don't really implement the Connection I have...) So, unless someone has a brilliant idea I guess I will abandon this idea for now... Ray - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Chainsaw v2 now in jakarta-log4j module
Paul Smith wrote: I tagged both repos prior to the change, tag may be a bit verbose, but there you go. Checked in all the Chainsaw files, and modified build.xml to ensure it hasn't broken anything. I've still got to move over a couple of example log4j.xml files, but I've run out of lunch time, but Chainsaw v2 should start straight out the box with an ant chainsaw command (after configuring the jakarta oro in build.properties) Let me know if I've broken anything, or anyone needs assistance. Paul, I am getting compilation errors on a clean build unless I add the regexp.oro.jar to the compile.classpath in the build.xml. The errors are essentially complaining about not finding the ORO classes. Thanks, Ray - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: log4j 1.3 packaging
My vote would be for a build that includes the jar file as it is now and another jar file containing the minimal set of classes. If a developer is interested in keeping the jar file size down he or she would probably not be intimidated by having to pick and choose appenders to add to the minimal jar. Ceki Gülcü wrote: Breaking log4j.jar to too many pieces will result in confusion. Also note that both ant.jar and option.jar are over 600Kb each. Having said that, if we can define a good separation with log4j.jar and option.jar, then why not. But there is also advantage in having a single, albeit large, jar file: simplicity. At 07:49 AM 6/25/2003 +1000, you wrote: In an effort to get the size of the log4j.jar core file down, is there some more breaking apart we can do? Scott's done a lot of work in the XML JDK 1.4 receiving, but perhaps they could be in a utility jar along with some others? (sort of like Ant's option.jar). - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Log4J Future and Avalon
Berin Loritsch wrote: I had an encouraging chat with the Log4J folks (Ceki in particular), and we have some good news from the logger front. We all knew that Log4J surpasses LogKit in the feature list. We also know that LogKit does its job well for only 25% of the weight. We also know that Log4J is not currently friendly to IOC with the Logger.getLogger() call. Stupid question time (especially since every else seems to know): What does IOC stand for? [snip] The only thing that Log4J 1.3 cannot address is the factory method (Logger.getLogger()) due to compatibility issues. At the same time, Log4J 2.0 will address this issue. In fact Logger will not be a class, but an interface. What about creating a separate interface, e.g. ILogger that Logger can implement? Then Logger still exists as is for backwards compatibility and moving forward people could use ILogger. I'm not sure of the total impact of this on log4j but I imagine it is doable. The simple approach is to make ILogger contain every public method that Logger contains and then to replace Logger with ILogger throughout the log4j code wherever possible. I believe the best course of action is to continue to support LogKit until Log4J 2.0 is released. However, in the mean time we should start putting together stronger support for Log4J in the Avalon containers. Many of our users will most likely be more willing to work with Log4J, and it will be one less issue to worry about. I would also like us to help make Log4J 2.0 a reality. If there are any volunteers who want to help in that direction, please subscribe to the Log4J list. - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [RT] Agnostic logging support
Ceki Gülcü wrote: At 04:23 PM 6/18/2003 +0200, you wrote: Finally, there is the speed issue. As fast as an if.isDebugEnabled() may be, we have seen that some places need a logging statement in a close loop, and this makes performance degrade. How is that possible? If the logging statements are disabled, then they are not used. Otherwise, if they are enabled, then they generate massive output rendering the logs useless. So placing log statements in tight loops is always a lose-lose proposition, or? Well, I can see the value of logging in tight loops at the DEBUG level. Even though you end up with a lot of log statements you might only be interested in the last one (the one that failed). Perhaps a little creative coding can alleviate the performance hit: void doLoop() { if (log.isDebugEnabled()) { for (int i = 0; i limit; i++) { log.debug(i = + i); process(i); } } else { for (int i = 0; i limit; i++) { process(i); } } } void process(int i) { // loop interitor } - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: PreparedStatementAppender
Raymond DeCampo wrote: All, I have polished up the PreparedStatementAppender I have been working on. It has been javadoc'd and jalopy-ized and only awaits a committer to adopt it and place it in the repository (or to provide feedback as to what needs to be done with it before it is worthy of committing to the repository). I have attached the files to bug 20395. Thank you, Ray DeCampo Hello, I posted this about a week ago, but I haven't seen any responses. Could one of the comitters please take a look or promise to take a look when they have the time? Thanks, Ray - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: PreparedStatementAppender
Mark Womack wrote: Hi Raymond, I will do this tonight or tomorrow in the log4j-sandbox. -Mark - Original Message - From: Raymond DeCampo [EMAIL PROTECTED] To: Log4J Developers List [EMAIL PROTECTED] Sent: Sunday, June 08, 2003 7:21 AM Subject: Re: PreparedStatementAppender Thanks, Mark - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
PreparedStatementAppender
All, I have polished up the PreparedStatementAppender I have been working on. It has been javadoc'd and jalopy-ized and only awaits a committer to adopt it and place it in the repository (or to provide feedback as to what needs to be done with it before it is worthy of committing to the repository). I have attached the files to bug 20395. Thank you, Ray DeCampo - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: SV: ContextClassLoaderSelector
Jacob Kjome wrote: I think you've missed the point of what is being done with javax.servlet.context.tempdir. Yes, I assumed you were using it for it's intended purpose. It is absolutely, utterly, guaranteed that any and all containers claiming to have support for the servlet spec *will* provide a temporary directory that is unique for each web application. If they don't, they aren't compliant. I have no worries about that. Here is what you are missing. I don't care about using the actual directory. I just care about the directory name. What I was trying to accomplish was a way that one didn't have to keep multiple configuration files in sync with the name of some property...and I also needed to have some pretty decent assurance that that name wouldn't exist already as a system property. Since webapps must have unique context path names, that turns out to be a pretty good way to name system properties. However, the servlet spec doesn't provide any direct way to obtain the servlet context path (eg... /mycontext) via the ServletContext, which is all I have to work with in the servlet context listener. However, I can grab the value of the system property javax.servlet.context.tempdir. As it turns out, the way Tomcat name tempdirs is very consistent. For instance, a context with the path of /mycontext would have a tempdir named something like this... C:\Java\Apache\Jakarta\tomcat-4.1.24\work\Standalone\localhost\mycontext So, I just grab the string following the last index of the value returned by File.separator and, low and behold, I've obtained the name of the currently running context. Is this any different from ServletContext.getServletContextName() (available in 2.3) or would that be equivalent when available? I take that and append .log.home, use that as a system property name, and set the physical path to where logs should be written for that context which could either be the default of the WEB-INF/logs of the webapp or a user defined path. What breaks down in other servlet containers is that the string following the last index of the value returned by File.separator for a context with a path of /mycontext might be some-other_random-string_having-nothing_to-do_with-the_name-of_the-context_path. Now, in one sense, this is fine because it is unique since we don't want to accidentally overwrite a system property being used by some other application. However, it is far from predictable and might change with each deployment of the webapp in some containers. We need to be able to put something we can count on in log4j.xml such as the following an know it will just work... param name=File value=${mycontext.log.home}/main.log / In summation, I require... 1. a name that is reasonably guaranteed to be unique in the VM - this is achieved by using the name of the context path which must be unique within the container so a system property named after something that is already unique is pretty well guaranteed to be itself 2. not have to specify this name in multiple configuration files. Only log4j.xml. - It is extra work to have to change things in two places. To avoid this, instead of requiring the use to have to provide a context-param with the name of the system variable, I just have the configuration derive it on its own. This also prevents arbitrary naming that might not be as unque in the VM as one might hope. 3. the name must be predictable - one has to reference a system property name in log4j.xml that they can be assured will exist at runtime, otherwise it is of no use. Defining a naming scheme based on [context path].log.home is entirely predictable and the dynamically derived system variable name works for this every time under Tomcat. Let me ask some stupid questions, since I do not really know the purpose of the ContextClassLoaderSelector: How does this work outside of a servlet container? Or is it only intended to run inside a container? What are the other configuration files you refer to? Might there be a way to point both places to the same config file? What happens if tomcat changes the way it implements the temporary directory mechanism? Like I've said, #3 breaks down in containers outside of Tomcat which is why I plan to add a context-param which, if specified, will override the dynamic generation of the system property. Of course this, in turn, breaks down #2, but I don't see any way to get around that. If one continues to use a naming scheme that matches something like [context path].log.home then, at the very least, #1 and #3 continue to hold true. Hopefully that clears things up. If I am just being totally dense and missing your point (which is entirely possible), please point out how #1, #2, and #3 are better achieved by using the java.io.tmpdir system property. - To unsubscribe, e-mail: [EMAIL PROTECTED] For
JDBC Appender
Hello all, I finally have more time as a major deadline has passed at work. I was thinking about writing an improved JDBC appender. My intention is to create a new appender from scratch. As discussed previously, I figured I would have an abstract base class with an abstract getConnection() class and two concrete derivatives; one for getting the connection from a JNDI context and one for getting the connection from the DriverManager. I just wanted to check in to see if anybody is working on this already. I also have a couple of questions: 1) The original JDBCAppender class has a buffer where it stored the events until a limit is hit. I'm not sure I understand the rationale behind this. Doesn't this cause most loggings to be fast but once in a while one client pays the bill for the rest? It also seems to have been a source of bugs in the past. Does anyone have a compelling reason for including it in the new appenders? 2) Is there a good place to look to get a feel for how the configuration works? Thanks, Ray - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: JDBC Appender
Paul Smith wrote: I figured I would have an abstract base class with an abstract getConnection() class and two concrete derivatives; one for getting the connection from a JNDI context and one for getting the connection from the DriverManager. This isn't too bad an idea, but I'm personally against an Abstract class here (and I'm no committer so take this with a grain of salt). What would be ideal is if the configuration of the JDBCAppender could be specified with an option that describes the Strategy to obtain a Connection. Just like you provide a Layout impl for an appender as a attribute. This way you have a single class, but have smaller inner classes with the different ways of getting the connection. I think this ends up being cleaner code, and easier to understand (I think a lot of people get lost with inheritence, and by that I include me). Well, in terms of cleaner code, I don't think that introducing inner classes is the way to go. Personally I think it will be much easier for the end-user to understand that if they are using a DataSource from JNDI they use the JNDIPreparedStatementAppender with set A of options and if they are using the traditional DriverManager they use URLPreparedStatementAppender (I'm open to suggestions on the name) with set B of options. They never need to know that there is an abstract class that contains the common code. Furthermore, it provides a clean way for an end-user to customize how they get their Connections if they are implementing pooling or such things themselves (i.e. extend the class and implement the getConnection() method). 1) The original JDBCAppender class has a buffer where it stored the events until a limit is hit. I'm not sure I understand the rationale behind this. Doesn't this cause most loggings to be fast but once in a while one client pays the bill for the rest? It also seems to have been a source of bugs in the past. Does anyone have a compelling reason for including it in the new appenders? You have a good point on the penalty (not sure if it does this, but if it does, it is bad). What would be more ideal is to buffer the events till some threshold, as it happens now, but when commiting the results to the JDBC connection, do this in a separate thread. Executing in a separate thread has consequences from within an EJB container (i.e., it's a no-no). - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: New Chainsaw features - feedback?
Scott Deboy wrote: I've spent some time working on enhancements to the Chainsaw UI and I thought I'd step back and see what people think. Here's what I've implemented so far: If there are any suggestions for improvement/changes/duplication of effort in what you see here, please let me know. 1: LoggingEvents can now be received from a UDPAppender and XMLLayout (support for multicast) via UDPReceiver. Just start log4j and help your neighbor debug without leaving your desk (as long as you're on the same subnet). 2: UDPAppender looks for an APP system property. If found, the name/value pair is added to the loggingevent properties - along with the machine name (or ip address if not resolvable) (used to uniquely identify each VM running on a machine in Chainsaw). 3: Tabbed pane support - a tabbed pane for each unique machinename/app combination. I thought about allowing the user to pick which fields are used to build the unique tabbed panes, but I'm not sure how useful it would be. I could see using the NDC or MDC on separate tabbed panes in some situations. 4: Jakarta RegExp used to build display and colorizing filters. The DisplayFilter associates columns with regular expressions. If the value in that column passes the regexp, then the row is added to the display. ColorFilters work the same way except they map columns and regular expressions to a Color. For example, colorFilter.addFilter(Level, WARN|INFO, Color.RED) will do the obvious. If a DisplayFilter exists, the row must pass at least one filter to be displayed. If there are no display filters, all rows pass. 5: Ascending/descending column sort with up/down icons - I have gained approval from Claude Duguay to place his JTable sorting code (see http://www.fawcette.com/javapro/2002_08/magazine/columns/visualcomponents/) under the Apache License for use in Log4j. He would like recognition somewhere and a note in the code saying this code has been placed under the Apache license with his explicit permission. Finally, great JSortTable functionality and cool up/down arrows! 6: Handy multi-line tooltip text - see Logger/Msg/Level/Exception information as you move the mouse over the table's rows - no more scrolling to the right to read the exception! 7: A right mouse button popup menu with 'clear log' (per tabbed pane) and toggle on/off of the multi-line tooltip (it is a little slower to update the tooltip over each row). 8. Updated log4j.dtd and LoggingEvent to support properties/mdc. I've made the changes with JDK1.4 and I think I've taken advantage of some of JDK1.4's functionality - but making it work on 1.3 shouldn't be difficult. I haven't looked at Log4J 1.3's receivers yet but hopefully my UDPReceiver will fit nicely. Still to do: 1. Save all settings to property file, including defined color/display filters, window position, column widths/maybe column order Scott, I've already implemented some property saving (window position/size, column widths/order, etc.). Oliver Burn has my diffs and will be proxying the changes into CVS in a few days. Although it appears there may be some merging to do. Ray - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Chainsaw and multiple files
All, I noticed that when you load multiple files with chainsaw that the effect is cumulative, i.e., logging events from all the files are simultaneously loaded. I am in the process of creating a recent files menu and I was going to save the state of the filters for each file. However, given the current behavior, that doesn't seem to fit. So: 1. Is this the desired behavior? 2. Assuming it is, does it make sense to store the state of the filters on a per file basis? I.e., I was going to reset the values of the filters when you load a file you have loaded previously to the values you previously had. Alternatively, I could just save the filter values globally. I should have something to submit this weekend (including saving column widths, a recent files menu, perhaps even column visibility and order). Who should I send the diffs to? Thanks, Ray - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Sorted or order-preserving Properties
Somebody was looking for sorted or order preserving implementations of java.util.Properties. For what it's worth, here's a couple. I haven't made any attempt to optimize them (the order-preserving one in particular is a resource hog), they are not thread-safe and they are a tangle of inner classes but here they are: public class SortedProperties extends Properties { public SortedProperties() { } public java.util.Enumeration keys() { return new java.util.Enumeration() { private java.util.Iterator iterator = new java.util.TreeSet(keySet()).iterator(); public boolean hasMoreElements() { return iterator.hasNext(); } public Object nextElement() { return iterator.next(); } }; } } public class OrderedProperties extends Properties { private int next = 0; private java.util.Map order = new java.util.HashMap(); public OrderedProperties() { } public Object put(Object key, Object value) { if (!order.containsKey(key)) { order.put(key, new Integer(next++)); } return super.put(key, value); } public java.util.Enumeration keys() { return new java.util.Enumeration() { private java.util.Iterator iterator; { java.util.SortedSet sortedKeySet = new java.util.TreeSet( new java.util.Comparator() { public int compare(Object x, Object y) { Integer xInt = (Integer)order.get(x); Integer yInt = (Integer)order.get(y); if (xInt == null) { xInt = new Integer(0); } if (yInt == null) { yInt = new Integer(0); } return xInt.compareTo(yInt); } }); sortedKeySet.addAll(keySet()); iterator = sortedKeySet.iterator(); } public boolean hasMoreElements() { return iterator.hasNext(); } public Object nextElement() { return iterator.next(); } }; } } They rely on the fact that java.util.Properties uses java.util.Hashtable.keys() to get the set of keys to iterate over for writing out the file. If that internal implementation detail changes, the classes will fail to work. All-in-all they are a non-production-level hack but hey -- doesn't everything start out that way? Ray - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Configuration GUI
Niclas Hedhman wrote: On Thursday 13 February 2003 03:03, robert burrell donkin wrote: On Tuesday, February 11, 2003, at 11:35 PM, Richard Bair wrote: snip BTW, Mark, I'm totally wrong. The java.beans package goes all the way back to 1.2.2 at least. I think it will work well for what we are doing here. if you're using java 1.3 (and maybe some earlier versions), you need to be a bit beware since reflection is buggy. This is a pretty bold statement... I have been using java.lang.reflect since it was introduced (in fact I had my own implementation in JDK 1.0), and have not experienced any issues, bugs or the like. AFAIK, Serialization also depends heavily on it, and RMI depends on Serialization, and J2EE depends heavily on RMI. You really think that anything buggy would be tolerated to stay around for that long (when was 1.2 released? 1998?, 1999?). Do you have any example of this reflection is buggy?? Niclas Niclas, There are documented bugs on Sun's web site (http://developer.java.sun.com/developer/bugParade/bugs/4477877.html). The bugs aren't in reflection but the Introspector. If I recall correctly the exact behavior depends on the order of the methods as returned by reflection. Since the order is indeterminate, it can change simply by loading another class or adding methods (a good analogy would be the order of items in a HashMap). Ray - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: JDBCAppender memory leak issue
Lutz Michael wrote: I will look at it. From what I've seen, it didn't look overly complicated, but I know how database code can get ... especially when you're trying to be RDBMS neutral. Please give me a few days to get back to you (I'm also busy of course). Also, the CLOB support was another point of importance, I'll consider that too. -Original Message- From: Ceki Gülcü [mailto:[EMAIL PROTECTED]] Sent: Wednesday, February 12, 2003 4:04 PM To: Log4J Developers List Subject: RE: JDBCAppender memory leak issue Mike, Have you looked at the code of JDBC Appender? If so, what do you think? At 13:37 12.02.2003 -0500, you wrote: When I looked over the code, my first thought is that it should use a PreparedStatement instead of a Statement. In this way you will solve a great number of issues (e.g. escaping ' in string literals would not be necessary). The configuration can match the order of the ?s to the properties of the logging event. The code can use PreparedStatement.setObject() to set the parameters and let the JDBC driver worry about mapping types. This would improve performance as well (at least in theory). Another improvement that immediately comes to mind is an option to use JNDI to get a DataSource instead of specifying the Connection. This would improve performance greatly on application servers where you would get connection pooling. Unfortunately I don't think that really makes the class easier to implement/maintain. (Probably the way to go here would be an abstract base class with an abstract getConnection() method with two concrete classes which get the connection in the two different manners.) As far as CLOBs go, they can be problematic. For whatever reason, there is no standard way in the JDBC specification to create a java.sql.Clob object for use in the PreparedStatement.setClob() method. The alternative is to use the setXXXStream() methods which are not always implemented in JDBC drivers (at least in one I am familiar with). Ray - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Where can I help?
Thanks for the suggestions. I think I'll give some effort towards improving Chainsaw. Toward that end, when I was trying to get Chainsaw going today, I noticed that it is not compatible with output from earlier XMLLayout output that use category instead of logger. Was this intentional or should I submit my fix? Is anybody else actively working on Chainsaw? If so we should coordinate our efforts. Thanks, Ray [EMAIL PROTECTED] wrote: All of Scott's suggestions are good. Ray, what are your interests in the log4j code? What area would you like to look at/contribute to? We can certainly suggest an area to look at, but if you have a specific area of interest, then it will be more interesting, certainly. Your interest and effort are most welcome. For anyone out there interested in contributing code, I started a wiki page with some guidelines/requirements: http://nagoya.apache.org/wiki/apachewiki.cgi?Log4JProjectPages/ContributingC ode I'd be very interested in documenting the steps one must go through to get the current log4j cvs code compiling on one's machine. Would someone be interested in documenting the process in that page as well? -Mark -Original Message- From: Scott Schram [mailto:[EMAIL PROTECTED]] Sent: Saturday, February 08, 2003 6:02 PM To: Log4J Developers List Subject: Re: Where can I help? Until the log4j gurus have a chance to respond, may I suggest: Take a look at the Wiki and see if information there is complete, or could use improving. http://nagoya.apache.org/wiki/apachewiki.cgi?Log4JProjectPages And the todo pages there for ideas: http://nagoya.apache.org/wiki/apachewiki.cgi?Log4JProjectPages/ToDo Make sure you can get the source code via CVS, and compile it. Here are some possible areas to work on: http://jakarta.apache.org/log4j/docs/plan.html A couple catch my eye: add automated tests. Improve Chainsaw. Scott At 12:25 PM 2/8/2003, you wrote: All, I haven't been involved with open source before but I've wanted to for a while. I figured I would take the plunge with log4j. Where can I be of help? Should I just grab some bugs from Bugzilla and go? Does anyone have any in particular they'd like to see tackled but don't have the time themselves? Thanks, Ray - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Where can I help?
All, I haven't been involved with open source before but I've wanted to for a while. I figured I would take the plunge with log4j. Where can I be of help? Should I just grab some bugs from Bugzilla and go? Does anyone have any in particular they'd like to see tackled but don't have the time themselves? Thanks, Ray - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]