Sampling application code that doesn't run in response to HTTP request

0

Hi,

I am trying to introduce Xray tracing in one of my services which basically is responsible for executing asynchronous tasks using SQS. This code that needs to be traced does not run in response to an HTTP request. I am not able to find a way where I can control the sampling of this code through the Sampling Rules that I configure on the Xray console. Since this application component spawns worker threads that run in background, I am resorting to creating and ending new segments around each such thread execution.

I understand that for application code triggered through HTTP request, the AWSXRayServletFilter polls for Sampling Rules when a CentralizedSamplingStrategy is configured. Is there a way of leveraging such sampling for application code that is not invoked from an HTTP request?

Any help would be greatly appreciated.

asked 5 years ago363 views
2 Answers
0

You can use CentralizedSamplingStrategy class independently just as how a servlet filter would use it. https://github.com/aws/aws-xray-sdk-java/blob/master/aws-xray-recorder-sdk-core/src/main/java/com/amazonaws/xray/strategy/sampling/CentralizedSamplingStrategy.java

The shouldTrace method takes a sampling request and returns a decision to the caller. Now the question becomes how would you like to use different rules for matching on certain message processing. Or if you just want to config the default rule in which case an empty sampling request object should just work.

Please let me know if this answers your question.

Thanks,
Haotian

AWS
answered 5 years ago
0

Hi,

Sorry for the late reply. Thanks for having a look and replying for my issue. Your answer helped me go ahead with the work around. Calling the shouldTrace API will internally kick off the RulePoller and TargetPoller which will regularly poll for rules that qualify for the current segment being started. So my understanding is that, all the rules that I have configured on the Xray console and that are applicable for this segment ( I identify segments based on unique service names ), will be automatically applied by Xray SDK. Here is the code that I developed for beginning segments for Worker Threads:

    /**
     * AWS XRay does not seem to support centralized sampling of custom segments started in a
     * application context which is not instantiated by a HTTP request [In Worker Threads]. As
     * a result, Sampling falls back to default localized sampling. As per Design, where it
     * is expected that the default Sampling Rules configured for the environment on the XRay
     * Console, these default rules should control the sampling rate always.
     *
     * This method helps in beginning a new segment in the above case where the Sampling strategy
     * configured on the recorder is consulted to check if the segment needs to sampled or not before
     * the segment is created.
     *
     * @param segmentName
     * @return
     */
    public static Segment beginSegment( String segmentName )
    {
        AWSXRayRecorder recorder = AWSXRay.getGlobalRecorder();
        SamplingStrategy samplingStrategy = recorder.getSamplingStrategy();
        Segment created = null;
        SamplingRequest samplingRequest = new SamplingRequest( segmentName, "", "", "", recorder.getOrigin() );
        SamplingResponse samplingResponse = samplingStrategy.shouldTrace( samplingRequest );
        SampleDecision sampleDecision = getSampleDecision( samplingResponse );
        if ( SampleDecision.SAMPLED.equals( sampleDecision ) ) {
            created = recorder.beginSegment( segmentName );
            if ( samplingResponse.getRuleName().isPresent() ) {
                LOGGER.debug( "Sampling strategy decided to use rule named: " + samplingResponse.getRuleName().get() + "." );
                created.setRuleName( samplingResponse.getRuleName().get() );
            }
        } else {
            if ( samplingStrategy.isForcedSamplingSupported() ) {
                created = recorder.beginSegment( segmentName );
                created.setSampled( false );
            } else {
                created = recorder.beginDummySegment();
            }
        }
        return created;
    }

Please do let me know if this is what you suggested. Also, please advice if I should factor in trace ID for the segments that I create this way.

Regards,
Shri

Edited by: shricloud on Jul 3, 2019 12:25 PM

Edited by: shricloud on Jul 3, 2019 12:26 PM

Edited by: shricloud on Jul 3, 2019 12:27 PM

answered 5 years ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions