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.filter; 018 019import javax.script.SimpleBindings; 020 021import org.apache.logging.log4j.Level; 022import org.apache.logging.log4j.Marker; 023import org.apache.logging.log4j.core.Filter; 024import org.apache.logging.log4j.core.LogEvent; 025import org.apache.logging.log4j.core.Logger; 026import org.apache.logging.log4j.core.config.Configuration; 027import org.apache.logging.log4j.core.config.Node; 028import org.apache.logging.log4j.core.config.plugins.Plugin; 029import org.apache.logging.log4j.core.config.plugins.PluginAttribute; 030import org.apache.logging.log4j.core.config.plugins.PluginConfiguration; 031import org.apache.logging.log4j.core.config.plugins.PluginElement; 032import org.apache.logging.log4j.core.config.plugins.PluginFactory; 033import org.apache.logging.log4j.core.script.AbstractScript; 034import org.apache.logging.log4j.core.script.ScriptRef; 035import org.apache.logging.log4j.message.Message; 036import org.apache.logging.log4j.message.ObjectMessage; 037import org.apache.logging.log4j.message.SimpleMessage; 038import org.apache.logging.log4j.status.StatusLogger; 039 040/** 041 * Returns the onMatch result if the script returns True and returns the onMismatch value otherwise. 042 */ 043@Plugin(name = "ScriptFilter", category = Node.CATEGORY, elementType = Filter.ELEMENT_TYPE, printObject = true) 044public final class ScriptFilter extends AbstractFilter { 045 046 private static org.apache.logging.log4j.Logger logger = StatusLogger.getLogger(); 047 048 private final AbstractScript script; 049 private final Configuration configuration; 050 051 private ScriptFilter(final AbstractScript script, final Configuration configuration, final Result onMatch, 052 final Result onMismatch) { 053 super(onMatch, onMismatch); 054 this.script = script; 055 this.configuration = configuration; 056 if (!(script instanceof ScriptRef)) { 057 configuration.getScriptManager().addScript(script); 058 } 059 } 060 061 @Override 062 public Result filter(final Logger logger, final Level level, final Marker marker, final String msg, 063 final Object... params) { 064 final SimpleBindings bindings = new SimpleBindings(); 065 bindings.put("logger", logger); 066 bindings.put("level", level); 067 bindings.put("marker", marker); 068 bindings.put("message", new SimpleMessage(msg)); 069 bindings.put("parameters", params); 070 bindings.put("throwable", null); 071 bindings.putAll(configuration.getProperties()); 072 bindings.put("substitutor", configuration.getStrSubstitutor()); 073 final Object object = configuration.getScriptManager().execute(script.getName(), bindings); 074 return object == null || !Boolean.TRUE.equals(object) ? onMismatch : onMatch; 075 } 076 077 @Override 078 public Result filter(final Logger logger, final Level level, final Marker marker, final Object msg, 079 final Throwable t) { 080 final SimpleBindings bindings = new SimpleBindings(); 081 bindings.put("logger", logger); 082 bindings.put("level", level); 083 bindings.put("marker", marker); 084 bindings.put("message", msg instanceof String ? new SimpleMessage((String)msg) : new ObjectMessage(msg)); 085 bindings.put("parameters", null); 086 bindings.put("throwable", t); 087 bindings.putAll(configuration.getProperties()); 088 bindings.put("substitutor", configuration.getStrSubstitutor()); 089 final Object object = configuration.getScriptManager().execute(script.getName(), bindings); 090 return object == null || !Boolean.TRUE.equals(object) ? onMismatch : onMatch; 091 } 092 093 @Override 094 public Result filter(final Logger logger, final Level level, final Marker marker, final Message msg, 095 final Throwable t) { 096 final SimpleBindings bindings = new SimpleBindings(); 097 bindings.put("logger", logger); 098 bindings.put("level", level); 099 bindings.put("marker", marker); 100 bindings.put("message", msg); 101 bindings.put("parameters", null); 102 bindings.put("throwable", t); 103 bindings.putAll(configuration.getProperties()); 104 bindings.put("substitutor", configuration.getStrSubstitutor()); 105 final Object object = configuration.getScriptManager().execute(script.getName(), bindings); 106 return object == null || !Boolean.TRUE.equals(object) ? onMismatch : onMatch; 107 } 108 109 @Override 110 public Result filter(final LogEvent event) { 111 final SimpleBindings bindings = new SimpleBindings(); 112 bindings.put("logEvent", event); 113 bindings.putAll(configuration.getProperties()); 114 bindings.put("substitutor", configuration.getStrSubstitutor()); 115 final Object object = configuration.getScriptManager().execute(script.getName(), bindings); 116 return object == null || !Boolean.TRUE.equals(object) ? onMismatch : onMatch; 117 } 118 119 @Override 120 public String toString() { 121 return script.getName(); 122 } 123 124 /** 125 * Creates the ScriptFilter. 126 * @param script The script to run. The script must return a boolean value. Either script or scriptFile must be 127 * provided. 128 * @param match The action to take if a match occurs. 129 * @param mismatch The action to take if no match occurs. 130 * @param configuration the configuration 131 * @return A ScriptFilter. 132 */ 133 // TODO Consider refactoring to use AbstractFilter.AbstractFilterBuilder 134 @PluginFactory 135 public static ScriptFilter createFilter( 136 @PluginElement("Script") final AbstractScript script, 137 @PluginAttribute("onMatch") final Result match, 138 @PluginAttribute("onMismatch") final Result mismatch, 139 @PluginConfiguration final Configuration configuration) { 140 141 if (script == null) { 142 LOGGER.error("A Script, ScriptFile or ScriptRef element must be provided for this ScriptFilter"); 143 return null; 144 } 145 if (script instanceof ScriptRef) { 146 if (configuration.getScriptManager().getScript(script.getName()) == null) { 147 logger.error("No script with name {} has been declared.", script.getName()); 148 return null; 149 } 150 } 151 152 return new ScriptFilter(script, configuration, match, mismatch); 153 } 154 155}