All Downloads are FREE. Search and download functionalities are using the official Maven repository.

hm.binkley.util.logging.MatchConverter Maven / Gradle / Ivy

There is a newer version: 6
Show newest version
/*
 * This is free and unencumbered software released into the public domain.
 *
 * Please see https://github.com/binkley/binkley/blob/master/LICENSE.md.
 */

package hm.binkley.util.logging;

import ch.qos.logback.classic.PatternLayout;
import ch.qos.logback.classic.pattern.ClassicConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.boolex.EvaluationException;
import ch.qos.logback.core.boolex.EventEvaluator;
import ch.qos.logback.core.status.ErrorStatus;

import javax.annotation.Nonnull;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import static ch.qos.logback.core.CoreConstants.EVALUATOR_MAP;
import static java.util.Collections.emptyMap;

/**
 * {@code MarkedConverter} provides alternate conversions based on conditions.  Enable with:
 * 
 * <conversionRule
 *     conversionWord="match"
 *     converterClass="hm.binkley.util.logging.MatchConverter"/>
Use as: *
 * <pattern>%match{cond1,patt1,...,fallback}</pattern>
Example: *
 * <evaluator name="WITH_MARKER">
 *     <expression>null != marker &mp;&mp; "ALERT".equals(marker.getName())</expression>
 * </evaluator>
 * <pattern>%match(WITH_MARKER,%marker/%level,%level)</pattern>
will log * "ALERT/ERROR" when marker is "ALERT" and level is "ERROR", otherwise just "ERROR". * * @author B. K. Oxley (binkley) * @todo Fix error reporting - logback swallows */ public final class MatchConverter extends ClassicConverter { private static final int MAX_ERROR_COUNT = 4; private Map conditions; private String unmatched; private Map> evaluators; private int errors; @SuppressWarnings("unchecked") @Override public void start() { final List options = getOptionList(); if (null == options || 2 > options.size()) { addError("Missing options for %match - " + (null == options ? "missing options" : options)); conditions = emptyMap(); unmatched = ""; return; } conditions = new LinkedHashMap<>(); for (int i = 0; i < options.size() - 1; i += 2) conditions.put(options.get(i), options.get(i + 1)); unmatched = 0 == options.size() % 2 ? "" : options.get(options.size() - 1); evaluators = (Map>) getContext() .getObject(EVALUATOR_MAP); super.start(); } @Nonnull @Override public String convert(@Nonnull final ILoggingEvent event) { for (final Map.Entry entry : conditions.entrySet()) if (evaluate(entry.getKey(), event)) return relayout(entry.getValue(), event); return relayout(unmatched, event); } private boolean evaluate(final String name, final ILoggingEvent event) { final EventEvaluator evaluator = evaluators.get(name); try { return null != evaluator && evaluator.evaluate(event); } catch (final EvaluationException e) { errors++; if (MAX_ERROR_COUNT > errors) { addError("Exception thrown for evaluator named [" + evaluator.getName() + "]", e); } else if (MAX_ERROR_COUNT == errors) { final ErrorStatus errorStatus = new ErrorStatus( "Exception thrown for evaluator named [" + evaluator.getName() + "].", this, e); errorStatus.add(new ErrorStatus( "This was the last warning about this evaluator's errors." + "We don't want the StatusManager to get flooded.", this)); addStatus(errorStatus); } return false; } } private String relayout(final String pattern, final ILoggingEvent event) { final PatternLayout layout = new PatternLayout(); layout.setContext(getContext()); layout.setPattern(pattern); layout.start(); return layout.doLayout(event); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy