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}