/// <summary>
        /// Common helper for all Begin Callbacks.
        /// </summary>
        /// <param name="thisObj">This object.</param>
        /// <param name="injectCorrelationHeaders">Flag that enables Request-Id and Correlation-Context headers injection.
        /// Should be set to true only for profiler and old versions of DiagnosticSource Http hook events.</param>
        /// <returns>Null object as all context is maintained in this class via weak tables.</returns>
        internal object OnBegin(object thisObj, bool injectCorrelationHeaders = true)
        {
            try
            {
                if (thisObj == null)
                {
                    DependencyCollectorEventSource.Log.NotExpectedCallback(0, "OnBeginHttp", "thisObj == null");
                    return(null);
                }

                WebRequest webRequest = thisObj as WebRequest;
                if (webRequest == null)
                {
                    DependencyCollectorEventSource.Log.UnexpectedCallbackParameter("WebRequest");
                }

                var url = GetUrl(webRequest);
                if (url == null)
                {
                    DependencyCollectorEventSource.Log.NotExpectedCallback(thisObj.GetHashCode(), "OnBeginHttp",
                                                                           "resourceName is empty");
                    return(null);
                }

                string httpMethod   = webRequest.Method;
                string resourceName = url.AbsolutePath;

                if (!string.IsNullOrEmpty(httpMethod))
                {
                    resourceName = httpMethod + " " + resourceName;
                }

                DependencyCollectorEventSource.Log.BeginCallbackCalled(thisObj.GetHashCode(), resourceName);

                if (this.applicationInsightsUrlFilter.IsApplicationInsightsUrl(url))
                {
                    // Not logging as we will be logging for all outbound AI calls
                    return(null);
                }

                if (webRequest.Headers[W3C.W3CConstants.TraceParentHeader] != null && Activity.DefaultIdFormat == ActivityIdFormat.W3C)
                {
                    DependencyCollectorEventSource.Log.HttpRequestAlreadyInstrumented();
                    return(null);
                }

                // If the object already exists, don't add again. This happens because either GetResponse or GetRequestStream could
                // be the starting point for the outbound call.
                DependencyTelemetry telemetry = null;
                var telemetryTuple            = this.GetTupleForWebDependencies(webRequest);
                if (telemetryTuple?.Item1 != null)
                {
                    DependencyCollectorEventSource.Log.TrackingAnExistingTelemetryItemVerbose();
                    return(null);
                }

                // Create and initialize a new telemetry object
                telemetry = ClientServerDependencyTracker.BeginTracking(this.telemetryClient);

                this.AddTupleForWebDependencies(webRequest, telemetry, false);

                if (string.IsNullOrEmpty(telemetry.Context.InstrumentationKey))
                {
                    // Instrumentation key is probably empty, because the context has not yet had a chance to associate the requestTelemetry to the telemetry client yet.
                    // and get they instrumentation key from all possible sources in the process. Let's do that now.
                    this.telemetryClient.InitializeInstrumentationKey(telemetry);
                }

                telemetry.Name   = resourceName;
                telemetry.Target = DependencyTargetNameHelper.GetDependencyTargetName(url);
                telemetry.Type   = RemoteDependencyConstants.HTTP;
                telemetry.Data   = url.OriginalString;
                telemetry.SetOperationDetail(RemoteDependencyConstants.HttpRequestOperationDetailName, webRequest);

                Activity currentActivity = Activity.Current;
                // Add the source instrumentation key header if collection is enabled, the request host is not in the excluded list and the same header doesn't already exist
                if (this.setCorrelationHeaders && !this.correlationDomainExclusionList.Contains(url.Host))
                {
                    string applicationId = null;
                    try
                    {
                        if (!string.IsNullOrEmpty(telemetry.Context.InstrumentationKey) &&
                            webRequest.Headers.GetNameValueHeaderValue(RequestResponseHeaders.RequestContextHeader,
                                                                       RequestResponseHeaders.RequestContextCorrelationSourceKey) == null &&
                            (this.configuration.ApplicationIdProvider?.TryGetApplicationId(
                                 telemetry.Context.InstrumentationKey, out applicationId) ?? false))
                        {
                            webRequest.Headers.SetNameValueHeaderValue(RequestResponseHeaders.RequestContextHeader,
                                                                       RequestResponseHeaders.RequestContextCorrelationSourceKey, applicationId);
                        }
                    }
                    catch (Exception ex)
                    {
                        AppMapCorrelationEventSource.Log.SetCrossComponentCorrelationHeaderFailed(
                            ex.ToInvariantString());
                    }

                    if (this.injectLegacyHeaders)
                    {
                        // Add the root ID
                        var rootId = telemetry.Context.Operation.Id;
                        if (!string.IsNullOrEmpty(rootId) &&
                            webRequest.Headers[RequestResponseHeaders.StandardRootIdHeader] == null)
                        {
                            webRequest.Headers.Add(RequestResponseHeaders.StandardRootIdHeader, rootId);
                        }

                        // Add the parent ID
                        var parentId = telemetry.Id;
                        if (!string.IsNullOrEmpty(parentId))
                        {
                            if (webRequest.Headers[RequestResponseHeaders.StandardParentIdHeader] == null)
                            {
                                webRequest.Headers.Add(RequestResponseHeaders.StandardParentIdHeader, parentId);
                            }
                        }
                    }

                    if (currentActivity != null)
                    {
                        // ApplicationInsights only needs to inject W3C, potentially Request-Id and Correlation-Context
                        // headers for profiler instrumentation.
                        // in case of Http Desktop DiagnosticSourceListener they are injected in
                        // DiagnosticSource (with the System.Net.Http.Desktop.HttpRequestOut.Start event)
                        if (injectCorrelationHeaders)
                        {
                            if (currentActivity.IdFormat == ActivityIdFormat.W3C)
                            {
                                if (webRequest.Headers[W3C.W3CConstants.TraceParentHeader] == null)
                                {
                                    webRequest.Headers.Add(W3C.W3CConstants.TraceParentHeader, currentActivity.Id);
                                }

                                if (webRequest.Headers[W3C.W3CConstants.TraceStateHeader] == null &&
                                    !string.IsNullOrEmpty(currentActivity.TraceStateString))
                                {
                                    webRequest.Headers.Add(W3C.W3CConstants.TraceStateHeader,
                                                           currentActivity.TraceStateString);
                                }
                            }
                            else
                            {
                                // Request-Id format
                                if (webRequest.Headers[RequestResponseHeaders.RequestIdHeader] == null)
                                {
                                    webRequest.Headers.Add(RequestResponseHeaders.RequestIdHeader, telemetry.Id);
                                }
                            }

                            InjectCorrelationContext(webRequest.Headers, currentActivity);
                        }
                    }
                }

                // Active bug in .NET Fx diagnostics hook: https://github.com/dotnet/corefx/pull/40777
                // Application Insights has to inject Request-Id to work it around
                if (currentActivity?.IdFormat == ActivityIdFormat.W3C)
                {
                    // if (this.injectRequestIdInW3CMode)
                    {
                        if (webRequest.Headers[RequestResponseHeaders.RequestIdHeader] == null)
                        {
                            webRequest.Headers.Add(RequestResponseHeaders.RequestIdHeader, string.Concat('|', telemetry.Context.Operation.Id, '.', telemetry.Id, '.'));
                        }
                    }
                }
            }
            catch (Exception exception)
            {
                DependencyCollectorEventSource.Log.CallbackError(thisObj == null ? 0 : thisObj.GetHashCode(),
                                                                 "OnBeginHttp", exception);
            }
            finally
            {
                Activity current = Activity.Current;
                if (current?.OperationName == ClientServerDependencyTracker.DependencyActivityName)
                {
                    current.Stop();
                }
            }

            return(null);
        }
