1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.pattern;
18
19 import java.text.SimpleDateFormat;
20 import java.util.Date;
21 import java.util.TimeZone;
22
23 import org.apache.logging.log4j.core.LogEvent;
24 import org.apache.logging.log4j.core.config.plugins.Plugin;
25
26
27
28
29 @Plugin(name = "DatePatternConverter", category = PatternConverter.CATEGORY)
30 @ConverterKeys({ "d", "date" })
31 public final class DatePatternConverter extends LogEventPatternConverter implements ArrayPatternConverter {
32
33 private abstract static class Formatter {
34 abstract String format(long time);
35
36 public String toPattern() {
37 return null;
38 }
39 }
40
41 private static class PatternFormatter extends Formatter {
42 private final SimpleDateFormat simpleDateFormat;
43
44 PatternFormatter(final SimpleDateFormat simpleDateFormat) {
45 this.simpleDateFormat = simpleDateFormat;
46 }
47
48 @Override
49 String format(final long time) {
50 return simpleDateFormat.format(Long.valueOf(time));
51 }
52
53 @Override
54 public String toPattern() {
55 return simpleDateFormat.toPattern();
56 }
57 }
58
59 private static class UnixFormatter extends Formatter {
60
61 @Override
62 String format(final long time) {
63 return Long.toString(time / 1000);
64 }
65
66 }
67
68 private static class UnixMillisFormatter extends Formatter {
69
70 @Override
71 String format(final long time) {
72 return Long.toString(time);
73 }
74
75 }
76
77
78
79
80 private static final String ABSOLUTE_FORMAT = "ABSOLUTE";
81
82
83
84
85 private static final String ABSOLUTE_TIME_PATTERN = "HH:mm:ss,SSS";
86
87
88
89
90 private static final String COMPACT_FORMAT = "COMPACT";
91
92
93
94
95 private static final String COMPACT_PATTERN = "yyyyMMddHHmmssSSS";
96
97
98
99
100 private static final String DATE_AND_TIME_FORMAT = "DATE";
101
102
103
104
105 private static final String DATE_AND_TIME_PATTERN = "dd MMM yyyy HH:mm:ss,SSS";
106
107
108
109
110 private static final String DEFAULT_FORMAT = "DEFAULT";
111
112
113
114
115
116 static final String DEFAULT_PATTERN = "yyyy-MM-dd HH:mm:ss,SSS";
117
118
119
120
121 private static final String ISO8601_BASIC_FORMAT = "ISO8601_BASIC";
122
123
124
125
126 private static final String ISO8601_BASIC_PATTERN = "yyyyMMdd'T'HHmmss,SSS";
127
128
129
130
131
132 static final String ISO8601_FORMAT = "ISO8601";
133
134
135
136
137
138 static final String ISO8601_PATTERN = "yyyy-MM-dd'T'HH:mm:ss,SSS";
139
140
141
142
143 private static final String UNIX_FORMAT = "UNIX";
144
145
146
147
148 private static final String UNIX_MILLIS_FORMAT = "UNIX_MILLIS";
149
150
151
152
153
154
155
156
157 public static DatePatternConverter newInstance(final String[] options) {
158 return new DatePatternConverter(options);
159 }
160
161
162
163
164 private String cachedDateString;
165
166 private final Formatter formatter;
167
168 private long lastTimestamp;
169
170
171
172
173
174
175
176 private DatePatternConverter(final String[] options) {
177 super("Date", "date");
178
179
180 final String patternOption = options != null && options.length > 0 ? options[0] : null;
181
182 String pattern = null;
183 Formatter tempFormatter = null;
184
185 if (patternOption == null || patternOption.equalsIgnoreCase(DEFAULT_FORMAT)) {
186 pattern = DEFAULT_PATTERN;
187 } else if (patternOption.equalsIgnoreCase(ISO8601_FORMAT)) {
188 pattern = ISO8601_PATTERN;
189 } else if (patternOption.equalsIgnoreCase(ISO8601_BASIC_FORMAT)) {
190 pattern = ISO8601_BASIC_PATTERN;
191 } else if (patternOption.equalsIgnoreCase(ABSOLUTE_FORMAT)) {
192 pattern = ABSOLUTE_TIME_PATTERN;
193 } else if (patternOption.equalsIgnoreCase(DATE_AND_TIME_FORMAT)) {
194 pattern = DATE_AND_TIME_PATTERN;
195 } else if (patternOption.equalsIgnoreCase(COMPACT_FORMAT)) {
196 pattern = COMPACT_PATTERN;
197 } else if (patternOption.equalsIgnoreCase(UNIX_FORMAT)) {
198 tempFormatter = new UnixFormatter();
199 } else if (patternOption.equalsIgnoreCase(UNIX_MILLIS_FORMAT)) {
200 tempFormatter = new UnixMillisFormatter();
201 } else {
202 pattern = patternOption;
203 }
204
205 if (pattern != null) {
206 SimpleDateFormat tempFormat;
207
208 try {
209 tempFormat = new SimpleDateFormat(pattern);
210 } catch (final IllegalArgumentException e) {
211 LOGGER.warn("Could not instantiate SimpleDateFormat with pattern " + patternOption, e);
212
213
214 tempFormat = new SimpleDateFormat(DEFAULT_PATTERN);
215 }
216
217
218 if (options != null && options.length > 1) {
219 final TimeZone tz = TimeZone.getTimeZone(options[1]);
220 tempFormat.setTimeZone(tz);
221 }
222 tempFormatter = new PatternFormatter(tempFormat);
223 }
224 formatter = tempFormatter;
225 }
226
227
228
229
230
231
232
233
234
235 public void format(final Date date, final StringBuilder toAppendTo) {
236 synchronized (this) {
237 toAppendTo.append(formatter.format(date.getTime()));
238 }
239 }
240
241
242
243
244 @Override
245 public void format(final LogEvent event, final StringBuilder output) {
246 final long timestamp = event.getTimeMillis();
247
248 synchronized (this) {
249 if (timestamp != lastTimestamp) {
250 lastTimestamp = timestamp;
251 cachedDateString = formatter.format(timestamp);
252 }
253 }
254 output.append(cachedDateString);
255 }
256
257
258
259
260 @Override
261 public void format(final Object obj, final StringBuilder output) {
262 if (obj instanceof Date) {
263 format((Date) obj, output);
264 }
265 super.format(obj, output);
266 }
267
268 @Override
269 public void format(final StringBuilder toAppendTo, final Object... objects) {
270 for (final Object obj : objects) {
271 if (obj instanceof Date) {
272 format(obj, toAppendTo);
273 break;
274 }
275 }
276 }
277
278
279
280
281
282
283 public String getPattern() {
284 return formatter.toPattern();
285 }
286
287 }