View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  package org.apache.logging.log4j.core.appender;
18  
19  import java.io.Serializable;
20  import java.util.Objects;
21  
22  import javax.script.Bindings;
23  
24  import org.apache.logging.log4j.core.Appender;
25  import org.apache.logging.log4j.core.Core;
26  import org.apache.logging.log4j.core.Filter;
27  import org.apache.logging.log4j.core.Layout;
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.Property;
31  import org.apache.logging.log4j.core.config.plugins.Plugin;
32  import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
33  import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
34  import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
35  import org.apache.logging.log4j.core.config.plugins.PluginElement;
36  import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
37  import org.apache.logging.log4j.core.script.AbstractScript;
38  import org.apache.logging.log4j.core.script.ScriptManager;
39  
40  @Plugin(name = "ScriptAppenderSelector", category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE, printObject = true)
41  public class ScriptAppenderSelector extends AbstractAppender {
42  
43      /**
44       * Builds an appender.
45       */
46      public static final class Builder implements org.apache.logging.log4j.core.util.Builder<Appender> {
47  
48          @PluginElement("AppenderSet")
49          @Required
50          private AppenderSet appenderSet;
51  
52          @PluginConfiguration
53          @Required
54          private Configuration configuration;
55  
56          @PluginBuilderAttribute
57          @Required
58          private String name;
59  
60          @PluginElement("Script")
61          @Required
62          private AbstractScript script;
63  
64          @Override
65  		public Appender build() {
66  			if (name == null) {
67  				LOGGER.error("Name missing.");
68  				return null;
69  			}
70  			if (script == null) {
71  				LOGGER.error("Script missing for ScriptAppenderSelector appender {}", name);
72  				return null;
73  			}
74  			if (appenderSet == null) {
75  				LOGGER.error("AppenderSet missing for ScriptAppenderSelector appender {}", name);
76  				return null;
77  			}
78  			if (configuration == null) {
79  				LOGGER.error("Configuration missing for ScriptAppenderSelector appender {}", name);
80  				return null;
81  			}
82  			final ScriptManager scriptManager = configuration.getScriptManager();
83  			scriptManager.addScript(script);
84  			final Bindings bindings = scriptManager.createBindings(script);
85  			LOGGER.debug("ScriptAppenderSelector '{}' executing {} '{}': {}", name, script.getLanguage(),
86  					script.getName(), script.getScriptText());
87  			final Object object = scriptManager.execute(script.getName(), bindings);
88  			final String actualAppenderName = Objects.toString(object, null);
89  			LOGGER.debug("ScriptAppenderSelector '{}' selected '{}'", name, actualAppenderName);
90  			return appenderSet.createAppender(actualAppenderName, name);
91  		}
92  
93          public AppenderSet getAppenderSet() {
94              return appenderSet;
95          }
96  
97          public Configuration getConfiguration() {
98              return configuration;
99          }
100 
101         public String getName() {
102             return name;
103         }
104 
105         public AbstractScript getScript() {
106             return script;
107         }
108 
109         public Builder withAppenderNodeSet(@SuppressWarnings("hiding") final AppenderSet appenderSet) {
110             this.appenderSet = appenderSet;
111             return this;
112         }
113 
114         public Builder withConfiguration(@SuppressWarnings("hiding") final Configuration configuration) {
115             this.configuration = configuration;
116             return this;
117         }
118 
119         public Builder withName(@SuppressWarnings("hiding") final String name) {
120             this.name = name;
121             return this;
122         }
123 
124         public Builder withScript(@SuppressWarnings("hiding") final AbstractScript script) {
125             this.script = script;
126             return this;
127         }
128 
129     }
130 
131     @PluginBuilderFactory
132     public static Builder newBuilder() {
133         return new Builder();
134     }
135 
136     private ScriptAppenderSelector(final String name, final Filter filter, final Layout<? extends Serializable> layout,
137             final Property[] properties) {
138         super(name, filter, layout, true, Property.EMPTY_ARRAY);
139     }
140 
141     @Override
142     public void append(final LogEvent event) {
143         // Do nothing: This appender is only used to discover and build another appender
144     }
145 
146 }