private void ParseResponse(HttpResponseMessage response, DependencyTelemetry telemetry) { try { string targetApplicationId = HttpHeadersUtilities.GetRequestContextKeyValue(response.Headers, RequestResponseHeaders.RequestContextCorrelationTargetKey); if (!string.IsNullOrEmpty(targetApplicationId) && !string.IsNullOrEmpty(telemetry.Context.InstrumentationKey)) { // We only add the cross component correlation key if the key does not represent the current component. string sourceApplicationId; if (this.correlationIdLookupHelper.TryGetXComponentCorrelationId(telemetry.Context.InstrumentationKey, out sourceApplicationId) && targetApplicationId != sourceApplicationId) { telemetry.Type = RemoteDependencyConstants.AI; telemetry.Target += " | " + targetApplicationId; } } } catch (Exception e) { AppMapCorrelationEventSource.Log.UnknownError(ExceptionUtilities.GetExceptionDetailString(e)); } int statusCode = (int)response.StatusCode; telemetry.ResultCode = (statusCode > 0) ? statusCode.ToString(CultureInfo.InvariantCulture) : string.Empty; telemetry.Success = (statusCode > 0) && (statusCode < 400); }
/// <summary> /// Provides the observer with new data. /// <seealso cref="IObserver{T}.OnNext(T)"/> /// </summary> /// <param name="evnt">The current notification information.</param> public void OnNext(KeyValuePair <string, object> evnt) { const string ErrorTemplateTypeCast = "Event {0}: cannot cast {1} to expected type {2}"; const string ErrorTemplateValueParse = "Event {0}: cannot parse '{1}' as type {2}"; try { switch (evnt.Key) { case HttpOutStartEventName: { var request = this.startRequestFetcher.Fetch(evnt.Value) as HttpRequestMessage; if (request == null) { var error = string.Format(CultureInfo.InvariantCulture, ErrorTemplateTypeCast, evnt.Key, "request", "HttpRequestMessage"); DependencyCollectorEventSource.Log.HttpCoreDiagnosticSourceListenerOnNextFailed(error); } else { this.OnActivityStart(request); } break; } case HttpOutStopEventName: { var response = this.stopResponseFetcher.Fetch(evnt.Value) as HttpResponseMessage; var request = this.stopRequestFetcher.Fetch(evnt.Value) as HttpRequestMessage; var requestTaskStatusString = this.stopRequestStatusFetcher.Fetch(evnt.Value).ToString(); TaskStatus requestTaskStatus; if (response == null) { var error = string.Format(CultureInfo.InvariantCulture, ErrorTemplateTypeCast, evnt.Key, "response", "HttpResponseMessage"); DependencyCollectorEventSource.Log.HttpCoreDiagnosticSourceListenerOnNextFailed(error); } else if (request == null) { var error = string.Format(CultureInfo.InvariantCulture, ErrorTemplateTypeCast, evnt.Key, "request", "HttpRequestMessage"); DependencyCollectorEventSource.Log.HttpCoreDiagnosticSourceListenerOnNextFailed(error); } else if (!Enum.TryParse(requestTaskStatusString, out requestTaskStatus)) { var error = string.Format(CultureInfo.InvariantCulture, ErrorTemplateValueParse, evnt.Key, requestTaskStatusString, "TaskStatus"); DependencyCollectorEventSource.Log.HttpCoreDiagnosticSourceListenerOnNextFailed(error); } else { this.OnActivityStop(response, request, requestTaskStatus); } break; } case HttpExceptionEventName: { var exception = this.exceptionFetcher.Fetch(evnt.Value) as Exception; var request = this.exceptionRequestFetcher.Fetch(evnt.Value) as HttpRequestMessage; if (exception == null) { var error = string.Format(CultureInfo.InvariantCulture, ErrorTemplateTypeCast, evnt.Key, "exception", "Exception"); DependencyCollectorEventSource.Log.HttpCoreDiagnosticSourceListenerOnNextFailed(error); } else if (request == null) { var error = string.Format(CultureInfo.InvariantCulture, ErrorTemplateTypeCast, evnt.Key, "request", "HttpRequestMessage"); DependencyCollectorEventSource.Log.HttpCoreDiagnosticSourceListenerOnNextFailed(error); } else { this.OnException(exception, request); } break; } case DeprecatedRequestEventName: { var request = this.deprecatedRequestFetcher.Fetch(evnt.Value) as HttpRequestMessage; var loggingRequestIdString = this.deprecatedRequestGuidFetcher.Fetch(evnt.Value).ToString(); Guid loggingRequestId; if (request == null) { var error = string.Format(CultureInfo.InvariantCulture, ErrorTemplateTypeCast, evnt.Key, "request", "HttpRequestMessage"); DependencyCollectorEventSource.Log.HttpCoreDiagnosticSourceListenerOnNextFailed(error); } else if (!Guid.TryParse(loggingRequestIdString, out loggingRequestId)) { var error = string.Format(CultureInfo.InvariantCulture, ErrorTemplateValueParse, evnt.Key, loggingRequestIdString, "Guid"); DependencyCollectorEventSource.Log.HttpCoreDiagnosticSourceListenerOnNextFailed(error); } else { this.OnRequest(request, loggingRequestId); } break; } case DeprecatedResponseEventName: { var response = this.deprecatedResponseFetcher.Fetch(evnt.Value) as HttpResponseMessage; var loggingRequestIdString = this.deprecatedResponseGuidFetcher.Fetch(evnt.Value).ToString(); Guid loggingRequestId; if (response == null) { var error = string.Format(CultureInfo.InvariantCulture, ErrorTemplateTypeCast, evnt.Key, "response", "HttpResponseMessage"); DependencyCollectorEventSource.Log.HttpCoreDiagnosticSourceListenerOnNextFailed(error); } else if (!Guid.TryParse(loggingRequestIdString, out loggingRequestId)) { var error = string.Format(CultureInfo.InvariantCulture, ErrorTemplateValueParse, evnt.Key, loggingRequestIdString, "Guid"); DependencyCollectorEventSource.Log.HttpCoreDiagnosticSourceListenerOnNextFailed(error); } else { this.OnResponse(response, loggingRequestId); } break; } } } catch (Exception ex) { DependencyCollectorEventSource.Log.HttpCoreDiagnosticSourceListenerOnNextFailed(ExceptionUtilities.GetExceptionDetailString(ex)); } }
private void InjectRequestHeaders(HttpRequestMessage request, string instrumentationKey, bool isLegacyEvent = false) { try { var currentActivity = Activity.Current; HttpRequestHeaders requestHeaders = request.Headers; if (requestHeaders != null && this.setComponentCorrelationHttpHeaders && !this.correlationDomainExclusionList.Contains(request.RequestUri.Host)) { try { if (!string.IsNullOrEmpty(instrumentationKey) && !HttpHeadersUtilities.ContainsRequestContextKeyValue(requestHeaders, RequestResponseHeaders.RequestContextCorrelationSourceKey)) { string sourceApplicationId; if (this.correlationIdLookupHelper.TryGetXComponentCorrelationId(instrumentationKey, out sourceApplicationId)) { HttpHeadersUtilities.SetRequestContextKeyValue(requestHeaders, RequestResponseHeaders.RequestContextCorrelationSourceKey, sourceApplicationId); } } } catch (Exception e) { AppMapCorrelationEventSource.Log.UnknownError(ExceptionUtilities.GetExceptionDetailString(e)); } // Add the root ID string rootId = currentActivity.RootId; if (!string.IsNullOrEmpty(rootId) && !requestHeaders.Contains(RequestResponseHeaders.StandardRootIdHeader)) { requestHeaders.Add(RequestResponseHeaders.StandardRootIdHeader, rootId); } // Add the parent ID string parentId = currentActivity.Id; if (!string.IsNullOrEmpty(parentId) && !requestHeaders.Contains(RequestResponseHeaders.StandardParentIdHeader)) { requestHeaders.Add(RequestResponseHeaders.StandardParentIdHeader, parentId); if (isLegacyEvent) { requestHeaders.Add(RequestResponseHeaders.RequestIdHeader, parentId); } } if (isLegacyEvent) { // we expect baggage to be empty or contain a few items using (IEnumerator <KeyValuePair <string, string> > e = currentActivity.Baggage.GetEnumerator()) { if (e.MoveNext()) { var baggage = new List <string>(); do { KeyValuePair <string, string> item = e.Current; baggage.Add(new NameValueHeaderValue(item.Key, item.Value).ToString()); }while (e.MoveNext()); request.Headers.Add(RequestResponseHeaders.CorrelationContextHeader, baggage); } } } } } catch (Exception e) { AppMapCorrelationEventSource.Log.UnknownError(ExceptionUtilities.GetExceptionDetailString(e)); } }
private void InjectRequestHeaders(HttpRequestMessage request, string instrumentationKey) { try { HttpRequestHeaders requestHeaders = request.Headers; if (requestHeaders != null && this.setComponentCorrelationHttpHeaders && !this.correlationDomainExclusionList.Contains(request.RequestUri.Host)) { string sourceApplicationId = null; try { if (!string.IsNullOrEmpty(instrumentationKey) && !HttpHeadersUtilities.ContainsRequestContextKeyValue(requestHeaders, RequestResponseHeaders.RequestContextCorrelationSourceKey) && (this.configuration.ApplicationIdProvider?.TryGetApplicationId(instrumentationKey, out sourceApplicationId) ?? false)) { HttpHeadersUtilities.SetRequestContextKeyValue(requestHeaders, RequestResponseHeaders.RequestContextCorrelationSourceKey, sourceApplicationId); } } catch (Exception e) { AppMapCorrelationEventSource.Log.UnknownError(ExceptionUtilities.GetExceptionDetailString(e)); } var currentActivity = Activity.Current; switch (this.httpInstrumentationVersion) { case HttpInstrumentationVersion.V1: // HttpClient does not add any headers // add W3C or Request-Id depending on Activity format // add correlation-context anyway if (currentActivity.IdFormat == ActivityIdFormat.W3C) { InjectW3CHeaders(currentActivity, requestHeaders); if (this.injectRequestIdInW3CMode) { InjectBackCompatibleRequestId(currentActivity, requestHeaders); } } else { if (!requestHeaders.Contains(RequestResponseHeaders.RequestIdHeader)) { requestHeaders.Add(RequestResponseHeaders.RequestIdHeader, currentActivity.Id); } } InjectCorrelationContext(requestHeaders, currentActivity); break; case HttpInstrumentationVersion.V2: // On V2, HttpClient adds Request-Id and Correlation-Context // but not W3C if (currentActivity.IdFormat == ActivityIdFormat.W3C) { // we are going to add W3C and Request-Id (in W3C-compatible format) // as a result HttpClient will not add Request-Id AND Correlation-Context InjectW3CHeaders(currentActivity, requestHeaders); if (this.injectRequestIdInW3CMode) { InjectBackCompatibleRequestId(currentActivity, requestHeaders); } InjectCorrelationContext(requestHeaders, currentActivity); } break; case HttpInstrumentationVersion.V3: // on V3, HttpClient adds either W3C or Request-Id depending on Activity format // and adds Correlation-Context if (currentActivity.IdFormat == ActivityIdFormat.W3C && this.injectRequestIdInW3CMode) { // we are going to override Request-Id to be in W3C compatible mode InjectBackCompatibleRequestId(currentActivity, requestHeaders); } break; } if (this.injectLegacyHeaders) { // Add the root ID (Activity.RootId works with W3C and Hierarchical format) string rootId = currentActivity.RootId; if (!string.IsNullOrEmpty(rootId) && !requestHeaders.Contains(RequestResponseHeaders.StandardRootIdHeader)) { requestHeaders.Add(RequestResponseHeaders.StandardRootIdHeader, rootId); } // Add the parent ID string parentId = currentActivity.IdFormat == ActivityIdFormat.W3C ? W3CUtilities.FormatTelemetryId(rootId, currentActivity.SpanId.ToHexString()) : currentActivity.Id; if (!string.IsNullOrEmpty(parentId) && !requestHeaders.Contains(RequestResponseHeaders.StandardParentIdHeader)) { requestHeaders.Add(RequestResponseHeaders.StandardParentIdHeader, parentId); } } } } catch (Exception e) { AppMapCorrelationEventSource.Log.UnknownError(ExceptionUtilities.GetExceptionDetailString(e)); } }
/// <summary> /// Provides the observer with new data. /// <seealso cref="IObserver{T}.OnNext(T)"/> /// </summary> /// <param name="evnt">The current notification information.</param> public void OnNext(KeyValuePair <string, object> evnt) { try { // It's possible to host multiple apps (ASP.NET Core or generic hosts) in the same process // Each of this apps has it's own DependencyTrackingModule and corresponding Http listener. // We should ignore events for all of them except one if (!SubscriptionManager.IsActive(this)) { DependencyCollectorEventSource.Log.NotActiveListenerNoTracking(evnt.Key, Activity.Current?.Id); return; } const string errorTemplateTypeCast = "Event {0}: cannot cast {1} to expected type {2}"; const string errorTemplateValueParse = "Event {0}: cannot parse '{1}' as type {2}"; switch (evnt.Key) { case HttpOutStartEventName: { var request = this.startRequestFetcher.Fetch(evnt.Value) as HttpRequestMessage; if (request == null) { var error = string.Format(CultureInfo.InvariantCulture, errorTemplateTypeCast, evnt.Key, "request", "HttpRequestMessage"); DependencyCollectorEventSource.Log.HttpCoreDiagnosticSourceListenerOnNextFailed(error); } else { this.OnActivityStart(request); } break; } case HttpOutStopEventName: { var response = this.stopResponseFetcher.Fetch(evnt.Value) as HttpResponseMessage; var request = this.stopRequestFetcher.Fetch(evnt.Value) as HttpRequestMessage; var requestTaskStatusString = this.stopRequestStatusFetcher.Fetch(evnt.Value).ToString(); if (request == null) { var error = string.Format(CultureInfo.InvariantCulture, errorTemplateTypeCast, evnt.Key, "request", "HttpRequestMessage"); DependencyCollectorEventSource.Log.HttpCoreDiagnosticSourceListenerOnNextFailed(error); } else if (!Enum.TryParse(requestTaskStatusString, out TaskStatus requestTaskStatus)) { var error = string.Format(CultureInfo.InvariantCulture, errorTemplateValueParse, evnt.Key, requestTaskStatusString, "TaskStatus"); DependencyCollectorEventSource.Log.HttpCoreDiagnosticSourceListenerOnNextFailed(error); } else { this.OnActivityStop(response, request, requestTaskStatus); } break; } case HttpExceptionEventName: { var exception = this.exceptionFetcher.Fetch(evnt.Value) as Exception; var request = this.exceptionRequestFetcher.Fetch(evnt.Value) as HttpRequestMessage; if (exception == null) { var error = string.Format(CultureInfo.InvariantCulture, errorTemplateTypeCast, evnt.Key, "exception", "Exception"); DependencyCollectorEventSource.Log.HttpCoreDiagnosticSourceListenerOnNextFailed(error); } else if (request == null) { var error = string.Format(CultureInfo.InvariantCulture, errorTemplateTypeCast, evnt.Key, "request", "HttpRequestMessage"); DependencyCollectorEventSource.Log.HttpCoreDiagnosticSourceListenerOnNextFailed(error); } else { this.OnException(exception, request); } break; } case DeprecatedRequestEventName: { if (this.httpInstrumentationVersion != HttpInstrumentationVersion.V1) { // 2.0+ publishes new events, and this should be just ignored to prevent duplicates. break; } var request = this.deprecatedRequestFetcher.Fetch(evnt.Value) as HttpRequestMessage; var loggingRequestIdString = this.deprecatedRequestGuidFetcher.Fetch(evnt.Value).ToString(); if (request == null) { var error = string.Format(CultureInfo.InvariantCulture, errorTemplateTypeCast, evnt.Key, "request", "HttpRequestMessage"); DependencyCollectorEventSource.Log.HttpCoreDiagnosticSourceListenerOnNextFailed(error); } else if (!Guid.TryParse(loggingRequestIdString, out Guid loggingRequestId)) { var error = string.Format(CultureInfo.InvariantCulture, errorTemplateValueParse, evnt.Key, loggingRequestIdString, "Guid"); DependencyCollectorEventSource.Log.HttpCoreDiagnosticSourceListenerOnNextFailed(error); } else { this.OnRequest(request, loggingRequestId); } break; } case DeprecatedResponseEventName: { if (this.httpInstrumentationVersion != HttpInstrumentationVersion.V1) { // 2.0+ publishes new events, and this should be just ignored to prevent duplicates. break; } var response = this.deprecatedResponseFetcher.Fetch(evnt.Value) as HttpResponseMessage; var loggingRequestIdString = this.deprecatedResponseGuidFetcher.Fetch(evnt.Value).ToString(); if (response == null) { var error = string.Format(CultureInfo.InvariantCulture, errorTemplateTypeCast, evnt.Key, "response", "HttpResponseMessage"); DependencyCollectorEventSource.Log.HttpCoreDiagnosticSourceListenerOnNextFailed(error); } else if (!Guid.TryParse(loggingRequestIdString, out Guid loggingRequestId)) { var error = string.Format(CultureInfo.InvariantCulture, errorTemplateValueParse, evnt.Key, loggingRequestIdString, "Guid"); DependencyCollectorEventSource.Log.HttpCoreDiagnosticSourceListenerOnNextFailed(error); } else { this.OnResponse(response, loggingRequestId); } break; } } } catch (Exception ex) { DependencyCollectorEventSource.Log.HttpCoreDiagnosticSourceListenerOnNextFailed(ExceptionUtilities.GetExceptionDetailString(ex)); } }
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)); } }
#pragma warning disable 612, 618 private void InjectRequestHeaders(HttpRequestMessage request, string instrumentationKey, bool isLegacyEvent = false) { try { HttpRequestHeaders requestHeaders = request.Headers; if (requestHeaders != null && this.setComponentCorrelationHttpHeaders && !this.correlationDomainExclusionList.Contains(request.RequestUri.Host)) { string sourceApplicationId = null; try { if (!string.IsNullOrEmpty(instrumentationKey) && !HttpHeadersUtilities.ContainsRequestContextKeyValue(requestHeaders, RequestResponseHeaders.RequestContextCorrelationSourceKey) && (this.configuration.ApplicationIdProvider?.TryGetApplicationId(instrumentationKey, out sourceApplicationId) ?? false)) { HttpHeadersUtilities.SetRequestContextKeyValue(requestHeaders, RequestResponseHeaders.RequestContextCorrelationSourceKey, sourceApplicationId); } } catch (Exception e) { AppMapCorrelationEventSource.Log.UnknownError(ExceptionUtilities.GetExceptionDetailString(e)); } var currentActivity = Activity.Current; if (isLegacyEvent) { if (!requestHeaders.Contains(RequestResponseHeaders.RequestIdHeader)) { requestHeaders.Add(RequestResponseHeaders.RequestIdHeader, currentActivity.Id); } InjectCorrelationContext(requestHeaders, currentActivity); } if (this.injectLegacyHeaders) { // Add the root ID string rootId = currentActivity.RootId; if (!string.IsNullOrEmpty(rootId) && !requestHeaders.Contains(RequestResponseHeaders.StandardRootIdHeader)) { requestHeaders.Add(RequestResponseHeaders.StandardRootIdHeader, rootId); } // Add the parent ID string parentId = currentActivity.Id; if (!string.IsNullOrEmpty(parentId) && !requestHeaders.Contains(RequestResponseHeaders.StandardParentIdHeader)) { requestHeaders.Add(RequestResponseHeaders.StandardParentIdHeader, parentId); } } if (this.injectW3CHeaders) { currentActivity.UpdateContextOnActivity(); string traceParent = currentActivity.GetTraceparent(); if (traceParent != null && !requestHeaders.Contains(W3CConstants.TraceParentHeader)) { requestHeaders.Add(W3CConstants.TraceParentHeader, traceParent); } string traceState = currentActivity.GetTracestate(); if (!requestHeaders.Contains(W3CConstants.TraceStateHeader)) { if (sourceApplicationId != null) { // TODO: there could be another az in the state. // last updated state should appear first in the tracestate string appIdPair = StringUtilities.FormatAzureTracestate(sourceApplicationId); if (traceState == null) { traceState = appIdPair; } else { traceState = appIdPair + "," + traceState; } } if (traceState != null) { requestHeaders.Add(W3CConstants.TraceStateHeader, traceState); } } } } } catch (Exception e) { AppMapCorrelationEventSource.Log.UnknownError(ExceptionUtilities.GetExceptionDetailString(e)); } }
void IObserver <KeyValuePair <string, object> > .OnNext(KeyValuePair <string, object> evnt) { try { // It's possible to host multiple apps (ASP.NET Core or generic hosts) in the same process // Each of this apps has it's own DependencyTrackingModule and corresponding SQL listener. // We should ignore events for all of them except one if (!SubscriptionManager.IsActive(this)) { DependencyCollectorEventSource.Log.NotActiveListenerNoTracking(evnt.Key, Activity.Current?.Id); return; } switch (evnt.Key) { case SqlBeforeExecuteCommand: { this.BeforeExecuteHelper(evnt, CommandBefore.OperationId, CommandBefore.Command, CommandBefore.CommandText, CommandBefore.Connection, CommandBefore.DataSource, CommandBefore.Database, CommandBefore.CommandType, CommandBefore.Timestamp); break; } case SqlMicrosoftBeforeExecuteCommand: { this.BeforeExecuteHelper(evnt, CommandBeforeMicrosoft.OperationId, CommandBeforeMicrosoft.Command, CommandBeforeMicrosoft.CommandText, CommandBeforeMicrosoft.Connection, CommandBeforeMicrosoft.DataSource, CommandBeforeMicrosoft.Database, CommandBeforeMicrosoft.CommandType, CommandBeforeMicrosoft.Timestamp); break; } case SqlAfterExecuteCommand: { this.AfterExecuteHelper(evnt, CommandAfter.OperationId, CommandAfter.Command, CommandAfter.Timestamp); break; } case SqlMicrosoftAfterExecuteCommand: { this.AfterExecuteHelper(evnt, CommandAfterMicrosoft.OperationId, CommandAfterMicrosoft.Command, CommandAfterMicrosoft.Timestamp); break; } case SqlErrorExecuteCommand: { this.ErrorExecuteHelper(evnt, CommandError.OperationId, CommandError.Command, CommandError.Timestamp, CommandError.Exception, CommandError.Number); break; } case SqlMicrosoftErrorExecuteCommand: { this.ErrorExecuteHelper(evnt, CommandErrorMicrosoft.OperationId, CommandErrorMicrosoft.Command, CommandErrorMicrosoft.Timestamp, CommandErrorMicrosoft.Exception, CommandErrorMicrosoft.Number); break; } case SqlBeforeOpenConnection: { this.BeforeOpenConnectionHelper(evnt, ConnectionBefore.OperationId, ConnectionBefore.Connection, ConnectionBefore.Operation, ConnectionBefore.Timestamp, ConnectionBefore.DataSource, ConnectionBefore.Database); break; } case SqlMicrosoftBeforeOpenConnection: { this.BeforeOpenConnectionHelper(evnt, ConnectionBeforeMicrosoft.OperationId, ConnectionBeforeMicrosoft.Connection, ConnectionBeforeMicrosoft.Operation, ConnectionBeforeMicrosoft.Timestamp, ConnectionBeforeMicrosoft.DataSource, ConnectionBeforeMicrosoft.Database); break; } case SqlAfterOpenConnection: { this.AfterOpenConnectionHelper(evnt, ConnectionAfter.OperationId, ConnectionAfter.Connection); break; } case SqlMicrosoftAfterOpenConnection: { this.AfterOpenConnectionHelper(evnt, ConnectionAfterMicrosoft.OperationId, ConnectionAfterMicrosoft.Connection); break; } case SqlErrorOpenConnection: { this.ErrorOpenConnectionHelper(evnt, ConnectionError.OperationId, ConnectionError.Connection, ConnectionError.Timestamp, ConnectionError.Exception, ConnectionError.Number); break; } case SqlMicrosoftErrorOpenConnection: { this.ErrorOpenConnectionHelper(evnt, ConnectionErrorMicrosoft.OperationId, ConnectionErrorMicrosoft.Connection, ConnectionErrorMicrosoft.Timestamp, ConnectionErrorMicrosoft.Exception, ConnectionErrorMicrosoft.Number); break; } case SqlBeforeCommitTransaction: { this.BeforeCommitHelper(evnt, TransactionCommitBefore.OperationId, TransactionCommitBefore.Connection, TransactionCommitBefore.Operation, TransactionCommitBefore.Timestamp, TransactionCommitBefore.IsolationLevel, TransactionCommitBefore.DataSource, TransactionCommitBefore.Database); break; } case SqlMicrosoftBeforeCommitTransaction: { this.BeforeCommitHelper(evnt, TransactionCommitBeforeMicrosoft.OperationId, TransactionCommitBeforeMicrosoft.Connection, TransactionCommitBeforeMicrosoft.Operation, TransactionCommitBeforeMicrosoft.Timestamp, TransactionCommitBeforeMicrosoft.IsolationLevel, TransactionCommitBeforeMicrosoft.DataSource, TransactionCommitBeforeMicrosoft.Database); break; } case SqlBeforeRollbackTransaction: { this.BeforeRollbackHelper(evnt, TransactionRollbackBefore.OperationId, TransactionRollbackBefore.Connection, TransactionRollbackBefore.Operation, TransactionRollbackBefore.Timestamp, TransactionRollbackBefore.IsolationLevel, TransactionRollbackBefore.DataSource, TransactionRollbackBefore.Database); break; } case SqlMicrosoftBeforeRollbackTransaction: { this.BeforeRollbackHelper(evnt, TransactionRollbackBeforeMicrosoft.OperationId, TransactionRollbackBeforeMicrosoft.Connection, TransactionRollbackBeforeMicrosoft.Operation, TransactionRollbackBeforeMicrosoft.Timestamp, TransactionRollbackBeforeMicrosoft.IsolationLevel, TransactionRollbackBeforeMicrosoft.DataSource, TransactionRollbackBeforeMicrosoft.Database); break; } case SqlAfterCommitTransaction: { this.AfterCommitHelper(evnt, TransactionCommitAfter.OperationId, TransactionCommitAfter.Connection, TransactionCommitAfter.Timestamp); break; } case SqlMicrosoftAfterCommitTransaction: { this.AfterCommitHelper(evnt, TransactionCommitAfterMicrosoft.OperationId, TransactionCommitAfterMicrosoft.Connection, TransactionCommitAfterMicrosoft.Timestamp); break; } case SqlAfterRollbackTransaction: { this.AfterRollBackHelper(evnt, TransactionRollbackAfter.OperationId, TransactionRollbackAfter.Connection, TransactionRollbackAfter.Timestamp); break; } case SqlMicrosoftAfterRollbackTransaction: { this.AfterRollBackHelper(evnt, TransactionRollbackAfterMicrosoft.OperationId, TransactionRollbackAfterMicrosoft.Connection, TransactionRollbackAfterMicrosoft.Timestamp); break; } case SqlErrorCommitTransaction: { this.ErrorCommitHelper(evnt, TransactionCommitError.OperationId, TransactionCommitError.Connection, TransactionCommitError.Timestamp, TransactionCommitError.Exception, TransactionCommitError.Number); break; } case SqlMicrosoftErrorCommitTransaction: { this.ErrorCommitHelper(evnt, TransactionCommitErrorMicrosoft.OperationId, TransactionCommitErrorMicrosoft.Connection, TransactionCommitErrorMicrosoft.Timestamp, TransactionCommitErrorMicrosoft.Exception, TransactionCommitErrorMicrosoft.Number); break; } case SqlErrorRollbackTransaction: { this.ErrorRollbackHelper(evnt, TransactionRollbackError.OperationId, TransactionRollbackError.Connection, TransactionRollbackError.Timestamp, TransactionRollbackError.Exception, TransactionRollbackError.Number); break; } case SqlMicrosoftErrorRollbackTransaction: { this.ErrorRollbackHelper(evnt, TransactionRollbackErrorMicrosoft.OperationId, TransactionRollbackErrorMicrosoft.Connection, TransactionRollbackErrorMicrosoft.Timestamp, TransactionRollbackErrorMicrosoft.Exception, TransactionRollbackErrorMicrosoft.Number); break; } } } catch (Exception ex) { DependencyCollectorEventSource.Log .SqlClientDiagnosticSourceListenerOnNextFailed(ExceptionUtilities.GetExceptionDetailString(ex)); } }