Example #2
0
        //// netcoreapp 2.0 event

        /// <summary>
        /// Handler for Activity stop event (response is received for the outgoing request).
        /// </summary>
        internal void OnActivityStop(HttpResponseMessage response, HttpRequestMessage request, TaskStatus requestTaskStatus)
        {
            // Even though we have the IsEnabled filter to reject ApplicationInsights URLs before any events are fired, if there
            // are multiple subscribers and one subscriber returns true to IsEnabled then all subscribers will receive the event.
            if (this.applicationInsightsUrlFilter.IsApplicationInsightsUrl(request.RequestUri))
            {
                return;
            }

            Activity currentActivity = Activity.Current;

            if (currentActivity == null)
            {
                DependencyCollectorEventSource.Log.CurrentActivityIsNull(HttpOutStopEventName);
                return;
            }

            if (Activity.DefaultIdFormat == ActivityIdFormat.W3C &&
                request.Headers.TryGetValues(W3C.W3CConstants.TraceParentHeader, out var parents) &&
                parents.FirstOrDefault() != currentActivity.Id)
            {
                DependencyCollectorEventSource.Log.HttpRequestAlreadyInstrumented();
                return;
            }

            DependencyCollectorEventSource.Log.HttpCoreDiagnosticSourceListenerStop(currentActivity.Id);

            Uri requestUri   = request.RequestUri;
            var resourceName = request.Method.Method + " " + requestUri.AbsolutePath;

            DependencyTelemetry telemetry = new DependencyTelemetry();

            telemetry.SetOperationDetail(RemoteDependencyConstants.HttpRequestOperationDetailName, request);

            // properly fill dependency telemetry operation context: OperationCorrelationTelemetryInitializer initializes child telemetry
            if (currentActivity.IdFormat == ActivityIdFormat.W3C)
            {
                var traceId = currentActivity.TraceId.ToHexString();
                telemetry.Context.Operation.Id = traceId;
                if (currentActivity.ParentSpanId != default)
                {
                    telemetry.Context.Operation.ParentId = W3CUtilities.FormatTelemetryId(traceId, currentActivity.ParentSpanId.ToHexString());
                }

                telemetry.Id = W3CUtilities.FormatTelemetryId(traceId, currentActivity.SpanId.ToHexString());
            }
            else
            {
                telemetry.Context.Operation.Id       = currentActivity.RootId;
                telemetry.Context.Operation.ParentId = currentActivity.ParentId;
                telemetry.Id = currentActivity.Id;
            }

            foreach (var item in currentActivity.Baggage)
            {
                if (!telemetry.Properties.ContainsKey(item.Key))
                {
                    telemetry.Properties[item.Key] = item.Value;
                }
            }

            // TODO[tracestate]: remove, this is done in base SDK
            if (!string.IsNullOrEmpty(currentActivity.TraceStateString) && !telemetry.Properties.ContainsKey(W3CConstants.TracestatePropertyKey))
            {
                telemetry.Properties.Add(W3CConstants.TracestatePropertyKey, currentActivity.TraceStateString);
            }

            this.client.Initialize(telemetry);

            // If we started auxiliary Activity before to override the Id with W3C compatible one,
            // now it's time to set end time on it
            if (currentActivity.Duration == TimeSpan.Zero)
            {
                currentActivity.SetEndTime(DateTime.UtcNow);
            }

            telemetry.Timestamp = currentActivity.StartTimeUtc;
            telemetry.Name      = resourceName;
            telemetry.Target    = DependencyTargetNameHelper.GetDependencyTargetName(requestUri);
            telemetry.Type      = RemoteDependencyConstants.HTTP;
            telemetry.Data      = requestUri.OriginalString;
            telemetry.Duration  = currentActivity.Duration;
            if (response != null)
            {
                this.ParseResponse(response, telemetry);
                telemetry.SetOperationDetail(RemoteDependencyConstants.HttpResponseOperationDetailName, response);
            }
            else
            {
                if (this.pendingExceptions.TryRemove(currentActivity.Id, out Exception exception))
                {
                    telemetry.Properties[RemoteDependencyConstants.DependencyErrorPropertyKey] = exception.GetBaseException().Message;
                }

                telemetry.ResultCode = requestTaskStatus.ToString();
                telemetry.Success    = false;
            }

            this.client.TrackDependency(telemetry);
        }
        private void BeforeExecuteHelper(KeyValuePair <string, object> evnt,
                                         PropertyFetcher operationIdFetcher,
                                         PropertyFetcher commandFetcher,
                                         PropertyFetcher commandTextFetcher,
                                         PropertyFetcher connectionFetcher,
                                         PropertyFetcher dataSourceFetcher,
                                         PropertyFetcher databaseFetcher,
                                         PropertyFetcher commandTypeFetcher,
                                         PropertyFetcher timeStampFetcher)
        {
            var fet         = CommandBefore.OperationId;
            var operationId = (Guid)operationIdFetcher.Fetch(evnt.Value);

            DependencyCollectorEventSource.Log.SqlClientDiagnosticSubscriberCallbackCalled(operationId, evnt.Key);

            var command = commandFetcher.Fetch(evnt.Value);

            if (this.operationHolder.Get(command) == null)
            {
                var dependencyName = string.Empty;
                var target         = string.Empty;

                var commandText = (string)commandTextFetcher.Fetch(command);
                var con         = connectionFetcher.Fetch(command);
                if (con != null)
                {
                    var dataSource = dataSourceFetcher.Fetch(con);
                    var database   = databaseFetcher.Fetch(con);
                    target = string.Join(" | ", dataSource, database);

                    // https://docs.microsoft.com/dotnet/api/system.data.commandtype
                    // 4 indicate StoredProcedure
                    var commandName = (int)commandTypeFetcher.Fetch(command) == 4
                        ? commandText
                        : string.Empty;

                    dependencyName = string.IsNullOrEmpty(commandName)
                        ? string.Join(" | ", dataSource, database)
                        : string.Join(" | ", dataSource, database, commandName);
                }

                var timestamp = timeStampFetcher.Fetch(evnt.Value) as long?
                                ?? Stopwatch.GetTimestamp(); // TODO corefx#20748 - timestamp missing from event data

                var telemetry = new DependencyTelemetry()
                {
                    Id      = operationId.ToStringInvariant("N"),
                    Name    = dependencyName,
                    Type    = RemoteDependencyConstants.SQL,
                    Target  = target,
                    Data    = commandText,
                    Success = true,
                };

                // Populate the operation details for initializers
                telemetry.SetOperationDetail(RemoteDependencyConstants.SqlCommandOperationDetailName, command);

                InitializeTelemetry(telemetry, operationId, timestamp);

                this.operationHolder.Store(command, Tuple.Create(telemetry, /* isCustomCreated: */ false));
            }
            else
            {
                DependencyCollectorEventSource.Log.TrackingAnExistingTelemetryItemVerbose();
            }
        }
