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.nio.charset.Charset;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23
24 import org.apache.logging.log4j.core.LogEvent;
25 import org.apache.logging.log4j.core.config.Configuration;
26 import org.apache.logging.log4j.core.config.plugins.Plugin;
27 import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
28 import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
29 import org.apache.logging.log4j.core.config.plugins.PluginElement;
30 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
31 import org.apache.logging.log4j.core.helpers.Booleans;
32 import org.apache.logging.log4j.core.helpers.Charsets;
33 import org.apache.logging.log4j.core.helpers.OptionConverter;
34 import org.apache.logging.log4j.core.pattern.LogEventPatternConverter;
35 import org.apache.logging.log4j.core.pattern.PatternFormatter;
36 import org.apache.logging.log4j.core.pattern.PatternParser;
37 import org.apache.logging.log4j.core.pattern.RegexReplacement;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 @Plugin(name = "PatternLayout", category = "Core", elementType = "layout", printObject = true)
53 public final class PatternLayout extends AbstractStringLayout {
54
55
56
57
58
59 public static final String DEFAULT_CONVERSION_PATTERN = "%m%n";
60
61
62
63
64
65 public static final String TTCC_CONVERSION_PATTERN =
66 "%r [%t] %p %c %x - %m%n";
67
68
69
70
71
72 public static final String SIMPLE_CONVERSION_PATTERN =
73 "%d [%t] %p %c - %m%n";
74
75
76 public static final String KEY = "Converter";
77
78
79
80
81 private List<PatternFormatter> formatters;
82
83
84
85
86 private final String conversionPattern;
87
88
89
90
91
92 private final Configuration config;
93
94 private final RegexReplacement replace;
95
96 private final boolean alwaysWriteExceptions;
97
98 private final boolean noConsoleNoAnsi;
99
100
101
102
103
104
105
106
107
108
109
110
111
112 private PatternLayout(final Configuration config, final RegexReplacement replace, final String pattern,
113 final Charset charset, final boolean alwaysWriteExceptions, boolean noConsoleNoAnsi) {
114 super(charset);
115 this.replace = replace;
116 this.conversionPattern = pattern;
117 this.config = config;
118 this.alwaysWriteExceptions = alwaysWriteExceptions;
119 this.noConsoleNoAnsi = noConsoleNoAnsi;
120 final PatternParser parser = createPatternParser(config);
121 this.formatters = parser.parse(pattern == null ? DEFAULT_CONVERSION_PATTERN : pattern, this.alwaysWriteExceptions, this.noConsoleNoAnsi);
122 }
123
124
125
126
127
128
129
130
131 public void setConversionPattern(final String conversionPattern) {
132 final String pattern = OptionConverter.convertSpecialChars(conversionPattern);
133 if (pattern == null) {
134 return;
135 }
136 final PatternParser parser = createPatternParser(this.config);
137 formatters = parser.parse(pattern, this.alwaysWriteExceptions, this.noConsoleNoAnsi);
138 }
139
140 public String getConversionPattern() {
141 return conversionPattern;
142 }
143
144
145
146
147
148
149
150
151 @Override
152 public Map<String, String> getContentFormat()
153 {
154 final Map<String, String> result = new HashMap<String, String>();
155 result.put("structured", "false");
156 result.put("formatType", "conversion");
157 result.put("format", conversionPattern);
158 return result;
159 }
160
161
162
163
164
165
166
167
168 @Override
169 public String toSerializable(final LogEvent event) {
170 final StringBuilder buf = new StringBuilder();
171 for (final PatternFormatter formatter : formatters) {
172 formatter.format(event, buf);
173 }
174 String str = buf.toString();
175 if (replace != null) {
176 str = replace.format(str);
177 }
178 return str;
179 }
180
181
182
183
184
185
186 public static PatternParser createPatternParser(final Configuration config) {
187 if (config == null) {
188 return new PatternParser(config, KEY, LogEventPatternConverter.class);
189 }
190 PatternParser parser = config.getComponent(KEY);
191 if (parser == null) {
192 parser = new PatternParser(config, KEY, LogEventPatternConverter.class);
193 config.addComponent(KEY, parser);
194 parser = (PatternParser) config.getComponent(KEY);
195 }
196 return parser;
197 }
198
199 @Override
200 public String toString() {
201 return conversionPattern;
202 }
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222 @PluginFactory
223 public static PatternLayout createLayout(
224 @PluginAttribute("pattern") final String pattern,
225 @PluginConfiguration final Configuration config,
226 @PluginElement("Replace") final RegexReplacement replace,
227 @PluginAttribute("charset") final String charsetName,
228 @PluginAttribute("alwaysWriteExceptions") final String always,
229 @PluginAttribute("noConsoleNoAnsi") final String noConsoleNoAnsiStr) {
230 final Charset charset = Charsets.getSupportedCharset(charsetName);
231 final boolean alwaysWriteExceptions = Booleans.parseBoolean(always, true);
232 final boolean noConsoleNoAnsi = Booleans.parseBoolean(noConsoleNoAnsiStr, false);
233 return new PatternLayout(config, replace, pattern == null ? DEFAULT_CONVERSION_PATTERN : pattern, charset,
234 alwaysWriteExceptions, noConsoleNoAnsi);
235 }
236 }