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

Can I force subsegments to be the direct child of a segment? #332

Open
digithead1011 opened this issue May 16, 2022 · 5 comments
Open

Can I force subsegments to be the direct child of a segment? #332

digithead1011 opened this issue May 16, 2022 · 5 comments
Assignees

Comments

@digithead1011
Copy link

I am writing an AWS Lambda function in Java that uses Project Reactor and reactive programming paradigms. The methods that I want to trace return Mono or Flux, which is really just a promise to return something in the future. This means that the work isn't "done" when the method exits. Instead, the subsegment should be started when the method is called and ended when the Mono or Flux complete.

More importantly, though, work is being done parallel and any new subsegment should be a direct child of the segment created by the Lambda runtime, and not a child of the "current" subsegment. Is there a way to specify this when creating a subsegment? I don't see that in AWSXRay. All of the methods to begin or create a subsegment ultimately use AWSXRayRecorder.beginSubsegment(String), which delegates the task to the context. In the case of LambdaSegmentContext anyway, the newly created subsegment only seems to be added directly to the segment when it is the first subsegment. After that, newly created subsegments are added as a child of the "current" subsegment.

With the way that subsegments are created by default, a graph of my trace would look like this, where S is the segment and 1, 2, 3, and 4 are the subsegments:

SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
   11111111111111111111111111111111111
        222222222222222222222222222
               33333333333333333
                     44444444

By comparison, if I were (am?) able to specify the segment as the parent, the work being done would be graphed more like this instead, which is how it's actually happening:

SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
   1111111
        2222222222
               33333333333333333
                               44444444
@digithead1011
Copy link
Author

It's probably worth mentioning that ThreadLocalSegmentContext appears to always create new subsegments as an immediate child of the segment rather than as a child of the currently traced entity, which could be another subsegment. I'm too new here to understand the nuances of why LambdaSegmentContext has different behavior.

I'm guessing that I can't control which type of context is used.

@wangzlei
Copy link
Contributor

Hi,

In theory, user can parent a subsegment to any other segment(or subsegment) by manually create data in low-level API.

We don't officially suggest that because xray segment data model is rigid, that touches some low level logic such as a subsegment has to have a parent segment(not subsegment).

@Kurru
Copy link
Contributor

Kurru commented Jul 22, 2022

In my experience Lambda has some slightly different rules for when it creates the segment which was a little confusing for us. IIRC, you cant interact with the lambda segment much, but you can manipulate lambda subsegments fine (but I could be mistaken).

Outside of lambda, we did have good luck with manipulating the X-Ray context using AWSXRay.setTraceEntity(originalSegment); to move the current context around, which allowed us to support async actions and AWSXRay.endSubsegment(otherSegment) to end these floating subsegments.

Using setTraceEntity has been the way we've added support for various async xray segments, but do be wary of #318

Subsegment original = AWSXray.getTraceEntity();
Subsegment asyncSegment = AWSXray.beginSubsegment("concurrent");
ListenableFuture<?> future = beginFuture();
future.addListener(() -> AWSXray.endSubsegment(asyncSegment));
AWSXRay.setTraceEntity(original); // Restore the segment back to the original

@twbecker
Copy link

I just hit this issue as well. I'm kicking off a number of asynchronous tasks and want each one to be represented by a subsegment that is a direct child of the current segment at the point where the tasks are submitted. I was able to work around this similarly to how @Kurru described:

    private Subsegment getAsyncSubsegment(String name) {
        Entity previous = AWSXRay.getTraceEntity();
        try {
            return AWSXRay.beginSubsegment(name);
        } finally {
            AWSXRay.setTraceEntity(previous);
        }
    }

This works, but it's clumsy and AWSXRay.setTraceEntity() is deprecated. It would be nice to provide a way to hang subsegments off a segment without updating the context.

@Kurru
Copy link
Contributor

Kurru commented Jan 19, 2024

I assumed setTraceEntity() isn't really deprecated, but rather annotated as such to highlight the typically more convenient method: AWSXRay.createSubsegment(). Without it, dunno how these custom flows would be configured

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

No branches or pull requests

4 participants