From 21e9a645144fb78e31e8a3c0cd292f96b9b4a5ae Mon Sep 17 00:00:00 2001 From: Min Xia Date: Fri, 21 Jul 2023 12:39:17 -0700 Subject: [PATCH] Add the missing remote flag for X-Ray remote segment exceptions --- .../fix-xray-segment-status-attributes.yaml | 2 +- .../internal/translator/cause.go | 20 ++- .../internal/translator/cause_test.go | 118 +++++++++++++----- 3 files changed, 104 insertions(+), 36 deletions(-) diff --git a/.chloggen/fix-xray-segment-status-attributes.yaml b/.chloggen/fix-xray-segment-status-attributes.yaml index f0c748c9bfdc..79a690754b9c 100755 --- a/.chloggen/fix-xray-segment-status-attributes.yaml +++ b/.chloggen/fix-xray-segment-status-attributes.yaml @@ -9,7 +9,7 @@ change_type: bug_fix component: awsxrayexporter # A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Fix X-Ray Segment status code for otel http spans. +note: Fix X-Ray Segment status code and exception translations. # Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. issues: [24381] diff --git a/exporter/awsxrayexporter/internal/translator/cause.go b/exporter/awsxrayexporter/internal/translator/cause.go index 38389685a610..b5d477a0e282 100644 --- a/exporter/awsxrayexporter/internal/translator/cause.go +++ b/exporter/awsxrayexporter/internal/translator/cause.go @@ -49,6 +49,10 @@ func makeCause(span ptrace.Span, attributes map[string]pcommon.Value, resource p if val, ok := resource.Attributes().Get(conventions.AttributeTelemetrySDKLanguage); ok { language = val.Str() } + isRemote := false + if span.Kind() == ptrace.SpanKindClient || span.Kind() == ptrace.SpanKindProducer { + isRemote = true + } var exceptions []awsxray.Exception for i := 0; i < span.Events().Len(); i++ { @@ -70,7 +74,7 @@ func makeCause(span ptrace.Span, attributes map[string]pcommon.Value, resource p stacktrace = val.Str() } - parsed := parseException(exceptionType, message, stacktrace, language) + parsed := parseException(exceptionType, message, stacktrace, isRemote, language) exceptions = append(exceptions, parsed...) } } @@ -155,12 +159,13 @@ func makeCause(span ptrace.Span, attributes map[string]pcommon.Value, resource p return isError, isFault, isThrottle, filtered, cause } -func parseException(exceptionType string, message string, stacktrace string, language string) []awsxray.Exception { +func parseException(exceptionType string, message string, stacktrace string, isRemote bool, language string) []awsxray.Exception { exceptions := make([]awsxray.Exception, 0, 1) segmentID := newSegmentID() exceptions = append(exceptions, awsxray.Exception{ ID: aws.String(hex.EncodeToString(segmentID[:])), Type: aws.String(exceptionType), + Remote: aws.Bool(isRemote), Message: aws.String(message), }) @@ -192,6 +197,7 @@ func fillJavaStacktrace(stacktrace string, exceptions []awsxray.Exception) []aws // Skip first line containing top level message exception := &exceptions[0] + isRemote := exception.Remote _, err := r.ReadLine() if err != nil { return exceptions @@ -250,16 +256,16 @@ func fillJavaStacktrace(stacktrace string, exceptions []awsxray.Exception) []aws if strings.HasPrefix(line, "\tat ") && strings.IndexByte(line, '(') >= 0 && line[len(line)-1] == ')' { // Stack frame (hopefully, user can masquerade since we only have a string), process above. break - } else { - // String append overhead in this case, but multiline messages should be far less common than single - // line ones. - causeMessage += line } + // String append overhead in this case, but multiline messages should be far less common than single + // line ones. + causeMessage += line } segmentID := newSegmentID() exceptions = append(exceptions, awsxray.Exception{ ID: aws.String(hex.EncodeToString(segmentID[:])), Type: aws.String(causeType), + Remote: isRemote, Message: aws.String(causeMessage), Stack: nil, }) @@ -299,6 +305,7 @@ func fillPythonStacktrace(stacktrace string, exceptions []awsxray.Exception) []a } line := lines[lineIdx] exception := &exceptions[0] + isRemote := exception.Remote exception.Stack = nil for { @@ -356,6 +363,7 @@ func fillPythonStacktrace(stacktrace string, exceptions []awsxray.Exception) []a exceptions = append(exceptions, awsxray.Exception{ ID: aws.String(hex.EncodeToString(segmentID[:])), Type: aws.String(causeType), + Remote: isRemote, Message: aws.String(causeMessage), }) // when append causes `exceptions` to outgrow its existing diff --git a/exporter/awsxrayexporter/internal/translator/cause_test.go b/exporter/awsxrayexporter/internal/translator/cause_test.go index bf7487203d25..3a6466f2028f 100644 --- a/exporter/awsxrayexporter/internal/translator/cause_test.go +++ b/exporter/awsxrayexporter/internal/translator/cause_test.go @@ -373,12 +373,14 @@ func TestParseExceptionWithoutStacktrace(t *testing.T) { exceptionType := "com.foo.Exception" message := "Error happened" stacktrace := "" + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "") assert.Len(t, exceptions, 1) assert.NotEmpty(t, exceptions[0].ID) assert.Equal(t, "com.foo.Exception", *exceptions[0].Type) assert.Equal(t, "Error happened", *exceptions[0].Message) + assert.Equal(t, isRemote, *exceptions[0].Remote) assert.Nil(t, exceptions[0].Stack) } @@ -386,12 +388,14 @@ func TestParseExceptionWithoutMessage(t *testing.T) { exceptionType := "com.foo.Exception" message := "" stacktrace := "" + isRemote := false - exceptions := parseException(exceptionType, message, stacktrace, "") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "") assert.Len(t, exceptions, 1) assert.NotEmpty(t, exceptions[0].ID) assert.Equal(t, "com.foo.Exception", *exceptions[0].Type) assert.Empty(t, exceptions[0].Message) + assert.Equal(t, isRemote, *exceptions[0].Remote) assert.Nil(t, exceptions[0].Stack) } @@ -403,8 +407,9 @@ func TestParseExceptionWithJavaStacktraceNoCause(t *testing.T) { at io.opentelemetry.sdk.trace.RecordEventsReadableSpanTest.recordException(RecordEventsReadableSpanTest.java:626) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)` + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "java") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "java") assert.Len(t, exceptions, 1) assert.NotEmpty(t, exceptions[0].ID) assert.Equal(t, "com.foo.Exception", *exceptions[0].Type) @@ -419,6 +424,7 @@ func TestParseExceptionWithJavaStacktraceNoCause(t *testing.T) { assert.Equal(t, "jdk.internal.reflect.NativeMethodAccessorImpl.invoke", *exceptions[0].Stack[2].Label) assert.Equal(t, "NativeMethodAccessorImpl.java", *exceptions[0].Stack[2].Path) assert.Equal(t, 62, *exceptions[0].Stack[2].Line) + assert.Equal(t, isRemote, *exceptions[0].Remote) } func TestParseExceptionWithStacktraceNotJava(t *testing.T) { @@ -429,13 +435,15 @@ func TestParseExceptionWithStacktraceNotJava(t *testing.T) { at io.opentelemetry.sdk.trace.RecordEventsReadableSpanTest.recordException(RecordEventsReadableSpanTest.java:626) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)` + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "") assert.Len(t, exceptions, 1) assert.NotEmpty(t, exceptions[0].ID) assert.Equal(t, "com.foo.Exception", *exceptions[0].Type) assert.Equal(t, "Error happened", *exceptions[0].Message) assert.Empty(t, exceptions[0].Stack) + assert.Equal(t, isRemote, *exceptions[0].Remote) } func TestParseExceptionWithJavaStacktraceAndCauseWithoutStacktrace(t *testing.T) { @@ -447,8 +455,9 @@ func TestParseExceptionWithJavaStacktraceAndCauseWithoutStacktrace(t *testing.T) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) Caused by: java.lang.IllegalArgumentException: bad argument` + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "java") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "java") assert.Len(t, exceptions, 2) assert.NotEmpty(t, exceptions[0].ID) assert.Equal(t, "com.foo.Exception", *exceptions[0].Type) @@ -468,6 +477,7 @@ Caused by: java.lang.IllegalArgumentException: bad argument` assert.Equal(t, "java.lang.IllegalArgumentException", *exceptions[1].Type) assert.Equal(t, "bad argument", *exceptions[1].Message) assert.Empty(t, exceptions[1].Stack) + assert.Equal(t, isRemote, *exceptions[0].Remote) } func TestParseExceptionWithJavaStacktraceAndCauseWithoutMessageOrStacktrace(t *testing.T) { @@ -479,8 +489,9 @@ func TestParseExceptionWithJavaStacktraceAndCauseWithoutMessageOrStacktrace(t *t at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) Caused by: java.lang.IllegalArgumentException` + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "java") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "java") assert.Len(t, exceptions, 2) assert.NotEmpty(t, exceptions[0].ID) assert.Equal(t, "com.foo.Exception", *exceptions[0].Type) @@ -500,6 +511,7 @@ Caused by: java.lang.IllegalArgumentException` assert.Equal(t, "java.lang.IllegalArgumentException", *exceptions[1].Type) assert.Empty(t, *exceptions[1].Message) assert.Empty(t, exceptions[1].Stack) + assert.Equal(t, isRemote, *exceptions[0].Remote) } func TestParseExceptionWithJavaStacktraceAndCauseWithStacktrace(t *testing.T) { @@ -513,8 +525,9 @@ func TestParseExceptionWithJavaStacktraceAndCauseWithStacktrace(t *testing.T) { Caused by: java.lang.IllegalArgumentException: bad argument at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java)` + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "java") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "java") assert.Len(t, exceptions, 2) assert.NotEmpty(t, exceptions[0].ID) assert.Equal(t, "com.foo.Exception", *exceptions[0].Type) @@ -540,6 +553,7 @@ Caused by: java.lang.IllegalArgumentException: bad argument assert.Equal(t, "org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively", *exceptions[1].Stack[1].Label) assert.Equal(t, "NodeTestTask.java", *exceptions[1].Stack[1].Path) assert.Equal(t, 0, *exceptions[1].Stack[1].Line) + assert.Equal(t, isRemote, *exceptions[0].Remote) } func TestParseExceptionWithJavaStacktraceAndCauseWithStacktraceSkipCommonAndSuppressedAndMalformed(t *testing.T) { @@ -564,8 +578,9 @@ Caused by: java.lang.IllegalArgumentException: bad argument at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java) ... 99 more` + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "java") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "java") assert.Len(t, exceptions, 2) assert.NotEmpty(t, exceptions[0].ID) assert.Equal(t, "com.foo.Exception", *exceptions[0].Type) @@ -595,6 +610,7 @@ Caused by: java.lang.IllegalArgumentException: bad argument assert.Equal(t, "org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively", *exceptions[1].Stack[1].Label) assert.Equal(t, "NodeTestTask.java", *exceptions[1].Stack[1].Path) assert.Equal(t, 0, *exceptions[1].Stack[1].Line) + assert.Equal(t, isRemote, *exceptions[0].Remote) } func TestParseExceptionWithPythonStacktraceNoCause(t *testing.T) { @@ -607,8 +623,9 @@ func TestParseExceptionWithPythonStacktraceNoCause(t *testing.T) { File "greetings.py", line 12, in greet_many print('hi, ' + person) TypeError: must be str, not int` + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "python") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "python") assert.Len(t, exceptions, 1) assert.NotEmpty(t, exceptions[0].ID) assert.Equal(t, "TypeError", *exceptions[0].Type) @@ -620,6 +637,7 @@ TypeError: must be str, not int` assert.Equal(t, "", *exceptions[0].Stack[1].Label) assert.Equal(t, "main.py", *exceptions[0].Stack[1].Path) assert.Equal(t, 14, *exceptions[0].Stack[1].Line) + assert.Equal(t, isRemote, *exceptions[0].Remote) } func TestParseExceptionWithPythonStacktraceAndCause(t *testing.T) { @@ -641,8 +659,9 @@ Traceback (most recent call last): File "greetings.py", line 12, in greet_many print('hi, ' + person) TypeError: must be str, not int` + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "python") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "python") assert.Len(t, exceptions, 2) assert.NotEmpty(t, exceptions[0].ID) assert.Equal(t, "TypeError", *exceptions[0].Type) @@ -665,6 +684,7 @@ TypeError: must be str, not int` assert.Equal(t, "greet_many", *exceptions[1].Stack[1].Label) assert.Equal(t, "bar.py", *exceptions[1].Stack[1].Path) assert.Equal(t, 10, *exceptions[1].Stack[1].Line) + assert.Equal(t, isRemote, *exceptions[0].Remote) } func TestParseExceptionWithPythonStacktraceAndMultiLineCause(t *testing.T) { @@ -688,8 +708,9 @@ Traceback (most recent call last): File "greetings.py", line 12, in greet_many print('hi, ' + person) TypeError: must be str, not int` + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "python") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "python") assert.Len(t, exceptions, 2) assert.NotEmpty(t, exceptions[0].ID) assert.Equal(t, "TypeError", *exceptions[0].Type) @@ -712,6 +733,7 @@ TypeError: must be str, not int` assert.Equal(t, "greet_many", *exceptions[1].Stack[1].Label) assert.Equal(t, "bar.py", *exceptions[1].Stack[1].Path) assert.Equal(t, 10, *exceptions[1].Stack[1].Line) + assert.Equal(t, isRemote, *exceptions[0].Remote) } func TestParseExceptionWithPythonStacktraceMalformedLines(t *testing.T) { @@ -728,8 +750,9 @@ func TestParseExceptionWithPythonStacktraceMalformedLines(t *testing.T) { File "greetings.py", line 12, in greet_many print('hi, ' + person) TypeError: must be str, not int` + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "python") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "python") assert.Len(t, exceptions, 1) assert.NotEmpty(t, exceptions[0].ID) assert.Equal(t, "TypeError", *exceptions[0].Type) @@ -744,6 +767,7 @@ TypeError: must be str, not int` assert.Equal(t, "", *exceptions[0].Stack[2].Label) assert.Equal(t, "main.py", *exceptions[0].Stack[2].Path) assert.Equal(t, 0, *exceptions[0].Stack[2].Line) + assert.Equal(t, isRemote, *exceptions[0].Remote) } func TestParseExceptionWithPythonStacktraceAndMalformedCause(t *testing.T) { @@ -761,8 +785,9 @@ Traceback (most recent call last): File "greetings.py", line 12, in greet_many print('hi, ' + person) TypeError: must be str, not int` + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "python") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "python") assert.Len(t, exceptions, 1) assert.NotEmpty(t, exceptions[0].ID) assert.Equal(t, "TypeError", *exceptions[0].Type) @@ -774,6 +799,7 @@ TypeError: must be str, not int` assert.Equal(t, "", *exceptions[0].Stack[1].Label) assert.Equal(t, "main.py", *exceptions[0].Stack[1].Path) assert.Equal(t, 14, *exceptions[0].Stack[1].Line) + assert.Equal(t, isRemote, *exceptions[0].Remote) } func TestParseExceptionWithPythonStacktraceAndMalformedCauseMessage(t *testing.T) { @@ -795,8 +821,9 @@ Traceback (most recent call last): File "greetings.py", line 12, in greet_many print('hi, ' + person) TypeError: must be str, not int` + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "python") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "python") assert.Len(t, exceptions, 1) assert.NotEmpty(t, exceptions[0].ID) assert.Equal(t, "TypeError", *exceptions[0].Type) @@ -808,6 +835,7 @@ TypeError: must be str, not int` assert.Equal(t, "", *exceptions[0].Stack[1].Label) assert.Equal(t, "main.py", *exceptions[0].Stack[1].Path) assert.Equal(t, 14, *exceptions[0].Stack[1].Line) + assert.Equal(t, isRemote, *exceptions[0].Remote) } func TestParseExceptionWithJavaScriptStacktrace(t *testing.T) { @@ -821,8 +849,9 @@ func TestParseExceptionWithJavaScriptStacktrace(t *testing.T) { at node.js:906:3 at Array.forEach (native) at native` + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "javascript") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "javascript") assert.Len(t, exceptions, 1) assert.NotEmpty(t, exceptions[0].ID) assert.Equal(t, "TypeError", *exceptions[0].Type) @@ -846,6 +875,7 @@ func TestParseExceptionWithJavaScriptStacktrace(t *testing.T) { assert.Equal(t, "", *exceptions[0].Stack[5].Label) assert.Equal(t, "native", *exceptions[0].Stack[5].Path) assert.Equal(t, 0, *exceptions[0].Stack[5].Line) + assert.Equal(t, isRemote, *exceptions[0].Remote) } func TestParseExceptionWithStacktraceNotJavaScript(t *testing.T) { @@ -856,13 +886,15 @@ func TestParseExceptionWithStacktraceNotJavaScript(t *testing.T) { at speedy (/home/gbusey/file.js:6:11) at makeFaster (/home/gbusey/file.js:5:3) at Object. (/home/gbusey/file.js:10:1)` + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "") assert.Len(t, exceptions, 1) assert.NotEmpty(t, exceptions[0].ID) assert.Equal(t, "TypeError", *exceptions[0].Type) assert.Equal(t, "Cannot read property 'value' of null", *exceptions[0].Message) assert.Empty(t, exceptions[0].Stack) + assert.Equal(t, isRemote, *exceptions[0].Remote) } func TestParseExceptionWithJavaScriptStactracekMalformedLines(t *testing.T) { @@ -873,8 +905,9 @@ func TestParseExceptionWithJavaScriptStactracekMalformedLines(t *testing.T) { at speedy (/home/gbusey/file.js) at makeFaster (/home/gbusey/file.js:5:3)malformed123 at Object. (/home/gbusey/file.js:10` + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "javascript") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "javascript") assert.Len(t, exceptions, 1) assert.NotEmpty(t, exceptions[0].ID) assert.Equal(t, "TypeError", *exceptions[0].Type) @@ -883,6 +916,7 @@ func TestParseExceptionWithJavaScriptStactracekMalformedLines(t *testing.T) { assert.Equal(t, "speedy ", *exceptions[0].Stack[0].Label) assert.Equal(t, "/home/gbusey/file.js", *exceptions[0].Stack[0].Path) assert.Equal(t, 0, *exceptions[0].Stack[0].Line) + assert.Equal(t, isRemote, *exceptions[0].Remote) } func TestParseExceptionWithSimpleStacktrace(t *testing.T) { @@ -896,8 +930,9 @@ func TestParseExceptionWithSimpleStacktrace(t *testing.T) { at System.Int32.Parse(String s) at MyNamespace.IntParser.Parse(String s) in C:\apps\MyNamespace\IntParser.cs:line 11 at MyNamespace.Program.Main(String[] args) in C:\apps\MyNamespace\Program.cs:line 12` + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "dotnet") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "dotnet") assert.Len(t, exceptions, 1) assert.Equal(t, "System.FormatException", *exceptions[0].Type) assert.Equal(t, "Input string was not in a correct format", *exceptions[0].Message) @@ -917,6 +952,7 @@ func TestParseExceptionWithSimpleStacktrace(t *testing.T) { assert.Equal(t, "MyNamespace.Program.Main(String[] args)", *exceptions[0].Stack[4].Label) assert.Equal(t, "C:\\apps\\MyNamespace\\Program.cs", *exceptions[0].Stack[4].Path) assert.Equal(t, 12, *exceptions[0].Stack[4].Line) + assert.Equal(t, isRemote, *exceptions[0].Remote) } func TestParseExceptionWithInnerExceptionStacktrace(t *testing.T) { @@ -930,8 +966,9 @@ func TestParseExceptionWithInnerExceptionStacktrace(t *testing.T) { " --- End of inner exception stack trace ---\r\n" + " at TestAppApi.Services.ForecastService.GetWeatherForecasts() in D:\\Users\\foobar\\test-app\\TestAppApi\\Services\\ForecastService.cs:line 12\r\n" + " at TestAppApi.Controllers.WeatherForecastController.Get() in D:\\Users\\foobar\\test-app\\TestAppApi\\Controllers\\WeatherForecastController.cs:line 31" + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "dotnet") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "dotnet") assert.Len(t, exceptions, 1) assert.Equal(t, "System.Exception", *exceptions[0].Type) assert.Equal(t, "test", *exceptions[0].Message) @@ -942,6 +979,7 @@ func TestParseExceptionWithInnerExceptionStacktrace(t *testing.T) { assert.Equal(t, "TestAppApi.Controllers.WeatherForecastController.Get()", *exceptions[0].Stack[2].Label) assert.Equal(t, "D:\\Users\\foobar\\test-app\\TestAppApi\\Controllers\\WeatherForecastController.cs", *exceptions[0].Stack[2].Path) assert.Equal(t, 31, *exceptions[0].Stack[2].Line) + assert.Equal(t, isRemote, *exceptions[0].Remote) } func TestParseExceptionWithMalformedStacktrace(t *testing.T) { @@ -953,8 +991,9 @@ func TestParseExceptionWithMalformedStacktrace(t *testing.T) { at integration_test_app.Controllers.AppController.OutgoingHttp() in /Users/bhautip/Documents/otel-dotnet/aws-otel-dotnet/integration-test-app/integration-test-app/Controllers/AppController.cs:line 21 at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context malformed at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken) non-malformed` + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "dotnet") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "dotnet") assert.Len(t, exceptions, 1) assert.Equal(t, "System.Exception", *exceptions[0].Type) assert.Equal(t, "test", *exceptions[0].Message) @@ -965,6 +1004,7 @@ func TestParseExceptionWithMalformedStacktrace(t *testing.T) { assert.Equal(t, "System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)", *exceptions[0].Stack[1].Label) assert.Equal(t, "", *exceptions[0].Stack[1].Path) assert.Equal(t, 0, *exceptions[0].Stack[1].Line) + assert.Equal(t, isRemote, *exceptions[0].Remote) } func TestParseExceptionPhpStacktrace(t *testing.T) { @@ -976,8 +1016,9 @@ func TestParseExceptionPhpStacktrace(t *testing.T) { at parent_func(test.php:51) at child_func(test.php:44) at main(test.php:63)` + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "php") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "php") assert.Len(t, exceptions, 1) assert.NotEmpty(t, exceptions[0].ID) @@ -996,6 +1037,7 @@ func TestParseExceptionPhpStacktrace(t *testing.T) { assert.Equal(t, "main", *exceptions[0].Stack[3].Label) assert.Equal(t, "test.php", *exceptions[0].Stack[3].Path) assert.Equal(t, 63, *exceptions[0].Stack[3].Line) + assert.Equal(t, isRemote, *exceptions[0].Remote) } func TestParseExceptionPhpWithoutStacktrace(t *testing.T) { @@ -1003,14 +1045,16 @@ func TestParseExceptionPhpWithoutStacktrace(t *testing.T) { message := "Thrown from grandparent" stacktrace := "" + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "php") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "php") assert.Len(t, exceptions, 1) assert.NotEmpty(t, exceptions[0].ID) assert.Equal(t, "Exception", *exceptions[0].Type) assert.Equal(t, "Thrown from grandparent", *exceptions[0].Message) assert.Nil(t, exceptions[0].Stack) + assert.Equal(t, isRemote, *exceptions[0].Remote) } func TestParseExceptionPhpStacktraceWithCause(t *testing.T) { @@ -1022,8 +1066,9 @@ func TestParseExceptionPhpStacktraceWithCause(t *testing.T) { at fail(test.php:81) at main(test.php:89) Caused by: Exception: Thrown from class A` + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "php") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "php") assert.Len(t, exceptions, 2) assert.Equal(t, "Exception", *exceptions[0].Type) @@ -1039,10 +1084,12 @@ Caused by: Exception: Thrown from class A` assert.Equal(t, "main", *exceptions[0].Stack[2].Label) assert.Equal(t, "test.php", *exceptions[0].Stack[2].Path) assert.Equal(t, 89, *exceptions[0].Stack[2].Line) + assert.Equal(t, isRemote, *exceptions[0].Remote) assert.Equal(t, "Exception", *exceptions[1].Type) assert.Equal(t, "Thrown from class A", *exceptions[1].Message) assert.Empty(t, exceptions[1].Stack) + assert.Equal(t, isRemote, *exceptions[1].Remote) } func TestParseExceptionPhpStacktraceWithCauseAndStacktrace(t *testing.T) { @@ -1057,8 +1104,9 @@ Caused by: Exception: Thrown from class A at A.exc(test.php:48) at B.exc(test.php:56) ... 2 more` + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "php") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "php") assert.Len(t, exceptions, 2) assert.NotEmpty(t, exceptions[0].ID) @@ -1075,6 +1123,7 @@ Caused by: Exception: Thrown from class A assert.Equal(t, "main", *exceptions[0].Stack[2].Label) assert.Equal(t, "test.php", *exceptions[0].Stack[2].Path) assert.Equal(t, 89, *exceptions[0].Stack[2].Line) + assert.Equal(t, isRemote, *exceptions[0].Remote) assert.Len(t, exceptions[1].Stack, 2) assert.NotEmpty(t, exceptions[1].ID) @@ -1086,6 +1135,7 @@ Caused by: Exception: Thrown from class A assert.Equal(t, "B.exc", *exceptions[1].Stack[1].Label) assert.Equal(t, "test.php", *exceptions[1].Stack[1].Path) assert.Equal(t, 56, *exceptions[1].Stack[1].Line) + assert.Equal(t, isRemote, *exceptions[1].Remote) } func TestParseExceptionPhpStacktraceWithMultipleCause(t *testing.T) { @@ -1103,8 +1153,9 @@ Caused by: Exception: Thrown from class A at A.exc(test.php:48) at B.exc(test.php:56) ... 4 more` + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "php") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "php") assert.Len(t, exceptions, 3) assert.NotEmpty(t, exceptions[0].ID) @@ -1118,6 +1169,7 @@ Caused by: Exception: Thrown from class A assert.Equal(t, "main", *exceptions[0].Stack[1].Label) assert.Equal(t, "test.php", *exceptions[0].Stack[1].Path) assert.Equal(t, 89, *exceptions[0].Stack[1].Line) + assert.Equal(t, isRemote, *exceptions[0].Remote) assert.Len(t, exceptions[1].Stack, 2) assert.Equal(t, *exceptions[1].Cause, *exceptions[2].ID) @@ -1126,6 +1178,7 @@ Caused by: Exception: Thrown from class A assert.Equal(t, "B.exc", *exceptions[1].Stack[0].Label) assert.Equal(t, "test.php", *exceptions[1].Stack[0].Path) assert.Equal(t, 59, *exceptions[1].Stack[0].Line) + assert.Equal(t, isRemote, *exceptions[1].Remote) assert.Len(t, exceptions[2].Stack, 2) assert.NotEmpty(t, exceptions[2].ID) @@ -1134,6 +1187,7 @@ Caused by: Exception: Thrown from class A assert.Equal(t, "B.exc", *exceptions[2].Stack[1].Label) assert.Equal(t, "test.php", *exceptions[2].Stack[1].Path) assert.Equal(t, 56, *exceptions[2].Stack[1].Line) + assert.Equal(t, isRemote, *exceptions[2].Remote) } func TestParseExceptionPhpStacktraceMalformedLines(t *testing.T) { @@ -1144,8 +1198,9 @@ func TestParseExceptionPhpStacktraceMalformedLines(t *testing.T) { at B.exc(test.php:59) at fail(test.php:81 malformed at main(test.php:89)` + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "php") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "php") assert.Len(t, exceptions, 1) assert.NotEmpty(t, exceptions[0].ID) @@ -1158,6 +1213,7 @@ func TestParseExceptionPhpStacktraceMalformedLines(t *testing.T) { assert.Equal(t, "main", *exceptions[0].Stack[1].Label) assert.Equal(t, "test.php", *exceptions[0].Stack[1].Path) assert.Equal(t, 89, *exceptions[0].Stack[1].Line) + assert.Equal(t, isRemote, *exceptions[0].Remote) } func TestParseExceptionGoWithoutStacktrace(t *testing.T) { @@ -1165,8 +1221,9 @@ func TestParseExceptionGoWithoutStacktrace(t *testing.T) { message := "Thrown from grandparent" stacktrace := "" + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "go") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "go") assert.Len(t, exceptions, 1) assert.NotEmpty(t, exceptions[0].ID) @@ -1190,8 +1247,9 @@ testing.tRunner(0xc000102900, 0x1484410) /usr/local/Cellar/go/1.16.3/libexec/src/testing/testing.go:1193 +0x1a3 created by testing.(*T).Run /usr/local/Cellar/go/1.16.3/libexec/src/testing/testing.go:1238 +0x63c` + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "go") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "go") assert.Len(t, exceptions, 1) assert.NotEmpty(t, exceptions[0].ID) assert.Equal(t, "Exception", *exceptions[0].Type) @@ -1240,8 +1298,9 @@ testing.tRunner(0xc000186600, 0x1484440) /usr/local/Cellar/go/1.16.3/libexec/src/testing/testing.go:1193 +0x1a3 created by testing.(*T).Run /usr/local/Cellar/go/1.16.3/libexec/src/testing/testing.go:1238 +0x63c` + isRemote := true - exceptions := parseException(exceptionType, message, stacktrace, "go") + exceptions := parseException(exceptionType, message, stacktrace, isRemote, "go") assert.Len(t, exceptions, 1) assert.NotEmpty(t, exceptions[0].ID) assert.Equal(t, "Exception", *exceptions[0].Type) @@ -1260,4 +1319,5 @@ created by testing.(*T).Run assert.True(t, strings.HasPrefix(*exceptions[0].Stack[10].Label, "created by testing.(*T).Run")) assert.Equal(t, "/usr/local/Cellar/go/1.16.3/libexec/src/testing/testing.go", *exceptions[0].Stack[10].Path) assert.Equal(t, 1238, *exceptions[0].Stack[10].Line) + assert.Equal(t, isRemote, *exceptions[0].Remote) }