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

Continue Trace but with existing transaction #4021

Open
m-kovac opened this issue Mar 3, 2025 · 4 comments
Open

Continue Trace but with existing transaction #4021

m-kovac opened this issue Mar 3, 2025 · 4 comments

Comments

@m-kovac
Copy link

m-kovac commented Mar 3, 2025

Problem Statement

TL;DR We want to continue trace in the desktop WPF application with sentry-header received from embedded application but with existing transaction already present.

This WPF application is embedding chromium webview. We are creating global transaction that is alive during the lifetime of WPF application and one or more spans that represents the instance - there can be more than one instance of the embedded chromium. When the webview is starting, it will receive the traceId and spanId of the parent span which is then continued in different methods with continueTrace. User can e.g. log in in the chromium. This will produce span in web app and sends the traceId and spanId as parameters to login method back in the WPF application. We want to continue that particular span produced in the web application back in the WPF app. This appears to be currently not possible.

Solution Brainstorm

Currently we tried to use the ContinueTrace API as documented here. But this produces no span in Sentry in our case. We suspect that this has something to do with creating concurrent transaction.

// Sampled
var transaction = SentrySdk.StartTransaction("ROOT", "ROOT_OPERATION");
// Sampled
var span = transaction.StartChild("CHILD_OPERATION");

// receive trace data from application running in chromium webview

// Continue span
if (span?.IsSampled.HasValue == true)
{
    var sampled = (bool)span?.IsSampled ? "1" : "0";
    var header = $"{span?.TraceId}-{span?.SpanId}-{sampled}";
    var context = SentrySdk.ContinueTrace(header, null);

    // Not sampled
    var continuedTransaction = SentrySdk.StartTransaction(context);
    var continuedSpan = continuedTransaction.StartChild("CONTINUED_CHILD_OPERATION");

    continuedSpan.Finish();
}
span?.Finish();
transaction?.Finish();

The continued trace is not sampled.
We would expect similar API as in JS

Span span = SentrySdk.ContinueSpan("sentry-header", "CONTINUED_CHILD_OPERATION");
@jamescrosswell
Copy link
Collaborator

Hi @m-kovac ,

SentrySdk.ContinueTrace is probably badly named. Something like SentrySdk.PropagateTrace would better describe what it does... Essentially, if you have three machines/processes in your trace A -> B -> C and tracing is enabled in nodes A and C but not in node B, node B and "continue" the trace by ensuring trace headers received from node A get passed to node C, even though node B doesn't actually add any transactions/spans to the trace.

I don't entirely follow what you're trying to do (it seems like a complex scenario), but if you want to create a transaction with a traceid or a spanid that you know ahead of time, you can create the transaction context manually using this overload:

public TransactionContext(
string name,
string operation,
SpanId? spanId = null,
SpanId? parentSpanId = null,
SentryId? traceId = null,
string? description = "",
SpanStatus? status = null,
bool? isSampled = null,
bool? isParentSampled = null,
TransactionNameSource nameSource = TransactionNameSource.Custom
)

@m-kovac
Copy link
Author

m-kovac commented Mar 4, 2025

Our scenario is different, more like A->B->A->C. This should be distributed trace, so the arrow represents parent->child relationship between spans. All those apps have tracing enabled. Yes It's complex scenario, we would like to figure out. Thanks for pointing the TransactionContext out, I will check, if it can help us.

@getsantry getsantry bot moved this to Waiting for: Product Owner in GitHub Issues with 👀 3 Mar 4, 2025
@m-kovac
Copy link
Author

m-kovac commented Mar 4, 2025

I see that the ContinueTrace is instantiating new TransactionContext . As I mentioned before, we suspect that creating another transaction when one is existing already, is the problem why the continued span is not recorded. We want the first transaction to be alive during the whole lifetime of the WPF application, but also create new spans in WPF application which parents will be spans from other application.

@jamescrosswell
Copy link
Collaborator

Transactions are basically "spans with no parent" so you can't have a transaction that's a child of another transaction.

You can start/build two transactions at the same time. For example you could do (pseudo-code):

var t1 = new transaction
var t2 = new transaction
t1.startchild
t2.startchild
Foo.DoSomeWork()
t1.finish
t2.finish

Multiple transactions can be tied together as part of a single "Trace" however (typically in distributed applications). It sounds like this is what you want to do. In that case you can have

MachineA
- var t1 = new transaction
- request MachineB.Foo

MachineB.Foo
- var t2 is new transaction
- DoSomeWork
- t2.Finish

Machine A
- t1.Finish

And all of that would be collected in a single trace in Sentry.

Is the WPF application creating the first transaction? And then you want each of the WebView's to start other transactions that you want to see on the same "Trace"? And so is your question how to propagate the trace information from the WPF application to the various WebViews?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: No status
Status: No status
Development

No branches or pull requests

2 participants