/// <summary>
        /// OnMethodBegin callback
        /// </summary>
        /// <typeparam name="TTarget">Type of the target</typeparam>
        /// <typeparam name="TRequest">Type of the request</typeparam>
        /// <param name="instance">Instance value, aka `this` of the instrumented method.</param>
        /// <param name="requestMessage">HttpRequest message instance</param>
        /// <param name="cancellationToken">CancellationToken value</param>
        /// <returns>Calltarget state value</returns>
        public static CallTargetState OnMethodBegin <TTarget, TRequest>(TTarget instance, TRequest requestMessage, CancellationToken cancellationToken)
            where TRequest : IHttpRequestMessage
        {
            if (IsTracingEnabled(requestMessage.Headers))
            {
                Scope scope = ScopeFactory.CreateOutboundHttpScope(Tracer.Instance, requestMessage.Method.Method, requestMessage.RequestUri, IntegrationId, out HttpTags tags);
                if (scope != null)
                {
                    tags.HttpClientHandlerType = instance.GetType().FullName;

                    // add distributed tracing headers to the HTTP request
                    SpanContextPropagator.Instance.Inject(scope.Span.Context, new HttpHeadersCollection(requestMessage.Headers));

                    return(new CallTargetState(scope));
                }
            }

            return(CallTargetState.GetDefault());
        }
Exemple #2
0
        /// <summary>
        /// OnMethodBegin callback
        /// </summary>
        /// <typeparam name="TTarget">Type of the target</typeparam>
        /// <param name="instance">Instance value, aka `this` of the instrumented method.</param>
        /// <returns>Calltarget state value</returns>
        public static CallTargetState GetResponse_OnMethodBegin <TTarget>(TTarget instance)
        {
            if (instance is HttpWebRequest request && IsTracingEnabled(request))
            {
                Tracer tracer = Tracer.Instance;

                // Check if any headers were injected by a previous call to GetRequestStream
                var spanContext = SpanContextPropagator.Instance.Extract(request.Headers.Wrap());

                // If this operation creates the trace, then we need to re-apply the sampling priority
                bool setSamplingPriority = spanContext?.SamplingPriority != null && tracer.ActiveScope == null;

                Scope scope = null;

                try
                {
                    scope = ScopeFactory.CreateOutboundHttpScope(tracer, request.Method, request.RequestUri, IntegrationId, out _, spanContext?.TraceId, spanContext?.SpanId);

                    if (scope != null)
                    {
                        if (setSamplingPriority && spanContext?.SamplingPriority is not null)
                        {
                            scope.Span.SetTraceSamplingPriority(spanContext.SamplingPriority.Value);
                        }

                        // add distributed tracing headers to the HTTP request
                        SpanContextPropagator.Instance.Inject(scope.Span.Context, request.Headers.Wrap());

                        tracer.TracerManager.Telemetry.IntegrationGeneratedSpan(IntegrationId);

                        return(new CallTargetState(scope));
                    }
                }
                catch
                {
                    scope?.Dispose();
                    throw;
                }
            }

            return(CallTargetState.GetDefault());
        }
        /// <summary>
        /// OnMethodBegin callback
        /// </summary>
        /// <typeparam name="TTarget">Type of the target</typeparam>
        /// <typeparam name="TSendMessageRequest">Type of the request object</typeparam>
        /// <param name="instance">Instance value, aka `this` of the instrumented method</param>
        /// <param name="request">The request for the SQS operation</param>
        /// <param name="cancellationToken">CancellationToken value</param>
        /// <returns>Calltarget state value</returns>
        internal static CallTargetState OnMethodBegin <TTarget, TSendMessageRequest>(TTarget instance, TSendMessageRequest request, CancellationToken cancellationToken)
        {
            if (request is null)
            {
                return(CallTargetState.GetDefault());
            }

            var requestProxy = request.DuckCast <ISendMessageRequest>();

            var scope = AwsSqsCommon.CreateScope(Tracer.Instance, Operation, out AwsSqsTags tags);

            tags.QueueUrl = requestProxy.QueueUrl;

            if (scope?.Span.Context != null)
            {
                ContextPropagation.InjectHeadersIntoMessage <TSendMessageRequest>(requestProxy, scope.Span.Context);
            }

            return(new CallTargetState(scope));
        }
        /// <summary>
        /// OnMethodBegin callback
        /// </summary>
        /// <typeparam name="TTarget">Type of the target</typeparam>
        /// <typeparam name="TCollection">Type of the collection</typeparam>
        /// <typeparam name="TFunc">Type of the </typeparam>
        /// <param name="instance">Instance value, aka `this` of the instrumented method. This method is static so this parameter will always be null</param>
        /// <param name="methods">The methods to be invoked</param>
        /// <param name="setHostingEnvironmentCultures">The function to set the environment culture</param>
        /// <returns>Calltarget state value</returns>
        internal static CallTargetState OnMethodBegin <TTarget, TCollection, TFunc>(TTarget instance, TCollection methods, TFunc setHostingEnvironmentCultures)
        {
            if (Interlocked.Exchange(ref _firstInitialization, 0) != 1)
            {
                // The HttpModule was already registered
                return(CallTargetState.GetDefault());
            }

            try
            {
                HttpApplication.RegisterModule(typeof(TracingHttpModule));
            }
            catch
            {
                // Unable to dynamically register module
                // Not sure if we can technically log yet or not, so do nothing
            }

            return(CallTargetState.GetDefault());
        }
