1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.appender.routing;
18
19 import static org.apache.logging.log4j.core.appender.routing.RoutingAppender.STATIC_VARIABLES_KEY;
20
21 import java.util.Objects;
22 import java.util.concurrent.ConcurrentMap;
23
24 import javax.script.Bindings;
25
26 import org.apache.logging.log4j.Logger;
27 import org.apache.logging.log4j.core.Core;
28 import org.apache.logging.log4j.core.LogEvent;
29 import org.apache.logging.log4j.core.config.Configuration;
30 import org.apache.logging.log4j.core.config.plugins.Plugin;
31 import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
32 import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
33 import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
34 import org.apache.logging.log4j.core.config.plugins.PluginElement;
35 import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
36 import org.apache.logging.log4j.core.script.AbstractScript;
37 import org.apache.logging.log4j.core.script.ScriptManager;
38 import org.apache.logging.log4j.status.StatusLogger;
39
40
41
42
43 @Plugin(name = "Routes", category = Core.CATEGORY_NAME, printObject = true)
44 public final class Routes {
45
46 private static final String LOG_EVENT_KEY = "logEvent";
47
48 public static class Builder implements org.apache.logging.log4j.core.util.Builder<Routes> {
49
50 @PluginConfiguration
51 private Configuration configuration;
52
53 @PluginAttribute("pattern")
54 private String pattern;
55
56 @PluginElement("Script")
57 private AbstractScript patternScript;
58
59 @PluginElement("Routes")
60 @Required
61 private Route[] routes;
62
63 @Override
64 public Routes build() {
65 if (routes == null || routes.length == 0) {
66 LOGGER.error("No Routes configured.");
67 return null;
68 }
69 if (patternScript != null && pattern != null) {
70 LOGGER.warn("In a Routes element, you must configure either a Script element or a pattern attribute.");
71 }
72 if (patternScript != null) {
73 if (configuration == null) {
74 LOGGER.error("No Configuration defined for Routes; required for Script");
75 } else {
76 configuration.getScriptManager().addScript(patternScript);
77 }
78 }
79 return new Routes(configuration, patternScript, pattern, routes);
80 }
81
82 public Configuration getConfiguration() {
83 return configuration;
84 }
85
86 public String getPattern() {
87 return pattern;
88 }
89
90 public AbstractScript getPatternScript() {
91 return patternScript;
92 }
93
94 public Route[] getRoutes() {
95 return routes;
96 }
97
98 public Builder withConfiguration(@SuppressWarnings("hiding") final Configuration configuration) {
99 this.configuration = configuration;
100 return this;
101 }
102
103 public Builder withPattern(@SuppressWarnings("hiding") final String pattern) {
104 this.pattern = pattern;
105 return this;
106 }
107
108 public Builder withPatternScript(@SuppressWarnings("hiding") final AbstractScript patternScript) {
109 this.patternScript = patternScript;
110 return this;
111 }
112
113 public Builder withRoutes(@SuppressWarnings("hiding") final Route[] routes) {
114 this.routes = routes;
115 return this;
116 }
117
118 }
119
120 private static final Logger LOGGER = StatusLogger.getLogger();
121
122
123
124
125
126
127
128
129 @Deprecated
130 public static Routes createRoutes(
131 final String pattern,
132 final Route... routes) {
133 if (routes == null || routes.length == 0) {
134 LOGGER.error("No routes configured");
135 return null;
136 }
137 return new Routes(null, null, pattern, routes);
138 }
139
140 @PluginBuilderFactory
141 public static Builder newBuilder() {
142 return new Builder();
143 }
144
145 private final Configuration configuration;
146
147 private final String pattern;
148
149 private final AbstractScript patternScript;
150
151
152 private final Route[] routes;
153
154 private Routes(final Configuration configuration, final AbstractScript patternScript, final String pattern, final Route... routes) {
155 this.configuration = configuration;
156 this.patternScript = patternScript;
157 this.pattern = pattern;
158 this.routes = routes;
159 }
160
161
162
163
164
165
166
167 public String getPattern(final LogEvent event, final ConcurrentMap<Object, Object> scriptStaticVariables) {
168 if (patternScript != null) {
169 final ScriptManager scriptManager = configuration.getScriptManager();
170 final Bindings bindings = scriptManager.createBindings(patternScript);
171 bindings.put(STATIC_VARIABLES_KEY, scriptStaticVariables);
172 bindings.put(LOG_EVENT_KEY, event);
173 final Object object = scriptManager.execute(patternScript.getName(), bindings);
174 bindings.remove(LOG_EVENT_KEY);
175 return Objects.toString(object, null);
176 }
177 return pattern;
178 }
179
180
181
182
183
184 public AbstractScript getPatternScript() {
185 return patternScript;
186 }
187
188 public Route getRoute(final String key) {
189 for (final Route route : routes) {
190 if (Objects.equals(route.getKey(), key)) {
191 return route;
192 }
193 }
194 return null;
195 }
196
197
198
199
200
201 public Route[] getRoutes() {
202 return routes;
203 }
204
205 @Override
206 public String toString() {
207 final StringBuilder sb = new StringBuilder("{");
208 boolean first = true;
209 for (final Route route : routes) {
210 if (!first) {
211 sb.append(',');
212 }
213 first = false;
214 sb.append(route.toString());
215 }
216 sb.append('}');
217 return sb.toString();
218
219 }
220
221 }