【问题标题】:How to implement Date pattern converter in log4j2如何在 log4j2 中实现日期模式转换器
【发布时间】:2016-01-06 02:43:36
【问题描述】:

我有一个用log4j 编写的日期模式转换器。此转换器通过使用PatternParserextractOption() 获取日期格式,将日期格式作为字符串,并将其与不同的log4j 日期格式进行比较,并根据确定的日期格式格式化日期。

用到的相关代码如下:

TestPatternParser (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);
    }
 }
}

TestDatePatternConverter (log4j):

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; 
 }
}

我已经编写了日期转换器,但是如何获取默认日期格式并与log4j2 中的标准日期格式进行比较?

TestDatePatternConverter (log4j2):

@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);


}

}
  1. 我怎样才能在等效的log4j 代码中获得PatternParser 中提到的日期格式。

  2. 以下在 log4j2 中不可用,等价物是什么?

    AbsoluteTimeDateFormat.ISO8601_DATE_FORMAT AbsoluteTimeDateFormat.ABS_TIME_DATE_FORMAT AbsoluteTimeDateFormat.DATE_AND_TIME_DATE_FORMAT

    ISO8601日期格式
    绝对时间日期格式
    日期时间日期格式

请帮忙。谢谢。

【问题讨论】:

    标签: java jakarta-ee logging log4j log4j2


    【解决方案1】:

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

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

    Log4j 2.4 做了大量工作来提高日期格式化性能,尤其是在多线程场景中(LOG4J2-812LOG4J2-1097)。如果您能从这些改进中受益,那就太好了。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 非常感谢.. rgoers。我对日期进行了自定义(在记录之前调整时间戳逻辑)。所以,我需要在java中保留这个转换。如何在java中获取日期格式并在附加之前格式化日期。
      • 我需要知道您所说的“调整时间戳逻辑”是什么意思。你的意思是时间戳的值还是别的什么。 Log4j 使用来自 Apache Commons Logging -commons.apache.org/proper/commons-lang/javadocs/api-release/… 的 FastDateFormat 的副本。你想要的东西不支持吗?
      • 如果您想实际修改事件时间戳,可以使用 Remko 下面提到的方法,也可以使用 RewritePolicy。这使您可以在 LogEvent 通过 Appender 时对其进行修改。
      猜你喜欢
      • 1970-01-01
      • 2016-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多