Exemple #5
0
        /// <summary>
        /// OnMethodBegin callback
        /// </summary>
        /// <typeparam name="TTarget">Type of the target</typeparam>
        /// <typeparam name="TTargets">The type of the TargetWithFilterChain </typeparam>
        /// <typeparam name="TLogEventInfo">The type of the LogEventInfo</typeparam>
        /// <typeparam name="TLogFactory">The type of the LogFactory</typeparam>
        /// <param name="instance">Instance value, aka `this` of the instrumented method.</param>
        /// <param name="loggerType">The instance of the logger type</param>
        /// <param name="targetsForLevel">The instance of the targets for the level</param>
        /// <param name="logEvent">The logging event instance</param>
        /// <param name="factory">The LogFactory instance</param>
        /// <returns>Calltarget state value</returns>
        internal static CallTargetState OnMethodBegin <TTarget, TTargets, TLogEventInfo, TLogFactory>(TTarget instance, Type loggerType, TTargets targetsForLevel, TLogEventInfo logEvent, TLogFactory factory)
        {
            var tracer = Tracer.Instance;

            if (tracer.Settings.LogsInjectionEnabled)
            {
                if (DiagnosticContextHelper.Cache <TTarget> .Mdlc is { } mdlc)
                {
                    var state = DiagnosticContextHelper.SetMdlcState(mdlc, tracer);
                    return(new CallTargetState(scope: null, state));
                }

                if (DiagnosticContextHelper.Cache <TTarget> .Mdc is { } mdc)
                {
                    var removeSpanId = DiagnosticContextHelper.SetMdcState(mdc, tracer);
                    return(new CallTargetState(scope: null, removeSpanId));
                }
            }

            return(CallTargetState.GetDefault());
        }
        internal static CallTargetState OnMethodBegin(HttpResponse response, int httpStatusCode, int grpcStatusCode, string message)
        {
            var tracer = Tracer.Instance;

            if (GrpcCoreApiVersionHelper.IsSupported &&
                tracer.Settings.IsIntegrationEnabled(IntegrationId.Grpc) &&
                tracer.ActiveScope?.Span is Span {
                Tags : GrpcServerTags
            } span)
            {
                // This code path is only called when there's a fundamental failure that isn't even processed
                // (e.g. wrong Http protocol, invalid content-type etc)
                GrpcCommon.RecordFinalStatus(span, grpcStatusCode, message, ex : null);

                // There won't be any response metadata, as interceptors haven't executed, but we can grab
                // the request metadata directly from the HttpRequest
                var request = response.HttpContext.Request;
                span.SetHeaderTags(new HeadersCollectionAdapter(request.Headers), tracer.Settings.GrpcTags, defaultTagPrefix: GrpcCommon.RequestMetadataTagPrefix);
            }

            return(CallTargetState.GetDefault());
        }
            public Task <HttpResponseMessage> PublicSendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
            {
                Task <HttpResponseMessage> result = CachedResult;
                CallTargetState            state  = CallTargetState.GetDefault();
                CallTargetReturn <Task <HttpResponseMessage> > cReturn = CallTargetReturn <Task <HttpResponseMessage> > .GetDefault();

                Exception exception = null;

                try
                {
                    try
                    {
                        state = CallTargetInvoker.BeginMethod <HttpClientHandlerIntegration, HttpClientHandler, HttpRequestMessage, CancellationToken>(this, request, cancellationToken);
                    }
                    catch (Exception ex)
                    {
                        CallTargetInvoker.LogException <HttpClientHandlerIntegration, HttpClientHandler>(ex);
                    }
                    result = CachedResult;
                }
                catch (Exception ex)
                {
                    exception = ex;
                    throw;
                }
                finally
                {
                    try
                    {
                        cReturn = CallTargetInvoker.EndMethod <HttpClientHandlerIntegration, HttpClientHandler, Task <HttpResponseMessage> >(this, result, exception, state);
                        result  = cReturn.GetReturnValue();
                    }
                    catch (Exception ex)
                    {
                        CallTargetInvoker.LogException <HttpClientHandlerIntegration, HttpClientHandler>(ex);
                    }
                }
                return(result);
            }
 static BeginMethodHandler()
 {
     try
     {
         DynamicMethod dynMethod = IntegrationMapper.CreateBeginMethodDelegate(typeof(TIntegration), typeof(TTarget), Array.Empty <Type>());
         if (dynMethod != null)
         {
             _invokeDelegate = (InvokeDelegate)dynMethod.CreateDelegate(typeof(InvokeDelegate));
         }
     }
     catch (Exception ex)
     {
         throw new CallTargetInvokerException(ex);
     }
     finally
     {
         if (_invokeDelegate is null)
         {
             _invokeDelegate = instance => CallTargetState.GetDefault();
         }
     }
 }
 static BeginMethodSlowHandler()
 {
     try
     {
         DynamicMethod dynMethod = IntegrationMapper.CreateSlowBeginMethodDelegate(typeof(TIntegration), typeof(TTarget));
         if (dynMethod != null)
         {
             _invokeDelegate = (InvokeDelegate)dynMethod.CreateDelegate(typeof(InvokeDelegate));
         }
     }
     catch (Exception ex)
     {
         throw new CallTargetInvokerException(ex);
     }
     finally
     {
         if (_invokeDelegate is null)
         {
             _invokeDelegate = (instance, arguments) => CallTargetState.GetDefault();
         }
     }
 }
 static BeginMethodHandler()
 {
     try
     {
         DynamicMethod dynMethod = IntegrationMapper.CreateBeginMethodDelegate(typeof(TIntegration), typeof(TTarget), new[] { typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4) });
         if (dynMethod != null)
         {
             _invokeDelegate = (InvokeDelegate)dynMethod.CreateDelegate(typeof(InvokeDelegate));
         }
     }
     catch (Exception ex)
     {
         throw new CallTargetInvokerException(ex);
     }
     finally
     {
         if (_invokeDelegate is null)
         {
             _invokeDelegate = (instance, arg1, arg2, arg3, arg4) => CallTargetState.GetDefault();
         }
     }
 }
