如何全局配置OpenTelemetry StartActivity自动追踪所有方法调用?
自动追踪方法调用的可行方案
你当前配置的AspNetCore、HttpClient、EFCore Instrumentation已经会自动生成对应接口请求、外部HTTP调用、数据库操作的Span,自定义业务方法的Span可以通过以下两种全局方案实现,无需手动在每个方法添加StartActivity代码。
方案1:Controller层使用内置过滤器实现全局追踪
通过ASP.NET Core自带的ActionFilter全局拦截所有Controller接口请求,自动生成对应Activity:
- 自定义追踪过滤器
public class TraceActionFilter : IAsyncActionFilter { private readonly ActivitySource _activitySource; public TraceActionFilter(ActivitySource activitySource) { _activitySource = activitySource; } public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { var activityName = $"{context.Controller.GetType().Name}.{context.ActionDescriptor.ActionName}"; using var activity = _activitySource.StartActivity(activityName); // 可选:添加自定义标签,比如请求参数 activity?.SetTag("request.parameters", System.Text.Json.JsonSerializer.Serialize(context.ActionArguments)); await next(); } }
- 全局注册过滤器
// 注册过滤器到DI容器 services.AddScoped<TraceActionFilter>(); // 全局添加到MVC管道,所有Controller请求自动触发 services.AddControllers(options => { options.Filters.Add<TraceActionFilter>(); });
方案2:业务层/数据访问层使用AOP动态代理实现全局方法追踪
通过动态代理拦截所有业务类方法调用,自动生成Activity,推荐使用Castle DynamicProxy框架实现:
- 安装必要NuGet包
Castle.Core、Castle.Core.AsyncInterceptor - 自定义业务方法拦截器
using Castle.DynamicProxy; public class BusinessTraceInterceptor : IAsyncInterceptor { private readonly ActivitySource _activitySource; public BusinessTraceInterceptor(ActivitySource activitySource) { _activitySource = activitySource; } // 同步方法拦截 public void InterceptSynchronous(IInvocation invocation) { var activityName = $"{invocation.TargetType.Name}.{invocation.Method.Name}"; using var activity = _activitySource.StartActivity(activityName); // 可选:添加入参标签 activity?.SetTag("method.parameters", System.Text.Json.JsonSerializer.Serialize(invocation.Arguments)); invocation.Proceed(); } // 无返回值异步方法拦截 public void InterceptAsynchronous(IInvocation invocation) { var activityName = $"{invocation.TargetType.Name}.{invocation.Method.Name}"; using var activity = _activitySource.StartActivity(activityName); invocation.Proceed(); } // 有返回值异步方法拦截 public void InterceptAsynchronous<TResult>(IInvocation invocation) { var activityName = $"{invocation.TargetType.Name}.{invocation.Method.Name}"; using var activity = _activitySource.StartActivity(activityName); invocation.Proceed(); } }
- 注册服务时添加拦截器
// 注册拦截器到DI容器 services.AddSingleton<BusinessTraceInterceptor>(); // 注册业务服务时用代理包装,替换原有注册逻辑 services.AddScoped<IMyBusinessService>(sp => { var target = new MyBusinessService(/* 构造函数依赖自行传入 */); var proxyGenerator = new ProxyGenerator(); var interceptor = sp.GetRequiredService<BusinessTraceInterceptor>(); return proxyGenerator.CreateInterfaceProxyWithTarget<IMyBusinessService>(target, interceptor); });
如果使用Autofac等第三方IOC容器,可以配置批量拦截规则,无需逐个修改业务服务注册逻辑。
可选优化点
- 自定义
[IgnoreTrace]特性,拦截器中判断方法标注该特性时跳过生成Activity,避免生成多余Span - 可在Activity中添加异常信息标签,方法执行抛出异常时自动记录错误栈,方便排查问题
- 控制追踪粒度,避免拦截过于底层的工具类方法,减少性能损耗和链路冗余
内容的提问来源于stack exchange,提问作者Unknown
相关产品推荐
相关产品推荐

