github.com/newrelic/go-agent@v3.26.0+incompatible/_integrations/nrawssdk/v1/nrawssdk_test.go (about)

     1  // Copyright 2020 New Relic Corporation. All rights reserved.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package nrawssdk
     5  
     6  import (
     7  	"bytes"
     8  	"errors"
     9  	"io/ioutil"
    10  	"net/http"
    11  	"testing"
    12  
    13  	"github.com/aws/aws-sdk-go/aws"
    14  	"github.com/aws/aws-sdk-go/aws/credentials"
    15  	"github.com/aws/aws-sdk-go/aws/request"
    16  	"github.com/aws/aws-sdk-go/aws/session"
    17  	"github.com/aws/aws-sdk-go/service/dynamodb"
    18  	"github.com/aws/aws-sdk-go/service/lambda"
    19  	newrelic "github.com/newrelic/go-agent"
    20  	"github.com/newrelic/go-agent/internal"
    21  	"github.com/newrelic/go-agent/internal/integrationsupport"
    22  )
    23  
    24  func testApp() integrationsupport.ExpectApp {
    25  	return integrationsupport.NewTestApp(integrationsupport.SampleEverythingReplyFn, integrationsupport.DTEnabledCfgFn)
    26  }
    27  
    28  type fakeTransport struct{}
    29  
    30  func (t fakeTransport) RoundTrip(r *http.Request) (*http.Response, error) {
    31  	return &http.Response{
    32  		Status:     "200 OK",
    33  		StatusCode: 200,
    34  		Body:       ioutil.NopCloser(bytes.NewReader([]byte(""))),
    35  		Header: http.Header{
    36  			"X-Amzn-Requestid": []string{requestID},
    37  		},
    38  	}, nil
    39  }
    40  
    41  type fakeCreds struct{}
    42  
    43  func (c *fakeCreds) Retrieve() (credentials.Value, error) {
    44  	return credentials.Value{}, nil
    45  }
    46  func (c *fakeCreds) IsExpired() bool { return false }
    47  
    48  func newSession() *session.Session {
    49  	r := "us-west-2"
    50  	ses := session.New()
    51  	ses.Config.Credentials = credentials.NewCredentials(&fakeCreds{})
    52  	ses.Config.HTTPClient.Transport = &fakeTransport{}
    53  	ses.Config.Region = &r
    54  	return ses
    55  }
    56  
    57  const (
    58  	requestID = "testing request id"
    59  	txnName   = "aws-txn"
    60  )
    61  
    62  var (
    63  	genericSpan = internal.WantEvent{
    64  		Intrinsics: map[string]interface{}{
    65  			"name":          "OtherTransaction/Go/" + txnName,
    66  			"sampled":       true,
    67  			"category":      "generic",
    68  			"priority":      internal.MatchAnything,
    69  			"guid":          internal.MatchAnything,
    70  			"transactionId": internal.MatchAnything,
    71  			"nr.entryPoint": true,
    72  			"traceId":       internal.MatchAnything,
    73  		},
    74  		UserAttributes:  map[string]interface{}{},
    75  		AgentAttributes: map[string]interface{}{},
    76  	}
    77  	externalSpan = internal.WantEvent{
    78  		Intrinsics: map[string]interface{}{
    79  			"name":          "External/lambda.us-west-2.amazonaws.com/http/POST",
    80  			"sampled":       true,
    81  			"category":      "http",
    82  			"priority":      internal.MatchAnything,
    83  			"guid":          internal.MatchAnything,
    84  			"transactionId": internal.MatchAnything,
    85  			"traceId":       internal.MatchAnything,
    86  			"parentId":      internal.MatchAnything,
    87  			"component":     "http",
    88  			"span.kind":     "client",
    89  		},
    90  		UserAttributes: map[string]interface{}{},
    91  		AgentAttributes: map[string]interface{}{
    92  			"aws.operation": "Invoke",
    93  			"aws.region":    "us-west-2",
    94  			"aws.requestId": requestID,
    95  			"http.method":   "POST",
    96  			"http.url":      "https://lambda.us-west-2.amazonaws.com/2015-03-31/functions/non-existent-function/invocations",
    97  		},
    98  	}
    99  	externalSpanNoRequestID = internal.WantEvent{
   100  		Intrinsics: map[string]interface{}{
   101  			"name":          "External/lambda.us-west-2.amazonaws.com/http/POST",
   102  			"sampled":       true,
   103  			"category":      "http",
   104  			"priority":      internal.MatchAnything,
   105  			"guid":          internal.MatchAnything,
   106  			"transactionId": internal.MatchAnything,
   107  			"traceId":       internal.MatchAnything,
   108  			"parentId":      internal.MatchAnything,
   109  			"component":     "http",
   110  			"span.kind":     "client",
   111  		},
   112  		UserAttributes: map[string]interface{}{},
   113  		AgentAttributes: map[string]interface{}{
   114  			"aws.operation": "Invoke",
   115  			"aws.region":    "us-west-2",
   116  			"http.method":   "POST",
   117  			"http.url":      "https://lambda.us-west-2.amazonaws.com/2015-03-31/functions/non-existent-function/invocations",
   118  		},
   119  	}
   120  	datastoreSpan = internal.WantEvent{
   121  		Intrinsics: map[string]interface{}{
   122  			"name":          "Datastore/statement/DynamoDB/thebesttable/DescribeTable",
   123  			"sampled":       true,
   124  			"category":      "datastore",
   125  			"priority":      internal.MatchAnything,
   126  			"guid":          internal.MatchAnything,
   127  			"transactionId": internal.MatchAnything,
   128  			"traceId":       internal.MatchAnything,
   129  			"parentId":      internal.MatchAnything,
   130  			"component":     "DynamoDB",
   131  			"span.kind":     "client",
   132  		},
   133  		UserAttributes: map[string]interface{}{},
   134  		AgentAttributes: map[string]interface{}{
   135  			"aws.operation": "DescribeTable",
   136  			"aws.region":    "us-west-2",
   137  			"aws.requestId": requestID,
   138  			"db.collection": "thebesttable",
   139  			"db.statement":  "'DescribeTable' on 'thebesttable' using 'DynamoDB'",
   140  			"peer.address":  "dynamodb.us-west-2.amazonaws.com:unknown",
   141  			"peer.hostname": "dynamodb.us-west-2.amazonaws.com",
   142  		},
   143  	}
   144  
   145  	txnMetrics = []internal.WantMetric{
   146  		{Name: "DurationByCaller/Unknown/Unknown/Unknown/Unknown/all", Scope: "", Forced: false, Data: nil},
   147  		{Name: "DurationByCaller/Unknown/Unknown/Unknown/Unknown/allOther", Scope: "", Forced: false, Data: nil},
   148  		{Name: "OtherTransaction/Go/" + txnName, Scope: "", Forced: true, Data: nil},
   149  		{Name: "OtherTransaction/all", Scope: "", Forced: true, Data: nil},
   150  		{Name: "OtherTransactionTotalTime/Go/" + txnName, Scope: "", Forced: false, Data: nil},
   151  		{Name: "OtherTransactionTotalTime", Scope: "", Forced: true, Data: nil},
   152  	}
   153  	externalMetrics = append([]internal.WantMetric{
   154  		{Name: "External/all", Scope: "", Forced: true, Data: nil},
   155  		{Name: "External/allOther", Scope: "", Forced: true, Data: nil},
   156  		{Name: "External/lambda.us-west-2.amazonaws.com/all", Scope: "", Forced: false, Data: nil},
   157  		{Name: "External/lambda.us-west-2.amazonaws.com/http/POST", Scope: "OtherTransaction/Go/" + txnName, Forced: false, Data: nil},
   158  	}, txnMetrics...)
   159  	datastoreMetrics = append([]internal.WantMetric{
   160  		{Name: "Datastore/DynamoDB/all", Scope: "", Forced: true, Data: nil},
   161  		{Name: "Datastore/DynamoDB/allOther", Scope: "", Forced: true, Data: nil},
   162  		{Name: "Datastore/all", Scope: "", Forced: true, Data: nil},
   163  		{Name: "Datastore/allOther", Scope: "", Forced: true, Data: nil},
   164  		{Name: "Datastore/instance/DynamoDB/dynamodb.us-west-2.amazonaws.com/unknown", Scope: "", Forced: false, Data: nil},
   165  		{Name: "Datastore/operation/DynamoDB/DescribeTable", Scope: "", Forced: false, Data: nil},
   166  		{Name: "Datastore/statement/DynamoDB/thebesttable/DescribeTable", Scope: "", Forced: false, Data: nil},
   167  		{Name: "Datastore/statement/DynamoDB/thebesttable/DescribeTable", Scope: "OtherTransaction/Go/" + txnName, Forced: false, Data: nil},
   168  	}, txnMetrics...)
   169  )
   170  
   171  func TestInstrumentRequestExternal(t *testing.T) {
   172  	app := testApp()
   173  	txn := app.StartTransaction(txnName, nil, nil)
   174  
   175  	client := lambda.New(newSession())
   176  	input := &lambda.InvokeInput{
   177  		ClientContext:  aws.String("MyApp"),
   178  		FunctionName:   aws.String("non-existent-function"),
   179  		InvocationType: aws.String("Event"),
   180  		LogType:        aws.String("Tail"),
   181  		Payload:        []byte("{}"),
   182  	}
   183  
   184  	req, out := client.InvokeRequest(input)
   185  	InstrumentHandlers(&req.Handlers)
   186  	req.HTTPRequest = newrelic.RequestWithTransactionContext(req.HTTPRequest, txn)
   187  
   188  	err := req.Send()
   189  	if nil != err {
   190  		t.Error(err)
   191  	}
   192  	if 200 != *out.StatusCode {
   193  		t.Error("wrong status code on response", out.StatusCode)
   194  	}
   195  
   196  	txn.End()
   197  
   198  	app.ExpectMetrics(t, externalMetrics)
   199  	app.ExpectSpanEvents(t, []internal.WantEvent{
   200  		genericSpan, externalSpan})
   201  }
   202  
   203  func TestInstrumentRequestDatastore(t *testing.T) {
   204  	app := testApp()
   205  	txn := app.StartTransaction(txnName, nil, nil)
   206  
   207  	client := dynamodb.New(newSession())
   208  	input := &dynamodb.DescribeTableInput{
   209  		TableName: aws.String("thebesttable"),
   210  	}
   211  
   212  	req, _ := client.DescribeTableRequest(input)
   213  	InstrumentHandlers(&req.Handlers)
   214  	req.HTTPRequest = newrelic.RequestWithTransactionContext(req.HTTPRequest, txn)
   215  
   216  	err := req.Send()
   217  	if nil != err {
   218  		t.Error(err)
   219  	}
   220  
   221  	txn.End()
   222  
   223  	app.ExpectMetrics(t, datastoreMetrics)
   224  	app.ExpectSpanEvents(t, []internal.WantEvent{
   225  		genericSpan, datastoreSpan})
   226  }
   227  
   228  func TestInstrumentRequestExternalNoTxn(t *testing.T) {
   229  	client := lambda.New(newSession())
   230  	input := &lambda.InvokeInput{
   231  		ClientContext:  aws.String("MyApp"),
   232  		FunctionName:   aws.String("non-existent-function"),
   233  		InvocationType: aws.String("Event"),
   234  		LogType:        aws.String("Tail"),
   235  		Payload:        []byte("{}"),
   236  	}
   237  
   238  	req, out := client.InvokeRequest(input)
   239  	InstrumentHandlers(&req.Handlers)
   240  
   241  	err := req.Send()
   242  	if nil != err {
   243  		t.Error(err)
   244  	}
   245  	if 200 != *out.StatusCode {
   246  		t.Error("wrong status code on response", out.StatusCode)
   247  	}
   248  }
   249  
   250  func TestInstrumentRequestDatastoreNoTxn(t *testing.T) {
   251  	client := dynamodb.New(newSession())
   252  	input := &dynamodb.DescribeTableInput{
   253  		TableName: aws.String("thebesttable"),
   254  	}
   255  
   256  	req, _ := client.DescribeTableRequest(input)
   257  	InstrumentHandlers(&req.Handlers)
   258  
   259  	err := req.Send()
   260  	if nil != err {
   261  		t.Error(err)
   262  	}
   263  }
   264  
   265  func TestInstrumentSessionExternal(t *testing.T) {
   266  	app := testApp()
   267  	txn := app.StartTransaction(txnName, nil, nil)
   268  
   269  	ses := newSession()
   270  	InstrumentHandlers(&ses.Handlers)
   271  	client := lambda.New(ses)
   272  
   273  	input := &lambda.InvokeInput{
   274  		ClientContext:  aws.String("MyApp"),
   275  		FunctionName:   aws.String("non-existent-function"),
   276  		InvocationType: aws.String("Event"),
   277  		LogType:        aws.String("Tail"),
   278  		Payload:        []byte("{}"),
   279  	}
   280  
   281  	req, out := client.InvokeRequest(input)
   282  	req.HTTPRequest = newrelic.RequestWithTransactionContext(req.HTTPRequest, txn)
   283  
   284  	err := req.Send()
   285  	if nil != err {
   286  		t.Error(err)
   287  	}
   288  	if 200 != *out.StatusCode {
   289  		t.Error("wrong status code on response", out.StatusCode)
   290  	}
   291  
   292  	txn.End()
   293  
   294  	app.ExpectMetrics(t, externalMetrics)
   295  	app.ExpectSpanEvents(t, []internal.WantEvent{
   296  		genericSpan, externalSpan})
   297  }
   298  
   299  func TestInstrumentSessionDatastore(t *testing.T) {
   300  	app := testApp()
   301  	txn := app.StartTransaction(txnName, nil, nil)
   302  
   303  	ses := newSession()
   304  	InstrumentHandlers(&ses.Handlers)
   305  	client := dynamodb.New(ses)
   306  
   307  	input := &dynamodb.DescribeTableInput{
   308  		TableName: aws.String("thebesttable"),
   309  	}
   310  
   311  	req, _ := client.DescribeTableRequest(input)
   312  	req.HTTPRequest = newrelic.RequestWithTransactionContext(req.HTTPRequest, txn)
   313  
   314  	err := req.Send()
   315  	if nil != err {
   316  		t.Error(err)
   317  	}
   318  
   319  	txn.End()
   320  
   321  	app.ExpectMetrics(t, datastoreMetrics)
   322  	app.ExpectSpanEvents(t, []internal.WantEvent{
   323  		genericSpan, datastoreSpan})
   324  }
   325  
   326  func TestInstrumentSessionExternalNoTxn(t *testing.T) {
   327  	ses := newSession()
   328  	InstrumentHandlers(&ses.Handlers)
   329  	client := lambda.New(ses)
   330  
   331  	input := &lambda.InvokeInput{
   332  		ClientContext:  aws.String("MyApp"),
   333  		FunctionName:   aws.String("non-existent-function"),
   334  		InvocationType: aws.String("Event"),
   335  		LogType:        aws.String("Tail"),
   336  		Payload:        []byte("{}"),
   337  	}
   338  
   339  	req, out := client.InvokeRequest(input)
   340  	req.HTTPRequest = newrelic.RequestWithTransactionContext(req.HTTPRequest, nil)
   341  
   342  	err := req.Send()
   343  	if nil != err {
   344  		t.Error(err)
   345  	}
   346  	if 200 != *out.StatusCode {
   347  		t.Error("wrong status code on response", out.StatusCode)
   348  	}
   349  }
   350  
   351  func TestInstrumentSessionDatastoreNoTxn(t *testing.T) {
   352  	ses := newSession()
   353  	InstrumentHandlers(&ses.Handlers)
   354  	client := dynamodb.New(ses)
   355  
   356  	input := &dynamodb.DescribeTableInput{
   357  		TableName: aws.String("thebesttable"),
   358  	}
   359  
   360  	req, _ := client.DescribeTableRequest(input)
   361  	req.HTTPRequest = newrelic.RequestWithTransactionContext(req.HTTPRequest, nil)
   362  
   363  	err := req.Send()
   364  	if nil != err {
   365  		t.Error(err)
   366  	}
   367  }
   368  
   369  func TestInstrumentSessionExternalTxnNotInCtx(t *testing.T) {
   370  	app := testApp()
   371  	txn := app.StartTransaction(txnName, nil, nil)
   372  
   373  	ses := newSession()
   374  	InstrumentHandlers(&ses.Handlers)
   375  	client := lambda.New(ses)
   376  
   377  	input := &lambda.InvokeInput{
   378  		ClientContext:  aws.String("MyApp"),
   379  		FunctionName:   aws.String("non-existent-function"),
   380  		InvocationType: aws.String("Event"),
   381  		LogType:        aws.String("Tail"),
   382  		Payload:        []byte("{}"),
   383  	}
   384  
   385  	req, out := client.InvokeRequest(input)
   386  
   387  	err := req.Send()
   388  	if nil != err {
   389  		t.Error(err)
   390  	}
   391  	if 200 != *out.StatusCode {
   392  		t.Error("wrong status code on response", out.StatusCode)
   393  	}
   394  
   395  	txn.End()
   396  
   397  	app.ExpectMetrics(t, txnMetrics)
   398  }
   399  
   400  func TestInstrumentSessionDatastoreTxnNotInCtx(t *testing.T) {
   401  	app := testApp()
   402  	txn := app.StartTransaction(txnName, nil, nil)
   403  
   404  	ses := newSession()
   405  	InstrumentHandlers(&ses.Handlers)
   406  	client := dynamodb.New(ses)
   407  
   408  	input := &dynamodb.DescribeTableInput{
   409  		TableName: aws.String("thebesttable"),
   410  	}
   411  
   412  	req, _ := client.DescribeTableRequest(input)
   413  
   414  	err := req.Send()
   415  	if nil != err {
   416  		t.Error(err)
   417  	}
   418  
   419  	txn.End()
   420  
   421  	app.ExpectMetrics(t, txnMetrics)
   422  }
   423  
   424  func TestDoublyInstrumented(t *testing.T) {
   425  	hs := &request.Handlers{}
   426  	if found := hs.Send.Len(); 0 != found {
   427  		t.Error("unexpected number of Send handlers found:", found)
   428  	}
   429  
   430  	InstrumentHandlers(hs)
   431  	if found := hs.Send.Len(); 2 != found {
   432  		t.Error("unexpected number of Send handlers found:", found)
   433  	}
   434  
   435  	InstrumentHandlers(hs)
   436  	if found := hs.Send.Len(); 2 != found {
   437  		t.Error("unexpected number of Send handlers found:", found)
   438  	}
   439  }
   440  
   441  type firstFailingTransport struct {
   442  	failing bool
   443  }
   444  
   445  func (t *firstFailingTransport) RoundTrip(r *http.Request) (*http.Response, error) {
   446  	if t.failing {
   447  		t.failing = false
   448  		return nil, errors.New("Oops this failed")
   449  	}
   450  	return &http.Response{
   451  		Status:     "200 OK",
   452  		StatusCode: 200,
   453  		Body:       ioutil.NopCloser(bytes.NewReader([]byte(""))),
   454  		Header: http.Header{
   455  			"X-Amzn-Requestid": []string{requestID},
   456  		},
   457  	}, nil
   458  }
   459  
   460  func TestRetrySend(t *testing.T) {
   461  	app := testApp()
   462  	txn := app.StartTransaction(txnName, nil, nil)
   463  
   464  	ses := newSession()
   465  	ses.Config.HTTPClient.Transport = &firstFailingTransport{failing: true}
   466  
   467  	client := lambda.New(ses)
   468  	input := &lambda.InvokeInput{
   469  		ClientContext:  aws.String("MyApp"),
   470  		FunctionName:   aws.String("non-existent-function"),
   471  		InvocationType: aws.String("Event"),
   472  		LogType:        aws.String("Tail"),
   473  		Payload:        []byte("{}"),
   474  	}
   475  
   476  	req, out := client.InvokeRequest(input)
   477  	InstrumentHandlers(&req.Handlers)
   478  	req.HTTPRequest = newrelic.RequestWithTransactionContext(req.HTTPRequest, txn)
   479  
   480  	err := req.Send()
   481  	if nil != err {
   482  		t.Error(err)
   483  	}
   484  	if 200 != *out.StatusCode {
   485  		t.Error("wrong status code on response", out.StatusCode)
   486  	}
   487  
   488  	txn.End()
   489  
   490  	app.ExpectMetrics(t, externalMetrics)
   491  	app.ExpectSpanEvents(t, []internal.WantEvent{
   492  		genericSpan, externalSpanNoRequestID, externalSpan})
   493  }
   494  
   495  func TestRequestSentTwice(t *testing.T) {
   496  	app := testApp()
   497  	txn := app.StartTransaction(txnName, nil, nil)
   498  
   499  	client := lambda.New(newSession())
   500  	input := &lambda.InvokeInput{
   501  		ClientContext:  aws.String("MyApp"),
   502  		FunctionName:   aws.String("non-existent-function"),
   503  		InvocationType: aws.String("Event"),
   504  		LogType:        aws.String("Tail"),
   505  		Payload:        []byte("{}"),
   506  	}
   507  
   508  	req, out := client.InvokeRequest(input)
   509  	InstrumentHandlers(&req.Handlers)
   510  	req.HTTPRequest = newrelic.RequestWithTransactionContext(req.HTTPRequest, txn)
   511  
   512  	firstErr := req.Send()
   513  	if nil != firstErr {
   514  		t.Error(firstErr)
   515  	}
   516  	if 200 != *out.StatusCode {
   517  		t.Error("wrong status code on response", out.StatusCode)
   518  	}
   519  
   520  	secondErr := req.Send()
   521  	if nil != secondErr {
   522  		t.Error(secondErr)
   523  	}
   524  	if 200 != *out.StatusCode {
   525  		t.Error("wrong status code on response", out.StatusCode)
   526  	}
   527  
   528  	txn.End()
   529  
   530  	app.ExpectMetrics(t, []internal.WantMetric{
   531  		{Name: "DurationByCaller/Unknown/Unknown/Unknown/Unknown/all", Scope: "", Forced: false, Data: nil},
   532  		{Name: "DurationByCaller/Unknown/Unknown/Unknown/Unknown/allOther", Scope: "", Forced: false, Data: nil},
   533  		{Name: "External/all", Scope: "", Forced: true, Data: []float64{2}},
   534  		{Name: "External/allOther", Scope: "", Forced: true, Data: []float64{2}},
   535  		{Name: "External/lambda.us-west-2.amazonaws.com/all", Scope: "", Forced: false, Data: []float64{2}},
   536  		{Name: "External/lambda.us-west-2.amazonaws.com/http/POST", Scope: "OtherTransaction/Go/" + txnName, Forced: false, Data: []float64{2}},
   537  		{Name: "OtherTransaction/Go/" + txnName, Scope: "", Forced: true, Data: nil},
   538  		{Name: "OtherTransaction/all", Scope: "", Forced: true, Data: nil},
   539  		{Name: "OtherTransactionTotalTime/Go/" + txnName, Scope: "", Forced: false, Data: nil},
   540  		{Name: "OtherTransactionTotalTime", Scope: "", Forced: true, Data: nil},
   541  	})
   542  	app.ExpectSpanEvents(t, []internal.WantEvent{
   543  		genericSpan, externalSpan, externalSpan})
   544  }
   545  
   546  type noRequestIDTransport struct{}
   547  
   548  func (t *noRequestIDTransport) RoundTrip(r *http.Request) (*http.Response, error) {
   549  	return &http.Response{
   550  		Status:     "200 OK",
   551  		StatusCode: 200,
   552  		Body:       ioutil.NopCloser(bytes.NewReader([]byte(""))),
   553  	}, nil
   554  }
   555  
   556  func TestNoRequestIDFound(t *testing.T) {
   557  	app := testApp()
   558  	txn := app.StartTransaction(txnName, nil, nil)
   559  
   560  	ses := newSession()
   561  	ses.Config.HTTPClient.Transport = &noRequestIDTransport{}
   562  
   563  	client := lambda.New(ses)
   564  	input := &lambda.InvokeInput{
   565  		ClientContext:  aws.String("MyApp"),
   566  		FunctionName:   aws.String("non-existent-function"),
   567  		InvocationType: aws.String("Event"),
   568  		LogType:        aws.String("Tail"),
   569  		Payload:        []byte("{}"),
   570  	}
   571  
   572  	req, out := client.InvokeRequest(input)
   573  	InstrumentHandlers(&req.Handlers)
   574  	req.HTTPRequest = newrelic.RequestWithTransactionContext(req.HTTPRequest, txn)
   575  
   576  	err := req.Send()
   577  	if nil != err {
   578  		t.Error(err)
   579  	}
   580  	if 200 != *out.StatusCode {
   581  		t.Error("wrong status code on response", out.StatusCode)
   582  	}
   583  
   584  	txn.End()
   585  
   586  	app.ExpectMetrics(t, externalMetrics)
   587  	app.ExpectSpanEvents(t, []internal.WantEvent{
   588  		genericSpan, externalSpanNoRequestID})
   589  }