Exemple #11
0
        /// <summary>
        /// OnMethodBegin callback
        /// </summary>
        /// <typeparam name="TTarget">Type of the target</typeparam>
        /// <param name="instance">Instance value, aka `this` of the instrumented method.</param>
        /// <param name="callback">The AsyncCallback delegate</param>
        /// <param name="state">An object containing state information for this asynchronous request</param>
        /// <returns>Calltarget state value</returns>
        internal static CallTargetState OnMethodBegin <TTarget>(TTarget instance, AsyncCallback callback, object state)
        {
            if (instance is HttpWebRequest request && WebRequestCommon.IsTracingEnabled(request))
            {
                var tracer = Tracer.Instance;

                // We may have already set headers
                if (request.Headers.Get(HttpHeaderNames.TraceId) is null)
                {
                    var span = ScopeFactory.CreateInactiveOutboundHttpSpan(tracer, request.Method, request.RequestUri, WebRequestCommon.IntegrationId, out _, traceId: null, spanId: null, startTime: null, addToTraceContext: false);

                    if (span?.Context != null)
                    {
                        // Add distributed tracing headers to the HTTP request.
                        // We don't want to set an active scope now, because it's possible that EndGetResponse will never be called.
                        // Instead, we generate a spancontext and inject it in the headers. EndGetResponse will fetch them and create an active scope with the right id.
                        SpanContextPropagator.Instance.Inject(span.Context, request.Headers.Wrap());
                    }
                }
            }

            return(CallTargetState.GetDefault());
        }
Exemple #12
0
 static BeginMethodHandler()
 {
     try
     {
         Type          tArg1ByRef = typeof(TArg1).IsByRef ? typeof(TArg1) : typeof(TArg1).MakeByRefType();
         DynamicMethod dynMethod  = IntegrationMapper.CreateBeginMethodDelegate(typeof(TIntegration), typeof(TTarget), new[] { tArg1ByRef });
         if (dynMethod != null)
         {
             _invokeDelegate = (InvokeDelegate)dynMethod.CreateDelegate(typeof(InvokeDelegate));
         }
     }
     catch (Exception ex)
     {
         throw new CallTargetInvokerException(ex);
     }
     finally
     {
         if (_invokeDelegate is null)
         {
             _invokeDelegate = (TTarget instance, ref TArg1 arg1) => CallTargetState.GetDefault();
         }
     }
 }
        /// <summary>
        /// OnMethodBegin callback
        /// </summary>
        /// <typeparam name="TTarget">Type of the target</typeparam>
        /// <param name="instance">Instance value, aka `this` of the instrumented method.</param>
        /// <returns>Calltarget state value</returns>
        internal static CallTargetState OnMethodBegin <TTarget>(TTarget instance)
        {
            if (instance is HttpWebRequest request && WebRequestCommon.IsTracingEnabled(request))
            {
                var tracer = Tracer.Instance;

                if (tracer.Settings.IsIntegrationEnabled(WebRequestCommon.IntegrationId))
                {
                    var span = ScopeFactory.CreateInactiveOutboundHttpSpan(tracer, request.Method, request.RequestUri, WebRequestCommon.IntegrationId, out _, traceId: null, spanId: null, startTime: null, addToTraceContext: false);

                    if (span?.Context != null)
                    {
                        // Add distributed tracing headers to the HTTP request.
                        // The expected sequence of calls is GetRequestStream -> GetResponse. Headers can't be modified after calling GetRequestStream.
                        // At the same time, we don't want to set an active scope now, because it's possible that GetResponse will never be called.
                        // Instead, we generate a spancontext and inject it in the headers. GetResponse will fetch them and create an active scope with the right id.
                        SpanContextPropagator.Instance.Inject(span.Context, request.Headers.Wrap());
                    }
                }
            }

            return(CallTargetState.GetDefault());
        }