Example #4
0
        void IObserver <KeyValuePair <string, object> > .OnNext(KeyValuePair <string, object> evnt)
        {
            try
            {
                switch (evnt.Key)
                {
                case SqlBeforeExecuteCommand:
                {
                    var operationId = (Guid)CommandBefore.OperationId.Fetch(evnt.Value);

                    DependencyCollectorEventSource.Log.SqlClientDiagnosticSubscriberCallbackCalled(operationId, evnt.Key);

                    var command = (SqlCommand)CommandBefore.Command.Fetch(evnt.Value);

                    if (this.operationHolder.Get(command) == null)
                    {
                        var           dependencyName = string.Empty;
                        var           target         = string.Empty;
                        SqlConnection connection     = null;

                        if (command.Connection != null)
                        {
                            connection = command.Connection;
                            target     = string.Join(" | ", connection.DataSource, connection.Database);

                            var commandName = command.CommandType == CommandType.StoredProcedure
                                    ? command.CommandText
                                    : string.Empty;

                            dependencyName = string.IsNullOrEmpty(commandName)
                                    ? string.Join(" | ", connection.DataSource, connection.Database)
                                    : string.Join(" | ", connection.DataSource, connection.Database, commandName);
                        }

                        var timestamp = CommandBefore.Timestamp.Fetch(evnt.Value) as long?
                                        ?? Stopwatch.GetTimestamp(); // TODO corefx#20748 - timestamp missing from event data

                        var telemetry = new DependencyTelemetry()
                        {
                            Id      = operationId.ToString("N"),
                            Name    = dependencyName,
                            Type    = RemoteDependencyConstants.SQL,
                            Target  = target,
                            Data    = command.CommandText,
                            Success = true
                        };

                        // Populate the operation details for intializers
                        telemetry.SetOperationDetail(RemoteDependencyConstants.SqlCommandOperationDetailName, command);

                        InitializeTelemetry(telemetry, operationId, timestamp);

                        this.operationHolder.Store(command, Tuple.Create(telemetry, /* isCustomCreated: */ false));
                    }
                    else
                    {
                        DependencyCollectorEventSource.Log.TrackingAnExistingTelemetryItemVerbose();
                    }

                    break;
                }

                case SqlAfterExecuteCommand:
                {
                    var operationId = (Guid)CommandAfter.OperationId.Fetch(evnt.Value);

                    DependencyCollectorEventSource.Log.SqlClientDiagnosticSubscriberCallbackCalled(operationId, evnt.Key);

                    var command = (SqlCommand)CommandAfter.Command.Fetch(evnt.Value);
                    var tuple   = this.operationHolder.Get(command);

                    if (tuple != null)
                    {
                        this.operationHolder.Remove(command);

                        var telemetry = tuple.Item1;

                        var timestamp = (long)CommandAfter.Timestamp.Fetch(evnt.Value);

                        telemetry.Stop(timestamp);

                        this.client.TrackDependency(telemetry);
                    }
                    else
                    {
                        DependencyCollectorEventSource.Log.EndCallbackWithNoBegin(operationId.ToString("N"));
                    }

                    break;
                }

                case SqlErrorExecuteCommand:
                {
                    var operationId = (Guid)CommandError.OperationId.Fetch(evnt.Value);

                    DependencyCollectorEventSource.Log.SqlClientDiagnosticSubscriberCallbackCalled(operationId, evnt.Key);

                    var command = (SqlCommand)CommandError.Command.Fetch(evnt.Value);
                    var tuple   = this.operationHolder.Get(command);

                    if (tuple != null)
                    {
                        this.operationHolder.Remove(command);

                        var telemetry = tuple.Item1;

                        var timestamp = (long)CommandError.Timestamp.Fetch(evnt.Value);

                        telemetry.Stop(timestamp);

                        var exception = (Exception)CommandError.Exception.Fetch(evnt.Value);

                        ConfigureExceptionTelemetry(telemetry, exception);

                        this.client.TrackDependency(telemetry);
                    }
                    else
                    {
                        DependencyCollectorEventSource.Log.EndCallbackWithNoBegin(operationId.ToString("N"));
                    }

                    break;
                }

                case SqlBeforeOpenConnection:
                {
                    var operationId = (Guid)ConnectionBefore.OperationId.Fetch(evnt.Value);

                    DependencyCollectorEventSource.Log.SqlClientDiagnosticSubscriberCallbackCalled(operationId, evnt.Key);

                    var connection = (SqlConnection)ConnectionBefore.Connection.Fetch(evnt.Value);

                    if (this.operationHolder.Get(connection) == null)
                    {
                        var operation = (string)ConnectionBefore.Operation.Fetch(evnt.Value);
                        var timestamp = (long)ConnectionBefore.Timestamp.Fetch(evnt.Value);

                        var telemetry = new DependencyTelemetry()
                        {
                            Id      = operationId.ToString("N"),
                            Name    = string.Join(" | ", connection.DataSource, connection.Database, operation),
                            Type    = RemoteDependencyConstants.SQL,
                            Target  = string.Join(" | ", connection.DataSource, connection.Database),
                            Data    = operation,
                            Success = true
                        };

                        InitializeTelemetry(telemetry, operationId, timestamp);

                        this.operationHolder.Store(connection, Tuple.Create(telemetry, /* isCustomCreated: */ false));
                    }
                    else
                    {
                        DependencyCollectorEventSource.Log.TrackingAnExistingTelemetryItemVerbose();
                    }

                    break;
                }

                case SqlAfterOpenConnection:
                {
                    var operationId = (Guid)ConnectionAfter.OperationId.Fetch(evnt.Value);

                    DependencyCollectorEventSource.Log.SqlClientDiagnosticSubscriberCallbackCalled(operationId, evnt.Key);

                    var connection = (SqlConnection)ConnectionAfter.Connection.Fetch(evnt.Value);
                    var tuple      = this.operationHolder.Get(connection);

                    if (tuple != null)
                    {
                        this.operationHolder.Remove(connection);
                    }
                    else
                    {
                        DependencyCollectorEventSource.Log.EndCallbackWithNoBegin(operationId.ToString("N"));
                    }

                    break;
                }

                case SqlErrorOpenConnection:
                {
                    var operationId = (Guid)ConnectionError.OperationId.Fetch(evnt.Value);

                    DependencyCollectorEventSource.Log.SqlClientDiagnosticSubscriberCallbackCalled(operationId, evnt.Key);

                    var connection = (SqlConnection)ConnectionError.Connection.Fetch(evnt.Value);
                    var tuple      = this.operationHolder.Get(connection);

                    if (tuple != null)
                    {
                        this.operationHolder.Remove(connection);

                        var telemetry = tuple.Item1;

                        var timestamp = (long)ConnectionError.Timestamp.Fetch(evnt.Value);

                        telemetry.Stop(timestamp);

                        var exception = (Exception)ConnectionError.Exception.Fetch(evnt.Value);

                        ConfigureExceptionTelemetry(telemetry, exception);

                        this.client.TrackDependency(telemetry);
                    }
                    else
                    {
                        DependencyCollectorEventSource.Log.EndCallbackWithNoBegin(operationId.ToString("N"));
                    }

                    break;
                }

                case SqlBeforeCommitTransaction:
                {
                    var operationId = (Guid)TransactionCommitBefore.OperationId.Fetch(evnt.Value);

                    DependencyCollectorEventSource.Log.SqlClientDiagnosticSubscriberCallbackCalled(operationId, evnt.Key);

                    var connection = (SqlConnection)TransactionCommitBefore.Connection.Fetch(evnt.Value);

                    if (this.operationHolder.Get(connection) == null)
                    {
                        var operation      = (string)TransactionCommitBefore.Operation.Fetch(evnt.Value);
                        var timestamp      = (long)TransactionCommitBefore.Timestamp.Fetch(evnt.Value);
                        var isolationLevel = (IsolationLevel)TransactionCommitBefore.IsolationLevel.Fetch(evnt.Value);

                        var telemetry = new DependencyTelemetry()
                        {
                            Id      = operationId.ToString("N"),
                            Name    = string.Join(" | ", connection.DataSource, connection.Database, operation, isolationLevel),
                            Type    = RemoteDependencyConstants.SQL,
                            Target  = string.Join(" | ", connection.DataSource, connection.Database),
                            Data    = operation,
                            Success = true
                        };

                        InitializeTelemetry(telemetry, operationId, timestamp);

                        this.operationHolder.Store(connection, Tuple.Create(telemetry, /* isCustomCreated: */ false));
                    }
                    else
                    {
                        DependencyCollectorEventSource.Log.TrackingAnExistingTelemetryItemVerbose();
                    }

                    break;
                }

                case SqlBeforeRollbackTransaction:
                {
                    var operationId = (Guid)TransactionRollbackBefore.OperationId.Fetch(evnt.Value);

                    DependencyCollectorEventSource.Log.SqlClientDiagnosticSubscriberCallbackCalled(operationId, evnt.Key);

                    var connection = (SqlConnection)TransactionRollbackBefore.Connection.Fetch(evnt.Value);

                    if (this.operationHolder.Get(connection) == null)
                    {
                        var operation      = (string)TransactionRollbackBefore.Operation.Fetch(evnt.Value);
                        var timestamp      = (long)TransactionRollbackBefore.Timestamp.Fetch(evnt.Value);
                        var isolationLevel = (IsolationLevel)TransactionRollbackBefore.IsolationLevel.Fetch(evnt.Value);

                        var telemetry = new DependencyTelemetry()
                        {
                            Id      = operationId.ToString("N"),
                            Name    = string.Join(" | ", connection.DataSource, connection.Database, operation, isolationLevel),
                            Type    = RemoteDependencyConstants.SQL,
                            Target  = string.Join(" | ", connection.DataSource, connection.Database),
                            Data    = operation,
                            Success = true
                        };

                        InitializeTelemetry(telemetry, operationId, timestamp);

                        this.operationHolder.Store(connection, Tuple.Create(telemetry, /* isCustomCreated: */ false));
                    }
                    else
                    {
                        DependencyCollectorEventSource.Log.TrackingAnExistingTelemetryItemVerbose();
                    }

                    break;
                }

                case SqlAfterCommitTransaction:
                case SqlAfterRollbackTransaction:
                {
                    var operationId = (Guid)TransactionAfter.OperationId.Fetch(evnt.Value);

                    DependencyCollectorEventSource.Log.SqlClientDiagnosticSubscriberCallbackCalled(operationId, evnt.Key);

                    var connection = (SqlConnection)TransactionAfter.Connection.Fetch(evnt.Value);
                    var tuple      = this.operationHolder.Get(connection);

                    if (tuple != null)
                    {
                        this.operationHolder.Remove(connection);

                        var telemetry = tuple.Item1;

                        var timestamp = (long)TransactionAfter.Timestamp.Fetch(evnt.Value);

                        telemetry.Stop(timestamp);

                        this.client.TrackDependency(telemetry);
                    }
                    else
                    {
                        DependencyCollectorEventSource.Log.EndCallbackWithNoBegin(operationId.ToString("N"));
                    }

                    break;
                }

                case SqlErrorCommitTransaction:
                case SqlErrorRollbackTransaction:
                {
                    var operationId = (Guid)TransactionError.OperationId.Fetch(evnt.Value);

                    DependencyCollectorEventSource.Log.SqlClientDiagnosticSubscriberCallbackCalled(operationId, evnt.Key);

                    var connection = (SqlConnection)TransactionError.Connection.Fetch(evnt.Value);
                    var tuple      = this.operationHolder.Get(connection);

                    if (tuple != null)
                    {
                        this.operationHolder.Remove(connection);

                        var telemetry = tuple.Item1;

                        var timestamp = (long)TransactionError.Timestamp.Fetch(evnt.Value);

                        telemetry.Stop(timestamp);

                        var exception = (Exception)TransactionError.Exception.Fetch(evnt.Value);

                        ConfigureExceptionTelemetry(telemetry, exception);

                        this.client.TrackDependency(telemetry);
                    }
                    else
                    {
                        DependencyCollectorEventSource.Log.EndCallbackWithNoBegin(operationId.ToString("N"));
                    }

                    break;
                }
                }
            }
            catch (Exception ex)
            {
                DependencyCollectorEventSource.Log
                .SqlClientDiagnosticSourceListenerOnNextFailed(ExceptionUtilities.GetExceptionDetailString(ex));
            }
        }
