Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: How to store Activity.Id before start it? #2213

Closed
shawnzxx opened this issue Jan 27, 2020 · 2 comments
Closed

Question: How to store Activity.Id before start it? #2213

shawnzxx opened this issue Jan 27, 2020 · 2 comments
Labels
area-Diagnostics-coreclr question Answer questions and provide assistance, not an issue with source code or documentation. tracking This issue is tracking the completion of other related issues.
Milestone

Comments

@shawnzxx
Copy link

shawnzxx commented Jan 27, 2020

Context:

I have a special requirement to store "dependencyActivity.id" in a transaction, see a line of code attached below:
await SaveOutgoingEventAsync(String.Empty);
I am currently storing an empty string as a temp version of dependencyActivity.id, and update it to the actual value of dependencyActivity.Id after I start the dependencyActivity. Use this way to pass down the parent and child relationship to the next external process, dependencyActivity.Id as my downstream service's operationParentId.

Question:

1: What is the best practice to store dependent id before I start and stop telemetry operation?

Code:

public async Task<ReturnOrderDto> SubmitOrderAsync(SubmitOrderDto order)
{
    var executionStrategy = _orderDbContext.Database.CreateExecutionStrategy();
    await executionStrategy.ExecuteAsync(async () =>
    {
        using (var transaction = _orderDbContext.Database.BeginTransaction(IsolationLevel.ReadCommitted))
        {
            //Some processing code
            ......
            ......

            //Store empty string as dependencyActivity.Id in database
            await SaveOutgoingEventAsync(String.Empty);
            // Commit incoming, business and outgoing entities together in outbox pattern
            await transaction.CommitAsync();
        }
    });

    var dependencyActivity = new Activity("Publish Message");
    dependencyActivity.SetParentId(Activity.Current.Id);
    dependencyActivity.Start();
    var operation = _telemetryClient.StartOperation<DependencyTelemetry>(dependencyActivity);
    var messageHeader = new KafkaMessageHeader(dependencyActivity.TraceId.ToString(), dependencyActivity.Id);
    kafkaMessage.UpdateHeader(messageHeader);
    await _publisher.ProduceAsync(kafkaMessage);
    _telemetryClient.StopOperation(operation);
    
    //update previous stored empty Id to dependencyActivity.Id
    outgoingEvent.UpdateOutgoingIntegrationEvent(dependencyActivity.TraceId.ToString(), dependencyActivity.Id);
    outgoingEvent.MarkAsSent();
    await _outgoingEventRepository.SaveChangesAsync();

    return new ReturnOrderDto { OrderId = _orderEntity.OrderId };
}
@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added the untriaged New issue has not been triaged by the area owner label Jan 27, 2020
@noahfalk
Copy link
Member

A typical order of operations looks like:

  1. Start Activity
  2. Record the activity information
  3. Do some work
  4. Stop the activity

It is a domain specific judgement what work belongs inside the scope of the activity (step 3). The ID is created by invoking start so it is impossible to log the id before Start() has occurred, but you can delay it until later if you want to (as your example does).

The main risk of doing it later is that if the operation fails you might want the ID to diagnose but not have it. For example if await _publisher.ProduceAsync(kafkaMessage); threw an exception then outgoingEvent.UpdateOutgoingIntegrationEvent(…) would be skipped. You can either try to handle such failures (try/finally), decide that you don't need the ID in failure cases, or move the logging to occur before the failure.

Was that the info you were looking for or something else?

One other random note, "dependencyActivity.SetParentId(Activity.Current.Id);" isn't needed, this will happen by default when an Activity is started.

@tommcdon tommcdon added question Answer questions and provide assistance, not an issue with source code or documentation. and removed untriaged New issue has not been triaged by the area owner labels Mar 27, 2020
@tommcdon tommcdon added this to the 5.0 milestone Mar 27, 2020
@tommcdon tommcdon added the tracking This issue is tracking the completion of other related issues. label Jul 6, 2020
@tommcdon tommcdon modified the milestones: 5.0.0, 6.0.0 Jul 8, 2020
@noahfalk
Copy link
Member

Going to close this assuming the question is answered : ) If not we can always re-open.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-Diagnostics-coreclr question Answer questions and provide assistance, not an issue with source code or documentation. tracking This issue is tracking the completion of other related issues.
Projects
None yet
Development

No branches or pull requests

5 participants