Exemple #14
0
        /// <summary>
        /// OnMethodBegin callback
        /// </summary>
        /// <typeparam name="TTarget">Type of the target</typeparam>
        /// <typeparam name="TSendMessageBatchRequest">Type of the request object</typeparam>
        /// <param name="instance">Instance value, aka `this` of the instrumented method</param>
        /// <param name="request">The request for the SQS operation</param>
        /// <param name="cancellationToken">CancellationToken value</param>
        /// <returns>Calltarget state value</returns>
        internal static CallTargetState OnMethodBegin <TTarget, TSendMessageBatchRequest>(TTarget instance, TSendMessageBatchRequest request, CancellationToken cancellationToken)
        {
            if (request is null)
            {
                return(CallTargetState.GetDefault());
            }

            var requestProxy = request.DuckCast <ISendMessageBatchRequest>();

            var scope = AwsSqsCommon.CreateScope(Tracer.Instance, Operation, out AwsSqsTags tags);

            tags.QueueUrl = requestProxy.QueueUrl;

            if (scope?.Span?.Context != null && requestProxy.Entries.Count > 0)
            {
                for (int i = 0; i < requestProxy.Entries.Count; i++)
                {
                    var entry = requestProxy.Entries[i].DuckCast <IContainsMessageAttributes>();
                    ContextPropagation.InjectHeadersIntoMessage <TSendMessageBatchRequest>(entry, scope.Span.Context);
                }
            }

            return(new CallTargetState(scope));
        }
        internal static CallTargetState CommonOnMethodBegin <TOperation>(TOperation tOperation)
        {
            if (!Tracer.Instance.Settings.IsIntegrationEnabled(IntegrationId) || tOperation == null)
            {
                // integration disabled, don't create a scope, skip this trace
                return(CallTargetState.GetDefault());
            }

            var operation = tOperation.DuckCast <OperationStruct>();

            var host = operation.CurrentHost?.Address?.ToString();
            var port = operation.CurrentHost?.Port.ToString();
            var code = operation.OperationCode.ToString();

            var tags = new CouchbaseTags()
            {
                OperationCode = code,
                Key           = operation.Key,
                Host          = host,
                Port          = port
            };

            return(CommonOnMethodBegin(tags));
        }
        /// <summary>
        /// OnMethodBegin callback
        /// </summary>
        /// <typeparam name="TTarget">Type of the target</typeparam>
        /// <typeparam name="TKey">Type of the message key</typeparam>
        /// <typeparam name="TValue">Type of the message value</typeparam>
        /// <typeparam name="TActionOfDeliveryReport">Type of the delivery report</typeparam>
        /// <param name="instance">Instance value, aka `this` of the instrumented method.</param>
        /// <param name="topic">The topic to which the message was sent</param>
        /// <param name="key">The message key value</param>
        /// <param name="value">The message value</param>
        /// <param name="handler">The delivery handler instance</param>
        /// <returns>Calltarget state value</returns>
        public static CallTargetState OnMethodBegin <TTarget, TKey, TValue, TActionOfDeliveryReport>(TTarget instance, string topic, TKey key, TValue value, TActionOfDeliveryReport handler)
        {
            if (handler is null)
            {
                // Handled in KafkaProduceSyncIntegration
                return(CallTargetState.GetDefault());
            }

            try
            {
                var agent = Agent.Instance;

                // The current span should be started in KafkaProduceSyncIntegration.OnMethodBegin
                // The OnMethodBegin and OnMethodEnd of this integration happens between KafkaProduceSyncIntegration.OnMethodBegin
                // and KafkaProduceSyncIntegration.OnMethodEnd, so the consumer span is active for the duration of this integration
                var span = agent.Tracer.CurrentSpan;
                // span may be null when the Produce call is to an ignored topic.
                if (span is null)
                {
                    return(CallTargetState.GetDefault());
                }

                var newAction = CachedWrapperDelegate <TActionOfDeliveryReport> .CreateWrapper(handler, span);

                Action <ITypedDeliveryHandlerShimAction> updateHandlerAction = inst => inst.Handler = newAction;

                // store the call to update the handler variable as state
                // so we update it at the _end_ of the constructor
                return(new CallTargetState(span, updateHandlerAction));
            }
            catch (Exception ex)
            {
                Agent.Instance.Logger.Error()?.LogException(ex, "Error creating wrapped delegate for delivery report");
                return(CallTargetState.GetDefault());
            }
        }
        /// <summary>
        /// OnMethodBegin callback
        /// </summary>
        /// <typeparam name="TTarget">Type of the target</typeparam>
        /// <typeparam name="TContext">Controller context</typeparam>
        /// <param name="instance">Instance value, aka `this` of the instrumented method.</param>
        /// <param name="controllerContext">The context of the controller</param>
        /// <param name="actionName">Name of the action</param>
        /// <param name="callback">Async callback</param>
        /// <param name="state">The state of the method</param>
        /// <returns>Calltarget state value</returns>
        public static CallTargetState OnMethodBegin <TTarget, TContext>(TTarget instance, TContext controllerContext, string actionName, AsyncCallback callback, object state)
        {
            Scope scope = null;

            try
            {
                if (HttpContext.Current != null)
                {
                    scope = AspNetMvcIntegration.CreateScope(controllerContext.DuckCast <ControllerContextStruct>());
                    HttpContext.Current.Items[AspNetMvcIntegration.HttpContextKey] = scope;
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Error instrumenting method {MethodName}", "System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction()");
            }

            if (scope == null)
            {
                return(CallTargetState.GetDefault());
            }

            return(new CallTargetState(scope));
        }
        /// <summary>
        /// OnMethodBegin callback
        /// </summary>
        /// <typeparam name="TTarget">Type of the target</typeparam>
        /// <typeparam name="TCollection">Type of the collection</typeparam>
        /// <typeparam name="TFunc">Type of the </typeparam>
        /// <param name="instance">Instance value, aka `this` of the instrumented method. This method is static so this parameter will always be null</param>
        /// <param name="methods">The methods to be invoked</param>
        /// <param name="setHostingEnvironmentCultures">The function to set the environment culture</param>
        /// <returns>Calltarget state value</returns>
        public static CallTargetState OnMethodBegin <TTarget, TCollection, TFunc>(TTarget instance, TCollection methods, TFunc setHostingEnvironmentCultures)
        {
            if (Interlocked.Exchange(ref FirstInitialization, 0) != 1)
            {
                // The HttpModule was already registered
                return(CallTargetState.GetDefault());
            }

            try
            {
// directive applied just to here and to .NET framework specific using directives, to allow
// the integrations file generator to pick this integration up, irrespective of version.
#if NETFRAMEWORK
                HttpApplication.RegisterModule(typeof(ElasticApmModule));
#endif
            }
            catch
            {
                // Unable to dynamically register module
                // Not sure if we can technically log yet or not, so do nothing
            }

            return(CallTargetState.GetDefault());
        }
Exemple #19
0
 /// <summary>
 /// OnMethodBegin callback
 /// </summary>
 /// <typeparam name="TTarget">Type of the target</typeparam>
 /// <param name="instance">Instance value, aka `this` of the instrumented method.</param>
 /// <param name="millisecondsTimeout">The maximum period of time the call may block.</param>
 /// <returns>Calltarget state value</returns>
 internal static CallTargetState OnMethodBegin <TTarget>(TTarget instance, int millisecondsTimeout)
 {
     // If we are already in a consumer scope, close it, and start a new one on method exit.
     KafkaHelper.CloseConsumerScope(Tracer.Instance);
     return(CallTargetState.GetDefault());
 }
Exemple #20
0
 /// <summary>
 /// OnMethodBegin callback
 /// </summary>
 /// <typeparam name="TTarget">Type of the target</typeparam>
 /// <param name="instance">Instance value, aka `this` of the instrumented method.</param>
 /// <returns>Calltarget state value</returns>
 public static CallTargetState OnMethodBegin <TTarget>(TTarget instance)
 {
     // If we are already in a consumer scope, close it.
     KafkaIntegration.CloseConsumerTransaction(Agent.Instance);
     return(CallTargetState.GetDefault());
 }
        /// <summary>
        /// OnMethodBegin callback
        /// </summary>
        /// <typeparam name="TTarget">Type of the target</typeparam>
        /// <param name="instance">Instance value, aka `this` of the instrumented method.</param>
        /// <returns>Calltarget state value</returns>
        public static CallTargetState OnMethodBegin <TTarget>(TTarget instance)
            where TTarget : ITestMethodRunner, IDuckType
        {
            if (!Tracer.Instance.Settings.IsIntegrationEnabled(IntegrationId))
            {
                return(CallTargetState.GetDefault());
            }

            ITestMethod testMethodInfo = instance.TestMethodInfo;
            MethodInfo  testMethod     = testMethodInfo.MethodInfo;

            object[] testMethodArguments = testMethodInfo.Arguments;

            string testFramework = "MSTestV2 " + instance.Type.Assembly.GetName().Version;
            string testSuite     = testMethodInfo.TestClassName;
            string testName      = testMethodInfo.TestMethodName;

            Tracer tracer = Tracer.Instance;
            Scope  scope  = tracer.StartActive("mstest.test");
            Span   span   = scope.Span;

            span.Type = SpanTypes.Test;
            span.SetTraceSamplingPriority(SamplingPriority.AutoKeep);
            span.ResourceName = $"{testSuite}.{testName}";
            span.SetTag(TestTags.Suite, testSuite);
            span.SetTag(TestTags.Name, testName);
            span.SetTag(TestTags.Framework, testFramework);
            span.SetTag(TestTags.Type, TestTags.TypeTest);
            CIEnvironmentValues.DecorateSpan(span);

            var framework = FrameworkDescription.Instance;

            span.SetTag(CommonTags.RuntimeName, framework.Name);
            span.SetTag(CommonTags.RuntimeOSArchitecture, framework.OSArchitecture);
            span.SetTag(CommonTags.RuntimeOSPlatform, framework.OSPlatform);
            span.SetTag(CommonTags.RuntimeProcessArchitecture, framework.ProcessArchitecture);
            span.SetTag(CommonTags.RuntimeVersion, framework.ProductVersion);

            // Get test parameters
            ParameterInfo[] methodParameters = testMethod.GetParameters();
            if (methodParameters?.Length > 0)
            {
                for (int i = 0; i < methodParameters.Length; i++)
                {
                    if (testMethodArguments != null && i < testMethodArguments.Length)
                    {
                        span.SetTag($"{TestTags.Arguments}.{methodParameters[i].Name}", testMethodArguments[i]?.ToString() ?? "(null)");
                    }
                    else
                    {
                        span.SetTag($"{TestTags.Arguments}.{methodParameters[i].Name}", "(default)");
                    }
                }
            }

            // Get traits
            Dictionary <string, List <string> > testTraits = GetTraits(testMethod);

            if (testTraits != null)
            {
                foreach (KeyValuePair <string, List <string> > keyValuePair in testTraits)
                {
                    span.SetTag($"{TestTags.Traits}.{keyValuePair.Key}", string.Join(", ", keyValuePair.Value) ?? "(null)");
                }
            }

            span.ResetStartTime();
            return(new CallTargetState(scope));
        }
Exemple #22
0
 /// <summary>
 /// OnMethodBegin callback
 /// </summary>
 /// <typeparam name="TTarget">Type of the target</typeparam>
 /// <param name="instance">Instance value, aka `this` of the instrumented method.</param>
 /// <param name="millisecondsTimeout">The maximum period of time the call may block.</param>
 /// <returns>Calltarget state value</returns>
 public static CallTargetState OnMethodBegin <TTarget>(TTarget instance, int millisecondsTimeout)
 {
     // If we are already in a consumer scope, close it, and start a new one on method exit.
     KafkaIntegration.CloseConsumerTransaction(Agent.Instance);
     return(CallTargetState.GetDefault());
 }
Exemple #23
0
 /// <summary>
 /// OnMethodBegin callback
 /// </summary>
 /// <typeparam name="TTarget">Type of the target</typeparam>
 /// <param name="instance">Instance value, aka `this` of the instrumented method.</param>
 /// <returns>Calltarget state value</returns>
 public static CallTargetState OnMethodBegin <TTarget>(TTarget instance)
 {
     return(CallTargetState.GetDefault());
 }
Exemple #24
0
        public async Task ExceptionGenericTest()
        {
            Exception ex = null;

            // Normal
            ex = await Assert.ThrowsAsync <CustomException>(() => GetPreviousTask().AsTask());

            Assert.Equal("Internal Test Exception", ex.Message);

            // Using the continuation
            var tcg = new ValueTaskContinuationGenerator <ValueTaskContinuationGeneratorTests, ValueTaskContinuationGeneratorTests, ValueTask <bool>, bool>();

            ex = await Assert.ThrowsAsync <CustomException>(() => tcg.SetContinuation(this, GetPreviousTask(), null, CallTargetState.GetDefault()).AsTask());

            Assert.Equal("Internal Test Exception", ex.Message);

            async ValueTask <bool> GetPreviousTask()
            {
                await Task.Delay(1000).ConfigureAwait(false);

                throw new CustomException("Internal Test Exception");
            }
        }
Exemple #25
0
 /// <summary>
 /// OnMethodBegin callback
 /// </summary>
 /// <typeparam name="TTarget">Type of the target</typeparam>
 /// <typeparam name="TTestMethod">Type of the ITestMethod</typeparam>
 /// <param name="instance">Instance value, aka `this` of the instrumented method.</param>
 /// <param name="testMethod">Test method instance</param>
 /// <returns>Calltarget state value</returns>
 public static CallTargetState OnMethodBegin <TTarget, TTestMethod>(TTarget instance, TTestMethod testMethod)
 {
     return(CallTargetState.GetDefault());
 }
Exemple #26
0
 static BeginMethodHandler()
 {
     try
     {
         Type          tArg1ByRef = typeof(TArg1).IsByRef ? typeof(TArg1) : typeof(TArg1).MakeByRefType();
         Type          tArg2ByRef = typeof(TArg2).IsByRef ? typeof(TArg2) : typeof(TArg2).MakeByRefType();
         Type          tArg3ByRef = typeof(TArg3).IsByRef ? typeof(TArg3) : typeof(TArg3).MakeByRefType();
         Type          tArg4ByRef = typeof(TArg4).IsByRef ? typeof(TArg4) : typeof(TArg4).MakeByRefType();
         Type          tArg5ByRef = typeof(TArg5).IsByRef ? typeof(TArg5) : typeof(TArg5).MakeByRefType();
         Type          tArg6ByRef = typeof(TArg6).IsByRef ? typeof(TArg6) : typeof(TArg6).MakeByRefType();
         Type          tArg7ByRef = typeof(TArg7).IsByRef ? typeof(TArg7) : typeof(TArg7).MakeByRefType();
         Type          tArg8ByRef = typeof(TArg8).IsByRef ? typeof(TArg8) : typeof(TArg8).MakeByRefType();
         DynamicMethod dynMethod  = IntegrationMapper.CreateBeginMethodDelegate(typeof(TIntegration), typeof(TTarget), new[] { tArg1ByRef, tArg2ByRef, tArg3ByRef, tArg4ByRef, tArg5ByRef, tArg6ByRef, tArg7ByRef, tArg8ByRef });
         if (dynMethod != null)
         {
             _invokeDelegate = (InvokeDelegate)dynMethod.CreateDelegate(typeof(InvokeDelegate));
         }
     }
     catch (Exception ex)
     {
         throw new CallTargetInvokerException(ex);
     }
     finally
     {
         if (_invokeDelegate is null)
         {
             _invokeDelegate = (TTarget instance, ref TArg1 arg1, ref TArg2 arg2, ref TArg3 arg3, ref TArg4 arg4, ref TArg5 arg5, ref TArg6 arg6, ref TArg7 arg7, ref TArg8 arg8) => CallTargetState.GetDefault();
         }
     }
 }
        /// <summary>
        /// OnMethodBegin callback
        /// </summary>
        /// <typeparam name="TTarget">Type of the target</typeparam>
        /// <param name="instance">Instance value, aka `this` of the instrumented method.</param>
        /// <returns>Calltarget state value</returns>
        public static CallTargetState OnMethodBegin <TTarget>(TTarget instance)
            where TTarget : ITestMethodRunner, IDuckType
        {
            if (!Common.TestTracer.Settings.IsIntegrationEnabled(IntegrationId))
            {
                return(CallTargetState.GetDefault());
            }

            ITestMethod testMethodInfo = instance.TestMethodInfo;
            MethodInfo  testMethod     = testMethodInfo.MethodInfo;

            object[] testMethodArguments = testMethodInfo.Arguments;

            string testFramework = "MSTestV2 " + instance.Type.Assembly.GetName().Version;
            string testSuite     = testMethodInfo.TestClassName;
            string testName      = testMethodInfo.TestMethodName;

            Scope scope = Common.TestTracer.StartActive("mstest.test", serviceName: Common.ServiceName);
            Span  span  = scope.Span;

            span.Type = SpanTypes.Test;
            span.SetTraceSamplingPriority(SamplingPriority.AutoKeep);
            span.ResourceName = $"{testSuite}.{testName}";
            span.SetTag(TestTags.Suite, testSuite);
            span.SetTag(TestTags.Name, testName);
            span.SetTag(TestTags.Framework, testFramework);
            span.SetTag(TestTags.Type, TestTags.TypeTest);
            CIEnvironmentValues.DecorateSpan(span);

            var framework = FrameworkDescription.Instance;

            span.SetTag(CommonTags.RuntimeName, framework.Name);
            span.SetTag(CommonTags.RuntimeVersion, framework.ProductVersion);
            span.SetTag(CommonTags.RuntimeArchitecture, framework.ProcessArchitecture);
            span.SetTag(CommonTags.OSArchitecture, framework.OSArchitecture);
            span.SetTag(CommonTags.OSPlatform, framework.OSPlatform);
            span.SetTag(CommonTags.OSVersion, Environment.OSVersion.VersionString);

            // Get test parameters
            ParameterInfo[] methodParameters = testMethod.GetParameters();
            if (methodParameters?.Length > 0)
            {
                TestParameters testParameters = new TestParameters();
                testParameters.Metadata  = new Dictionary <string, object>();
                testParameters.Arguments = new Dictionary <string, object>();

                for (int i = 0; i < methodParameters.Length; i++)
                {
                    if (testMethodArguments != null && i < testMethodArguments.Length)
                    {
                        testParameters.Arguments[methodParameters[i].Name] = testMethodArguments[i]?.ToString() ?? "(null)";
                    }
                    else
                    {
                        testParameters.Arguments[methodParameters[i].Name] = "(default)";
                    }
                }

                span.SetTag(TestTags.Parameters, testParameters.ToJSON());
            }

            // Get traits
            Dictionary <string, List <string> > testTraits = GetTraits(testMethod);

            if (testTraits != null && testTraits.Count > 0)
            {
                span.SetTag(TestTags.Traits, Datadog.Trace.Vendors.Newtonsoft.Json.JsonConvert.SerializeObject(testTraits));
            }

            span.ResetStartTime();
            return(new CallTargetState(scope));
        }
        private static CallTargetState CreateCosmosDbCallState <TTarget, TQueryDefinition>(TTarget instance, TQueryDefinition queryDefinition, string containerId, string databaseId, string endpoint)
        {
            if (!Tracer.Instance.Settings.IsIntegrationEnabled(IntegrationId))
            {
                // integration disabled, don't create a scope, skip this trace
                return(CallTargetState.GetDefault());
            }

            try
            {
                string query;
                if (queryDefinition is string queryDefinitionString)
                {
                    query = queryDefinitionString;
                }
                else
                {
                    var success = queryDefinition.TryDuckCast <QueryDefinitionStruct>(out var queryDefinitionObj);
                    query = queryDefinitionObj.QueryText;
                }

                var tracer = Tracer.Instance;

                var parent = tracer.ActiveScope?.Span;

                if (parent != null &&
                    parent.Type == SpanTypes.Sql &&
                    parent.GetTag(Tags.DbType) == "cosmosdb" &&
                    parent.ResourceName == query)
                {
                    // we are already instrumenting this,
                    // don't instrument nested methods that belong to the same stacktrace
                    return(new CallTargetState(null));
                }

                var tags = new CosmosDbTags
                {
                    ContainerId = containerId,
                    DatabaseId  = databaseId,
                    Host        = endpoint,
                    DbType      = "cosmosdb",
                };

                tags.SetAnalyticsSampleRate(IntegrationId, tracer.Settings, enabledWithGlobalSetting: false);

                var serviceName = tracer.Settings.GetServiceName(tracer, ServiceName);
                var scope       = tracer.StartActiveInternal(OperationName, tags: tags, serviceName: serviceName);

                var span = scope.Span;

                span.ResourceName = query;
                span.Type         = SpanTypes.Sql;
                tracer.TracerManager.Telemetry.IntegrationGeneratedSpan(IntegrationId);

                return(new CallTargetState(scope));
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Error creating or populating scope.");
            }

            return(new CallTargetState(null));
        }
Exemple #29
0
 /// <summary>
 /// OnMethodBegin callback
 /// </summary>
 /// <typeparam name="TTarget">Type of the target</typeparam>
 /// <param name="instance">Instance value, aka `this` of the instrumented method.</param>
 /// <returns>Calltarget state value</returns>
 public static CallTargetState OnMethodBegin <TTarget>(TTarget instance)
 {
     // If we are already in a consumer scope, close it.
     KafkaHelper.CloseConsumerScope(Tracer.Instance);
     return(CallTargetState.GetDefault());
 }
Exemple #30
0
 /// <summary>
 /// OnMethodBegin callback
 /// </summary>
 /// <typeparam name="TTarget">Type of the target</typeparam>
 /// <typeparam name="TArg1">Type of the argument 1</typeparam>
 /// <typeparam name="TArg2">Type of the argument 2</typeparam>
 /// <typeparam name="TArg3">Type of the argument 3</typeparam>
 /// <typeparam name="TArg4">Type of the argument 4</typeparam>
 /// <typeparam name="TArg5">Type of the argument 5</typeparam>
 /// <typeparam name="TArg6">Type of the argument 6</typeparam>
 /// <param name="instance">Instance value, aka `this` of the instrumented method.</param>
 /// <param name="testCases">Test cases</param>
 /// <param name="testAssembly">Test assembly</param>
 /// <param name="executionTime">Execution time</param>
 /// <param name="testsRun">Test runs</param>
 /// <param name="testsFailed">Tests failed</param>
 /// <param name="testsSkipped">Tests skipped</param>
 /// <returns>Calltarget state value</returns>
 internal static CallTargetState OnMethodBegin <TTarget, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>(TTarget instance, TArg1 testCases, TArg2 testAssembly, TArg3 executionTime, TArg4 testsRun, TArg5 testsFailed, TArg6 testsSkipped)
 {
     Common.FlushSpans(XUnitIntegration.IntegrationId);
     return(CallTargetState.GetDefault());
 }