Example #5
0
        //// netcoreapp 2.0 event

        /// <summary>
        /// Handler for Activity stop event (response is received for the outgoing request).
        /// </summary>
        internal void OnActivityStop(HttpResponseMessage response, HttpRequestMessage request, TaskStatus requestTaskStatus)
        {
            // Even though we have the IsEnabled filter to reject ApplicationInsights URLs before any events are fired, if there
            // are multiple subscribers and one subscriber returns true to IsEnabled then all subscribers will receive the event.
            if (this.applicationInsightsUrlFilter.IsApplicationInsightsUrl(request.RequestUri))
            {
                return;
            }

            Activity currentActivity = Activity.Current;

            if (currentActivity == null)
            {
                DependencyCollectorEventSource.Log.CurrentActivityIsNull(HttpOutStopEventName);
                return;
            }

            DependencyCollectorEventSource.Log.HttpCoreDiagnosticSourceListenerStop(currentActivity.Id);

            Uri requestUri   = request.RequestUri;
            var resourceName = request.Method.Method + " " + requestUri.AbsolutePath;

            DependencyTelemetry telemetry = new DependencyTelemetry();

            telemetry.SetOperationDetail(RemoteDependencyConstants.HttpRequestOperationDetailName, request);

            // properly fill dependency telemetry operation context: OperationCorrelationTelemetryInitializer initializes child telemetry
            telemetry.Context.Operation.Id       = currentActivity.RootId;
            telemetry.Context.Operation.ParentId = currentActivity.ParentId;
            telemetry.Id = currentActivity.Id;
            foreach (var item in currentActivity.Baggage)
            {
                if (!telemetry.Properties.ContainsKey(item.Key))
                {
                    telemetry.Properties[item.Key] = item.Value;
                }
            }

            this.client.Initialize(telemetry);

            // If we started auxiliary Activity before to override the Id with W3C compatible one, now it's time to stop it
            if (currentActivity.Duration == TimeSpan.Zero)
            {
                currentActivity.Stop();
            }

            telemetry.Timestamp = currentActivity.StartTimeUtc;
            telemetry.Name      = resourceName;
            telemetry.Target    = requestUri.Host;
            telemetry.Type      = RemoteDependencyConstants.HTTP;
            telemetry.Data      = requestUri.OriginalString;
            telemetry.Duration  = currentActivity.Duration;
            if (response != null)
            {
                this.ParseResponse(response, telemetry);
                telemetry.SetOperationDetail(RemoteDependencyConstants.HttpResponseOperationDetailName, response);
            }
            else
            {
                if (this.pendingExceptions.TryRemove(currentActivity.Id, out Exception exception))
                {
                    telemetry.Properties[DependencyErrorPropertyKey] = exception.GetBaseException().Message;
                }

                telemetry.ResultCode = requestTaskStatus.ToString();
                telemetry.Success    = false;
            }

            if (this.injectW3CHeaders)
            {
                // this.SetLegacyId(telemetry, request);
            }

            this.client.TrackDependency(telemetry);
        }