业务日志关联调用链的TraceId信息Arms
您可以在应用的业务日志中关联调用链的TraceId信息,从而在应用出现问题时,能够通过调用链的TraceId快速关联到业务日志,及时定位分析、解决问题。
背景信息
ARMS在业务日志中关联调用链TraceId的功能基于MDC(Mapped Diagnostic Context)机制实现,支持主流的Log4j、Log4j2和Logback日志框架。开启关联业务日志与TraceId开关
- 登录ARMS控制台,在左侧导航栏选择
- 在应用列表页面顶部选择目标地域,然后单击目标应用名称。
- 在左侧导航栏中单击应用设置,并在右侧单击自定义配置页签。
- 在自定义配置页签的应用日志关联配置区域,选择日志源为日志服务,打开关联业务日志与TraceId开关,选择日志服务所在地域,然后绑定Project和Logstore。
说明
- 开启此开关后,业务日志中将会自动生成调用链的TraceId。
在您业务日志的Layout的Pattern属性中添加%X{EagleEye-TraceID}
配置。
{EagleEye-TraceID}
,请参见ARMS SDK使用说明。下面分别展示Log4j、Log4j2和Logback组件的示例配置文件:
log4j.appender.warn.layout=org.apache.log4j.PatternLayout log4j.appender.warn.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss}-[%p]-(%C:%L) - traceId:%X{EagleEye-TraceID} - %m%n
Log4j2配置文件log4j2.xml的修改示例:
<console name="Console" target="SYSTEM_OUT"> <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - traceId:%X{EagleEye-TraceID} - %m%n"/> </console>
Logback配置文件logback.xml的修改示例:
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - traceId:%X{EagleEye-TraceID} - %msg%n</pattern> </encoder>
重启应用。
用户自己的异步线程,这个是没有埋点的,需要按照这个文档配置一下包名
对于通过Spring @Async标签实现的异步任务,ARMS默认支持对其进行监控。此外,ARMS还支持通过添加异步透传扫描包和使用ARMS SDK进行手动透传对自定义异步任务实现监控。若您的异步任务出现接口超时等异常,可以通过调用链路查看异步任务上下游以便及时处理潜在问题。
前提条件
方式一:默认支持Spring @Async标签
- Executor:
- org.springframework.scheduling.concurrent.ConcurrentTaskExecutor
- org.springframework.core.task.SimpleAsyncTaskExecutor
- org.springframework.scheduling.quartz.SimpleThreadPoolTaskExecutor
- org.springframework.core.task.support.TaskExecutorAdapter
- org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
- org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler
- org.springframework.jca.work.WorkManagerTaskExecutor
- org.springframework.scheduling.commonj.WorkManagerTaskExecutor
- Task:
- org.springframework.aop.interceptor.AsyncExecutionInterceptor$1
- org.springframework.aop.interceptor.AsyncExecutionInterceptor$$Lambda$
方式二:添加异步透传扫描包
您可以选择在应用设置中添加异步透传扫描包实现异步任务监控。异步透传扫描包中的Runnable、Callable和Supplier接口在创建新对象时会自动捕获当前线程调用链的上下文,并在异步线程中执行时使用该调用链上下文,完成串联。
package com.alibaba.arms.brightroar.console.service; //arms @Service public class NameService { private ExecutorService es = Executors.newFixedThreadPool(5); public void name() { es.submit(new Runnable() { @Override public void run() { System.out.println(System.currentTimeMillis()+ ": my name is john, " + Thread.currentThread().getId()); } }); } }
方式三:使用ARMS SDK手动透传
当您的使用方式比较复杂,上述场景无法满足需求时,您还可以选择使用ARMS SDK进行手动透传。通过手动增强Runnable接口、Callable接口和Executor,在异步线程中完成调用链串联,实现异步任务监控。
-
方式一:增强Runnable接口和Callable接口
使用TraceRunnable.asyncEntry()
增强Runnable接口,使用TraceCallable.asyncEntry()
增强Callable接口。示例代码如下:public class AsyncEntryExample { private final ExecutorService executor = Executors.newSingleThreadExecutor(); @GetMapping(value = "/sdk-async-plugin/asyncEntry-propagation") public String asyncEntryAndExecute() throws Exception { CompletableFuture<String> future = new CompletableFuture<>(); Runnable command = TraceRunnable.asyncEntry(() -> future.complete("asyncEntry-execute")); executor.execute(command); Thread.sleep(1000); return future.get(); } }
方式二:增强Executor
使用TraceExecutors.wrapExecutorService(executr, true)
增强Executor。示例代码如下:public class AutoExample { private final ExecutorService contextPropagationExecutor = TraceExecutors.wrapExecutorService(Executors.newSingleThreadExecutor(), true); @GetMapping(value = "/sdk-async-plugin/auto-context-propagation") public String autoWrapAndExecute() throws Exception { CompletableFuture<String> future = new CompletableFuture<>(); contextPropagationExecutor.execute(() -> future.complete("auto-execute")); Thread.sleep(1000); return future.get(); } }
方式三:同时增强Runnable接口、Callable接口和Executor
示例代码如下:public class ManualExample { private final ExecutorService traceExecutor = TraceExecutors.wrapExecutorService(Executors.newSingleThreadExecutor()); @GetMapping(value = "/sdk-async-plugin/manual-context-propagation") public String manualWrapAndExecute() throws Exception { CompletableFuture<String> future = new CompletableFuture<>(); traceExecutor.execute(TraceRunnable.wrap(() -> future.complete("manual-execute"))); traceExecutor.execute(() -> "Not captured"); Thread.sleep(1000); return future.get(); } }
执行结果
配置完成后,您可以在调用链路详情页查看异步任务的调用链详情。具体详情,请参见调用链路查询。
https://help.aliyun.com/document_detail/158582.html