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 org.apache.logging.log4j.core.impl.Log4jLogEvent;
25 import org.apache.logging.log4j.core.jackson.JsonConstants;
26 import org.apache.logging.log4j.core.jackson.Log4jJsonObjectMapper;
27 import org.apache.logging.log4j.core.jackson.Log4jXmlObjectMapper;
28 import org.apache.logging.log4j.core.jackson.Log4jYamlObjectMapper;
29 import org.apache.logging.log4j.core.jackson.XmlConstants;
30 import org.codehaus.stax2.XMLStreamWriter2;
31
32 import com.fasterxml.jackson.core.PrettyPrinter;
33 import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
34 import com.fasterxml.jackson.core.util.MinimalPrettyPrinter;
35 import com.fasterxml.jackson.databind.ObjectMapper;
36 import com.fasterxml.jackson.databind.ObjectWriter;
37 import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
38 import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
39 import com.fasterxml.jackson.dataformat.xml.util.DefaultXmlPrettyPrinter;
40
41 abstract class JacksonFactory {
42
43 static class JSON extends JacksonFactory {
44
45 private final boolean encodeThreadContextAsList;
46 private final boolean includeStacktrace;
47 private final boolean stacktraceAsString;
48
49 public JSON(final boolean encodeThreadContextAsList, final boolean includeStacktrace, final boolean stacktraceAsString) {
50 this.encodeThreadContextAsList = encodeThreadContextAsList;
51 this.includeStacktrace = includeStacktrace;
52 this.stacktraceAsString = stacktraceAsString;
53 }
54
55 @Override
56 protected String getPropertNameForContextMap() {
57 return JsonConstants.ELT_CONTEXT_MAP;
58 }
59
60 @Override
61 protected String getPropertNameForSource() {
62 return JsonConstants.ELT_SOURCE;
63 }
64
65 @Override
66 protected String getPropertNameForNanoTime() {
67 return JsonConstants.ELT_NANO_TIME;
68 }
69
70 @Override
71 protected PrettyPrinter newCompactPrinter() {
72 return new MinimalPrettyPrinter();
73 }
74
75 @Override
76 protected ObjectMapper newObjectMapper() {
77 return new Log4jJsonObjectMapper(encodeThreadContextAsList, includeStacktrace, stacktraceAsString);
78 }
79
80 @Override
81 protected PrettyPrinter newPrettyPrinter() {
82 return new DefaultPrettyPrinter();
83 }
84 }
85
86 static class XML extends JacksonFactory {
87
88 static final int DEFAULT_INDENT = 1;
89
90 private final boolean includeStacktrace;
91 private final boolean stacktraceAsString;
92
93
94 public XML(final boolean includeStacktrace, final boolean stacktraceAsString) {
95 this.includeStacktrace = includeStacktrace;
96 this.stacktraceAsString = stacktraceAsString;
97 }
98
99 @Override
100 protected String getPropertNameForContextMap() {
101 return XmlConstants.ELT_CONTEXT_MAP;
102 }
103
104 @Override
105 protected String getPropertNameForSource() {
106 return XmlConstants.ELT_SOURCE;
107 }
108
109 @Override
110 protected String getPropertNameForNanoTime() {
111 return JsonConstants.ELT_NANO_TIME;
112 }
113
114 @Override
115 protected PrettyPrinter newCompactPrinter() {
116
117 return null;
118 }
119
120 @Override
121 protected ObjectMapper newObjectMapper() {
122 return new Log4jXmlObjectMapper(includeStacktrace, stacktraceAsString);
123 }
124
125 @Override
126 protected PrettyPrinter newPrettyPrinter() {
127 return new Log4jXmlPrettyPrinter(DEFAULT_INDENT);
128 }
129 }
130
131 static class YAML extends JacksonFactory {
132
133 private final boolean includeStacktrace;
134 private final boolean stacktraceAsString;
135
136
137 public YAML(final boolean includeStacktrace, final boolean stacktraceAsString) {
138 this.includeStacktrace = includeStacktrace;
139 this.stacktraceAsString = stacktraceAsString;
140 }
141
142 @Override
143 protected String getPropertNameForContextMap() {
144 return JsonConstants.ELT_CONTEXT_MAP;
145 }
146
147 @Override
148 protected String getPropertNameForSource() {
149 return JsonConstants.ELT_SOURCE;
150 }
151
152 @Override
153 protected String getPropertNameForNanoTime() {
154 return JsonConstants.ELT_NANO_TIME;
155 }
156
157 @Override
158 protected PrettyPrinter newCompactPrinter() {
159 return new MinimalPrettyPrinter();
160 }
161
162 @Override
163 protected ObjectMapper newObjectMapper() {
164 return new Log4jYamlObjectMapper(false, includeStacktrace, stacktraceAsString);
165 }
166
167 @Override
168 protected PrettyPrinter newPrettyPrinter() {
169 return new DefaultPrettyPrinter();
170 }
171 }
172
173
174
175
176
177
178
179
180
181
182
183
184 static class Log4jXmlPrettyPrinter extends DefaultXmlPrettyPrinter {
185
186 private static final long serialVersionUID = 1L;
187
188 Log4jXmlPrettyPrinter(final int nesting) {
189 _nesting = nesting;
190 }
191
192 @Override
193 public void writePrologLinefeed(final XMLStreamWriter2 sw) throws XMLStreamException {
194
195 }
196
197
198
199
200 @Override
201 public DefaultXmlPrettyPrinter createInstance() {
202 return new Log4jXmlPrettyPrinter(XML.DEFAULT_INDENT);
203 }
204
205 }
206
207 abstract protected String getPropertNameForContextMap();
208
209 abstract protected String getPropertNameForSource();
210
211 abstract protected String getPropertNameForNanoTime();
212
213 abstract protected PrettyPrinter newCompactPrinter();
214
215 abstract protected ObjectMapper newObjectMapper();
216
217 abstract protected PrettyPrinter newPrettyPrinter();
218
219 ObjectWriter newWriter(final boolean locationInfo, final boolean properties, final boolean compact) {
220 final SimpleFilterProvider filters = new SimpleFilterProvider();
221 final Set<String> except = new HashSet<>(2);
222 if (!locationInfo) {
223 except.add(this.getPropertNameForSource());
224 }
225 if (!properties) {
226 except.add(this.getPropertNameForContextMap());
227 }
228 except.add(this.getPropertNameForNanoTime());
229 filters.addFilter(Log4jLogEvent.class.getName(), SimpleBeanPropertyFilter.serializeAllExcept(except));
230 final ObjectWriter writer = this.newObjectMapper().writer(compact ? this.newCompactPrinter() : this.newPrettyPrinter());
231 return writer.with(filters);
232 }
233
234 }