6161import static org .apache .hadoop .fs .s3a .Constants .MULTIPART_UPLOADS_ENABLED ;
6262import static org .apache .hadoop .fs .s3a .audit .AWSRequestAnalyzer .isRequestMultipartIO ;
6363import static org .apache .hadoop .fs .s3a .audit .AWSRequestAnalyzer .isRequestNotAlwaysInSpan ;
64+ import static org .apache .hadoop .fs .s3a .audit .AWSRequestAnalyzer .isRequestAuditedOutsideOfCurrentSpan ;
6465import static org .apache .hadoop .fs .s3a .audit .S3AAuditConstants .OUTSIDE_SPAN ;
6566import static org .apache .hadoop .fs .s3a .audit .S3AAuditConstants .REFERRER_HEADER_ENABLED ;
6667import static org .apache .hadoop .fs .s3a .audit .S3AAuditConstants .REFERRER_HEADER_ENABLED_DEFAULT ;
6970import static org .apache .hadoop .fs .s3a .commit .CommitUtils .extractJobID ;
7071import static org .apache .hadoop .fs .s3a .impl .HeaderProcessing .HEADER_REFERRER ;
7172import static org .apache .hadoop .fs .s3a .statistics .impl .StatisticsFromAwsSdkImpl .mapErrorStatusCodeToStatisticName ;
73+ import static software .amazon .s3 .analyticsaccelerator .request .Constants .OPERATION_NAME ;
74+ import static software .amazon .s3 .analyticsaccelerator .request .Constants .SPAN_ID ;
7275
7376/**
7477 * The LoggingAuditor logs operations at DEBUG (in SDK Request) and
@@ -85,7 +88,6 @@ public class LoggingAuditor
8588 private static final Logger LOG =
8689 LoggerFactory .getLogger (LoggingAuditor .class );
8790
88-
8991 /**
9092 * Some basic analysis for the logs.
9193 */
@@ -267,8 +269,9 @@ HttpReferrerAuditHeader getReferrer(AuditSpanS3A span) {
267269 */
268270 private class LoggingAuditSpan extends AbstractAuditSpanImpl {
269271
270- private final HttpReferrerAuditHeader referrer ;
272+ private HttpReferrerAuditHeader referrer ;
271273
274+ private final HttpReferrerAuditHeader .Builder headerBuilder ;
272275 /**
273276 * Attach Range of data for GetObject Request.
274277 * @param request the sdk request to be modified
@@ -300,7 +303,7 @@ private LoggingAuditSpan(
300303 final String path2 ) {
301304 super (spanId , operationName );
302305
303- this .referrer = HttpReferrerAuditHeader .builder ()
306+ this .headerBuilder = HttpReferrerAuditHeader .builder ()
304307 .withContextId (getAuditorId ())
305308 .withSpanId (spanId )
306309 .withOperationName (operationName )
@@ -312,8 +315,9 @@ private LoggingAuditSpan(
312315 currentThreadID ())
313316 .withAttribute (PARAM_TIMESTAMP , Long .toString (getTimestamp ()))
314317 .withEvaluated (context .getEvaluatedEntries ())
315- .withFilter (filters )
316- .build ();
318+ .withFilter (filters );
319+
320+ this .referrer = this .headerBuilder .build ();
317321
318322 this .description = referrer .buildHttpReferrer ();
319323 }
@@ -384,12 +388,33 @@ public SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context,
384388 SdkHttpRequest httpRequest = context .httpRequest ();
385389 SdkRequest sdkRequest = context .request ();
386390
391+ // If spanId and operationName are set in execution attributes, then use these values,
392+ // instead of the ones in the current span. This is useful when requests are happening in dependencies such as
393+ // the analytics accelerator library (AAL), where they cannot be attached to the correct span. In which case, AAL
394+ // will attach the current spanId and operationName via execution attributes during it's request creation. These
395+ // can then used to update the values in the logger and referrer header. Without this overwriting, the operation
396+ // name and corresponding span will be whichever is active on the thread the request is getting executed on.
397+ boolean isRequestAuditedOutsideCurrentSpan = isRequestAuditedOutsideOfCurrentSpan (executionAttributes );
398+
399+ String spanId = isRequestAuditedOutsideCurrentSpan ?
400+ executionAttributes .getAttribute (SPAN_ID ) : getSpanId ();
401+
402+ String operationName = isRequestAuditedOutsideCurrentSpan ?
403+ executionAttributes .getAttribute (OPERATION_NAME ) : getOperationName ();
404+
405+ if (isRequestAuditedOutsideCurrentSpan ) {
406+ this .headerBuilder .withSpanId (spanId );
407+ this .headerBuilder .withOperationName (operationName );
408+ this .referrer = this .headerBuilder .build ();
409+ }
410+
387411 // attach range for GetObject requests
388412 attachRangeFromRequest (httpRequest , executionAttributes );
389413
390414 // for delete op, attach the number of files to delete
391415 attachDeleteKeySizeAttribute (sdkRequest );
392416
417+
393418 // build the referrer header
394419 final String header = referrer .buildHttpReferrer ();
395420 // update the outer class's field.
@@ -400,11 +425,12 @@ public SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context,
400425 .appendHeader (HEADER_REFERRER , header )
401426 .build ();
402427 }
428+
403429 if (LOG .isDebugEnabled ()) {
404430 LOG .debug ("[{}] {} Executing {} with {}; {}" ,
405431 currentThreadID (),
406- getSpanId () ,
407- getOperationName () ,
432+ spanId ,
433+ operationName ,
408434 analyzer .analyze (context .request ()),
409435 header );
410436 }
@@ -533,10 +559,12 @@ public void beforeExecution(Context.BeforeExecution context,
533559 + analyzer .analyze (context .request ());
534560 final String unaudited = getSpanId () + " "
535561 + UNAUDITED_OPERATION + " " + error ;
562+ // If request is attached to a span in the modifyHttpRequest, as is the case for requests made by AAL, treat it
563+ // as an audited request.
536564 if (isRequestNotAlwaysInSpan (context .request ())) {
537- // can get by auditing during a copy, so don't overreact
565+ // can get by auditing during a copy, so don't overreact.
538566 LOG .debug (unaudited );
539- } else {
567+ } else if (! isRequestAuditedOutsideOfCurrentSpan ( executionAttributes )) {
540568 final RuntimeException ex = new AuditFailureException (unaudited );
541569 LOG .debug (unaudited , ex );
542570 if (isRejectOutOfSpan ()) {
@@ -547,5 +575,4 @@ public void beforeExecution(Context.BeforeExecution context,
547575 super .beforeExecution (context , executionAttributes );
548576 }
549577 }
550-
551578}
0 commit comments