Skip to content

Commit

Permalink
name is optional in EventEvaluator, add ExceptionMatchEvaluator with …
Browse files Browse the repository at this point in the history
…a test

Signed-off-by: Ceki Gulcu <[email protected]>
  • Loading branch information
ceki committed Dec 20, 2024
1 parent 11a3951 commit 020610a
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* Logback: the reliable, generic, fast and flexible logging framework.
* Copyright (C) 1999-2024, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
* or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/

package ch.qos.logback.classic.boolex;

import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.core.boolex.EvaluationException;
import ch.qos.logback.core.boolex.EventEvaluatorBase;

/**
* A simple {@link ch.qos.logback.core.boolex.EventEvaluator} that checks whether the
* logging event being evaluated has a throwable of the same class as specified by the
* {@link #exceptionClass} parameter.
*
* <p>Here is a </p>
* <pre>
* &lt;configuration>
* &lt;import class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"/>
* &lt;import class="ch.qos.logback.core.filter.EvaluatorFilter"/>
* &lt;import class="ch.qos.logback.classic.boolex.ExceptionMatchEvaluator"/>
* &lt;import class="ch.qos.logback.core.ConsoleAppender"/>
*
* &lt;appender name="CONSOLE" class="ConsoleAppender">
* &lt;filter class="EvaluatorFilter">
* &lt;evaluator class="ExceptionMatchEvaluator">
* &lt;exceptionClass>java.lang.RuntimeException&lt;/exceptionClass>
* &lt;/evaluator>
* &lt;OnMismatch>DENY&lt;/OnMismatch>
* &lt;OnMatch>NEUTRAL&lt;/OnMatch>
* &lt;/filter>
*
* &lt;encoder class="PatternLayoutEncoder">
* &lt;pattern>%-4relative [%thread] %-5level %logger -%kvp -%msg%n&lt;/pattern>
* &lt;/encoder>
* &lt;/appender>
*
* &lt;root level="INFO">
* &lt;appender-ref ref="CONSOLE"/>
* &lt;/root>
* &lt;/configuration>
*
*
* </pre>
*/
public class ExceptionMatchEvaluator extends EventEvaluatorBase<ILoggingEvent> {

String exceptionClass;
private boolean start = false;

public void start() {
if (exceptionClass == null) {
addError("The exceptionClass must be set");
return;
}
start = true;
}

public void stop() {
start = false;
}

public boolean isStarted() {
return start;
}

@Override
public boolean evaluate(ILoggingEvent event) throws NullPointerException, EvaluationException {

IThrowableProxy throwableProxy = event.getThrowableProxy();
if (throwableProxy == null) {
return false;
}
return throwableProxy.getClassName().equalsIgnoreCase(exceptionClass);
}

public String getExceptionClass() {
return exceptionClass;
}

public void setExceptionClass(String exceptionClass) {
this.exceptionClass = exceptionClass;
}

}
41 changes: 41 additions & 0 deletions logback-classic/src/test/input/joran/boolex/exceptionEvaluator.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration>

<!--
~ Logback: the reliable, generic, fast and flexible logging framework.
~ Copyright (C) 1999-2024, QOS.ch. All rights reserved.
~
~ This program and the accompanying materials are dual-licensed under
~ either the terms of the Eclipse Public License v1.0 as published by
~ the Eclipse Foundation
~
~ or (per the licensee's choosing)
~
~ under the terms of the GNU Lesser General Public License version 2.1
~ as published by the Free Software Foundation.
-->

<configuration>
<import class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"/>
<import class="ch.qos.logback.core.filter.EvaluatorFilter"/>
<import class="ch.qos.logback.classic.boolex.ExceptionMatchEvaluator"/>
<import class="ch.qos.logback.core.read.ListAppender"/>

<appender name="LIST" class="ListAppender">
<filter class="EvaluatorFilter">
<evaluator class="ExceptionMatchEvaluator">
<exceptionClass>java.lang.RuntimeException</exceptionClass>
</evaluator>
<OnMismatch>DENY</OnMismatch>
<OnMatch>NEUTRAL</OnMatch>
</filter>

<encoder class="PatternLayoutEncoder">
<pattern>%-4relative [%thread] %-5level %logger -%kvp -%msg%n</pattern>
</encoder>
</appender>

<root level="INFO">
<appender-ref ref="LIST"/>
</root>
</configuration>
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import ch.qos.logback.classic.model.ConfigurationModel;
import ch.qos.logback.classic.model.LoggerModel;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.classic.turbo.DebugUsersTurboFilter;
import ch.qos.logback.classic.turbo.NOPTurboFilter;
import ch.qos.logback.classic.turbo.TurboFilter;
Expand Down Expand Up @@ -757,6 +758,24 @@ public void levelFromAPropertyTest() throws JoranException {

}

@Test
public void exceptionEventFilter() throws JoranException {
configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "boolex/exceptionEvaluator.xml");
Logger root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
root.info("deny");
root.info("allow", new RuntimeException("test"));

ListAppender<ILoggingEvent> listAppender = (ListAppender<ILoggingEvent>) root.getAppender("LIST");
assertNotNull(listAppender);
assertEquals(1, listAppender.list.size());

ILoggingEvent le = listAppender.list.get(0);

assertNotNull(le.getThrowableProxy());
assertEquals(RuntimeException.class.getName(), le.getThrowableProxy().getClassName());

}

@Test
public void modelSerialization() throws JoranException, IOException, ClassNotFoundException {
String outputPath = OUTPUT_DIR_PREFIX + "minimal_" + diff + MODEL_CONFIG_FILE_EXTENSION;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ public interface EventEvaluator<E> extends ContextAware, LifeCycle {
boolean evaluate(E event) throws NullPointerException, EvaluationException;

/**
* Evaluators are named entities.
* An evaluator may optionally have a name.
*
* @return The name of this evaluator.
*/
String getName();

/**
* Evaluators are named entities.
* An evaluator may optionally have a name.
*/
void setName(String name);
}

2 comments on commit 020610a

@ppkarwasz
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't ExceptionMatchEvaluator be documented as @since 1.5.15?

@ceki
Copy link
Member Author

@ceki ceki commented on 020610a Dec 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ppkarwasz Yes, it should. Thank you for the heads up.

Please sign in to comment.