Repasting code with markup (cannot edit the JIRA I created!):
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 java.util.Objects;
importstatic ch.qos.logback.core.CoreConstants.EVALUATOR_MAP;
importstatic java.util.Collections.emptyMap;
/**
* {@code MarkedConverter} provides alternate conversions based on conditions. Enable with:
* <pre>
* <conversionRule
* conversionWord="match"
* converterClass="mbl.laboratory.util.logging.osi.MatchConverter"/></pre> Use as:
* <pre>
* <pattern>%match{cond1,patt1,...,fallback}</pattern></pre> Example:
* <pre>
* <evaluator name="WITH_MARKER">
* <expression>null != marker &mp;&mp; "ALERT".equals(marker.getName())</expression>
* </evaluator>
* <pattern>%match(WITH_MARKER,%marker/%level,%level)</pattern></pre> will log
* "ALERT/ERROR" when marker is "ALERT" and level is "ERROR", otherwise just "ERROR".
*
* @author <a href="mailto:binkley@alumni.rice.edu">B. K. Oxley (binkley)</a>
* @todo Fix error reporting - logback swallows
*/
publicfinal class MatchConverter
extends ClassicConverter {
privatestaticfinalint MAX_ERROR_COUNT = 4;
private Map<String, String> conditions;
privateString unmatched;
private Map<String, EventEvaluator<ILoggingEvent>> evaluators;
privateint errors;
@Override
public void start() {
final List<String> options = getOptionList();
if (null == options || 2 > options.size()) {
addError("Missing options for %match - " + Objects.toString(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<String, EventEvaluator<ILoggingEvent>>) getContext()
.getObject(EVALUATOR_MAP);
super.start();
}
@Nonnull
@Override
publicString convert(@Nonnull final ILoggingEvent event) {
for (final Map.Entry<String, String> entry : conditions.entrySet())
if (evaluate(entry.getKey(), event))
return relayout(entry.getValue(), event);
return relayout(unmatched, event);
}
privateboolean evaluate(finalString name, final ILoggingEvent event) {
final EventEvaluator<ILoggingEvent> evaluator = evaluators.get(name);
try {
returnnull != evaluator && evaluator.evaluate(event);
} catch (final EvaluationException e) {
errors++;
if (errors < MAX_ERROR_COUNT) {
addError("Exception thrown for evaluator named [" + evaluator.getName() + "]", e);
} elseif (errors == MAX_ERROR_COUNT) {
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);
}
returnfalse;
}
}
privateString relayout(finalString pattern, final ILoggingEvent event) {
final PatternLayout layout = new PatternLayout();
layout.setContext(getContext());
layout.setPattern(pattern);
layout.start();
return layout.doLayout(event);
}
}
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira
Repasting code with markup (cannot edit the JIRA I created!):