CorrelationIdFormatter Class — spring-boot Architecture
Architecture documentation for the CorrelationIdFormatter class in CorrelationIdFormatter.java from the spring-boot codebase.
Entity Profile
Relationship Graph
Source Code
core/spring-boot/src/main/java/org/springframework/boot/logging/CorrelationIdFormatter.java lines 68–202
public final class CorrelationIdFormatter {
/**
* Default {@link CorrelationIdFormatter}.
*/
public static final CorrelationIdFormatter DEFAULT = CorrelationIdFormatter.of("traceId(32),spanId(16)");
private final List<Part> parts;
private final String blank;
private CorrelationIdFormatter(List<Part> parts) {
this.parts = parts;
this.blank = String.format("[%s] ", parts.stream().map(Part::blank).collect(Collectors.joining(" ")));
}
/**
* Format a correlation from the values in the given resolver.
* @param resolver the resolver used to resolve named values
* @return a formatted correlation id
*/
public String format(UnaryOperator<@Nullable String> resolver) {
StringBuilder result = new StringBuilder(this.blank.length());
formatTo(resolver, result);
return result.toString();
}
/**
* Format a correlation from the values in the given resolver and append it to the
* given {@link Appendable}.
* @param resolver the resolver used to resolve named values
* @param appendable the appendable for the formatted correlation id
*/
public void formatTo(UnaryOperator<@Nullable String> resolver, Appendable appendable) {
Predicate<Part> canResolve = (part) -> StringUtils.hasLength(resolver.apply(part.name()));
try {
if (this.parts.stream().anyMatch(canResolve)) {
appendable.append('[');
for (Iterator<Part> iterator = this.parts.iterator(); iterator.hasNext();) {
appendable.append(iterator.next().resolve(resolver));
if (iterator.hasNext()) {
appendable.append('-');
}
}
appendable.append("] ");
}
else {
appendable.append(this.blank);
}
}
catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}
@Override
public String toString() {
return this.parts.stream().map(Part::toString).collect(Collectors.joining(","));
}
/**
* Create a new {@link CorrelationIdFormatter} instance from the given specification.
* @param spec a comma-separated specification
* @return a new {@link CorrelationIdFormatter} instance
*/
public static CorrelationIdFormatter of(@Nullable String spec) {
try {
return (!StringUtils.hasText(spec)) ? DEFAULT : of(List.of(spec.split(",")));
}
catch (Exception ex) {
throw new IllegalStateException("Unable to parse correlation formatter spec '%s'".formatted(spec), ex);
}
}
/**
* Create a new {@link CorrelationIdFormatter} instance from the given specification.
* @param spec a pre-separated specification
* @return a new {@link CorrelationIdFormatter} instance
*/
public static CorrelationIdFormatter of(String @Nullable [] spec) {
return of((spec != null) ? List.of(spec) : Collections.emptyList());
}
/**
* Create a new {@link CorrelationIdFormatter} instance from the given specification.
* @param spec a pre-separated specification
* @return a new {@link CorrelationIdFormatter} instance
*/
public static CorrelationIdFormatter of(Collection<String> spec) {
if (CollectionUtils.isEmpty(spec)) {
return DEFAULT;
}
List<Part> parts = spec.stream().map(Part::of).toList();
return new CorrelationIdFormatter(parts);
}
/**
* A part of the correlation id.
*
* @param name the name of the correlation part
* @param length the expected length of the correlation part
*/
record Part(String name, int length) {
private static final Pattern pattern = Pattern.compile("^(.+?)\\((\\d+)\\)$");
String resolve(UnaryOperator<@Nullable String> resolver) {
String resolved = resolver.apply(name());
if (resolved == null) {
return blank();
}
int padding = length() - resolved.length();
return (padding <= 0) ? resolved : resolved + " ".repeat(padding);
}
String blank() {
return " ".repeat(this.length);
}
@Override
public String toString() {
return "%s(%s)".formatted(name(), length());
}
static Part of(String part) {
Matcher matcher = pattern.matcher(part.trim());
Assert.state(matcher.matches(), () -> "Invalid specification part '%s'".formatted(part));
String name = matcher.group(1);
int length = Integer.parseInt(matcher.group(2));
return new Part(name, length);
}
}
}
Domain
Source
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free