简体   繁体   中英

How to implement Date pattern converter in log4j2

I have a date pattern converter written in log4j . This converter takes dateformat by using extractOption() of PatternParser to get the dateformat as String and this is compared with different log4j dateformats and the date is formatted based on the idenfified dateformat.

The related code used is mentioned below:

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

I have written the date converter but how to get the default date format and compare against standard date formats in 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. How can I get the date format as mentioned in the PatternParser in the equivalent log4j code.

  2. Below are not available in log4j2 and what is the equivalent ?

    AbsoluteTimeDateFormat.ISO8601_DATE_FORMAT AbsoluteTimeDateFormat.ABS_TIME_DATE_FORMAT AbsoluteTimeDateFormat.DATE_AND_TIME_DATE_FORMAT

    ISO8601DateFormat
    AbsoluteTimeDateFormat
    DateTimeDateFormat

Please help. Thanks.

Not sure about your use case, but if you need to adjust the time stamp to implement a "time shift" of some sort, it may be easiest to provide a custom Clock implementation that adds/subtracts a fixed number of milliseconds to the system time. You can accomplish this by specifying the fully qualified class name of your Clock implementation class in system property log4j.Clock .

Combining this with one of the predefined date formats (like %d{ABSOLUTE} , %d{DEFAULT} , etc) in PatternLayout will give the best performance.

Log4j 2.4 did quite a lot of work to improve date formatting performance, especially in multi-threaded scenarios ( LOG4J2-812 , LOG4J2-1097 ). It would be good if you can benefit from those improvements.

Have you looked at the DatePatternConverter? The options are passed in and then passed to FixedDateFormat. If it is not one of the standard formats FixedDateFormat knows about it will try to create a custom format using FastDateFormat.getInstance().

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM