如何在log4j2中实现日期模式转换器

时间:2015-10-08 12:53:31

标签: java java-ee logging log4j log4j2

我有一个用log4j编写的日期模式转换器。此转换器使用extractOption()的{​​{1}}来获取日期格式,以将日期格式设置为字符串,并将其与不同的PatternParser日期格式进行比较,并根据标识的日期格式设置日期格式。

使用的相关代码如下:

TestPatternParser(log4j):

log4j

TestDatePatternConverter(log4j):

public class TestPatternParser extends PatternParser {

private static final char DATETIME_CHAR = 'd';

public TestPatternParser(String pattern) {
    super(pattern);
}

@Override
protected void finalizeConverter(char c) {
    switch (c) {
        case DATETIME_CHAR:
            String dateFormatStr = AbsoluteTimeDateFormat.ISO8601_DATE_FORMAT;
            DateFormat df;
            String dOpt = extractOption();
            if (dOpt != null)
                dateFormatStr = dOpt;

            if (dateFormatStr.equalsIgnoreCase(AbsoluteTimeDateFormat.ISO8601_DATE_FORMAT))
                df = new ISO8601DateFormat();
            else if (dateFormatStr.equalsIgnoreCase(AbsoluteTimeDateFormat.ABS_TIME_DATE_FORMAT))
                df = new AbsoluteTimeDateFormat();
            else if (dateFormatStr.equalsIgnoreCase(AbsoluteTimeDateFormat.DATE_AND_TIME_DATE_FORMAT))
                df = new DateTimeDateFormat();
            else {
                try {
                    df = new SimpleDateFormat(dateFormatStr);
                } catch (IllegalArgumentException e) {
                    LogLog.error("Could not instantiate SimpleDateFormat with " + dateFormatStr, e);
                    df = (DateFormat) OptionConverter.instantiateByClassName(
                            "org.apache.log4j.helpers.ISO8601DateFormat", DateFormat.class, null);
                }
            }
            PatternConverter pc = new TestDatePatternConverter(formattingInfo, df);
            currentLiteral.setLength(0);
            addConverter(pc);                
            break;
        default:
            super.finalizeConverter(c);
    }
 }
}

我编写了日期转换器但是如何获取默认日期格式并与public class TestDatePatternConverter extends PatternConverter { private DateFormat df; private Date date; TestDatePatternConverter(FormattingInfo formattingInfo, DateFormat df) { super(formattingInfo); date = new Date(); this.df = df; } public String convert(LoggingEvent event) { long eventTimestamp = event.timeStamp; TestContext testContext; if (TestLogHandler.getTimestampDelta() != 0) { eventTimestamp = event.timeStamp + TestLogHandler.getTimestampDelta(); } else if (null != (testContext = TestContextHolder.getTestContextForThread())) { long timeStamp = testContext.getLogTimeStamp(); if (timeStamp != 0) { eventTimestamp = timeStamp; } } date.setTime(eventTimestamp); String converted = null; try { converted = df.format(date); } catch (Exception ex) { LogLog.error("Error occured while converting date.", ex); } return converted; } } 中的标准日期格式进行比较?

TestDatePatternConverter(log4j2):

log4j2
  1. 如何在等效的@Plugin(name = "TestDatePatternConverter", category = "Converter") @ConverterKeys({"d"}) public class TestDatePatternConverter extends LogEventPatternConverter { private Date date; protected TestDatePatternConverter(String name, String style) { super(name, style); date = new Date(); } public static TestDatePatternConverter newInstance(final String[] options) { return new TestDatePatternConverter("d", "d"); } @Override public void format(LogEvent event, StringBuilder toAppendTo) { long eventTimestamp = event.getTimeMillis(); TestContext testContext; if (TestLogHandler.getTimestampDelta() != 0) { eventTimestamp = event.getTimeMillis() + TestLogHandler.getTimestampDelta(); } else if (null != (testContext = TestContextHolder.getTestContextForThread())) { long timeStamp = testContext.getLogTimeStamp(); if (timeStamp != 0) { eventTimestamp = timeStamp; } } date.setTime(eventTimestamp); String converted = null; try { ??? How can I compare and get the date format as mentioned in the PatternParser in log4j code. ??? converted = df.format(date); } catch (Exception ex) { StatusLogger.getLogger().error("Error occured while converting date.", ex); } toAppendTo.append(converted); } } 代码中获取PatternParser中提到的日期格式。

  2. 以下内容在log4j2中不可用,等同于什么?

    AbsoluteTimeDateFormat.ISO8601_DATE_FORMAT AbsoluteTimeDateFormat.ABS_TIME_DATE_FORMAT AbsoluteTimeDateFormat.DATE_AND_TIME_DATE_FORMAT

    ISO8601DateFormat
    AbsoluteTimeDateFormat
    DateTimeDateFormat

  3. 请帮忙。感谢。

2 个答案:

答案 0 :(得分:1)

不确定您的用例,但如果您需要调整时间戳以实现某种“时移”,则最简单的方法是提供一个自定义Clock实现,以添加/减去固定的系统时间的毫秒数。您可以通过在系统属性log4j.Clock中指定Clock实现类的完全限定类名来完成此操作。

将它与PatternLayout中的一种预定义日期格式(如%d{ABSOLUTE}%d{DEFAULT}等)相结合,可以获得最佳性能。

Log4j 2.4在改进日期格式化性能方面做了大量工作,尤其是在多线程场景中(LOG4J2-812LOG4J2-1097)。如果你能从这些改进中受益,那将是件好事。

答案 1 :(得分:0)

你看过DatePatternConverter吗?传递选项然后传递给FixedDateFormat。如果它不是FixedDateFormat知道的标准格式之一,它将尝试使用FastDateFormat.getInstance()创建自定义格式。