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.util.HashMap;
20  import java.util.List;
21  import java.util.Map;
22  
23  import org.apache.logging.log4j.core.Appender;
24  import org.apache.logging.log4j.core.Core;
25  import org.apache.logging.log4j.core.config.Configuration;
26  import org.apache.logging.log4j.core.config.Node;
27  import org.apache.logging.log4j.core.config.plugins.Plugin;
28  import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
29  import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
30  import org.apache.logging.log4j.core.config.plugins.PluginNode;
31  import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
32  import org.apache.logging.log4j.status.StatusLogger;
33  
34  /**
35   * A deferred plugin for appenders.
36   */
37  @Plugin(name = "AppenderSet", category = Core.CATEGORY_NAME, printObject = true, deferChildren = true)
38  public class AppenderSet {
39  
40      public static class Builder implements org.apache.logging.log4j.core.util.Builder<AppenderSet> {
41  
42          @PluginNode
43          private Node node;
44  
45          @PluginConfiguration
46          @Required
47          private Configuration configuration;
48  
49          @Override
50          public AppenderSet build() {
51              if (configuration == null) {
52                  LOGGER.error("Configuration is missing from AppenderSet {}", this);
53                  return null;
54              }
55              if (node == null) {
56                  LOGGER.error("No node in AppenderSet {}", this);
57                  return null;
58              }
59              final List<Node> children = node.getChildren();
60              if (children == null) {
61                  LOGGER.error("No children node in AppenderSet {}", this);
62                  return null;
63              }
64              final Map<String, Node> map = new HashMap<>(children.size());
65              for (final Node childNode : children) {
66                  final String key = childNode.getAttributes().get("name");
67                  if (key == null) {
68                      LOGGER.error("The attribute 'name' is missing from from the node {} in AppenderSet {}",
69                              childNode, children);
70                  } else {
71                      map.put(key, childNode);
72                  }
73              }
74              return new AppenderSet(configuration, map);
75          }
76  
77          public Node getNode() {
78              return node;
79          }
80  
81          public Configuration getConfiguration() {
82              return configuration;
83          }
84  
85          public Builder withNode(@SuppressWarnings("hiding") final Node node) {
86              this.node = node;
87              return this;
88          }
89  
90          public Builder withConfiguration(@SuppressWarnings("hiding") final Configuration configuration) {
91              this.configuration = configuration;
92              return this;
93          }
94  
95          @Override
96          public String toString() {
97              return getClass().getName() + " [node=" + node + ", configuration=" + configuration + "]";
98          }
99  
100     }
101 
102     private static final StatusLogger LOGGER = StatusLogger.getLogger();
103 
104     private final Configuration configuration;
105     private final Map<String, Node> nodeMap;
106 
107     @PluginBuilderFactory
108     public static Builder newBuilder() {
109         return new Builder();
110     }
111 
112     private AppenderSet(final Configuration configuration, final Map<String, Node> appenders) {
113         this.configuration = configuration;
114         this.nodeMap = appenders;
115     }
116 
117     public Appender createAppender(final String actualAppenderName, final String sourceAppenderName) {
118         final Node node = nodeMap.get(actualAppenderName);
119         if (node == null) {
120             LOGGER.error("No node named {} in {}", actualAppenderName, this);
121             return null;
122         }
123         node.getAttributes().put("name", sourceAppenderName);
124         if (node.getType().getElementName().equals(Appender.ELEMENT_TYPE)) {
125             final Node appNode = new Node(node);
126             configuration.createConfiguration(appNode, null);
127             if (appNode.getObject() instanceof Appender) {
128                 final Appender app = appNode.getObject();
129                 app.start();
130                 return app;
131             }
132             LOGGER.error("Unable to create Appender of type " + node.getName());
133             return null;
134         }
135         LOGGER.error("No Appender was configured for name {} " + actualAppenderName);
136         return null;
137     }
138 }