private void populateSubsegmentException(Subsegment subsegment, Context.FailedExecution context) { Throwable exception = context.exception(); subsegment.addException(exception); int statusCode = -1; if (exception instanceof SdkServiceException) { statusCode = ((SdkServiceException) exception).statusCode(); subsegment.getCause().setMessage(exception.getMessage()); if (((SdkServiceException) exception).isThrottlingException()) { subsegment.setThrottle(true); // throttling errors are considered client-side errors subsegment.setError(true); } setRemoteForException(subsegment, exception); } else if (context.httpResponse().isPresent()) { statusCode = context.httpResponse().get().statusCode(); } if (statusCode == -1) { return; } if (statusCode >= 400 && statusCode < 500) { subsegment.setFault(false); subsegment.setError(true); if (statusCode == 429) { subsegment.setThrottle(true); } } else if (statusCode >= 500) { subsegment.setFault(true); } }
public static void addRequestInformation(Subsegment subsegment, HttpRequest request, String url) { subsegment.setNamespace(Namespace.REMOTE.toString()); Segment parentSegment = subsegment.getParentSegment(); TraceHeader header = new TraceHeader(parentSegment.getTraceId(), parentSegment.isSampled() ? subsegment.getId() : null, parentSegment.isSampled() ? SampleDecision.SAMPLED : SampleDecision.NOT_SAMPLED); request.addHeader(TraceHeader.HEADER_KEY, header.toString()); Map<String, Object> requestInformation = new HashMap<>(); requestInformation.put("url", url); requestInformation.put("method", request.getRequestLine().getMethod()); subsegment.putHttp("request", requestInformation); }
private void populateSubsegmentWithResponse(Subsegment subsegment, SdkHttpResponse httpResponse) { if (subsegment == null || httpResponse == null) { return; } String extendedRequestId = extractExtendedRequestIdFromHttp(httpResponse); if (extendedRequestId != null) { subsegment.putAws(EntityDataKeys.AWS.EXTENDED_REQUEST_ID_KEY, extendedRequestId); } subsegment.putAllHttp(extractHttpResponseParameters(httpResponse)); }
public static void addResponseInformation(Subsegment subsegment, HttpResponse response) { if (null == subsegment) { return; } Map<String, Object> responseInformation = new HashMap<>(); int responseCode = response.getStatusLine().getStatusCode(); switch (responseCode/100) { case 4: subsegment.setError(true); if (429 == responseCode) { subsegment.setThrottle(true); } break; case 5: subsegment.setFault(true); break; } responseInformation.put("status", responseCode); if (null != response.getEntity()) { responseInformation.put("content_length", response.getEntity().getContentLength()); } subsegment.putHttp("response", responseInformation); }
private <R> R wrapHttpSupplier(Subsegment subsegment, HttpSupplier<R> supplier) throws IOException, ClientProtocolException { try { return supplier.get(); } catch (Exception e) { if (null != subsegment) { subsegment.addException(e); } throw e; } finally { if (null != subsegment) { recorder.endSubsegment(); } } }
subsegment.putAllSql(additionalParams); subsegment.setNamespace(Namespace.REMOTE.toString()); subsegment.addException(t);
currentSubsegment.setError(true); currentSubsegment.setThrottle(true); int statusCodePrefix = statusCode / 100; if (4 == statusCodePrefix) { currentSubsegment.setError(true); if (429 == statusCode) { currentSubsegment.setThrottle(true); currentSubsegment.addException(e);
return; currentSubsegment.putAllAws(extractRequestParameters(request)); currentSubsegment.putAws(EntityDataKeys.AWS.OPERATION_KEY, operationName); if (null != accountId) { currentSubsegment.putAws(EntityDataKeys.AWS.ACCOUNT_ID_SUBSEGMENT_KEY, accountId); currentSubsegment.setNamespace(Namespace.AWS.toString()); recorder.getCurrentSegment().isSampled() ? currentSubsegment.getId() : null, recorder.getCurrentSegment().isSampled() ? SampleDecision.SAMPLED : SampleDecision.NOT_SAMPLED); request.addHeader(TraceHeader.HEADER_KEY, header.toString());
@Override public void beforeExecution(Context.BeforeExecution context, ExecutionAttributes executionAttributes) { AWSXRayRecorder recorder = getRecorder(); Entity origin = recorder.getTraceEntity(); Subsegment subsegment = recorder.beginSubsegment(executionAttributes.getAttribute((SdkExecutionAttribute.SERVICE_NAME))); if (subsegment == null) { return; } subsegment.setNamespace(Namespace.AWS.toString()); subsegment.putAws(EntityDataKeys.AWS.OPERATION_KEY, executionAttributes.getAttribute(SdkExecutionAttribute.OPERATION_NAME)); Region region = executionAttributes.getAttribute(AwsExecutionAttribute.AWS_REGION); if (region != null) { subsegment.putAws(EntityDataKeys.AWS.REGION_KEY, region.id()); } subsegment.putAllAws(extractRequestParameters(context, executionAttributes)); if (accountId != null) { subsegment.putAws(EntityDataKeys.AWS.ACCOUNT_ID_SUBSEGMENT_KEY, accountId); } recorder.setTraceEntity(origin); // store the subsegment in the AWS SDK's executionAttributes so it can be accessed across threads executionAttributes.putAttribute(entityKey, subsegment); }
private void populateAndEndSubsegment(Subsegment currentSubsegment, Request<?> request, Response<?> response, AmazonServiceException ase) { if (null != response) { populateAndEndSubsegment(currentSubsegment, request, response); return; } else if (null != ase) { if (null != ase.getRequestId()) { currentSubsegment.putAws(REQUEST_ID_SUBSEGMENT_KEY, ase.getRequestId()); } if (null != ase.getHttpHeaders() && null != ase.getHttpHeaders().get(EntityHeaderKeys.AWS.EXTENDED_REQUEST_ID_HEADER)) { currentSubsegment.putAws(EntityDataKeys.AWS.EXTENDED_REQUEST_ID_KEY, ase.getHttpHeaders().get(EntityHeaderKeys.AWS.EXTENDED_REQUEST_ID_HEADER)); } if (null != ase.getErrorMessage()) { currentSubsegment.getCause().setMessage(ase.getErrorMessage()); } currentSubsegment.putAllHttp(extractHttpResponseInformation(ase)); } finalizeSubsegment(request); }
@Override public SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context, ExecutionAttributes executionAttributes) { SdkHttpRequest httpRequest = context.httpRequest(); Subsegment subsegment = executionAttributes.getAttribute(entityKey); if (subsegment == null) { return httpRequest; } boolean isSampled = subsegment.getParentSegment().isSampled(); TraceHeader header = new TraceHeader( subsegment.getParentSegment().getTraceId(), isSampled ? subsegment.getId() : null, isSampled ? TraceHeader.SampleDecision.SAMPLED : TraceHeader.SampleDecision.NOT_SAMPLED ); return httpRequest.toBuilder().appendHeader(TraceHeader.HEADER_KEY, header.toString()).build(); }
private void populateAndEndSubsegment(Subsegment currentSubsegment, Request<?> request, Response<?> response) { if (null != response) { String requestId = null; if (response.getAwsResponse() instanceof AmazonWebServiceResult<?>) { // Not all services return responses extending AmazonWebServiceResult (e.g. S3) ResponseMetadata metadata = ((AmazonWebServiceResult<?>) response.getAwsResponse()).getSdkResponseMetadata(); if (null != metadata) { requestId = metadata.getRequestId(); if (null != requestId) { currentSubsegment.putAws(REQUEST_ID_SUBSEGMENT_KEY, requestId); } } } else if (null != response.getHttpResponse()) { // S3 does not follow request id header convention if (null != response.getHttpResponse().getHeader(S3_REQUEST_ID_HEADER_KEY)) { currentSubsegment.putAws(REQUEST_ID_SUBSEGMENT_KEY, response.getHttpResponse().getHeader(S3_REQUEST_ID_HEADER_KEY)); } if (null != response.getHttpResponse().getHeader(EntityHeaderKeys.AWS.EXTENDED_REQUEST_ID_HEADER)) { currentSubsegment.putAws(EntityDataKeys.AWS.EXTENDED_REQUEST_ID_KEY, response.getHttpResponse().getHeader(EntityHeaderKeys.AWS.EXTENDED_REQUEST_ID_HEADER)); } } currentSubsegment.putAllAws(extractResponseParameters(request, response.getAwsResponse())); currentSubsegment.putAllHttp(extractHttpResponseInformation(response.getHttpResponse())); } finalizeSubsegment(request); }
@Override public void endSubsegment(AWSXRayRecorder recorder) { Entity current = getTraceEntity(); if (current instanceof Subsegment) { if (logger.isDebugEnabled()) { logger.debug("Ending subsegment named: " + current.getName()); } Subsegment currentSubsegment = (Subsegment) current; if (currentSubsegment.end()) { recorder.sendSegment(currentSubsegment.getParentSegment()); } else { if (recorder.getStreamingStrategy().requiresStreaming(currentSubsegment.getParentSegment())) { recorder.getStreamingStrategy().streamSome(currentSubsegment.getParentSegment(), recorder.getEmitter()); } setTraceEntity(current.getParent()); } } else { recorder.getContextMissingStrategy().contextMissing("Failed to end subsegment: subsegment cannot be found.", SubsegmentNotFoundException.class); } } }
/** * Ends the provided subsegment. This method doesn't touch context storage. * * @param subsegment * the subsegment to close. */ public void endSubsegment(Subsegment subsegment) { if(subsegment == null) { logger.debug("No input subsegment to end. No-op."); return; } boolean rootReady = subsegment.end(); // First handling the special case where its direct parent is a facade segment if(subsegment.getParent() instanceof FacadeSegment) { if(((FacadeSegment) subsegment.getParent()).isSampled()) { getEmitter().sendSubsegment(subsegment); } return; } // Otherwise we check the happy case where the entire segment is ready if (rootReady && !(subsegment.getParentSegment() instanceof FacadeSegment)) { sendSegment(subsegment.getParentSegment()); return; } // If not we try to stream closed subsegments regardless the root segment is facade or real if (this.getStreamingStrategy().requiresStreaming(subsegment.getParentSegment())) { this.getStreamingStrategy().streamSome(subsegment.getParentSegment(), this.getEmitter()); } }
subsegment.setParent(parentSegment); setTraceEntity(subsegment); return subsegment; if (null != environmentRootTraceId && !environmentRootTraceId.equals(parentSubsegment.getParentSegment().getTraceId())) { clearTraceEntity(); return beginSubsegment(recorder, name); Subsegment subsegment = new SubsegmentImpl(recorder, name, parentSubsegment.getParentSegment()); subsegment.setParent(parentSubsegment); parentSubsegment.addSubsegment(subsegment); setTraceEntity(subsegment); return subsegment;
private Optional<ThrowableDescription> referenceInChildren(Throwable throwable, List<Subsegment> subsegments) { return subsegments.parallelStream() .flatMap(subsegment -> subsegment.getCause().getExceptions().stream()) .filter(throwableDescription -> throwable.equals(throwableDescription.getThrowable())) .findAny(); }
/** * Sends a subsegment to the emitter if the subsegment's parent segment is marked as sampled. * * @param subsegment * the subsegment to send * @return * true if the subsegment was emitted succesfully. */ public boolean sendSubsegment(Subsegment subsegment) { if (subsegment.getParentSegment().isSampled()) { return emitter.sendSubsegment(subsegment); } return false; }
public void afterExecution(Context.AfterExecution context, ExecutionAttributes executionAttributes) { Subsegment subsegment = executionAttributes.getAttribute(entityKey); if (subsegment == null) { return; } populateRequestId(subsegment, context); populateSubsegmentWithResponse(subsegment, context.httpResponse()); subsegment.putAllAws(extractResponseParameters(context, executionAttributes)); getRecorder().endSubsegment(subsegment); }
private <R> R wrapHttpSupplier(Subsegment subsegment, HttpSupplier<R> supplier) throws IOException, ClientProtocolException { try { return supplier.get(); } catch (Exception e) { if (null != subsegment) { subsegment.addException(e); } throw e; } finally { if (null != subsegment) { recorder.endSubsegment(); } } }
subsegment.putAllSql(additionalParams); subsegment.setNamespace(Namespace.REMOTE.toString()); subsegment.addException(t);