前置信息
Skywalking oap 与 agent部署
https://blog.csdn.net/kismet2399/article/details/131560171
环境配置
- spring-cloud-starter-gateway:3.1.4
- Skywalking Agent:8.14.0
背景
SpringCloudGateway集成Skywalking后无法打印traceId
解决方式
目前没有找到logback的解决方式,所以日志打印改用log4j2
- mvn添加配置
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-log4j-2.x</artifactId>
<version>8.14.0</version>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<version>8.14.0</version>
</dependency>
<!--解决log4j2依赖问题-->
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.4.4</version>
</dependency>
- 让日志获取到traceId
import org.springframework.stereotype.Component;
import reactor.core.publisher.Hooks;
import reactor.core.publisher.Operators;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
* @author kismet
*/
@Component
public class LogHooks {
private static final String KEY = "logMdc";
@PostConstruct
public void setHook() {
Hooks.onEachOperator(KEY,
Operators.lift((scannable, coreSubscriber) -> new MdcSubscriber(coreSubscriber)));
}
@PreDestroy
public void resetHook() {
Hooks.resetOnEachOperator(KEY);
}
}
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.common.utils.JacksonUtils;
import org.jboss.logging.MDC;
import org.reactivestreams.Subscription;
import reactor.core.CoreSubscriber;
import reactor.util.context.Context;
import java.lang.reflect.Field;
import java.util.Optional;
/**
* @author zuozhuan
*/
public class MdcSubscriber implements CoreSubscriber {
private static final String TRACE_ID = "traceId";
private static final String SKYWALKING_CTX_SNAPSHOT = "SKYWALKING_CONTEXT_SNAPSHOT";
private final CoreSubscriber<Object> actual;
public MdcSubscriber(CoreSubscriber<Object> actual) {
this.actual = actual;
}
@Override
public void onSubscribe(Subscription s) {
actual.onSubscribe(s);
}
@Override
public void onNext(Object o) {
Context c = actual.currentContext();
Optional<String> traceIdOptional = Optional.empty();
if (!c.isEmpty() && c.hasKey(SKYWALKING_CTX_SNAPSHOT)) {
Object object = c.get(SKYWALKING_CTX_SNAPSHOT);
Object traceId = findField(object, "traceId");
String ids = JacksonUtils.toJson(traceId);
traceIdOptional = Optional.ofNullable(ids)
.map(JSON::parseObject)
.map(t -> t.get("id"))
.map(Object::toString);
}
MDC.put(TRACE_ID, traceIdOptional.orElse("N/A"));
actual.onNext(o);
}
private static Object findField(Object object, String field) {
if (object == null) {
return null;
}
try {
Class<?> aClass = object.getClass();
Field mValuesField = null;
mValuesField = aClass.getDeclaredField(field);
// 3、打开访问权限
mValuesField.setAccessible(true);
// 4、获取 memberValuesMap
return mValuesField.get(object);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void onError(Throwable throwable) {
actual.onError(throwable);
}
@Override
public void onComplete() {
actual.onComplete();
}
@Override
public Context currentContext() {
return actual.currentContext();
}
-
插件添加
将skywalking-agent下optional-plugins中的apm-spring-cloud-gateway-3.x-plugin-8.14.0.jar和apm-spring-webflux-5.x-plugin-8.14.0.jar移动到plugins下 -
log4j2.xml配置示例文章来源:https://www.toymoban.com/news/detail-544509.html
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Properties>
<Property name="PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [TID:%equals{%X{traceId}}{}{N/A}] [%thread] %-5level %logger{20} %msg%n"/>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${PATTERN}"/>
</Console>
<Async name="Async">
<AppenderRef ref="Console"/>
</Async>
<!--输出到日志文件,滚动分割日志文件,自动打包gz -->
<RollingFile name="INFO_FILE" fileName="${env:HOME}/logs/gateway/gateway.log" filePattern="${env:HOME}/logs/gateway/gateway-%d{yyyyMMdd}.log.%i">
<PatternLayout pattern="${PATTERN}"/>
<Policies>
<!--默认一天一个文件 -->
<TimeBasedTriggeringPolicy />
<!--一天内大于size就单独分隔-->
<SizeBasedTriggeringPolicy size="500MB"/>
</Policies>
</RollingFile>
<!--skywalking 日志收集 -->
<GRPCLogClientAppender name="APM_LOG">
<PatternLayout pattern="${PATTERN}"/>
</GRPCLogClientAppender>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="Console">
<Filters>
<PropertyFilter key="spring.profiles.active" value="dev" onMatch="ACCEPT" onMismatch="DENY" />
</Filters>
</AppenderRef>
<AppenderRef ref="INFO_FILE"/>
<AppenderRef ref="APM_LOG"/>
</Root>
</Loggers>
</Configuration>
- 如果使用skywalking 日志收集启动参数需添加启动参数
-Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
参考链接:
https://www.jianshu.com/p/40727a0b9604
https://skywalking.apache.org/docs/skywalking-java/v8.14.0/en/setup/service-agent/java-agent/application-toolkit-log4j-2.x/文章来源地址https://www.toymoban.com/news/detail-544509.html
到了这里,关于SpringCloudGateway使用Skywalking时日志打印traceId的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!