4

我知道如何使用 log4j 输出类名和方法名,这两个字段可以分别对齐和填充,例如这种模式:

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

产生类似的东西:

[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

这将对齐记录的文本(在大多数情况下),但类名和方法名的间距很难看。

所以我想输出的是这样的:

[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

这可能仅使用配置吗?

你能建议另一种输出方法名和类名的方法,保持记录的消息文本对齐吗?

4

1 回答 1

0

似乎仅使用配置是不可能的。下一个更简单的解决方案似乎是自定义 PatternLayout,然后可以在 log4j.ini 中使用字符“b”:

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

希望它也对其他人有所帮助。

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);
        }
    }
}
于 2012-10-03T06:52:52.777 回答