(tl;博士在底部)
从这个问题我想你已经发现
traceId
和 spanId
被放入 MDC 中。
如果您查看 sleuth 文档的 log 集成部分,您将看到示例中的跟踪信息位于日志级别 (
ERROR
) 和 pid (97192
) 之间。如果您尝试将其与 logback 配置 匹配,您将看到日志级别和 pid 之间没有任何内容:${LOG_LEVEL_PATTERN:-%5p} ${PID:- }
,因此跟踪信息如何到达那里可能是一个有效的问题。
如果您再看一下文档,它会这样说:
此日志配置是由 Sleuth 自动设置的。您可以通过
属性禁用 Sleuth 或放置您自己的spring.sleuth.enabled=false
属性来禁用它。logging.pattern.level
这仍然没有明确解释其机制,但它给了你一个巨大的提示:
投入自己的
财产logging.pattern.level
基于此,您可能会认为日志级别和 pid 之间没有任何内容,Sleuth 只是覆盖日志级别并将跟踪信息放入其中。如果您搜索文档在代码中提到的属性,您会发现这正是发生的事情: TL;博士
map.put("logging.pattern.level", "%5p [${spring.zipkin.service.name:" + "${spring.application.name:}},%X{traceId:-},%X{spanId:-}]");
TraceEnvironmentPostProcessor
必须与
META-INF/spring.factories
中的条目一起复制这是我对原始代码稍作修改以使其通过 SonarLint 的代码。
import java.util.HashMap;
import java.util.Map;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
class TraceEnvironmentPostProcessor implements EnvironmentPostProcessor {
private static final String DEFAULT_PROPERTIES_SOURCE_NAME = "defaultProperties";
@Override
public void postProcessEnvironment(
final ConfigurableEnvironment environment, final SpringApplication application) {
final Map<String, Object> map = new HashMap<>();
final boolean sleuthEnabled =
environment.getProperty("spring.sleuth.enabled", Boolean.class, true);
final boolean sleuthDefaultLoggingPatternEnabled =
environment.getProperty(
"spring.sleuth.default-logging-pattern-enabled", Boolean.class, true);
if (sleuthEnabled && sleuthDefaultLoggingPatternEnabled) {
map.put(
"logging.pattern.level",
"%5p [${spring.zipkin.service.name:${spring.application.name:}},%X{traceId:-},%X{spanId:-}]");
String neverRefreshables =
environment.getProperty(
"spring.cloud.refresh.never-refreshable", "com.zaxxer.hikari.HikariDataSource");
map.put(
"spring.cloud.refresh.never-refreshable",
neverRefreshables
+ ",org.springframework.cloud.sleuth.instrument.jdbc.DataSourceWrapper");
}
final var propertySources = environment.getPropertySources();
if (propertySources.contains(DEFAULT_PROPERTIES_SOURCE_NAME)) {
final var source = propertySources.get(DEFAULT_PROPERTIES_SOURCE_NAME);
if (source instanceof MapPropertySource target) {
map.entrySet().stream()
.filter(e -> !(target.containsProperty(e.getKey())))
.forEach(e -> target.getSource().put(e.getKey(), e.getValue()));
}
} else {
propertySources.addLast(new MapPropertySource(DEFAULT_PROPERTIES_SOURCE_NAME, map));
}
}
}
还有
org.springframework.boot.env.EnvironmentPostProcessor=\
net.trajano.swarm.logging.autoconfig.TraceEnvironmentPostProcessor
logback-spring.xml
文件并设置附加程序。
文档中的完整 logback 配置: https://github.com/spring-cloud-samples/sleuth-documentation-apps/blob/main/service1/src/main/resources/logback-spring.xml
<!-- Appender to log to file in a JSON format -->
<appender name="logstash" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_FILE}.json</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_FILE}.json.%d{yyyy-MM-dd}.gz</fileNamePattern>
<maxHistory>7</maxHistory>
</rollingPolicy>
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<timestamp>
<timeZone>UTC</timeZone>
</timestamp>
<pattern>
<pattern>
{
"timestamp": "@timestamp",
"severity": "%level",
"service": "${springAppName:-}",
"trace": "%X{traceId:-}",
"span": "%X{spanId:-}",
"baggage": "%X{key:-}",
"pid": "${PID:-}",
"thread": "%thread",
"class": "%logger{40}",
"rest": "%message"
}
</pattern>
</pattern>
</providers>
</encoder>
</appender>