8 Replies Latest reply on Dec 12, 2006 2:21 PM by gavin.king

    Seam Log4J wrapper

    monkeyden

      I'm trying to log some more verbose information about, like line number and calling method, but I think the Seam logger is stepping on these features of Log4J. For instance, I have this ConversionPattern in my log4j.xml file:

      <param name="ConversionPattern" value="%d{HH:mm:ss,SSS} %-5p [%c{1}.%M (%L)] %m%n"/>

      "M" is the method name and "L" is the line number. This ALWAYS result in "debug" and "84", respectively.

      My Seam source doesn't match up exactly but it looks like line 84 is, as you might expect, somewhere in here:
      public void debug(Object object, Throwable t, Object... params)
      {
       if ( isDebugEnabled() )
       {
       log.debug( interpolate(object, params), t );
       }
      }
      

      Has anyone else run into this? Found a solution/workaround?


        • 1. Re: Seam Log4J wrapper
          gavin.king

          Right, this is a limitation. I've been told there might be some log4j magic that can fix that (and there must be, since I don't think commons-logging suffers the problem) but I have not had time to figure out what it is.

          Perhaps its as simple as futzing with the stack frames (ick).

          If you would like to investigate (start looking at commons-logging) and come up with a fix, that would be awesome.

          • 2. Re: Seam Log4J wrapper
            monkeyden

             

            "gavin.king@jboss.com" wrote:

            Perhaps its as simple as futzing with the stack frames (ick).

            I have long suspected that that's how Log4J did it. I will soon find out for sure, unsavory as it may be. I'll look into it when finish this release.

            • 3. Re: Seam Log4J wrapper

              I've come across this before when wrapping commons-logging but never come up with a satisfactory fix.

              commons-logging works because it passes a Fully Qualified Class Name (FQCN) in to every call to the log4j library (check out the Log4JLogger in commons-logging). The log4j library then uses this as the "entry" point into the logging system and takes the line/method/file of the entry just below it in the stack frame (it uses nasty string searching because StackTraceElement is 1.4+). This obviously goes wrong when something adds another wrapping layer round the commons-logging.

              The only "fix" I have come up with, but never implemented, is to plugin a different commons-logging LogFactory implementation, trap the case where it detects log4j as the logging type and return a custom log4j wrapper rather than the one provided by commons-logging. The wrapper would then pass in it's own FQCN that would allow log4j to get the line numbers right.

              Another fix would be to use log4j directly in Seam which would make passing in the correct FQCN trivial. Of course doing this may not be viable if commons-logging must be used to support the other log implementations.

              If I can spare some time I may look into bodging the first solution together to at least see if it works.

              Cheers.

              Mike.

              • 4. Re: Seam Log4J wrapper
                gavin.king

                Thanks Mike, that would be awesome.

                • 5. Re: Seam Log4J wrapper

                  Done some looking into this. I have something that works for me but am unsure about the implications when it is running inside a web container because it creates it's own instance of a LogFactory which is not ideal. This will double up all the internal data structures etc.

                  Would probably need someone who's familiar with classloading issues in web containers to check this over. I know some applications call LogFactory.release(All) to avoid classloaders being held by the logging system and in turn causes memory leaks on a redeploy. Perhaps the Seam ServletContextListener could call release() on the Seam LogFactory when the context is destroyed.

                  The (unexpected) advantage of doing it this way is it isolates the Seam logs from the normal logs so even if you create a Seam log and a normal log from the same class/bean/pojo the line numbering should work ok for both. Reusing the same LogFactory would mean it would've been the first to open the log for that class wins.

                  Far as I've got so far, any thoughts? I can post the code somewhere, JIRA?, if it would be helpful.

                  Cheers.

                  Mike.

                  • 6. Re: Seam Log4J wrapper
                    gavin.king

                    Ugh, I really don't know too much about the classloading issues with logging, I would definitely be interested to see your code, however.

                    Maybe we should shift this discussion to JIRA?

                    • 7. Re: Seam Log4J wrapper
                      • 8. Re: Seam Log4J wrapper
                        gavin.king

                        thanks