public TracingIntercepter( TracingInterceptorOptions options, Func <ISpanBuilder, ISpanBuilder> spanBuilderTransform = null) { this.options = options; this.spanBuilderTransform = spanBuilderTransform; }
public static TInterface WrapInterfaceWithTracingAdapter <TInterface>( this object instance, TracingInterceptorOptions options) { return((TInterface)ProxyGenerator.CreateInterfaceProxyWithTargetInterface( typeof(TInterface), instance, ProxyGenerationOptions.Default, new TracingIntercepter(options))); }
protected override async Task <TResult> InterceptAsync <TResult>([NotNull] IInvocation invocation, Func <IInvocation, Task <TResult> > proceed) { // Must not have any await before await proceed, due to bug in the AsyncInterceptor library right now string operationName = invocation.Method.Name; if (this.options.IncludeClassName) { operationName = invocation.TargetType.FullName + "." + operationName; } var spanBuilder = GlobalTracer.Instance .BuildSpan(operationName); if (this.options.FormatArgumentForTag != null) { ParameterInfo[] parameterInfos = invocation.Method.GetParameters(); for (int i = 0; i < parameterInfos.Length; i++) { var param = parameterInfos[i]; var formattedValue = this.options.FormatArgumentForTag(invocation.Arguments[i]); spanBuilder.WithTag(param.Name, formattedValue); } } if (this.spanBuilderTransform != null) { spanBuilder = this.spanBuilderTransform(spanBuilder); } return(await spanBuilder .ExecuteInScopeAsync( async (span) => { var result = await proceed(invocation) .ConfigureAwait(false); if (this.options.FormatResultForTag != null) { var formattedResult = this.options.FormatResultForTag(result); span.Log( new Dictionary <string, object>(1) { ["result"] = formattedResult }); } if (!this.options.WrapInterfaces) { return result; } if (ReferenceEquals(result, null)) { return result; } if (!typeof(TResult).IsInterface) { return result; } // TODO: Permit this to be configured if (typeof(TResult).Namespace?.StartsWith("System") == true) { return result; } var newOptions = this.options; if (!this.options.RecursivelyWrapInterfaces) { newOptions = new TracingInterceptorOptions( this.options.FormatArgumentForTag, this.options.FormatResultForTag, wrapInterfaces: false, recursivelyWrapInterfaces: false); } var newResult = WrapInterfaceWithTracingAdapter <TResult>( result, newOptions); invocation.ReturnValue = newResult; return newResult; }) .ConfigureAwait(false)); }