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 org.apache.logging.log4j.core.LogEvent;
20 import org.apache.logging.log4j.core.config.Configuration;
21 import org.apache.logging.log4j.core.config.plugins.Plugin;
22 import org.apache.logging.log4j.core.config.plugins.PluginAttr;
23 import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
24 import org.apache.logging.log4j.core.config.plugins.PluginElement;
25 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
26 import org.apache.logging.log4j.core.helpers.OptionConverter;
27 import org.apache.logging.log4j.core.pattern.LogEventPatternConverter;
28 import org.apache.logging.log4j.core.pattern.PatternFormatter;
29 import org.apache.logging.log4j.core.pattern.PatternParser;
30 import org.apache.logging.log4j.core.pattern.RegexReplacement;
31
32 import java.nio.charset.Charset;
33 import java.util.List;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 @Plugin(name = "PatternLayout", type = "Core", elementType = "layout", printObject = true)
49 public final class PatternLayout extends AbstractStringLayout {
50
51
52
53
54
55 public static final String DEFAULT_CONVERSION_PATTERN = "%m%n";
56
57
58
59
60
61 public static final String TTCC_CONVERSION_PATTERN =
62 "%r [%t] %p %c %x - %m%n";
63
64
65
66
67
68 public static final String SIMPLE_CONVERSION_PATTERN =
69 "%d [%t] %p %c - %m%n";
70
71 private static final String KEY = "Converter";
72
73
74
75
76 private List<PatternFormatter> formatters;
77
78
79
80
81 private final String conversionPattern;
82
83
84
85
86 private boolean handlesExceptions;
87
88
89
90
91 private final Configuration config;
92
93 private final RegexReplacement replace;
94
95
96
97
98
99
100
101
102
103 private PatternLayout(Configuration config, final RegexReplacement replace, final String pattern,
104 final Charset charset) {
105 super(charset);
106 this.replace = replace;
107 this.conversionPattern = pattern;
108 this.config = config;
109 PatternParser parser = createPatternParser(config);
110 formatters = parser.parse((pattern == null) ? DEFAULT_CONVERSION_PATTERN : pattern);
111 handlesExceptions = parser.handlesExceptions();
112 }
113
114
115
116
117
118
119
120
121 public void setConversionPattern(final String conversionPattern) {
122 String pattern = OptionConverter.convertSpecialChars(conversionPattern);
123 if (pattern == null) {
124 return;
125 }
126 PatternParser parser = createPatternParser(this.config);
127 formatters = parser.parse(pattern);
128 handlesExceptions = parser.handlesExceptions();
129 }
130
131
132
133
134
135
136
137
138 public String toSerializable(final LogEvent event) {
139 StringBuilder buf = new StringBuilder();
140 for (PatternFormatter formatter : formatters) {
141 formatter.format(event, buf);
142 }
143 String str = buf.toString();
144 if (replace != null) {
145 str = replace.format(str);
146 }
147 return str;
148 }
149
150
151
152
153
154
155 public static PatternParser createPatternParser(Configuration config) {
156 if (config == null) {
157 return new PatternParser(config, KEY, LogEventPatternConverter.class);
158 }
159 PatternParser parser = (PatternParser) config.getComponent(KEY);
160 if (parser == null) {
161 parser = new PatternParser(config, KEY, LogEventPatternConverter.class);
162 config.addComponent(KEY, parser);
163 parser = (PatternParser) config.getComponent(KEY);
164 }
165 return parser;
166 }
167
168 @Override
169 public String toString() {
170 return conversionPattern;
171 }
172
173
174
175
176
177
178
179
180
181 @PluginFactory
182 public static PatternLayout createLayout(@PluginAttr("pattern") String pattern,
183 @PluginConfiguration Configuration config,
184 @PluginElement("replace") RegexReplacement replace,
185 @PluginAttr("charset") String charset) {
186 Charset c = Charset.isSupported("UTF-8") ? Charset.forName("UTF-8") : Charset.defaultCharset();
187 if (charset != null) {
188 if (Charset.isSupported(charset)) {
189 c = Charset.forName(charset);
190 } else {
191 LOGGER.error("Charset " + charset + " is not supported for layout, using " + c.displayName());
192 }
193 }
194 return new PatternLayout(config, replace, pattern == null ? DEFAULT_CONVERSION_PATTERN : pattern, c);
195 }
196 }