Skip to content

Instantly share code, notes, and snippets.

@stokito
Created November 11, 2017 15:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stokito/b20b69969b291c689a8db5c0fd460dd0 to your computer and use it in GitHub Desktop.
Save stokito/b20b69969b291c689a8db5c0fd460dd0 to your computer and use it in GitHub Desktop.
StacktracePatternLayout: LOG4J pattern enhanced for stacktraces
package com.example;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.helpers.PatternConverter;
import org.apache.log4j.helpers.PatternParser;
import org.apache.log4j.spi.LoggingEvent;
public class StacktracePatternLayout extends PatternLayout {
@Override
protected PatternParser createPatternParser(String pattern) {
return new PatternParser(pattern) {
@Override
protected void finalizeConverter(char c) {
if (c == 's') {
currentLiteral.setLength(0);
String options = extractOption();
Collection<String> includePackages = extractPackages(options, "+");
Collection<String> excludePackages = extractPackages(options, "-");
addConverter(new StacktracePatternConverter(includePackages, excludePackages));
} else {
super.finalizeConverter(c);
}
}
};
}
private Collection<String> extractPackages(String options, String prefix) {
if(options == null) {
return null;
}
List<String> packages = new ArrayList<String>();
for (String pkgOption : options.split(",")) {
if(pkgOption.startsWith(prefix)) {
packages.add(pkgOption.substring(prefix.length()));
}
}
return packages;
}
private static class StacktracePatternConverter extends PatternConverter {
private Collection<String> includePackages;
private Collection<String> excludePackages;
StacktracePatternConverter(Collection<String> includePackages, Collection<String> excludePackages) {
this.includePackages = includePackages;
this.excludePackages = excludePackages;
}
@Override
public String convert(LoggingEvent event) {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
int start = findIndex(event, stackTrace);
StringBuilder result = new StringBuilder();
for (int i = start; i < stackTrace.length; i++) {
StackTraceElement element = stackTrace[i];
if (includePackages != null && !matches(element.getClassName(), includePackages)) {
continue;
}
if (excludePackages != null && matches(element.getClassName(), excludePackages)) {
continue;
}
result.append("\tat ").append(element).append("\n");
}
return result.toString();
}
private boolean matches(String className, Collection<String> packages) {
for (String pkg : packages) {
if(className.startsWith(pkg)) {
return true;
}
}
return false;
}
private int findIndex(LoggingEvent event, StackTraceElement[] stackTrace) {
for (int i = 0; i < stackTrace.length; i++) {
if (stackTrace[i].getClassName().equals(event.getLocationInformation().getClassName())) {
return i;
}
}
throw new RuntimeException("Should never reach here");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment