001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache license, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the license for the specific language governing permissions and 015 * limitations under the license. 016 */ 017package org.apache.logging.log4j.core.appender; 018 019import java.util.HashMap; 020import java.util.List; 021import java.util.Map; 022 023import org.apache.logging.log4j.core.Appender; 024import org.apache.logging.log4j.core.Core; 025import org.apache.logging.log4j.core.config.Configuration; 026import org.apache.logging.log4j.core.config.Node; 027import org.apache.logging.log4j.core.config.plugins.Plugin; 028import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory; 029import org.apache.logging.log4j.core.config.plugins.PluginConfiguration; 030import org.apache.logging.log4j.core.config.plugins.PluginNode; 031import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required; 032import org.apache.logging.log4j.status.StatusLogger; 033 034/** 035 * A deferred plugin for appenders. 036 */ 037@Plugin(name = "AppenderSet", category = Core.CATEGORY_NAME, printObject = true, deferChildren = true) 038public class AppenderSet { 039 040 public static class Builder implements org.apache.logging.log4j.core.util.Builder<AppenderSet> { 041 042 @PluginNode 043 private Node node; 044 045 @PluginConfiguration 046 @Required 047 private Configuration configuration; 048 049 @Override 050 public AppenderSet build() { 051 if (configuration == null) { 052 LOGGER.error("Configuration is missing from AppenderSet {}", this); 053 return null; 054 } 055 if (node == null) { 056 LOGGER.error("No node in AppenderSet {}", this); 057 return null; 058 } 059 final List<Node> children = node.getChildren(); 060 if (children == null) { 061 LOGGER.error("No children node in AppenderSet {}", this); 062 return null; 063 } 064 final Map<String, Node> map = new HashMap<>(children.size()); 065 for (final Node childNode : children) { 066 final String key = childNode.getAttributes().get("name"); 067 if (key == null) { 068 LOGGER.error("The attribute 'name' is missing from from the node {} in AppenderSet {}", 069 childNode, children); 070 } else { 071 map.put(key, childNode); 072 } 073 } 074 return new AppenderSet(configuration, map); 075 } 076 077 public Node getNode() { 078 return node; 079 } 080 081 public Configuration getConfiguration() { 082 return configuration; 083 } 084 085 public Builder withNode(@SuppressWarnings("hiding") final Node node) { 086 this.node = node; 087 return this; 088 } 089 090 public Builder withConfiguration(@SuppressWarnings("hiding") final Configuration configuration) { 091 this.configuration = configuration; 092 return this; 093 } 094 095 @Override 096 public String toString() { 097 return getClass().getName() + " [node=" + node + ", configuration=" + configuration + "]"; 098 } 099 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}