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.HashMap;
20 import java.util.List;
21 import java.util.Map;
22
23 import org.apache.logging.log4j.Logger;
24 import org.apache.logging.log4j.Marker;
25 import org.apache.logging.log4j.core.LogEvent;
26 import org.apache.logging.log4j.core.config.Configuration;
27 import org.apache.logging.log4j.core.config.Node;
28 import org.apache.logging.log4j.core.config.plugins.Plugin;
29 import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
30 import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
31 import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
32 import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
33 import org.apache.logging.log4j.core.config.plugins.PluginElement;
34 import org.apache.logging.log4j.core.layout.ScriptPatternSelector.Builder;
35 import org.apache.logging.log4j.core.pattern.PatternFormatter;
36 import org.apache.logging.log4j.core.pattern.PatternParser;
37 import org.apache.logging.log4j.status.StatusLogger;
38
39
40
41
42 @Plugin(name = "MarkerPatternSelector", category = Node.CATEGORY, elementType = PatternSelector.ELEMENT_TYPE, printObject = true)
43 public class MarkerPatternSelector implements PatternSelector {
44
45
46
47
48 public static class Builder implements org.apache.logging.log4j.core.util.Builder<MarkerPatternSelector> {
49
50 @PluginElement("PatternMatch")
51 private PatternMatch[] properties;
52
53 @PluginBuilderAttribute("defaultPattern")
54 private String defaultPattern;
55
56 @PluginBuilderAttribute(value = "alwaysWriteExceptions")
57 private boolean alwaysWriteExceptions = true;
58
59 @PluginBuilderAttribute(value = "disableAnsi")
60 private boolean disableAnsi;
61
62 @PluginBuilderAttribute(value = "noConsoleNoAnsi")
63 private boolean noConsoleNoAnsi;
64
65 @PluginConfiguration
66 private Configuration configuration;
67
68 @Override
69 public MarkerPatternSelector build() {
70 if (defaultPattern == null) {
71 defaultPattern = PatternLayout.DEFAULT_CONVERSION_PATTERN;
72 }
73 if (properties == null || properties.length == 0) {
74 LOGGER.warn("No marker patterns were provided with PatternMatch");
75 return null;
76 }
77 return new MarkerPatternSelector(properties, defaultPattern, alwaysWriteExceptions, disableAnsi,
78 noConsoleNoAnsi, configuration);
79 }
80
81 public Builder setProperties(final PatternMatch[] properties) {
82 this.properties = properties;
83 return this;
84 }
85
86 public Builder setDefaultPattern(final String defaultPattern) {
87 this.defaultPattern = defaultPattern;
88 return this;
89 }
90
91 public Builder setAlwaysWriteExceptions(final boolean alwaysWriteExceptions) {
92 this.alwaysWriteExceptions = alwaysWriteExceptions;
93 return this;
94 }
95
96 public Builder setDisableAnsi(final boolean disableAnsi) {
97 this.disableAnsi = disableAnsi;
98 return this;
99 }
100
101 public Builder setNoConsoleNoAnsi(final boolean noConsoleNoAnsi) {
102 this.noConsoleNoAnsi = noConsoleNoAnsi;
103 return this;
104 }
105
106 public Builder setConfiguration(final Configuration configuration) {
107 this.configuration = configuration;
108 return this;
109 }
110
111 }
112
113 private final Map<String, PatternFormatter[]> formatterMap = new HashMap<>();
114
115 private final Map<String, String> patternMap = new HashMap<>();
116
117 private final PatternFormatter[] defaultFormatters;
118
119 private final String defaultPattern;
120
121 private static Logger LOGGER = StatusLogger.getLogger();
122
123
124
125
126
127 @Deprecated
128 public MarkerPatternSelector(final PatternMatch[] properties, final String defaultPattern,
129 final boolean alwaysWriteExceptions, final boolean noConsoleNoAnsi,
130 final Configuration config) {
131 this(properties, defaultPattern, alwaysWriteExceptions, false, noConsoleNoAnsi, config);
132 }
133
134 private MarkerPatternSelector(final PatternMatch[] properties, final String defaultPattern,
135 final boolean alwaysWriteExceptions, final boolean disableAnsi,
136 final boolean noConsoleNoAnsi, final Configuration config) {
137 final PatternParser parser = PatternLayout.createPatternParser(config);
138 for (final PatternMatch property : properties) {
139 try {
140 final List<PatternFormatter> list = parser.parse(property.getPattern(), alwaysWriteExceptions,
141 disableAnsi, noConsoleNoAnsi);
142 formatterMap.put(property.getKey(), list.toArray(new PatternFormatter[list.size()]));
143 patternMap.put(property.getKey(), property.getPattern());
144 } catch (final RuntimeException ex) {
145 throw new IllegalArgumentException("Cannot parse pattern '" + property.getPattern() + "'", ex);
146 }
147 }
148 try {
149 final List<PatternFormatter> list = parser.parse(defaultPattern, alwaysWriteExceptions, disableAnsi,
150 noConsoleNoAnsi);
151 defaultFormatters = list.toArray(new PatternFormatter[list.size()]);
152 this.defaultPattern = defaultPattern;
153 } catch (final RuntimeException ex) {
154 throw new IllegalArgumentException("Cannot parse pattern '" + defaultPattern + "'", ex);
155 }
156 }
157
158 @Override
159 public PatternFormatter[] getFormatters(final LogEvent event) {
160 final Marker marker = event.getMarker();
161 if (marker == null) {
162 return defaultFormatters;
163 }
164 for (final String key : formatterMap.keySet()) {
165 if (marker.isInstanceOf(key)) {
166 return formatterMap.get(key);
167 }
168 }
169 return defaultFormatters;
170 }
171
172
173
174
175
176
177 @PluginBuilderFactory
178 public static Builder newBuilder() {
179 return new Builder();
180 }
181
182
183
184
185
186
187
188
189
190
191
192 @Deprecated
193 public static MarkerPatternSelector createSelector(
194 final PatternMatch[] properties,
195 final String defaultPattern,
196 final boolean alwaysWriteExceptions,
197 final boolean noConsoleNoAnsi,
198 final Configuration configuration) {
199 final Builder builder = newBuilder();
200 builder.setProperties(properties);
201 builder.setDefaultPattern(defaultPattern);
202 builder.setAlwaysWriteExceptions(alwaysWriteExceptions);
203 builder.setNoConsoleNoAnsi(noConsoleNoAnsi);
204 builder.setConfiguration(configuration);
205 return builder.build();
206 }
207
208 @Override
209 public String toString() {
210 final StringBuilder sb = new StringBuilder();
211 boolean first = true;
212 for (final Map.Entry<String, String> entry : patternMap.entrySet()) {
213 if (!first) {
214 sb.append(", ");
215 }
216 sb.append("key=\"").append(entry.getKey()).append("\", pattern=\"").append(entry.getValue()).append("\"");
217 first = false;
218 }
219 if (!first) {
220 sb.append(", ");
221 }
222 sb.append("default=\"").append(defaultPattern).append("\"");
223 return sb.toString();
224 }
225 }