1   /*
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2026, QOS.ch. All rights reserved.
4    *
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v2.0 as published by
7    * the Eclipse Foundation
8    *
9    *   or (per the licensee's choosing)
10   *
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
13   */
14  package ch.qos.logback.classic.turbo;
15  
16  import ch.qos.logback.classic.LoggerContext;
17  import org.slf4j.LoggerFactory;
18  import org.slf4j.Marker;
19  
20  import ch.qos.logback.classic.Level;
21  import ch.qos.logback.classic.Logger;
22  import ch.qos.logback.core.spi.ContextAwareBase;
23  import ch.qos.logback.core.spi.FilterReply;
24  import ch.qos.logback.core.spi.LifeCycle;
25  
26  import java.util.List;
27  
28  /**
29   * TurboFilter is a specialized filter with a decide method that takes a bunch
30   * of parameters instead of a single event object. The latter is cleaner but the
31   * first is much more performant.
32   * <p>
33   * For more information about turbo filters, please refer to the online manual
34   * at https://logback.qos.ch/manual/filters.html#TurboFilter
35   *
36   * @author Ceki Gulcu
37   */
38  public abstract class TurboFilter extends ContextAwareBase implements LifeCycle {
39  
40      private String name;
41      boolean start = false;
42  
43      /**
44       * Make a decision based on the multiple parameters passed as arguments. The
45       * returned value should be one of <code>{@link FilterReply#DENY}</code>,
46       * <code>{@link FilterReply#NEUTRAL}</code>, or
47       * <code>{@link FilterReply#ACCEPT}</code>.
48       * 
49       * @param marker
50       * @param logger
51       * @param level
52       * @param format
53       * @param params
54       * @param t
55       * @return
56       */
57      public abstract FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params,
58              Throwable t);
59  
60  
61      /**
62       * <p>This method is intended to be called via SLF4J's fluent API and more specifically by
63       * {@link Logger#log(org.slf4j.event.LoggingEvent slf4jEvent)}. Derived classes are strongly
64       * encouraged to override this method with a better suited and more specialized
65       * implementation.
66       * </p>
67       *
68       * <p>The present default implementation translates the given SLF4J {@code LoggingEvent} into the
69       * set of parameters required by {@link #decide(Marker, Logger, Level, String, Object[], Throwable)}
70       * and delegate the decision to that method.
71       * </p>
72       *
73       * <p>Concretely, this method:
74       * <ul>
75       *   <li>extracts the first marker (if any) from the event's marker list,</li>
76       *   <li>maps the SLF4J level to Logback's {@link Level},</li>
77       *   <li>and forwards the event message, arguments and throwable.</li>
78       * </ul>
79       *
80       * <p>Returns the {@link ch.qos.logback.core.spi.FilterReply} produced by
81       * {@code decide(...)}, which should be one of DENY, NEUTRAL or ACCEPT.
82       *
83       * <p>Derived classes are strongly encouraged to override this method with a
84       * better suited and more specialized implementation.</p>
85       *
86       * @param logger the Logger that is logging the event; non-null
87       * @param slf4jEvent the SLF4J logging event to translate and evaluate; may be non-null
88       * @return the filter decision ({@code DENY}, {@code NEUTRAL} or {@code ACCEPT})
89       *
90       * @since 1.5.21
91       */
92      public FilterReply decide(Logger logger, org.slf4j.event.LoggingEvent slf4jEvent) {
93          List<Marker> markers = slf4jEvent.getMarkers();
94          Marker firstMarker = (markers != null && !markers.isEmpty()) ? markers.get(0) : null;
95  
96          Level logbackLevel = Level.convertAnSLF4JLevel(slf4jEvent.getLevel());
97          String format = slf4jEvent.getMessage();
98          Object[] params = slf4jEvent.getArgumentArray();
99          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 }