/// <summary> /// On end callback from Framework event source. /// </summary> /// <param name="id">The id.</param> /// <param name="success">The success to indicate if the dependency call completed successfully or not.</param> /// <param name="synchronous">The synchronous flag to indicate if the dependency call was synchronous or not.</param> /// <param name="statusCode">The HTTP status code of the response.</param> public void OnEndHttpCallback(long id, bool?success, bool synchronous, int?statusCode) { DependencyCollectorEventSource.Log.EndCallbackCalled(id); var telemetryTuple = this.TelemetryTable.Get(id); if (telemetryTuple == null) { DependencyCollectorEventSource.Log.EndCallbackWithNoBegin(id); return; } if (!telemetryTuple.Item2) { this.TelemetryTable.Remove(id); DependencyTelemetry telemetry = telemetryTuple.Item1; telemetry.DependencyKind = RemoteDependencyKind.Http.ToString(); if (!statusCode.HasValue) { statusCode = -1; } telemetry.ResultCode = statusCode.Value > 0 ? statusCode.Value.ToString(CultureInfo.InvariantCulture) : string.Empty; // We calculate success on the base of http code and do not use the 'success' method argument // because framework returns true all the time if you use HttpClient to create a request // statusCode == -1 if there is no Response telemetry.Success = (statusCode > 0) && (statusCode < 400); ClientServerDependencyTracker.EndTracking(this.telemetryClient, telemetry); } }
/// <summary> /// Common helper for all End Callbacks. /// </summary> /// <param name="request">The HttpWebRequest instance.</param> /// <param name="response">The HttpWebResponse instance.</param> internal void OnEndResponse(object request, object response) { try { if (this.TryGetPendingTelemetry(request, out DependencyTelemetry telemetry)) { if (response is HttpWebResponse responseObj) { int statusCode = -1; try { statusCode = (int)responseObj.StatusCode; this.SetTarget(telemetry, responseObj.Headers); // Set the operation details for the response telemetry.SetOperationDetail(RemoteDependencyConstants.HttpResponseOperationDetailName, responseObj); } catch (ObjectDisposedException) { // ObjectDisposedException is expected here in the following sequence: httpWebRequest.GetResponse().Dispose() -> httpWebRequest.GetResponse() // on the second call to GetResponse() we cannot determine the statusCode. } SetStatusCode(telemetry, statusCode); } ClientServerDependencyTracker.EndTracking(this.telemetryClient, telemetry); } } catch (Exception ex) { DependencyCollectorEventSource.Log.CallbackError(request == null ? 0 : request.GetHashCode(), "OnEndResponse", ex); } }
/// <summary> /// Common helper for all End Callbacks. /// </summary> /// <param name="request">WebRequest object.</param> /// <param name="statusCode">HttpStatusCode from response.</param> /// <param name="responseHeaders">Response headers.</param> internal void OnEndResponse(object request, object statusCode, object responseHeaders) { try { if (this.TryGetPendingTelemetry(request, out DependencyTelemetry telemetry)) { if (statusCode != null) { SetStatusCode(telemetry, (int)statusCode); } this.SetTarget(telemetry, (WebHeaderCollection)responseHeaders); if (this.injectW3CHeaders && request is HttpWebRequest httpRequest) { // this.SetLegacyId(telemetry, httpRequest.Headers); } telemetry.SetOperationDetail(RemoteDependencyConstants.HttpResponseHeadersOperationDetailName, responseHeaders); ClientServerDependencyTracker.EndTracking(this.telemetryClient, telemetry); } } catch (Exception ex) { DependencyCollectorEventSource.Log.CallbackError(request == null ? 0 : request.GetHashCode(), "OnEndResponse", ex); } }
/// <summary> /// Common helper for all End Callbacks. /// </summary> /// <param name="exception">The exception object if any.</param> /// <param name="thisObj">This object.</param> /// <param name="returnValue">Return value of the function if any.</param> private void OnEnd(object exception, object thisObj, object returnValue) { try { if (thisObj == null) { DependencyCollectorEventSource.Log.NotExpectedCallback(0, "OnBeginHttp", "thisObj == null"); return; } DependencyCollectorEventSource.Log.EndCallbackCalled(thisObj.GetHashCode()); Tuple <DependencyTelemetry, bool> telemetryTuple = this.TelemetryTable.Get(thisObj); if (telemetryTuple == null) { DependencyCollectorEventSource.Log.EndCallbackWithNoBegin(thisObj.GetHashCode()); return; } if (telemetryTuple.Item1 == null) { DependencyCollectorEventSource.Log.EndCallbackWithNoBegin(thisObj.GetHashCode()); return; } if (!telemetryTuple.Item2) { this.TelemetryTable.Remove(thisObj); DependencyTelemetry telemetry = telemetryTuple.Item1; var responseObj = returnValue as HttpWebResponse; int statusCode = -1; if (responseObj != null) { try { statusCode = (int)responseObj.StatusCode; } catch (ObjectDisposedException) { // ObjectDisposedException is expected here in the following sequence: httpWebRequest.GetResponse().Dispose() -> httpWebRequest.GetResponse() // on the second call to GetResponse() we cannot determine the statusCode. } } telemetry.ResultCode = statusCode > 0 ? statusCode.ToString(CultureInfo.InvariantCulture) : string.Empty; telemetry.Success = (statusCode > 0) && (statusCode < 400); ClientServerDependencyTracker.EndTracking(this.telemetryClient, telemetry); } } catch (Exception ex) { DependencyCollectorEventSource.Log.CallbackError(thisObj == null ? 0 : thisObj.GetHashCode(), "OnBeginHttp", ex); } }
public void EndTrackingComputesTheDurationOfTelemetryItem() { var telemetry = ClientServerDependencyTracker.BeginTracking(this.telemetryClient); ClientServerDependencyTracker.EndTracking(this.telemetryClient, telemetry); var telemetryItem = this.sendItems[0] as DependencyTelemetry; this.ValidateSentTelemetry(telemetryItem); }
/// <summary> /// Common helper for all End Callbacks. /// </summary> /// <param name="exceptionObj">The exception object if any.</param> /// <param name="thisObj">This object.</param> /// <param name="sendTelemetryItem">True if telemetry item should be sent, otherwise it only stops the telemetry item.</param> private void OnEndInternal(object exceptionObj, object thisObj, bool sendTelemetryItem = true) { if (thisObj == null) { DependencyCollectorEventSource.Log.NotExpectedCallback(0, "OnEndSql", "thisObj == null"); return; } DependencyCollectorEventSource.Log.EndCallbackCalled(thisObj.GetHashCode().ToString(CultureInfo.InvariantCulture)); DependencyTelemetry telemetry = null; Tuple <DependencyTelemetry, bool> telemetryTuple = null; bool isCustomGenerated = false; telemetryTuple = this.TelemetryTable.Get(thisObj); if (telemetryTuple != null) { telemetry = telemetryTuple.Item1; isCustomGenerated = telemetryTuple.Item2; } if (telemetry == null) { DependencyCollectorEventSource.Log.EndCallbackWithNoBegin(thisObj.GetHashCode().ToString(CultureInfo.InvariantCulture)); return; } if (!isCustomGenerated) { this.TelemetryTable.Remove(thisObj); if (sendTelemetryItem) { var exception = exceptionObj as Exception; if (exception != null) { telemetry.Success = false; telemetry.Properties.Add("ErrorMessage", exception.Message); var sqlEx = exception as SqlException; telemetry.ResultCode = sqlEx != null?sqlEx.Number.ToString(CultureInfo.InvariantCulture) : "0"; } else { telemetry.Success = true; } DependencyCollectorEventSource.Log.AutoTrackingDependencyItem(telemetry.Name); ClientServerDependencyTracker.EndTracking(this.telemetryClient, telemetry); } else { DependencyCollectorEventSource.Log.EndOperationNoTracking(telemetry.Name); ClientServerDependencyTracker.EndOperation(telemetry); } } }
public void EndTrackingSendsTelemetryItemOnSuccess() { var telemetry = ClientServerDependencyTracker.BeginTracking(this.telemetryClient); ClientServerDependencyTracker.EndTracking(this.telemetryClient, telemetry); Assert.AreEqual(1, this.sendItems.Count); telemetry = ClientServerDependencyTracker.BeginTracking(this.telemetryClient); ClientServerDependencyTracker.EndTracking(this.telemetryClient, telemetry); Assert.AreEqual(2, this.sendItems.Count); }
public void EndTrackingTracksTelemetryItemWithInitializedContent() { var telemetry = ClientServerDependencyTracker.BeginTracking(this.telemetryClient); ClientServerDependencyTracker.EndTracking(this.telemetryClient, telemetry); var telemetryItem = this.sendItems[0] as DependencyTelemetry; Assert.IsNotNull(telemetryItem.Context.User.Id); Assert.IsNotNull(telemetryItem.Context.Session.Id); Assert.AreEqual(telemetryItem.Context.User.Id, "UserID"); Assert.AreEqual(telemetryItem.Context.Session.Id, "SessionID"); }
/// <summary> /// Common helper for all End Callbacks. /// </summary> /// <param name="exception">The exception object if any.</param> /// <param name="request">HttpWebRequest instance.</param> internal void OnEndException(object exception, object request) { try { if (this.TryGetPendingTelemetry(request, out DependencyTelemetry telemetry)) { var webException = exception as WebException; if (webException?.Response is HttpWebResponse responseObj) { int statusCode = -1; try { statusCode = (int)responseObj.StatusCode; this.SetTarget(telemetry, responseObj.Headers); if (this.injectW3CHeaders && request is HttpWebRequest httpRequest) { // this.SetLegacyId(telemetry, httpRequest.Headers); } // Set the operation details for the response telemetry.SetOperationDetail(RemoteDependencyConstants.HttpResponseOperationDetailName, responseObj); } catch (ObjectDisposedException) { // ObjectDisposedException is expected here in the following sequence: httpWebRequest.GetResponse().Dispose() -> httpWebRequest.GetResponse() // on the second call to GetResponse() we cannot determine the statusCode. } SetStatusCode(telemetry, statusCode); } else if (exception != null) { if (webException != null) { telemetry.ResultCode = webException.Status.ToString(); } telemetry.Success = false; } ClientServerDependencyTracker.EndTracking(this.telemetryClient, telemetry); } } catch (Exception ex) { DependencyCollectorEventSource.Log.CallbackError(request == null ? 0 : request.GetHashCode(), "OnEndException", ex); } }
/// <summary> /// On end callback from Framework event source. /// </summary> /// <param name="id">The id.</param> /// <param name="success">The success to indicate if the dependency call completed successfully or not.</param> /// <param name="synchronous">The synchronous flag to indicate if the dependency call was synchronous or not.</param> /// <param name="statusCode">The HTTP status code of the response.</param> public void OnEndHttpCallback(long id, bool?success, bool synchronous, int?statusCode) { DependencyCollectorEventSource.Log.EndCallbackCalled(id.ToString(CultureInfo.InvariantCulture)); var telemetryTuple = this.TelemetryTable.Get(id); if (telemetryTuple == null) { DependencyCollectorEventSource.Log.EndCallbackWithNoBegin(id.ToString(CultureInfo.InvariantCulture)); return; } if (!telemetryTuple.Item2) { DependencyTelemetry telemetry = telemetryTuple.Item1; if (statusCode.HasValue) { if (DependencyTableStore.IsDesktopHttpDiagnosticSourceActivated && statusCode.Value > 0) { // HttpDesktopDiagnosticSourceListener do not get notifications about exceptions during requests processing. // We will report them here, and we will let HttpDesktopDiagnosticSourceListener track the dependency for successful response DependencyCollectorEventSource.Log.SkipTrackingTelemetryItemWithEventSource(id); return; } // We calculate success on the base of http code and do not use the 'success' method argument // because framework returns true all the time if you use HttpClient to create a request // statusCode == -1 if there is no Response telemetry.Success = (statusCode > 0) && (statusCode < 400); telemetry.ResultCode = statusCode.Value > 0 ? statusCode.Value.ToString(CultureInfo.InvariantCulture) : string.Empty; this.TelemetryTable.Remove(id); ClientServerDependencyTracker.EndTracking(this.telemetryClient, telemetry); } else { // This case is for 4.5.2 // We never collected statusCode or success before 2.1.0-beta4 // We also had duplicates if runtime is also 4.5.2 (4.6 runtime has no such problem) // So starting with 2.1.0-beta4 we are cutting support for HTTP dependencies in .NET 4.5.2. // But we will let DesktopDiagnosticSourceListener collect dependency if it is activated if (!DependencyTableStore.IsDesktopHttpDiagnosticSourceActivated) { this.TelemetryTable.Remove(id); } } } }
/// <summary> /// Common helper for all End Callbacks. /// </summary> /// <param name="context">The context.</param> /// <param name="exception">The exception object if any.</param> /// <param name="thisObj">This object.</param> /// <param name="isAsync">Whether the End is for an async invocation.</param> private void OnEnd(object context, object exception, object thisObj, bool isAsync) { try { if (thisObj == null) { DependencyCollectorEventSource.Log.NotExpectedCallback(0, "OnEndSql", "thisObj == null"); return; } DependencyCollectorEventSource.Log.EndCallbackCalled(thisObj.GetHashCode().ToString(CultureInfo.InvariantCulture)); DependencyTelemetry telemetry = null; Tuple <DependencyTelemetry, bool> telemetryTuple = null; bool isCustomGenerated = false; telemetryTuple = this.TelemetryTable.Get(thisObj); if (telemetryTuple != null) { telemetry = telemetryTuple.Item1; isCustomGenerated = telemetryTuple.Item2; } if (telemetry == null) { DependencyCollectorEventSource.Log.EndCallbackWithNoBegin(thisObj.GetHashCode().ToString(CultureInfo.InvariantCulture)); return; } if (!isCustomGenerated) { this.TelemetryTable.Remove(thisObj); telemetry.Success = exception == null; var sqlEx = exception as SqlException; if (sqlEx != null) { telemetry.ResultCode = sqlEx.Number.ToString(CultureInfo.InvariantCulture); } ClientServerDependencyTracker.EndTracking(this.telemetryClient, telemetry); } } catch (Exception ex) { DependencyCollectorEventSource.Log.CallbackError(thisObj == null ? 0 : thisObj.GetHashCode(), "OnEndSql", ex); } }
/// <summary> /// On end callback from Framework event source. /// </summary> /// <param name="id">The id.</param> /// <param name="success">The success to indicate if the dependency call completed successfully or not.</param> /// <param name="synchronous">The synchronous flag to indicate if the dependency call was synchronous or not.</param> /// <param name="statusCode">The HTTP status code of the response.</param> public void OnEndHttpCallback(long id, bool?success, bool synchronous, int?statusCode) { DependencyCollectorEventSource.Log.EndCallbackCalled(id.ToString(CultureInfo.InvariantCulture)); var telemetryTuple = this.TelemetryTable.Get(id); if (telemetryTuple == null) { DependencyCollectorEventSource.Log.EndCallbackWithNoBegin(id.ToString(CultureInfo.InvariantCulture)); return; } if (!telemetryTuple.Item2) { this.TelemetryTable.Remove(id); DependencyTelemetry telemetry = telemetryTuple.Item1; // If this telemetry was processed via the DiagnosticSource path, we should record that fact in the // SdkVersion field if (this.HasTouchedByDiagnosticSource(telemetry)) { telemetry.Context.GetInternalContext().SdkVersion = SdkVersionUtils.GetSdkVersion("rdd" + RddSource.FrameworkAndDiagnostic + ":"); } if (statusCode.HasValue) { // We calculate success on the base of http code and do not use the 'success' method argument // because framework returns true all the time if you use HttpClient to create a request // statusCode == -1 if there is no Response telemetry.Success = (statusCode > 0) && (statusCode < 400); telemetry.ResultCode = statusCode.Value > 0 ? statusCode.Value.ToString(CultureInfo.InvariantCulture) : string.Empty; ClientServerDependencyTracker.EndTracking(this.telemetryClient, telemetry); } else { // This case is for 4.5.2 // We never collected statusCode or success before 2.1.0-beta4 // We also had duplicates if runtime is also 4.5.2 (4.6 runtime has no such problem) // So starting with 2.1.0-beta4 we are cutting support for HTTP dependencies in .NET 4.5.2. } } }
/// <summary> /// Common helper for all End Callbacks. /// </summary> /// <param name="request">WebRequest object.</param> /// <param name="statusCode">HttpStatusCode from response.</param> /// <param name="responseHeaders">Response headers.</param> internal void OnEndResponse(object request, object statusCode, object responseHeaders) { try { if (this.TryGetPendingTelemetry(request, out DependencyTelemetry telemetry)) { if (statusCode != null) { this.SetStatusCode(telemetry, (int)statusCode); } this.SetTarget(telemetry, (WebHeaderCollection)responseHeaders); ClientServerDependencyTracker.EndTracking(this.telemetryClient, telemetry); } } catch (Exception ex) { DependencyCollectorEventSource.Log.CallbackError(request == null ? 0 : request.GetHashCode(), "OnEndResponse", ex); } }
/// <summary> /// On end callback from Framework event source. /// </summary> /// <param name="id">Identifier of SQL connection object.</param> /// <param name="success">Indicate whether operation completed successfully.</param> /// <param name="sqlExceptionNumber">SQL exception number.</param> public void OnEndExecuteCallback(long id, bool success, int sqlExceptionNumber) { DependencyCollectorEventSource.Log.EndCallbackCalled(id.ToString(CultureInfo.InvariantCulture)); var telemetryTuple = this.TelemetryTable.Get(id); if (telemetryTuple == null) { DependencyCollectorEventSource.Log.EndCallbackWithNoBegin(id.ToString(CultureInfo.InvariantCulture)); return; } if (!telemetryTuple.Item2) { this.TelemetryTable.Remove(id); var telemetry = telemetryTuple.Item1; telemetry.Success = success; telemetry.ResultCode = sqlExceptionNumber != 0 ? sqlExceptionNumber.ToString(CultureInfo.InvariantCulture) : string.Empty; DependencyCollectorEventSource.Log.AutoTrackingDependencyItem(telemetry.Name); ClientServerDependencyTracker.EndTracking(this.telemetryClient, telemetry); } }
/// <summary> /// On end callback from Framework event source. /// </summary> /// <param name="id">The id.</param> /// <param name="success">The success to indicate if the dependency call completed successfully or not.</param> /// <param name="synchronous">The synchronous flag to indicate if the dependency call was synchronous or not.</param> /// <param name="statusCode">The HTTP status code of the response.</param> public void OnEndHttpCallback(long id, bool?success, bool synchronous, int?statusCode) { DependencyCollectorEventSource.Log.EndCallbackCalled(id); var telemetryTuple = this.TelemetryTable.Get(id); if (telemetryTuple == null) { DependencyCollectorEventSource.Log.EndCallbackWithNoBegin(id); return; } if (!telemetryTuple.Item2) { this.TelemetryTable.Remove(id); var telemetry = telemetryTuple.Item1 as DependencyTelemetry; telemetry.DependencyKind = RemoteDependencyKind.Http.ToString(); telemetry.Success = success; telemetry.ResultCode = statusCode.HasValue ? statusCode.ToString() : string.Empty; ClientServerDependencyTracker.EndTracking(this.telemetryClient, telemetry); } }
/// <summary> /// On end callback from Framework event source. /// </summary> /// <param name="id">The id.</param> /// <param name="success">The success to indicate if the dependency call completed successfully or not.</param> /// <param name="synchronous">The synchronous flag to indicate if the dependency call was synchronous or not.</param> /// <param name="statusCode">The HTTP status code of the response.</param> public void OnEndHttpCallback(long id, bool?success, bool synchronous, int?statusCode) { DependencyCollectorEventSource.Log.EndCallbackCalled(id.ToString(CultureInfo.InvariantCulture)); var telemetryTuple = this.TelemetryTable.Get(id); if (telemetryTuple == null) { DependencyCollectorEventSource.Log.EndCallbackWithNoBegin(id.ToString(CultureInfo.InvariantCulture)); return; } if (!telemetryTuple.Item2) { this.TelemetryTable.Remove(id); DependencyTelemetry telemetry = telemetryTuple.Item1; telemetry.DependencyKind = RemoteDependencyKind.Http.ToString(); if (statusCode.HasValue) { // We calculate success on the base of http code and do not use the 'success' method argument // because framework returns true all the time if you use HttpClient to create a request // statusCode == -1 if there is no Response telemetry.Success = (statusCode > 0) && (statusCode < 400); telemetry.ResultCode = statusCode.Value > 0 ? statusCode.Value.ToString(CultureInfo.InvariantCulture) : string.Empty; ClientServerDependencyTracker.EndTracking(this.telemetryClient, telemetry); } else { // This case is for 4.5.2 // We never collected statusCode or success before 2.1.0-beta4 // We also had duplicates if runtime is also 4.5.2 (4.6 runtime has no such problem) // So starting with 2.1.0-beta4 we are cutting support for HTTP dependencies in .NET 4.5.2. } } }
/// <summary> /// Common helper for all End Callbacks. /// </summary> /// <param name="exception">The exception object if any.</param> /// <param name="thisObj">This object.</param> /// <param name="returnValue">Return value of the function if any.</param> private void OnEnd(object exception, object thisObj, object returnValue) { try { if (thisObj == null) { DependencyCollectorEventSource.Log.NotExpectedCallback(0, "OnBeginHttp", "thisObj == null"); return; } DependencyCollectorEventSource.Log.EndCallbackCalled(thisObj.GetHashCode().ToString(CultureInfo.InvariantCulture)); Tuple <DependencyTelemetry, bool> telemetryTuple = this.TelemetryTable.Get(thisObj); if (telemetryTuple == null) { DependencyCollectorEventSource.Log.EndCallbackWithNoBegin(thisObj.GetHashCode().ToString(CultureInfo.InvariantCulture)); return; } if (telemetryTuple.Item1 == null) { DependencyCollectorEventSource.Log.EndCallbackWithNoBegin(thisObj.GetHashCode().ToString(CultureInfo.InvariantCulture)); return; } // Not custom created if (!telemetryTuple.Item2) { this.TelemetryTable.Remove(thisObj); DependencyTelemetry telemetry = telemetryTuple.Item1; int statusCode = -1; var responseObj = returnValue as HttpWebResponse; if (responseObj == null && exception != null) { var webException = exception as WebException; if (webException != null) { responseObj = webException.Response as HttpWebResponse; } #if !NET40 if (responseObj == null) { var httpException = exception as HttpException; if (httpException != null) { statusCode = httpException.GetHttpCode(); } } #endif } if (responseObj != null) { try { statusCode = (int)responseObj.StatusCode; if (responseObj.Headers != null) { var targetIkeyHash = responseObj.Headers[RequestResponseHeaders.TargetInstrumentationKeyHeader]; // We only add the cross component correlation key if the key does not remain the current component. if (!string.IsNullOrEmpty(targetIkeyHash) && targetIkeyHash != InstrumentationKeyHashLookupHelper.GetInstrumentationKeyHash(telemetry.Context.InstrumentationKey)) { telemetry.Type = RemoteDependencyConstants.AI; telemetry.Target += " | " + targetIkeyHash; } } } catch (ObjectDisposedException) { // ObjectDisposedException is expected here in the following sequence: httpWebRequest.GetResponse().Dispose() -> httpWebRequest.GetResponse() // on the second call to GetResponse() we cannot determine the statusCode. } } telemetry.ResultCode = statusCode > 0 ? statusCode.ToString(CultureInfo.InvariantCulture) : string.Empty; telemetry.Success = (statusCode > 0) && (statusCode < 400); ClientServerDependencyTracker.EndTracking(this.telemetryClient, telemetry); } } catch (Exception ex) { DependencyCollectorEventSource.Log.CallbackError(thisObj == null ? 0 : thisObj.GetHashCode(), "OnBeginHttp", ex); } }
/// <summary> /// Common helper for all End Callbacks. /// </summary> /// <param name="exception">The exception object if any.</param> /// <param name="thisObj">This object.</param> /// <param name="returnValue">Return value of the function if any.</param> internal void OnEnd(object exception, object thisObj, object returnValue) { try { if (thisObj == null) { DependencyCollectorEventSource.Log.NotExpectedCallback(0, "OnBeginHttp", "thisObj == null"); return; } DependencyCollectorEventSource.Log.EndCallbackCalled(thisObj.GetHashCode().ToString(CultureInfo.InvariantCulture)); WebRequest webRequest = thisObj as WebRequest; if (webRequest == null) { DependencyCollectorEventSource.Log.UnexpectedCallbackParameter("WebRequest"); } var telemetryTuple = this.GetTupleForWebDependencies(webRequest); if (telemetryTuple == null) { DependencyCollectorEventSource.Log.EndCallbackWithNoBegin(thisObj.GetHashCode().ToString(CultureInfo.InvariantCulture)); return; } if (telemetryTuple.Item1 == null) { DependencyCollectorEventSource.Log.EndCallbackWithNoBegin(thisObj.GetHashCode().ToString(CultureInfo.InvariantCulture)); return; } // Not custom created if (!telemetryTuple.Item2) { this.RemoveTupleForWebDependencies(webRequest); DependencyTelemetry telemetry = telemetryTuple.Item1; var responseObj = returnValue as HttpWebResponse; if (responseObj == null && exception != null) { var webException = exception as WebException; if (webException != null) { responseObj = webException.Response as HttpWebResponse; } } if (responseObj != null) { int statusCode = -1; try { statusCode = (int)responseObj.StatusCode; } catch (ObjectDisposedException) { // ObjectDisposedException is expected here in the following sequence: httpWebRequest.GetResponse().Dispose() -> httpWebRequest.GetResponse() // on the second call to GetResponse() we cannot determine the statusCode. } telemetry.ResultCode = statusCode > 0 ? statusCode.ToString(CultureInfo.InvariantCulture) : string.Empty; telemetry.Success = (statusCode > 0) && (statusCode < 400); } else if (exception != null) { var webException = exception as WebException; if (webException != null) { telemetry.ResultCode = webException.Status.ToString(); } telemetry.Success = false; } if (responseObj != null) { try { if (responseObj.Headers != null) { string targetAppId = null; try { targetAppId = responseObj.Headers.GetNameValueHeaderValue(RequestResponseHeaders.RequestContextHeader, RequestResponseHeaders.RequestContextCorrelationTargetKey); } catch (Exception ex) { AppMapCorrelationEventSource.Log.GetCrossComponentCorrelationHeaderFailed(ex.ToInvariantString()); } string currentComponentAppId; if (this.correlationIdLookupHelper.TryGetXComponentCorrelationId(telemetry.Context.InstrumentationKey, out currentComponentAppId)) { // We only add the cross component correlation key if the key does not remain the current component. if (!string.IsNullOrEmpty(targetAppId) && targetAppId != currentComponentAppId) { telemetry.Type = RemoteDependencyConstants.AI; telemetry.Target += " | " + targetAppId; } } string targetRoleName = null; try { targetRoleName = responseObj.Headers.GetNameValueHeaderValue(RequestResponseHeaders.RequestContextHeader, RequestResponseHeaders.RequestContextTargetRoleNameKey); } catch (Exception ex) { AppMapCorrelationEventSource.Log.GetComponentRoleNameHeaderFailed(ex.ToInvariantString()); } if (!string.IsNullOrEmpty(targetRoleName)) { telemetry.Type = RemoteDependencyConstants.AI; telemetry.Target += " | roleName:" + targetRoleName; } } } catch (ObjectDisposedException) { // ObjectDisposedException is expected here in the following sequence: httpWebRequest.GetResponse().Dispose() -> httpWebRequest.GetResponse() // on the second call to GetResponse() we cannot determine the statusCode. } } ClientServerDependencyTracker.EndTracking(this.telemetryClient, telemetry); } } catch (Exception ex) { DependencyCollectorEventSource.Log.CallbackError(thisObj == null ? 0 : thisObj.GetHashCode(), "OnBeginHttp", ex); } }