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.io.Serializable; 020import java.util.Objects; 021 022import javax.script.Bindings; 023 024import org.apache.logging.log4j.core.Appender; 025import org.apache.logging.log4j.core.Core; 026import org.apache.logging.log4j.core.Filter; 027import org.apache.logging.log4j.core.Layout; 028import org.apache.logging.log4j.core.LogEvent; 029import org.apache.logging.log4j.core.config.Configuration; 030import org.apache.logging.log4j.core.config.Property; 031import org.apache.logging.log4j.core.config.plugins.Plugin; 032import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute; 033import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory; 034import org.apache.logging.log4j.core.config.plugins.PluginConfiguration; 035import org.apache.logging.log4j.core.config.plugins.PluginElement; 036import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required; 037import org.apache.logging.log4j.core.script.AbstractScript; 038import org.apache.logging.log4j.core.script.ScriptManager; 039 040@Plugin(name = "ScriptAppenderSelector", category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE, printObject = true) 041public class ScriptAppenderSelector extends AbstractAppender { 042 043 /** 044 * Builds an appender. 045 */ 046 public static final class Builder implements org.apache.logging.log4j.core.util.Builder<Appender> { 047 048 @PluginElement("AppenderSet") 049 @Required 050 private AppenderSet appenderSet; 051 052 @PluginConfiguration 053 @Required 054 private Configuration configuration; 055 056 @PluginBuilderAttribute 057 @Required 058 private String name; 059 060 @PluginElement("Script") 061 @Required 062 private AbstractScript script; 063 064 @Override 065 public Appender build() { 066 if (name == null) { 067 LOGGER.error("Name missing."); 068 return null; 069 } 070 if (script == null) { 071 LOGGER.error("Script missing for ScriptAppenderSelector appender {}", name); 072 return null; 073 } 074 if (appenderSet == null) { 075 LOGGER.error("AppenderSet missing for ScriptAppenderSelector appender {}", name); 076 return null; 077 } 078 if (configuration == null) { 079 LOGGER.error("Configuration missing for ScriptAppenderSelector appender {}", name); 080 return null; 081 } 082 final ScriptManager scriptManager = configuration.getScriptManager(); 083 scriptManager.addScript(script); 084 final Bindings bindings = scriptManager.createBindings(script); 085 LOGGER.debug("ScriptAppenderSelector '{}' executing {} '{}': {}", name, script.getLanguage(), 086 script.getName(), script.getScriptText()); 087 final Object object = scriptManager.execute(script.getName(), bindings); 088 final String actualAppenderName = Objects.toString(object, null); 089 LOGGER.debug("ScriptAppenderSelector '{}' selected '{}'", name, actualAppenderName); 090 return appenderSet.createAppender(actualAppenderName, name); 091 } 092 093 public AppenderSet getAppenderSet() { 094 return appenderSet; 095 } 096 097 public Configuration getConfiguration() { 098 return configuration; 099 } 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}