Is it possible to use format modifiers for two con

2019-06-27 22:23发布

问题:

I know how to output classname and methodname with log4j, both fields can be aligned and padded separately, e.g. this pattern:

[%d{ISO8601}] %-5p %-10C{1}:%-10M %m%n

produces something like:

[2012-09-20 08:25:12,111] WARN  Class     :method     Logtext1 which should align
[2012-09-20 08:25:12,111] WARN  ClassTwo  :methodName Logtext2 which should align

This will align the logged text (in most cases), but the classname and methodname are ugly spaced.

So what I would like to output is something like:

[2012-09-20 08:25:12,111] WARN  Class:method          Logtext1 which should align
[2012-09-20 08:25:12,111] WARN  ClassTwo:methodName   Logtext2 which should align

Is this possible using only configuration?

Can you suggest another way of outputting methodname and classname, keeping the logged message text aligned?

回答1:

It seems like this is not possible using only configuration. The next simpler solution seems to be a custom PatternLayout, which then can be used in the log4j.ini with the character 'b':

log4j.appender.filelog.layout= your.full.namespace.BPatternLayout log4j.appender.filelog.layout.ConversionPattern=[%d{ISO8601}] %-5p %-30b %m%n

Hope it helps someone else, too.

BPatternLayout.java:

import org.apache.log4j.PatternLayout;
import org.apache.log4j.helpers.PatternParser;

public class BPatternLayout extends PatternLayout
{
    @Override
    protected PatternParser createPatternParser(String pattern)
    {
        return new BPatternParser(pattern);
    }
}

BPatternParser.java:

import org.apache.log4j.helpers.FormattingInfo;
import org.apache.log4j.helpers.PatternConverter;
import org.apache.log4j.helpers.PatternParser;
import org.apache.log4j.spi.LocationInfo;
import org.apache.log4j.spi.LoggingEvent;

public class BPatternParser extends PatternParser
{
    public BPatternParser(String pattern)
    {
        super(pattern);
    }

    @Override
    protected void finalizeConverter(char c)
    {
        switch (c)
        {
        case 'b':
            currentLiteral.setLength(0);
            addConverter(new BPatternConverter(formattingInfo));
            break;
        default:
            super.finalizeConverter(c);
        }   
    }

    private class BPatternConverter extends PatternConverter
    {
        BPatternConverter(FormattingInfo formattingInfo)
        {
            super(formattingInfo);
        }

        @Override
        protected String convert(LoggingEvent evt)
        {
            LocationInfo locationInfo = evt.getLocationInformation();
            return getPartialClassName(locationInfo, 1) + ":" + locationInfo.getMethodName();
        }

        /**
         * Code from org.apache.log4j.helpers.PatternParser.NamedPatternConverter
         */
        private String getPartialClassName(LocationInfo loc, int precision)
        {
            String n = loc.getClassName();
            if (precision <= 0) {
                return n;
            }

            int len = n.length();

            // We substract 1 from 'len' when assigning to 'end' to avoid out of
            // bounds exception in return r.substring(end+1, len). This can happen if
            // precision is 1 and the category name ends with a dot.
            int end = len - 1;
            for (int i = precision; i > 0; i--)
            {
                end = n.lastIndexOf('.', end - 1);
                if (end == -1)
                    return n;
            }
            return n.substring(end + 1, len);
        }
    }
}


标签: log4j