aws / aws-xray-sdk-dotnet

The official AWS X-Ray SDK for .NET.
Apache License 2.0
109 stars 64 forks source link

EntityNotFoundException in EFInterceptor When Parent Segment Missing in MassTransit Outbox Pattern #299

Open cikdibest opened 5 months ago

cikdibest commented 5 months ago

We have configured our DbContext and MassTransit Outbox pattern as follows:

Setup:

 services.AddDbContext<ApplicationDbContext>(options =>
 {
options.UseNpgsql(config.ConnectionString, npgsqlOptionsAction: sqlOptions =>
{
    sqlOptions.MigrationsHistoryTable(HistoryRepository.DefaultTableName, dbSchemaName);
    sqlOptions.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name);
}).UseSnakeCaseNamingConvention();

options.EnableDetailedErrors();

options.AddXRayInterceptor(true);
 },
 ServiceLifetime.Scoped);

  x.AddEntityFrameworkOutbox<ApplicationDbContext>(o =>{
  o.UseBusOutbox();
  o.UsePostgres();
  });

  x.AddConsumers(typeof(UserProfileCreatedNotifyConsumer).Assembly);

  x.SetKebabCaseEndpointNameFormatter();
  x.UsingAmazonSqs((context, cfg) =>
    {

  cfg.Host("eu-west-2", h =>
  {

  });

  cfg.ClearSerialization();
  cfg.UseRawJsonSerializer();
  cfg.UseRawJsonDeserializer();

  cfg.ReceiveEndpoint("user-profile-created-notification-consumer", e =>
  {
      e.ConfigureConsumeTopology = false;
      e.ConfigureConsumer<UserProfileCreatedNotifyConsumer>(context);

      e.Subscribe("user-profile-created", x =>
          {
              x.Durable = true;
              x.AutoDelete = false;
          }
      );
  });`

Issue Description:

When using the AddXRayInterceptor(true) configuration, the EFInterceptor attempts to create a subsegment for every database query. However, during the execution of outbox-related queries, if the parent segment hasn't been created yet, the EFInterceptor fails to create the subsegment, leading to an EntityNotFoundException.

Suggested Enhancement:

It would be beneficial if the EFInterceptor could check whether the parent segment exists before attempting to create a subsegment. If the parent segment does not exist, ideally, the interceptor should start it. This enhancement would prevent the EntityNotFoundException and ensure smoother integration between Entity Framework and AWS X-Ray within the context of using MassTransit's Outbox pattern.

srprash commented 3 months ago

Hi @cikdibest , thanks for reporting the issue and also for providing the suggestion. The EntityNotFoundException is thrown when a parent segment or subsegment is missing when a new subsegment is created. We throw this exception instead of creating a parent segment on the fly because a) a parent segment should mostly exist on incoming requests when a service is instrumented correctly. b) creating segments on the fly may cause broken traces with unintended segments.

In your case, you can do either of the following:

  1. Instrument your service to create a segment on each incoming request. You can follow this doc to enable tracing of incoming requests: https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-dotnet-messagehandler.html
  2. Set the environment variable AWS_XRAY_CONTEXT_MISSING to IGNORE_ERROR and this will suppress logging the EntityNotFoundException. More details in this doc: https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-dotnet-configuration.html#xray-sdk-dotnet-configuration-envvars