4242import datadog .trace .bootstrap .instrumentation .decorator .http .ClientIpAddressResolver ;
4343import java .net .InetAddress ;
4444import java .util .BitSet ;
45+ import java .util .HashMap ;
4546import java .util .LinkedHashMap ;
4647import java .util .Locale ;
4748import java .util .Map ;
@@ -151,12 +152,20 @@ public Object getTag(String key) {
151152
152153 @ Override
153154 public AgentSpan setError (boolean error ) {
154- return serverSpan .setError (error );
155+ serverSpan .setError (error );
156+ if (inferredProxySpan != null ) {
157+ inferredProxySpan .setError (error );
158+ }
159+ return this ;
155160 }
156161
157162 @ Override
158163 public AgentSpan setError (boolean error , byte priority ) {
159- return serverSpan .setError (error , priority );
164+ serverSpan .setError (error , priority );
165+ if (inferredProxySpan != null ) {
166+ inferredProxySpan .setError (error , priority );
167+ }
168+ return this ;
160169 }
161170
162171 @ Override
@@ -171,12 +180,20 @@ public AgentSpan setErrorMessage(String errorMessage) {
171180
172181 @ Override
173182 public AgentSpan addThrowable (Throwable throwable ) {
174- return serverSpan .addThrowable (throwable );
183+ serverSpan .addThrowable (throwable );
184+ if (inferredProxySpan != null ) {
185+ inferredProxySpan .addThrowable (throwable );
186+ }
187+ return this ;
175188 }
176189
177190 @ Override
178191 public AgentSpan addThrowable (Throwable throwable , byte errorPriority ) {
179- return serverSpan .addThrowable (throwable , errorPriority );
192+ serverSpan .addThrowable (throwable , errorPriority );
193+ if (inferredProxySpan != null ) {
194+ inferredProxySpan .addThrowable (throwable , errorPriority );
195+ }
196+ return this ;
180197 }
181198
182199 @ Override
@@ -206,7 +223,11 @@ public AgentSpan setBaggageItem(String key, String value) {
206223
207224 @ Override
208225 public AgentSpan setHttpStatusCode (int statusCode ) {
209- return serverSpan .setHttpStatusCode (statusCode );
226+ serverSpan .setHttpStatusCode (statusCode );
227+ if (inferredProxySpan != null ) {
228+ inferredProxySpan .setHttpStatusCode (statusCode );
229+ }
230+ return this ;
210231 }
211232
212233 @ Override
@@ -417,6 +438,20 @@ public Flow.Action.RequestBlockingAction getRequestBlockingAction() {
417438 private static final Logger log = LoggerFactory .getLogger (HttpServerDecorator .class );
418439 private static final int UNSET_PORT = 0 ;
419440
441+ public static final String PROXY_SYSTEM = "x-dd-proxy" ;
442+ public static final String PROXY_START_TIME_MS = "x-dd-proxy-request-time-ms" ;
443+ public static final String PROXY_PATH = "x-dd-proxy-path" ;
444+ public static final String PROXY_HTTP_METHOD = "x-dd-proxy-httpmethod" ;
445+ public static final String PROXY_DOMAIN_NAME = "x-dd-proxy-domain-name" ;
446+ public static final String STAGE = "x-dd-proxy-stage" ;
447+
448+ public static final Map <String , String > SUPPORTED_PROXIES ;
449+
450+ static {
451+ SUPPORTED_PROXIES = new HashMap <>();
452+ SUPPORTED_PROXIES .put ("aws-apigateway" , "aws.apigateway" );
453+ }
454+
420455 public static final String DD_SPAN_ATTRIBUTE = "datadog.span" ;
421456 public static final String DD_DISPATCH_SPAN_ATTRIBUTE = "datadog.span.dispatch" ;
422457 public static final String DD_FIN_DISP_LIST_SPAN_ATTRIBUTE =
@@ -529,19 +564,7 @@ public AgentSpan startSpan(
529564 tracer ().getDataStreamsMonitoring ().setCheckpoint (span , fromTags (SERVER_PATHWAY_EDGE_TAGS ));
530565 }
531566
532- // errors
533- System .out .println (span );
534- System .out .println ("gtw status code before is: " + apiGtwSpan .getHttpStatusCode ());
535- apiGtwSpan .setHttpStatusCode (span .getHttpStatusCode ());
536-
537- System .out .println ("gtw status code after is: " + apiGtwSpan .getHttpStatusCode ());
538-
539- System .out .println ("span status code is: " + span .getHttpStatusCode ());
540-
541- System .out .println ("starting http server span" );
542- System .out .println (apiGtwSpan );
543- System .out .println (span );
544- if (addInferredProxy ) {
567+ if (addInferredProxy && apiGtwSpan != null ) {
545568 return new InferredProxySpanGroup (apiGtwSpan , span );
546569 } else {
547570 return span ;
@@ -550,37 +573,49 @@ public AgentSpan startSpan(
550573
551574 private AgentSpan startSpanWithInferredProxy (
552575 String instrumentationName , REQUEST_CARRIER carrier , AgentSpanContext .Extracted context ) {
553- // create the apigtw span
554576
555- AgentSpan apiGtwSpan =
556- tracer ().startSpan ("inferred_proxy" , "aws.apigateway" , callIGCallbackStart (context ));
557577 InferredProxyContext inferredProxy = InferredProxyContext .fromContext (Context .current ());
558578
559- Map <String , String > inferredProxyTagInfo = inferredProxy .getInferredProxyContext ();
560- // mocking tags
561- apiGtwSpan .setTag (Tags .COMPONENT , "aws.apigateway" );
562- // "GET /api/hello"
563- apiGtwSpan .setTag (
564- DDTags .RESOURCE_NAME ,
565- inferredProxyTagInfo .get ("x-dd-proxy-httpmethod" )
566- + " "
567- + inferredProxyTagInfo .get ("x-dd-proxy-path" ));
568- // 123
579+ if (inferredProxy == null ) {
580+ return null ;
581+ }
582+
583+ Map <String , String > headers = inferredProxy .getInferredProxyContext ();
584+
585+ // Check if timestamp and proxy system are present
586+ String startTimeStr = headers .get (PROXY_START_TIME_MS );
587+ String proxySystem = headers .get (PROXY_SYSTEM );
588+
589+ if (startTimeStr == null
590+ || proxySystem == null
591+ || !SUPPORTED_PROXIES .containsKey (proxySystem )) {
592+ return null ;
593+ }
594+
595+ long startTime ;
596+ try {
597+ startTime = Long .parseLong (startTimeStr ) * 1000 ; // Convert to microseconds
598+ } catch (NumberFormatException e ) {
599+ return null ; // Invalid timestamp
600+ }
601+
602+ AgentSpan apiGtwSpan =
603+ tracer ()
604+ .startSpan (
605+ "inferred_proxy" ,
606+ SUPPORTED_PROXIES .get (proxySystem ),
607+ callIGCallbackStart (context ),
608+ startTime );
609+
610+ apiGtwSpan .setTag (Tags .COMPONENT , proxySystem );
569611 apiGtwSpan .setTag (
570- DDTags .TRACE_START_TIME , inferredProxyTagInfo .get ("x-dd-proxy-request-time-ms" ));
571- // example.com
572- apiGtwSpan .setTag (DDTags .SERVICE_NAME , inferredProxyTagInfo .get ("x-dd-proxy-domain-name" ));
612+ DDTags .RESOURCE_NAME , headers .get (PROXY_HTTP_METHOD ) + " " + headers .get (PROXY_PATH ));
613+ apiGtwSpan .setTag (DDTags .SERVICE_NAME , headers .get (PROXY_DOMAIN_NAME ));
573614 apiGtwSpan .setTag (DDTags .SPAN_TYPE , "web" );
574- // GET
575- apiGtwSpan .setTag (Tags .HTTP_METHOD , inferredProxyTagInfo .get ("x-dd-proxy-httpmethod" ));
576- // "example.com/api/hello"
577- apiGtwSpan .setTag (
578- Tags .HTTP_URL ,
579- inferredProxyTagInfo .get ("x-dd-proxy-domain-name" )
580- + inferredProxyTagInfo .get ("x-dd-proxy-path" ));
581- // apiGtwSpan.setHttpStatusCode(200);
582- apiGtwSpan .setTag ("stage" , "dev" );
583- apiGtwSpan .setTag ("_dd.inferred_span" , "1" );
615+ apiGtwSpan .setTag (Tags .HTTP_METHOD , headers .get (PROXY_HTTP_METHOD ));
616+ apiGtwSpan .setTag (Tags .HTTP_URL , headers .get (PROXY_DOMAIN_NAME ) + headers .get (PROXY_PATH ));
617+ apiGtwSpan .setTag ("stage" , headers .get (STAGE ));
618+ apiGtwSpan .setTag ("_dd.inferred_span" , 1 );
584619 return apiGtwSpan ;
585620 }
586621
@@ -747,6 +782,7 @@ protected BlockResponseFunction createBlockResponseFunction(
747782 public AgentSpan onResponseStatus (final AgentSpan span , final int status ) {
748783 if (status > UNSET_STATUS ) {
749784 span .setHttpStatusCode (status );
785+
750786 // explicitly set here because some other decorators might already set an error without
751787 // looking at the status code
752788 // XXX: the logic is questionable: span.error becomes equivalent to status 5xx,
0 commit comments