Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTP Request Server Span semantic convention seems broken? #29423

Closed
sncariad opened this issue Nov 21, 2023 · 9 comments
Closed

HTTP Request Server Span semantic convention seems broken? #29423

sncariad opened this issue Nov 21, 2023 · 9 comments
Labels
bug Something isn't working exporter/azuremonitor needs triage New item requiring triage

Comments

@sncariad
Copy link

Component(s)

exporter/azuremonitor

Describe the issue you're reporting

Semantic Conventions for HTTP Spans #Status states the following:

For HTTP status codes in the 4xx range span status MUST be left unset in case of SpanKind.SERVER and MUST be set to Error in case of SpanKind.CLIENT.

However Azure Monitor Exporter does not consider SpanKind when setting Success=false/true.

func getDefaultFormattedSpanStatus(spanStatus ptrace.Status) (statusCodeAsString string, success bool) {
code := spanStatus.Code()
return strconv.FormatInt(int64(code), 10), code != ptrace.StatusCodeError
}

So in Log Analytics workspace, trace table all activities of Kind=Server with 404 gets Success=false. I believe it is incorrect and the code should consider SpanKind when deciding success or failure.

Expected Result

As per Semantic Convention for HTTP Span, when trace is of Server Kind, the 400 status codes are considered successful.

Actual Result

image

@sncariad sncariad added the needs triage New item requiring triage label Nov 21, 2023
Copy link
Contributor

Pinging code owners:

See Adding Labels via Comments if you do not have permissions to add labels yourself.

@crobert-1 crobert-1 added the bug Something isn't working label Nov 21, 2023
@crobert-1
Copy link
Member

crobert-1 commented Nov 21, 2023

Hello @sncariad, thanks for filing and including the references! I believe there's currently some level of ambiguity before this can be declared a bug or not. It seems like we're dealing with an issue of deciding the correct way to convert data from pdata to the format AppInsights uses.

As you're showing, the data.ResultCode variable is initially being set to the span's status code, which will be 0, 1, or 2. However, later on in the same call stack, this same data.ResultCode is being set to the HTTP status.

data.ResultCode, data.Success = getFormattedHTTPStatusValues(attrs.HTTPStatusCode)

Note the comment on the RemoteDependencyData.ResultCode member that's being set here:

	// Result code of a dependency call. Examples are SQL error code and HTTP
	// status code.
	ResultCode string `json:"resultCode"`

So I believe the first question that needs answered here is whether the RemoteDependencyData struct's ResultCode member should be the span status, or HTTP status code? @pcwiese Do you have a thought here?

I realize that maybe a check should be added just in case in the method you've referenced, but no matter what value it's set to (or not set to) it will be overwritten in the current call stack you're hitting.

@rajkumar-rangaraj
Copy link
Contributor

@sncariad This behavior is intentional. The Azure Monitor Exporter sets the status field to false when the HTTP status code exceeds 400. This approach differs from Semantic Conventions but is consistent with Azure Monitor’s practices. You can refer to a .NET implementation for more details -

https://github.com/Azure/azure-sdk-for-net/blob/bed75c756d48bb742254ba83b4c4536ad2e0cd56/sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/Customizations/Models/RequestData.cs#L60

@crobert-1
Copy link
Member

crobert-1 commented Nov 21, 2023

Thanks for the help here @rajkumar-rangaraj! It looks like setting the ResultCode and Success members by default lines up with Azure's expectations, and works as a placeholder in case it isn't set again later in the call stack.

Please let us know if you have any other questions @sncariad, I'm going to close for now.

@crobert-1 crobert-1 closed this as not planned Won't fix, can't repro, duplicate, stale Nov 21, 2023
@bunkrur
Copy link

bunkrur commented Nov 23, 2023

@sncariad This behavior is intentional. The Azure Monitor Exporter sets the status field to false when the HTTP status code exceeds 400. This approach differs from Semantic Conventions but is consistent with Azure Monitor’s practices. You can refer to a .NET implementation for more**** details -

https://github.com/Azure/azure-sdk-for-net/blob/bed75c756d48bb742254ba83b4c4536ad2e0cd56/sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/Customizations/Models/RequestData.cs#L60

Can you confirm the same for the scenario where we export via otlp to a collector and then into azure monitor via the golang azure monitor exporter?

Previously it was possible to override the success/failure within Azure App Insights SDK to allow 404s to be seen as successes. I've written a processor within a dotnet otel extension to try and recreate this functionality but are you saying that app insights will swap any client error to failure in otel regardless? @rajkumar-rangaraj

@sncariad
Copy link
Author

sncariad commented Nov 23, 2023

@sncariad This behavior is intentional. The Azure Monitor Exporter sets the status field to false when the HTTP status code exceeds 400. This approach differs from Semantic Conventions but is consistent with Azure Monitor’s practices. You can refer to a .NET implementation for more details -

https://github.com/Azure/azure-sdk-for-net/blob/bed75c756d48bb742254ba83b4c4536ad2e0cd56/sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/Customizations/Models/RequestData.cs#L60

Thanks for response and sharing the reference to .net version of exporter which does same as go version. But to my understanding; in either case they don't follow Semantic Conventions where they ignore to check if it is Request trace and not Dependency before considering Status to be Success or Failure for http status codes above 400.

Once again thank you for your support.

@crobert-1
Copy link
Member

From @sncariad:

But to my understanding; in either case they don't follow Semantic Conventions where they ignore to check if it is Request trace and not Dependency before considering Status to be Success or Failure for http status codes above 400.

The Semantic Conventions referenced apply only to the OpenTelemetry data format. In the code here, data is being converted to the format used by AppInsights. What we're saying here is that the Semantic Conventions are not relevant once converted to this other format, since it's no longer within the OpenTelemetry realm.

If data was being exported using OTLP, then your point would be correct, the status code would need to be set to the values you're expecting. However, since it's being exported in this ApplicationInsights format, it follows different conventions.

Please let me know if I've misunderstood your comment here.

@bunkrur
Copy link

bunkrur commented Nov 27, 2023

From @sncariad:

But to my understanding; in either case they don't follow Semantic Conventions where they ignore to check if it is Request trace and not Dependency before considering Status to be Success or Failure for http status codes above 400.

The Semantic Conventions referenced apply only to the OpenTelemetry data format. In the code here, data is being converted to the format used by AppInsights. What we're saying here is that the Semantic Conventions are not relevant once converted to this other format, since it's no longer within the OpenTelemetry realm.

If data was being exported using OTLP, then your point would be correct, the status code would need to be set to the values you're expecting. However, since it's being exported in this ApplicationInsights format, it follows different conventions.

Please let me know if I've misunderstood your comment here.

Can you confirm the same for the scenario where we export via otlp to a collector and then into azure monitor via the golang azure monitor exporter?

Like to really dumb it down, Applicaiton -> Otlp -> Otel Collector -> Azure Monitor Exporter would follow the OTLP format and not the in-code exporter format?

@crobert-1

@crobert-1
Copy link
Member

Can you confirm the same for the scenario where we export via otlp to a collector and then into azure monitor via the golang azure monitor exporter?

Like to really dumb it down, Applicaiton -> Otlp -> Otel Collector -> Azure Monitor Exporter would follow the OTLP format and not the in-code exporter format?

Exporting in OTLP to the Otel Collector should follow the OTEL semantic conventions. The collector exporting data using the Azure Monitor exporter does not need to follow conventions. Does that make sense? Did I answer the question here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working exporter/azuremonitor needs triage New item requiring triage
Projects
None yet
Development

No branches or pull requests

4 participants