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 = "Converter")
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(SimpleDateFormat simpleDateFormat) {
45 this.simpleDateFormat = simpleDateFormat;
46 }
47
48 @Override
49 String format(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(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(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 ISO8601_BASIC_FORMAT = "ISO8601_BASIC";
111
112
113
114
115 private static final String ISO8601_BASIC_PATTERN = "yyyyMMdd HHmmss,SSS";
116
117
118
119
120 private static final String ISO8601_FORMAT = "ISO8601";
121
122
123
124
125 private static final String ISO8601_PATTERN = "yyyy-MM-dd HH:mm:ss,SSS";
126
127
128
129
130 private static final String UNIX_FORMAT = "UNIX";
131
132
133
134
135 private static final String UNIX_MILLIS_FORMAT = "UNIX_MILLIS";
136
137
138
139
140
141
142
143
144 public static DatePatternConverter newInstance(final String[] options) {
145 return new DatePatternConverter(options);
146 }
147
148
149
150
151 private String cachedDateString;
152
153 private final Formatter formatter;
154
155 private long lastTimestamp;
156
157
158
159
160
161
162
163 private DatePatternConverter(final String[] options) {
164 super("Date", "date");
165
166
167 final String patternOption = options != null && options.length > 0 ? options[0] : null;
168
169 String pattern = null;
170 Formatter tempFormatter = null;
171
172 if (patternOption == null || patternOption.equalsIgnoreCase(ISO8601_FORMAT)) {
173 pattern = ISO8601_PATTERN;
174 } else if (patternOption.equalsIgnoreCase(ISO8601_BASIC_FORMAT)) {
175 pattern = ISO8601_BASIC_PATTERN;
176 } else if (patternOption.equalsIgnoreCase(ABSOLUTE_FORMAT)) {
177 pattern = ABSOLUTE_TIME_PATTERN;
178 } else if (patternOption.equalsIgnoreCase(DATE_AND_TIME_FORMAT)) {
179 pattern = DATE_AND_TIME_PATTERN;
180 } else if (patternOption.equalsIgnoreCase(COMPACT_FORMAT)) {
181 pattern = COMPACT_PATTERN;
182 } else if (patternOption.equalsIgnoreCase(UNIX_FORMAT)) {
183 tempFormatter = new UnixFormatter();
184 } else if (patternOption.equalsIgnoreCase(UNIX_MILLIS_FORMAT)) {
185 tempFormatter = new UnixMillisFormatter();
186 } else {
187 pattern = patternOption;
188 }
189
190 if (pattern != null) {
191 SimpleDateFormat tempFormat;
192
193 try {
194 tempFormat = new SimpleDateFormat(pattern);
195 } catch (final IllegalArgumentException e) {
196 LOGGER.warn("Could not instantiate SimpleDateFormat with pattern " + patternOption, e);
197
198
199 tempFormat = new SimpleDateFormat(ISO8601_PATTERN);
200 }
201
202
203 if (options != null && options.length > 1) {
204 final TimeZone tz = TimeZone.getTimeZone(options[1]);
205 tempFormat.setTimeZone(tz);
206 }
207 tempFormatter = new PatternFormatter(tempFormat);
208 }
209 formatter = tempFormatter;
210 }
211
212
213
214
215
216
217
218
219
220 public void format(final Date date, final StringBuilder toAppendTo) {
221 synchronized (this) {
222 toAppendTo.append(formatter.format(date.getTime()));
223 }
224 }
225
226
227
228
229 @Override
230 public void format(final LogEvent event, final StringBuilder output) {
231 final long timestamp = event.getTimeMillis();
232
233 synchronized (this) {
234 if (timestamp != lastTimestamp) {
235 lastTimestamp = timestamp;
236 cachedDateString = formatter.format(timestamp);
237 }
238 }
239 output.append(cachedDateString);
240 }
241
242
243
244
245 @Override
246 public void format(final Object obj, final StringBuilder output) {
247 if (obj instanceof Date) {
248 format((Date) obj, output);
249 }
250 super.format(obj, output);
251 }
252
253 @Override
254 public void format(final StringBuilder toAppendTo, final Object... objects) {
255 for (final Object obj : objects) {
256 if (obj instanceof Date) {
257 format(obj, toAppendTo);
258 break;
259 }
260 }
261 }
262
263
264
265
266
267
268 public String getPattern() {
269 return formatter.toPattern();
270 }
271
272 }