0

Environment

  • ASP.NET WebAPI calling external client services.
  • XRay incoming trace applied in Global.asax via

    AWSXRayASPNET.RegisterXRay(this, "CustomerAPI");
    
  • HttpClient instance hidden as private member in utility class, shared in a separate project with multiple WebAPI

  • HttpClient having delegating handler for Xray enable as follows:- (Ref: .NET HttpClient for outgoing XRay)

    bool isXrayEnabled = false;                    
    bool.TryParse(Config["XRayEnable"], out isXrayEnabled);
    
    if (isXrayEnabled)
    {
         Logger.Info("Enabling XRay tracing with Http calls");
         httpClient = new HttpClient(new HttpClientXRayTracingHandler(new HttpClientHandler()));
    }
    else
    {
         httpClient = new HttpClient();
         Logger.Info("Disabling XRay tracing with Http calls");
    }
    

Issue While all APIs shows incoming XRay trace, the outgoing trace is not shown at all. Incoming trace

Instead, following error is shown in the XRay logs

   Exception type: EntityNotAvailableException

    Exception message: Entity doesn't exist in HTTPContext
   at Amazon.XRay.Recorder.Core.Internal.Context.HybridContextContainer.InjectEntityInTraceContext()
   at Amazon.XRay.Recorder.Core.AWSXRayRecorderImpl.AddHttpInformation(String key, Object value)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Amazon.XRay.Recorder.Core.AWSXRayRecorderImpl.AddHttpInformation(String key, Object value)
   at Amazon.XRay.Recorder.Handlers.AspNet.AWSXRayASPNET.ProcessHTTPResponse(Object sender, EventArgs e)
   at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
NitinSingh
  • 2,029
  • 1
  • 15
  • 33

1 Answers1

0

From the error stack it looks like the exception occurs here :https://github.com/aws/aws-xray-sdk-dotnet/blob/master/sdk/src/Handlers/AspNet/AWSXRayASPNET.cs#L209. The response received in this event doesn't have Segment started by the middleware in the BeginRequest : https://github.com/aws/aws-xray-sdk-dotnet/blob/master/sdk/src/Handlers/AspNet/AWSXRayASPNET.cs#L141 and hence not able to store HTTP information.

Can you answer following questions:

  1. How is the flow for a given incoming request : request->WEBAPI->HTTPClient? Are the HTTPClient calls asynchronous?
  2. If you have ASP.NET middleware instrumented and do not enable HTTPClient X-Ray instrumentation, do you still get above error? Or this error is a result of enabling HTTPClient instrumentation. Reason to narrow down since the error stack is coming from X-Ray middleware and not HTTP client.
  3. HttpClientXRayTracingHandler creates a Subsegment for you. This instrumentor expects Segment to be already present in the TraceContext which in this case is created by AWSXRayASPNET. As per your statement, "HttpClient instance hidden as private member in utility class, shared in a separate project with multiple WebAPI", can you check whether Segment is present in the TraceContext just before making a network call using AWSXRayRecorder.Instance.GetEntity(). This should return Segment started by the middleware or subsegment if you have manually created before this call.
  4. Do you have any configuration related to threadpool leading to TraceContext not correctly propagated between threads?

In the above code snippet, you don't need to to do "isXrayEnabled()" check. By default you can instrument HTTPClient with X-Ray ant the middleware does this check for you : https://github.com/aws/aws-xray-sdk-dotnet/blob/master/sdk/src/Handlers/System.Net/Utils/RequestUtil.cs#L59

Thanks, Yogi

  • 1) Flow is (external request) -> WebAPI -> HttpClient -> Another WebAPI or external service. All the calls are asynchronous – NitinSingh Jun 12 '19 at 11:51
  • 2) We don't have any app level middleware, apart from the AWS XRay which is set for the incoming messages in Global.asax. The incoming traces are working correctly even with the present setup. We never examined the logs due to no error coming, before setting HttpClient instrumentation – NitinSingh Jun 12 '19 at 11:54
  • 4) No explicit configuration related to TraceContext or ThreadPool apart from that set by .NET Framework implicitly. The isXrayEnabled check is due to the fact that the containing utility is consumed by multiple clients and we may not enable XRay on all of them – NitinSingh Jun 12 '19 at 11:58
  • 3) In a sample app running locally over XRay daemon, when we place GetEntity call just before hitting httpClient.GetAsync, we get a valid instance, the property *Aws* contains a dictionary with values [(sdk, Xray for .net), (sdk_version, 2.5.2)], the segment name is reflected with the name given in the RegisterXray call, the Http property has correctly referring the url being hit. However, even for a simple url like Google, we are struck on getting response. – NitinSingh Jun 12 '19 at 13:26
  • Hello, thanks for detail reply. "However, even for a simple url like Google, we are struck on getting response" -> I think you need to enable debug logs for the X-Ray SDK to see whether we can get more insights on what is happening : https://github.com/aws/aws-xray-sdk-dotnet/tree/master#logging-net – Yogiraj Awati Jun 12 '19 at 17:01
  • Before starting Async call, correct Segment is present in the TraceContext. Somehow for the request lifecycle, this Segment is removed from the TraceContext. For ASP.NET middleware we store Segment/Subsegment in CallContext and a reference in HTTPContext : https://github.com/aws/aws-xray-sdk-dotnet/blob/master/sdk/src/Core/Internal/Context/HybridContextContainer.net45.cs . Is it possible for you to provide a sample app (redact sensitive information) so that I can do more analysis. – Yogiraj Awati Jun 12 '19 at 17:01
  • Sure where do I provide you the app. We have an app sample which runs locally via daemon service – NitinSingh Jun 12 '19 at 19:49
  • The sample sourcecode added to AWS Support ticket 6152616131. Let me know if I can send it directly to you as well – NitinSingh Jun 17 '19 at 05:59
  • Hello Nitin, we would carry further correspondence over the AWS Support ticket in order to avoid duplicate. – Yogiraj Awati Jun 18 '19 at 16:23