001/*
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2026, QOS.ch. All rights reserved.
004 *
005 * This program and the accompanying materials are dual-licensed under
006 * either the terms of the Eclipse Public License v2.0 as published by
007 * the Eclipse Foundation
008 *
009 *   or (per the licensee's choosing)
010 *
011 * under the terms of the GNU Lesser General Public License version 2.1
012 * as published by the Free Software Foundation.
013 */
014package ch.qos.logback.classic.turbo;
015
016import ch.qos.logback.classic.LoggerContext;
017import org.slf4j.LoggerFactory;
018import org.slf4j.Marker;
019
020import ch.qos.logback.classic.Level;
021import ch.qos.logback.classic.Logger;
022import ch.qos.logback.core.spi.ContextAwareBase;
023import ch.qos.logback.core.spi.FilterReply;
024import ch.qos.logback.core.spi.LifeCycle;
025
026import java.util.List;
027
028/**
029 * TurboFilter is a specialized filter with a decide method that takes a bunch
030 * of parameters instead of a single event object. The latter is cleaner but the
031 * first is much more performant.
032 * <p>
033 * For more information about turbo filters, please refer to the online manual
034 * at https://logback.qos.ch/manual/filters.html#TurboFilter
035 *
036 * @author Ceki Gulcu
037 */
038public abstract class TurboFilter extends ContextAwareBase implements LifeCycle {
039
040    private String name;
041    boolean start = false;
042
043    /**
044     * Make a decision based on the multiple parameters passed as arguments. The
045     * returned value should be one of <code>{@link FilterReply#DENY}</code>,
046     * <code>{@link FilterReply#NEUTRAL}</code>, or
047     * <code>{@link FilterReply#ACCEPT}</code>.
048     * 
049     * @param marker
050     * @param logger
051     * @param level
052     * @param format
053     * @param params
054     * @param t
055     * @return
056     */
057    public abstract FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params,
058            Throwable t);
059
060
061    /**
062     * <p>This method is intended to be called via SLF4J's fluent API and more specifically by
063     * {@link Logger#log(org.slf4j.event.LoggingEvent slf4jEvent)}. Derived classes are strongly
064     * encouraged to override this method with a better suited and more specialized
065     * implementation.
066     * </p>
067     *
068     * <p>The present default implementation translates the given SLF4J {@code LoggingEvent} into the
069     * set of parameters required by {@link #decide(Marker, Logger, Level, String, Object[], Throwable)}
070     * and delegate the decision to that method.
071     * </p>
072     *
073     * <p>Concretely, this method:
074     * <ul>
075     *   <li>extracts the first marker (if any) from the event's marker list,</li>
076     *   <li>maps the SLF4J level to Logback's {@link Level},</li>
077     *   <li>and forwards the event message, arguments and throwable.</li>
078     * </ul>
079     *
080     * <p>Returns the {@link ch.qos.logback.core.spi.FilterReply} produced by
081     * {@code decide(...)}, which should be one of DENY, NEUTRAL or ACCEPT.
082     *
083     * <p>Derived classes are strongly encouraged to override this method with a
084     * better suited and more specialized implementation.</p>
085     *
086     * @param logger the Logger that is logging the event; non-null
087     * @param slf4jEvent the SLF4J logging event to translate and evaluate; may be non-null
088     * @return the filter decision ({@code DENY}, {@code NEUTRAL} or {@code ACCEPT})
089     *
090     * @since 1.5.21
091     */
092    public FilterReply decide(Logger logger, org.slf4j.event.LoggingEvent slf4jEvent) {
093        List<Marker> markers = slf4jEvent.getMarkers();
094        Marker firstMarker = (markers != null && !markers.isEmpty()) ? markers.get(0) : null;
095
096        Level logbackLevel = Level.convertAnSLF4JLevel(slf4jEvent.getLevel());
097        String format = slf4jEvent.getMessage();
098        Object[] params = slf4jEvent.getArgumentArray();
099        Throwable t = slf4jEvent.getThrowable();
100
101        return decide(firstMarker, logger, logbackLevel, format, params, t);
102    }
103
104    public void start() {
105        this.start = true;
106    }
107
108    public boolean isStarted() {
109        return this.start;
110    }
111
112    public void stop() {
113        this.start = false;
114    }
115
116    public String getName() {
117        return name;
118    }
119
120    public void setName(String name) {
121        this.name = name;
122    }
123}