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 }