1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.layout;
18
19 import java.util.HashSet;
20 import java.util.Set;
21
22 import javax.xml.stream.XMLStreamException;
23
24 import com.fasterxml.jackson.databind.ser.FilterProvider;
25 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
26 import org.apache.logging.log4j.core.jackson.JsonConstants;
27 import org.apache.logging.log4j.core.jackson.Log4jJsonObjectMapper;
28 import org.apache.logging.log4j.core.jackson.Log4jXmlObjectMapper;
29 import org.apache.logging.log4j.core.jackson.Log4jYamlObjectMapper;
30 import org.apache.logging.log4j.core.jackson.XmlConstants;
31 import org.codehaus.stax2.XMLStreamWriter2;
32
33 import com.fasterxml.jackson.core.PrettyPrinter;
34 import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
35 import com.fasterxml.jackson.core.util.MinimalPrettyPrinter;
36 import com.fasterxml.jackson.databind.ObjectMapper;
37 import com.fasterxml.jackson.databind.ObjectWriter;
38 import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
39 import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
40 import com.fasterxml.jackson.dataformat.xml.util.DefaultXmlPrettyPrinter;
41
42 abstract class JacksonFactory {
43
44 static class JSON extends JacksonFactory {
45
46 private final boolean encodeThreadContextAsList;
47 private final boolean includeStacktrace;
48 private final boolean stacktraceAsString;
49 private final boolean objectMessageAsJsonObject;
50
51 public JSON(final boolean encodeThreadContextAsList, final boolean includeStacktrace, final boolean stacktraceAsString, final boolean objectMessageAsJsonObject) {
52 this.encodeThreadContextAsList = encodeThreadContextAsList;
53 this.includeStacktrace = includeStacktrace;
54 this.stacktraceAsString = stacktraceAsString;
55 this.objectMessageAsJsonObject = objectMessageAsJsonObject;
56 }
57
58 @Override
59 protected String getPropertNameForContextMap() {
60 return JsonConstants.ELT_CONTEXT_MAP;
61 }
62
63 @Override
64 protected String getPropertyNameForTimeMillis() {
65 return JsonConstants.ELT_TIME_MILLIS;
66 }
67
68 @Override
69 protected String getPropertyNameForInstant() {
70 return JsonConstants.ELT_INSTANT;
71 }
72
73 @Override
74 protected String getPropertNameForSource() {
75 return JsonConstants.ELT_SOURCE;
76 }
77
78 @Override
79 protected String getPropertNameForNanoTime() {
80 return JsonConstants.ELT_NANO_TIME;
81 }
82
83 @Override
84 protected PrettyPrinter newCompactPrinter() {
85 return new MinimalPrettyPrinter();
86 }
87
88 @Override
89 protected ObjectMapper newObjectMapper() {
90 return new Log4jJsonObjectMapper(encodeThreadContextAsList, includeStacktrace, stacktraceAsString, objectMessageAsJsonObject);
91 }
92
93 @Override
94 protected PrettyPrinter newPrettyPrinter() {
95 return new DefaultPrettyPrinter();
96 }
97
98 }
99
100 static class XML extends JacksonFactory {
101
102 static final int DEFAULT_INDENT = 1;
103
104 private final boolean includeStacktrace;
105 private final boolean stacktraceAsString;
106
107
108 public XML(final boolean includeStacktrace, final boolean stacktraceAsString) {
109 this.includeStacktrace = includeStacktrace;
110 this.stacktraceAsString = stacktraceAsString;
111 }
112
113 @Override
114 protected String getPropertyNameForTimeMillis() {
115 return XmlConstants.ELT_TIME_MILLIS;
116 }
117
118 @Override
119 protected String getPropertyNameForInstant() {
120 return XmlConstants.ELT_INSTANT;
121 }
122
123 @Override
124 protected String getPropertNameForContextMap() {
125 return XmlConstants.ELT_CONTEXT_MAP;
126 }
127
128 @Override
129 protected String getPropertNameForSource() {
130 return XmlConstants.ELT_SOURCE;
131 }
132
133 @Override
134 protected String getPropertNameForNanoTime() {
135 return JsonConstants.ELT_NANO_TIME;
136 }
137
138 @Override
139 protected PrettyPrinter newCompactPrinter() {
140
141 return null;
142 }
143
144 @Override
145 protected ObjectMapper newObjectMapper() {
146 return new Log4jXmlObjectMapper(includeStacktrace, stacktraceAsString);
147 }
148
149 @Override
150 protected PrettyPrinter newPrettyPrinter() {
151 return new Log4jXmlPrettyPrinter(DEFAULT_INDENT);
152 }
153 }
154
155 static class YAML extends JacksonFactory {
156
157 private final boolean includeStacktrace;
158 private final boolean stacktraceAsString;
159
160
161 public YAML(final boolean includeStacktrace, final boolean stacktraceAsString) {
162 this.includeStacktrace = includeStacktrace;
163 this.stacktraceAsString = stacktraceAsString;
164 }
165
166 @Override
167 protected String getPropertyNameForTimeMillis() {
168 return JsonConstants.ELT_TIME_MILLIS;
169 }
170
171 @Override
172 protected String getPropertyNameForInstant() {
173 return JsonConstants.ELT_INSTANT;
174 }
175
176 @Override
177 protected String getPropertNameForContextMap() {
178 return JsonConstants.ELT_CONTEXT_MAP;
179 }
180
181 @Override
182 protected String getPropertNameForSource() {
183 return JsonConstants.ELT_SOURCE;
184 }
185
186 @Override
187 protected String getPropertNameForNanoTime() {
188 return JsonConstants.ELT_NANO_TIME;
189 }
190
191 @Override
192 protected PrettyPrinter newCompactPrinter() {
193 return new MinimalPrettyPrinter();
194 }
195
196 @Override
197 protected ObjectMapper newObjectMapper() {
198 return new Log4jYamlObjectMapper(false, includeStacktrace, stacktraceAsString);
199 }
200
201 @Override
202 protected PrettyPrinter newPrettyPrinter() {
203 return new DefaultPrettyPrinter();
204 }
205 }
206
207
208
209
210
211
212
213
214
215
216
217
218 static class Log4jXmlPrettyPrinter extends DefaultXmlPrettyPrinter {
219
220 private static final long serialVersionUID = 1L;
221
222 Log4jXmlPrettyPrinter(final int nesting) {
223 _nesting = nesting;
224 }
225
226 @Override
227 public void writePrologLinefeed(final XMLStreamWriter2 sw) throws XMLStreamException {
228
229 }
230
231
232
233
234 @Override
235 public DefaultXmlPrettyPrinter createInstance() {
236 return new Log4jXmlPrettyPrinter(XML.DEFAULT_INDENT);
237 }
238
239 }
240
241 abstract protected String getPropertyNameForTimeMillis();
242
243 abstract protected String getPropertyNameForInstant();
244
245 abstract protected String getPropertNameForContextMap();
246
247 abstract protected String getPropertNameForSource();
248
249 abstract protected String getPropertNameForNanoTime();
250
251 abstract protected PrettyPrinter newCompactPrinter();
252
253 abstract protected ObjectMapper newObjectMapper();
254
255 abstract protected PrettyPrinter newPrettyPrinter();
256
257 ObjectWriter newWriter(final boolean locationInfo, final boolean properties, final boolean compact) {
258 return newWriter(locationInfo, properties, compact, false);
259 }
260
261 ObjectWriter newWriter(final boolean locationInfo, final boolean properties, final boolean compact,
262 final boolean includeMillis) {
263 final SimpleFilterProvider filters = new SimpleFilterProvider();
264 final Set<String> except = new HashSet<>(3);
265 if (!locationInfo) {
266 except.add(this.getPropertNameForSource());
267 }
268 if (!properties) {
269 except.add(this.getPropertNameForContextMap());
270 }
271 if (includeMillis) {
272 except.add(getPropertyNameForInstant());
273 } else {
274 except.add(getPropertyNameForTimeMillis());
275 }
276 except.add(this.getPropertNameForNanoTime());
277 filters.addFilter(Log4jLogEvent.class.getName(), SimpleBeanPropertyFilter.serializeAllExcept(except));
278 final ObjectWriter writer = this.newObjectMapper().writer(compact ? this.newCompactPrinter() : this.newPrettyPrinter());
279 return writer.with(filters);
280 }
281
282 }