views:

57

answers:

2

I have a project that uses Apache Commons Logging & log4j with a large number of classes doing logging. 95% of my logs show up with the same prefix

log4j.appender.MyCompany.layout.ConversionPattern=[%d][%-5p][%c] %m%n

[2010-08-05 11:44:18,940][DEBUG][com.mycompany.projectname.config.XMLConfigSource] Loading config from [filepath]
[2010-08-05 12:05:52,715][INFO ][com.mycompany.projectname.management.ManagerCore] Log entry 1
[2010-08-05 12:05:52,717][INFO ][com.mycompany.projectname.management.ManagerCore] Log entry 2

I know with %c{1}, I can just show the last part of the category (i.e. the class name), but is there a way to trim off the common portion 'com.mycompany.projectname' from each log under that package, considering how much room it takes up on each line?

A: 

Use %c{2} or %C{2}. The number specifies the number of right-most components to keep.

Refer to http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html.

Jonathon
Thanks, but I'm looking to trim from the left, since if something has com.mycompany.projectname.a.b.C, I'd like it to show up as a.b.C. If it's com.mycompany.projectname.d.E, I'd like it to show up as d.E. With %c{2}, I'd only get the two rightmost elements.
Shawn D.
@sdeer yes, that's what it does. If you specify the number 2, the 2 right-most items are kept: d.E
Jonathon
+2  A: 

If you are using Log4j 1.2.16, you can change your layout to EnhancedPatternLayout, which lets you specify a negative value for the category parameter. From the docs:

For example, for the category name "alpha.beta.gamma" ... %c{-2} will remove two elements [from the front] leaving "gamma"

Here is a more complete example:

log4j.appender.C.layout=org.apache.log4j.EnhancedPatternLayout
log4j.appender.C.layout.ConversionPattern=%d{ABSOLUTE} %-5p [%t] [%c{-3}] %m%n

which in your case should chop off com.mycompany.projectname.

However, this will apply to every message that is logged, even if it didn't come from your code. In other words, the category org.hibernate.engine.query.HQLQueryPlan would be trimmed to query.HQLQueryPlan, which may not be what you want.

If you need absolute control over this (i.e. you want to specifically strip out the text "com.mycompany.projectname" from every message), then you will need to implement your own Layout class. Something like this should do it:

import org.apache.log4j.PatternLayout;
import org.apache.log4j.spi.LoggingEvent;

public class MyPatternLayout extends PatternLayout
{
  @Override
  public String format(LoggingEvent event)
  {
    String msg = super.format(event);
    msg = msg.replace("com.mycompany.projectname", "");

    return msg;
  }
}

Good luck!

Matt Solnit
Thanks. That's just what I wanted.
Shawn D.