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 org.apache.logging.log4j.Level;
020import org.apache.logging.log4j.Marker;
021import org.apache.logging.log4j.core.Filter;
022import org.apache.logging.log4j.core.LogEvent;
023import org.apache.logging.log4j.core.Logger;
024import org.apache.logging.log4j.core.config.Node;
025import org.apache.logging.log4j.core.config.plugins.Plugin;
026import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
027import org.apache.logging.log4j.core.config.plugins.PluginFactory;
028import org.apache.logging.log4j.message.Message;
029import org.apache.logging.log4j.util.PerformanceSensitive;
030
031/**
032 * This filter returns the onMatch result if the level in the LogEvent is the same or more specific
033 * than the configured level and the onMismatch value otherwise. For example, if the ThresholdFilter
034 * is configured with Level ERROR and the LogEvent contains Level DEBUG then the onMismatch value will
035 * be returned since ERROR events are more specific than DEBUG.
036 *
037 * The default Level is ERROR.
038 */
039@Plugin(name = "ThresholdFilter", category = Node.CATEGORY, elementType = Filter.ELEMENT_TYPE, printObject = true)
040@PerformanceSensitive("allocation")
041public final class ThresholdFilter extends AbstractFilter {
042
043    private final Level level;
044
045    private ThresholdFilter(final Level level, final Result onMatch, final Result onMismatch) {
046        super(onMatch, onMismatch);
047        this.level = level;
048    }
049
050    @Override
051    public Result filter(final Logger logger, final Level testLevel, final Marker marker, final String msg,
052                         final Object... params) {
053        return filter(testLevel);
054    }
055
056    @Override
057    public Result filter(final Logger logger, final Level testLevel, final Marker marker, final Object msg,
058                         final Throwable t) {
059        return filter(testLevel);
060    }
061
062    @Override
063    public Result filter(final Logger logger, final Level testLevel, final Marker marker, final Message msg,
064                         final Throwable t) {
065        return filter(testLevel);
066    }
067
068    @Override
069    public Result filter(final LogEvent event) {
070        return filter(event.getLevel());
071    }
072
073    private Result filter(final Level testLevel) {
074        return testLevel.isMoreSpecificThan(this.level) ? onMatch : onMismatch;
075    }
076
077    @Override
078    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
079            final Object p0) {
080        return filter(level);
081    }
082
083    @Override
084    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
085            final Object p0, final Object p1) {
086        return filter(level);
087    }
088
089    @Override
090    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
091            final Object p0, final Object p1, final Object p2) {
092        return filter(level);
093    }
094
095    @Override
096    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
097            final Object p0, final Object p1, final Object p2, final Object p3) {
098        return filter(level);
099    }
100
101    @Override
102    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
103            final Object p0, final Object p1, final Object p2, final Object p3,
104            final Object p4) {
105        return filter(level);
106    }
107
108    @Override
109    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
110            final Object p0, final Object p1, final Object p2, final Object p3,
111            final Object p4, final Object p5) {
112        return filter(level);
113    }
114
115    @Override
116    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
117            final Object p0, final Object p1, final Object p2, final Object p3,
118            final Object p4, final Object p5, final Object p6) {
119        return filter(level);
120    }
121
122    @Override
123    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
124            final Object p0, final Object p1, final Object p2, final Object p3,
125            final Object p4, final Object p5, final Object p6,
126            final Object p7) {
127        return filter(level);
128    }
129
130    @Override
131    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
132            final Object p0, final Object p1, final Object p2, final Object p3,
133            final Object p4, final Object p5, final Object p6,
134            final Object p7, final Object p8) {
135        return filter(level);
136    }
137
138    @Override
139    public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
140            final Object p0, final Object p1, final Object p2, final Object p3,
141            final Object p4, final Object p5, final Object p6,
142            final Object p7, final Object p8, final Object p9) {
143        return filter(level);
144    }
145
146    public Level getLevel() {
147        return level;
148    }
149
150    @Override
151    public String toString() {
152        return level.toString();
153    }
154
155    /**
156     * Creates a ThresholdFilter.
157     * @param level The log Level.
158     * @param match The action to take on a match.
159     * @param mismatch The action to take on a mismatch.
160     * @return The created ThresholdFilter.
161     */
162    // TODO Consider refactoring to use AbstractFilter.AbstractFilterBuilder
163    @PluginFactory
164    public static ThresholdFilter createFilter(
165            @PluginAttribute("level") final Level level,
166            @PluginAttribute("onMatch") final Result match,
167            @PluginAttribute("onMismatch") final Result mismatch) {
168        final Level actualLevel = level == null ? Level.ERROR : level;
169        final Result onMatch = match == null ? Result.NEUTRAL : match;
170        final Result onMismatch = mismatch == null ? Result.DENY : mismatch;
171        return new ThresholdFilter(actualLevel, onMatch, onMismatch);
172    }
173
174}