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 final long serialVersionUID = 1L; 047 private static org.apache.logging.log4j.Logger logger = StatusLogger.getLogger(); 048 049 private final AbstractScript script; 050 private final Configuration configuration; 051 052 private ScriptFilter(final AbstractScript script, final Configuration configuration, final Result onMatch, 053 final Result onMismatch) { 054 super(onMatch, onMismatch); 055 this.script = script; 056 this.configuration = configuration; 057 if (!(script instanceof ScriptRef)) { 058 configuration.getScriptManager().addScript(script); 059 } 060 } 061 062 @Override 063 public Result filter(final Logger logger, final Level level, final Marker marker, final String msg, 064 final Object... params) { 065 SimpleBindings bindings = new SimpleBindings(); 066 bindings.put("logger", logger); 067 bindings.put("level", level); 068 bindings.put("marker", marker); 069 bindings.put("message", new SimpleMessage(msg)); 070 bindings.put("parameters", params); 071 bindings.put("throwable", null); 072 bindings.putAll(configuration.getProperties()); 073 bindings.put("substitutor", configuration.getStrSubstitutor()); 074 Object object = configuration.getScriptManager().execute(script.getName(), bindings); 075 return object == null || !Boolean.TRUE.equals(object) ? onMismatch : onMatch; 076 } 077 078 @Override 079 public Result filter(final Logger logger, final Level level, final Marker marker, final Object msg, 080 final Throwable t) { 081 SimpleBindings bindings = new SimpleBindings(); 082 bindings.put("logger", logger); 083 bindings.put("level", level); 084 bindings.put("marker", marker); 085 bindings.put("message", msg instanceof String ? new SimpleMessage((String)msg) : new ObjectMessage(msg)); 086 bindings.put("parameters", null); 087 bindings.put("throwable", t); 088 bindings.putAll(configuration.getProperties()); 089 bindings.put("substitutor", configuration.getStrSubstitutor()); 090 Object object = configuration.getScriptManager().execute(script.getName(), bindings); 091 return object == null || !Boolean.TRUE.equals(object) ? onMismatch : onMatch; 092 } 093 094 @Override 095 public Result filter(final Logger logger, final Level level, final Marker marker, final Message msg, 096 final Throwable t) { 097 SimpleBindings bindings = new SimpleBindings(); 098 bindings.put("logger", logger); 099 bindings.put("level", level); 100 bindings.put("marker", marker); 101 bindings.put("message", msg); 102 bindings.put("parameters", null); 103 bindings.put("throwable", t); 104 bindings.putAll(configuration.getProperties()); 105 bindings.put("substitutor", configuration.getStrSubstitutor()); 106 Object object = configuration.getScriptManager().execute(script.getName(), bindings); 107 return object == null || !Boolean.TRUE.equals(object) ? onMismatch : onMatch; 108 } 109 110 @Override 111 public Result filter(final LogEvent event) { 112 SimpleBindings bindings = new SimpleBindings(); 113 bindings.put("logEvent", event); 114 bindings.putAll(configuration.getProperties()); 115 bindings.put("substitutor", configuration.getStrSubstitutor()); 116 Object object = configuration.getScriptManager().execute(script.getName(), bindings); 117 return object == null || !Boolean.TRUE.equals(object) ? onMismatch : onMatch; 118 } 119 120 @Override 121 public String toString() { 122 return script.getName(); 123 } 124 125 /** 126 * Creates the ScriptFilter. 127 * @param script The script to run. The script must return a boolean value. Either script or scriptFile must be 128 * provided. 129 * @param match The action to take if a match occurs. 130 * @param mismatch The action to take if no match occurs. 131 * @param configuration the configuration 132 * @return A ScriptFilter. 133 */ 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}