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

ActivityContext.TryParse should support IsRemote #42575

Closed
Tracked by #62027
cg110 opened this issue Sep 22, 2020 · 9 comments · Fixed by #63692
Closed
Tracked by #62027

ActivityContext.TryParse should support IsRemote #42575

cg110 opened this issue Sep 22, 2020 · 9 comments · Fixed by #63692
Assignees
Labels
api-approved API was approved in API review, it can be implemented area-System.Diagnostics.Activity
Milestone

Comments

@cg110
Copy link

cg110 commented Sep 22, 2020

Edited and added the proposal by @tarekgh

Description

When using ActivitySource I wanted to support IsRemote (for opentelemetry), as the majority of the time any activity started with a w3c trace context will be remote.

To start an activity with IsRemote set needs an ActivityContext, the best option appears to be use:
ActivityContext.TryParse(traceParent, traceState, out var context)
However, a context then needs creating to copy the parsed context, and set IsRemote.

It would be useful if TryParse could provide a version that can pass IsRemote into the ActivityContext. I'd expect the majority of new activities that use TryParse are providing a traceparent and state from a remote caller.

Proposal

public readonly struct ActivityContext
{
   public static bool TryParse(string? traceParent, string? traceState, out System.Diagnostics.ActivityContext context)
+  public static bool TryParse(string? traceParent, string? traceState, bool isRemote, out System.Diagnostics.ActivityContext context)
}

Example

    const string w3cId = "00-99d43cb30a4cdb4fbeee3a19c29201b0-e82825765f051b47-01";
    if (TryParseActivityContext(w3cId, "k=v", isRemote: true, out ActivityContext context)) // Parse the context with setting isRemote to true
    {
        // do something with the context
    }

Alternatives

Users can manually add the following helper method but that means every user need this functionality will need to add this method.

    public static bool TryParseActivityContext(string? traceParent, string? traceState, bool isRemote, out ActivityContext context)
    {
        if (ActivityContext.TryParse(traceParent, traceState, out  context))
        {
            context = new ActivityContext(context.TraceId, context.SpanId, context.TraceFlags, context.TraceState, isRemote);
            return true;
        }
        return false;
    }
@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added area-System.Diagnostics.Tracing untriaged New issue has not been triaged by the area owner labels Sep 22, 2020
@ghost
Copy link

ghost commented Sep 22, 2020

Tagging subscribers to this area: @tarekgh, @tommcdon, @pjanotti
See info in area-owners.md if you want to be subscribed.

@tarekgh tarekgh added enhancement Product code improvement that does NOT require public API changes/additions and removed untriaged New issue has not been triaged by the area owner labels Sep 22, 2020
@tarekgh tarekgh added this to the Future milestone Sep 22, 2020
@tarekgh
Copy link
Member

tarekgh commented Sep 22, 2020

However, a context then needs creating to copy the parsed context, and set IsRemote.

Why this is not enough for you? ActivityContext is a struct and doing that wouldn't cause any real perf issue as it doesn't allocate and the struct size is really small. I don't think it is a good idea to expose a new API just to support this.

CC @noahfalk

@cg110
Copy link
Author

cg110 commented Sep 23, 2020

It's more that it's error prone, and easy to forget

Really I'd like to do Activity.StartActivity with trace parent, trace source, and isremote, but using activityContext seemed the next easiest alternative, but it needs a dance to get IsRemote set.

@tarekgh
Copy link
Member

tarekgh commented Sep 23, 2020

It's more that it's error prone, and easy to forget

I am not sure I understand this. How this is error prone? You can create your own helper method doing the functionality, it is simple and I wouldn't expect anyone can get it wrong. Easy to forget would be same as if someone manually creating ActivityContext object and forget to pass isRemote as it is optional parameters. Who cares about isRemote would never forget about it.

@tarekgh tarekgh added api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Diagnostics.Activity and removed area-System.Diagnostics.Tracing enhancement Product code improvement that does NOT require public API changes/additions labels Jan 8, 2021
@CodeBlanch
Copy link
Contributor

API proposal:

public readonly struct ActivityContext
{
   public static bool TryParse(
      string? traceParent,
      string? traceState,
      out System.Diagnostics.ActivityContext context,
      bool isRemote = false) // New parameter with default set to current behavior.
   {
   }

For me it isn't a question of whether the workaround is easy or not, it is a question of how do you know you need the workaround? You don't get immediate feedback that you made a misake. You might not even notice until in production when your sampling is off. If you do notice your sampling is off, it is natural to look at the sampler for issues. Triaging that all the way back to this API is difficult. I think adding the parameter would be a nice hint to users that they should consider whether or not the context belongs to a remote parent when it is created.

@tarekgh
Copy link
Member

tarekgh commented Nov 16, 2021

@CodeBlanch thanks for the proposal. We cannot add an extra parameter to the existing method as it will be a breaking change. It is like removing a method. I suggest we add extra overload. Something like:

public readonly struct ActivityContext
{
   public static bool TryParse(string? traceParent, string? traceState, out System.Diagnostics.ActivityContext context)
+  public static bool TryParse(string? traceParent, string? traceState, bool isRemote, out System.Diagnostics.ActivityContext context)
}

Note, isRomte is not defaulted parameter as I want to disnguish this overload from the already existing one. The other reason is I want to stick with the TryParse pattern which having the out parameter be last parameter. What do you think?

CC @noahfalk @cijothomas @reyang

@CodeBlanch
Copy link
Contributor

@tarekgh New method looks good to me. I suspected adding the parameter would be breaking but wasn't sure 😄

PS: How did you do that diff comment thing? That is neat.

@tarekgh
Copy link
Member

tarekgh commented Nov 17, 2021

PS: How did you do that diff comment thing? That is neat.

```diff

and having + in front of the line means added and will show up in green. having - in front of the line means deleted and will show up in red

@tarekgh tarekgh self-assigned this Nov 21, 2021
@tarekgh tarekgh modified the milestones: Future, .NET 7.0 Nov 24, 2021
@karelz karelz modified the milestones: .NET 7.0, 7.0.0 Nov 25, 2021
@tarekgh tarekgh added api-ready-for-review API is ready for review, it is NOT ready for implementation blocking Marks issues that we want to fast track in order to unblock other important work and removed api-suggestion Early API idea and discussion, it is NOT ready for implementation labels Jan 8, 2022
@bartonjs
Copy link
Member

bartonjs commented Jan 11, 2022

Video

Looks good as proposed.

namespace System.Diagnostics
{
    public readonly partial struct ActivityContext
    {
        // existing
        // public static bool TryParse(string? traceParent, string? traceState, out System.Diagnostics.ActivityContext context);

        // new
        public static bool TryParse(
            string? traceParent,
            string? traceState,
            bool isRemote,
            out System.Diagnostics.ActivityContext context);
    }
}

@bartonjs bartonjs added api-approved API was approved in API review, it can be implemented and removed blocking Marks issues that we want to fast track in order to unblock other important work api-ready-for-review API is ready for review, it is NOT ready for implementation labels Jan 11, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Feb 12, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-approved API was approved in API review, it can be implemented area-System.Diagnostics.Activity
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants