in log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java [229:303]
public static ThrowableFormatOptions newInstance(String[] options) {
if (options == null || options.length == 0) {
return DEFAULT;
}
// NOTE: The following code is present for backward compatibility
// and was copied from Extended/RootThrowablePatternConverter.
// This supports a single option with the format:
// %xEx{["none"|"short"|"full"|depth],[filters(packages)}
// However, the convention for multiple options should be:
// %xEx{["none"|"short"|"full"|depth]}[{filters(packages)}]
if (options.length == 1 && Strings.isNotEmpty(options[0])) {
final String[] opts = options[0].split(Patterns.COMMA_SEPARATOR, 2);
final String first = opts[0].trim();
try (final Scanner scanner = new Scanner(first)) {
if (opts.length > 1 && (first.equalsIgnoreCase(FULL) || first.equalsIgnoreCase(SHORT)
|| first.equalsIgnoreCase(NONE) || scanner.hasNextInt())) {
options = new String[] { first, opts[1].trim() };
}
}
}
int lines = DEFAULT.lines;
String separator = DEFAULT.separator;
List<String> packages = DEFAULT.ignorePackages;
TextRenderer ansiRenderer = DEFAULT.textRenderer;
String suffix = DEFAULT.getSuffix();
for (final String rawOption : options) {
if (rawOption != null) {
final String option = rawOption.trim();
if (option.isEmpty()) {
// continue;
} else if (option.startsWith("separator(") && option.endsWith(")")) {
separator = option.substring("separator(".length(), option.length() - 1);
} else if (option.startsWith("filters(") && option.endsWith(")")) {
final String filterStr = option.substring("filters(".length(), option.length() - 1);
if (filterStr.length() > 0) {
final String[] array = filterStr.split(Patterns.COMMA_SEPARATOR);
if (array.length > 0) {
packages = new ArrayList<>(array.length);
for (String token : array) {
token = token.trim();
if (token.length() > 0) {
packages.add(token);
}
}
}
}
} else if (option.equalsIgnoreCase(NONE)) {
lines = 0;
} else if (option.equalsIgnoreCase(SHORT) || option.equalsIgnoreCase(CLASS_NAME)
|| option.equalsIgnoreCase(METHOD_NAME) || option.equalsIgnoreCase(LINE_NUMBER)
|| option.equalsIgnoreCase(FILE_NAME) || option.equalsIgnoreCase(MESSAGE)
|| option.equalsIgnoreCase(LOCALIZED_MESSAGE)) {
lines = 2;
} else if (option.startsWith("ansi(") && option.endsWith(")") || option.equals("ansi")) {
if (Loader.isJansiAvailable()) {
final String styleMapStr = option.equals("ansi") ? Strings.EMPTY
: option.substring("ansi(".length(), option.length() - 1);
ansiRenderer = new JAnsiTextRenderer(new String[] { null, styleMapStr },
JAnsiTextRenderer.DefaultExceptionStyleMap);
} else {
StatusLogger.getLogger().warn(
"You requested ANSI exception rendering but JANSI is not on the classpath. Please see https://logging.apache.org/log4j/2.x/runtime-dependencies.html");
}
} else if (option.startsWith("S(") && option.endsWith(")")){
suffix = option.substring("S(".length(), option.length() - 1);
} else if (option.startsWith("suffix(") && option.endsWith(")")){
suffix = option.substring("suffix(".length(), option.length() - 1);
} else if (!option.equalsIgnoreCase(FULL)) {
lines = Integers.parseInt(option);
}
}
}
return new ThrowableFormatOptions(lines, separator, packages, ansiRenderer, suffix);
}