Home / Class/ CorrelationIdFormatter Class — spring-boot Architecture

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

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free