You've already forked opentelemetry-go
mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-09-16 09:26:25 +02:00
add new function to exclude span kind 4xx for status code (#2339)
* add new function to exclude span kind 4xx for status code * add changelog * make precommit * add unit test * feat: redo by reusing validateHTTPStatusCode * feat: make precommit * feat: move the judgement to SpanStatusFromHTTPStatusCodeAndSpanKind * feat: increase unittest coverage * feat: fix logic * feat: fix unittest * fix code style * Update CHANGELOG.md Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
This commit is contained in:
@@ -23,6 +23,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
||||
- The following interface types simply moved from `metric` to `metric/sdkapi`: `Descriptor`, `MeterImpl`, `InstrumentImpl`, `SyncImpl`, `BoundSyncImpl`, `AsyncImpl`, `AsyncRunner`, `AsyncSingleRunner`, and `AsyncBatchRunner`
|
||||
- The following struct types moved and are replaced with type aliases, since they are exposed to the user: `Observation`, `Measurement`.
|
||||
- The No-op implementations of sync and async instruments are no longer exported, new functions `sdkapi.NewNoopAsyncInstrument()` and `sdkapi.NewNoopSyncInstrument()` are provided instead. (#2271)
|
||||
- Add `SpanStatusFromHTTPStatusCodeAndSpanKind` to all `semconv` packages to return a span status code similar to `SpanStatusFromHTTPStatusCode`, but exclude `4XX` HTTP errors as span errors if the span is of server kind. (#2296)
|
||||
- Update the SDK `BatchSpanProcessor` to export all queued spans when `ForceFlush` is called. (#2080, #2335)
|
||||
- Change `resource.Default` to be evaluated the first time it is called, rather than on import. This allows the caller the option to update `OTEL_RESOURCE_ATTRIBUTES` first, such as with `os.Setenv`. (#2371)
|
||||
|
||||
|
@@ -23,6 +23,7 @@ import (
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
// HTTP scheme attributes.
|
||||
@@ -269,6 +270,21 @@ func SpanStatusFromHTTPStatusCode(code int) (codes.Code, string) {
|
||||
return spanCode, ""
|
||||
}
|
||||
|
||||
// SpanStatusFromHTTPStatusCodeAndSpanKind generates a status code and a message
|
||||
// as specified by the OpenTelemetry specification for a span.
|
||||
// Exclude 4xx for SERVER to set the appropriate status.
|
||||
func SpanStatusFromHTTPStatusCodeAndSpanKind(code int, spanKind trace.SpanKind) (codes.Code, string) {
|
||||
spanCode, valid := validateHTTPStatusCode(code)
|
||||
if !valid {
|
||||
return spanCode, fmt.Sprintf("Invalid HTTP status code %d", code)
|
||||
}
|
||||
category := code / 100
|
||||
if spanKind == trace.SpanKindServer && category == 4 {
|
||||
return codes.Unset, ""
|
||||
}
|
||||
return spanCode, ""
|
||||
}
|
||||
|
||||
// Validates the HTTP status code and returns corresponding span status code.
|
||||
// If the `code` is not a valid HTTP status code, returns span status Error
|
||||
// and false.
|
||||
|
@@ -20,6 +20,8 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
@@ -854,7 +856,7 @@ func TestHTTPAttributesFromHTTPStatusCode(t *testing.T) {
|
||||
|
||||
func TestSpanStatusFromHTTPStatusCode(t *testing.T) {
|
||||
for code := 0; code < 1000; code++ {
|
||||
expected := getExpectedCodeForHTTPCode(code)
|
||||
expected := getExpectedCodeForHTTPCode(code, trace.SpanKindClient)
|
||||
got, msg := SpanStatusFromHTTPStatusCode(code)
|
||||
assert.Equalf(t, expected, got, "%s vs %s", expected, got)
|
||||
|
||||
@@ -867,7 +869,24 @@ func TestSpanStatusFromHTTPStatusCode(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func getExpectedCodeForHTTPCode(code int) codes.Code {
|
||||
func TestSpanStatusFromHTTPStatusCodeAndSpanKind(t *testing.T) {
|
||||
for code := 0; code < 1000; code++ {
|
||||
expected := getExpectedCodeForHTTPCode(code, trace.SpanKindClient)
|
||||
got, msg := SpanStatusFromHTTPStatusCodeAndSpanKind(code, trace.SpanKindClient)
|
||||
assert.Equalf(t, expected, got, "%s vs %s", expected, got)
|
||||
|
||||
_, valid := validateHTTPStatusCode(code)
|
||||
if !valid {
|
||||
assert.NotEmpty(t, msg, "message should be set if error cannot be inferred from code")
|
||||
} else {
|
||||
assert.Empty(t, msg, "message should not be set if error can be inferred from code")
|
||||
}
|
||||
}
|
||||
code, _ := SpanStatusFromHTTPStatusCodeAndSpanKind(400, trace.SpanKindServer)
|
||||
assert.Equalf(t, codes.Unset, code, "message should be set if error cannot be inferred from code")
|
||||
}
|
||||
|
||||
func getExpectedCodeForHTTPCode(code int, spanKind trace.SpanKind) codes.Code {
|
||||
if http.StatusText(code) == "" {
|
||||
return codes.Error
|
||||
}
|
||||
@@ -886,6 +905,9 @@ func getExpectedCodeForHTTPCode(code int) codes.Code {
|
||||
if category > 0 && category < 4 {
|
||||
return codes.Unset
|
||||
}
|
||||
if spanKind == trace.SpanKindServer && category == 4 {
|
||||
return codes.Unset
|
||||
}
|
||||
return codes.Error
|
||||
}
|
||||
|
||||
|
@@ -23,6 +23,7 @@ import (
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
// HTTP scheme attributes.
|
||||
@@ -269,6 +270,21 @@ func SpanStatusFromHTTPStatusCode(code int) (codes.Code, string) {
|
||||
return spanCode, ""
|
||||
}
|
||||
|
||||
// SpanStatusFromHTTPStatusCodeAndSpanKind generates a status code and a message
|
||||
// as specified by the OpenTelemetry specification for a span.
|
||||
// Exclude 4xx for SERVER to set the appropriate status.
|
||||
func SpanStatusFromHTTPStatusCodeAndSpanKind(code int, spanKind trace.SpanKind) (codes.Code, string) {
|
||||
spanCode, valid := validateHTTPStatusCode(code)
|
||||
if !valid {
|
||||
return spanCode, fmt.Sprintf("Invalid HTTP status code %d", code)
|
||||
}
|
||||
category := code / 100
|
||||
if spanKind == trace.SpanKindServer && category == 4 {
|
||||
return codes.Unset, ""
|
||||
}
|
||||
return spanCode, ""
|
||||
}
|
||||
|
||||
// Validates the HTTP status code and returns corresponding span status code.
|
||||
// If the `code` is not a valid HTTP status code, returns span status Error
|
||||
// and false.
|
||||
|
@@ -23,6 +23,8 @@ import (
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
)
|
||||
@@ -854,7 +856,7 @@ func TestHTTPAttributesFromHTTPStatusCode(t *testing.T) {
|
||||
|
||||
func TestSpanStatusFromHTTPStatusCode(t *testing.T) {
|
||||
for code := 0; code < 1000; code++ {
|
||||
expected := getExpectedCodeForHTTPCode(code)
|
||||
expected := getExpectedCodeForHTTPCode(code, trace.SpanKindClient)
|
||||
got, msg := SpanStatusFromHTTPStatusCode(code)
|
||||
assert.Equalf(t, expected, got, "%s vs %s", expected, got)
|
||||
|
||||
@@ -867,7 +869,24 @@ func TestSpanStatusFromHTTPStatusCode(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func getExpectedCodeForHTTPCode(code int) codes.Code {
|
||||
func TestSpanStatusFromHTTPStatusCodeAndSpanKind(t *testing.T) {
|
||||
for code := 0; code < 1000; code++ {
|
||||
expected := getExpectedCodeForHTTPCode(code, trace.SpanKindClient)
|
||||
got, msg := SpanStatusFromHTTPStatusCodeAndSpanKind(code, trace.SpanKindClient)
|
||||
assert.Equalf(t, expected, got, "%s vs %s", expected, got)
|
||||
|
||||
_, valid := validateHTTPStatusCode(code)
|
||||
if !valid {
|
||||
assert.NotEmpty(t, msg, "message should be set if error cannot be inferred from code")
|
||||
} else {
|
||||
assert.Empty(t, msg, "message should not be set if error can be inferred from code")
|
||||
}
|
||||
}
|
||||
code, _ := SpanStatusFromHTTPStatusCodeAndSpanKind(400, trace.SpanKindServer)
|
||||
assert.Equalf(t, codes.Unset, code, "message should be set if error cannot be inferred from code")
|
||||
}
|
||||
|
||||
func getExpectedCodeForHTTPCode(code int, spanKind trace.SpanKind) codes.Code {
|
||||
if http.StatusText(code) == "" {
|
||||
return codes.Error
|
||||
}
|
||||
@@ -886,6 +905,9 @@ func getExpectedCodeForHTTPCode(code int) codes.Code {
|
||||
if category > 0 && category < 4 {
|
||||
return codes.Unset
|
||||
}
|
||||
if spanKind == trace.SpanKindServer && category == 4 {
|
||||
return codes.Unset
|
||||
}
|
||||
return codes.Error
|
||||
}
|
||||
|
||||
|
@@ -23,6 +23,7 @@ import (
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
// HTTP scheme attributes.
|
||||
@@ -269,6 +270,21 @@ func SpanStatusFromHTTPStatusCode(code int) (codes.Code, string) {
|
||||
return spanCode, ""
|
||||
}
|
||||
|
||||
// SpanStatusFromHTTPStatusCodeAndSpanKind generates a status code and a message
|
||||
// as specified by the OpenTelemetry specification for a span.
|
||||
// Exclude 4xx for SERVER to set the appropriate status.
|
||||
func SpanStatusFromHTTPStatusCodeAndSpanKind(code int, spanKind trace.SpanKind) (codes.Code, string) {
|
||||
spanCode, valid := validateHTTPStatusCode(code)
|
||||
if !valid {
|
||||
return spanCode, fmt.Sprintf("Invalid HTTP status code %d", code)
|
||||
}
|
||||
category := code / 100
|
||||
if spanKind == trace.SpanKindServer && category == 4 {
|
||||
return codes.Unset, ""
|
||||
}
|
||||
return spanCode, ""
|
||||
}
|
||||
|
||||
// Validates the HTTP status code and returns corresponding span status code.
|
||||
// If the `code` is not a valid HTTP status code, returns span status Error
|
||||
// and false.
|
||||
|
@@ -25,6 +25,7 @@ import (
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
type tlsOption int
|
||||
@@ -854,7 +855,7 @@ func TestHTTPAttributesFromHTTPStatusCode(t *testing.T) {
|
||||
|
||||
func TestSpanStatusFromHTTPStatusCode(t *testing.T) {
|
||||
for code := 0; code < 1000; code++ {
|
||||
expected := getExpectedCodeForHTTPCode(code)
|
||||
expected := getExpectedCodeForHTTPCode(code, trace.SpanKindClient)
|
||||
got, msg := SpanStatusFromHTTPStatusCode(code)
|
||||
assert.Equalf(t, expected, got, "%s vs %s", expected, got)
|
||||
|
||||
@@ -867,7 +868,24 @@ func TestSpanStatusFromHTTPStatusCode(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func getExpectedCodeForHTTPCode(code int) codes.Code {
|
||||
func TestSpanStatusFromHTTPStatusCodeAndSpanKind(t *testing.T) {
|
||||
for code := 0; code < 1000; code++ {
|
||||
expected := getExpectedCodeForHTTPCode(code, trace.SpanKindClient)
|
||||
got, msg := SpanStatusFromHTTPStatusCodeAndSpanKind(code, trace.SpanKindClient)
|
||||
assert.Equalf(t, expected, got, "%s vs %s", expected, got)
|
||||
|
||||
_, valid := validateHTTPStatusCode(code)
|
||||
if !valid {
|
||||
assert.NotEmpty(t, msg, "message should be set if error cannot be inferred from code")
|
||||
} else {
|
||||
assert.Empty(t, msg, "message should not be set if error can be inferred from code")
|
||||
}
|
||||
}
|
||||
code, _ := SpanStatusFromHTTPStatusCodeAndSpanKind(400, trace.SpanKindServer)
|
||||
assert.Equalf(t, codes.Unset, code, "message should be set if error cannot be inferred from code")
|
||||
}
|
||||
|
||||
func getExpectedCodeForHTTPCode(code int, spanKind trace.SpanKind) codes.Code {
|
||||
if http.StatusText(code) == "" {
|
||||
return codes.Error
|
||||
}
|
||||
@@ -886,6 +904,9 @@ func getExpectedCodeForHTTPCode(code int) codes.Code {
|
||||
if category > 0 && category < 4 {
|
||||
return codes.Unset
|
||||
}
|
||||
if spanKind == trace.SpanKindServer && category == 4 {
|
||||
return codes.Unset
|
||||
}
|
||||
return codes.Error
|
||||
}
|
||||
|
||||
|
@@ -21,6 +21,8 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
)
|
||||
@@ -269,6 +271,21 @@ func SpanStatusFromHTTPStatusCode(code int) (codes.Code, string) {
|
||||
return spanCode, ""
|
||||
}
|
||||
|
||||
// SpanStatusFromHTTPStatusCodeAndSpanKind generates a status code and a message
|
||||
// as specified by the OpenTelemetry specification for a span.
|
||||
// Exclude 4xx for SERVER to set the appropriate status.
|
||||
func SpanStatusFromHTTPStatusCodeAndSpanKind(code int, spanKind trace.SpanKind) (codes.Code, string) {
|
||||
spanCode, valid := validateHTTPStatusCode(code)
|
||||
if !valid {
|
||||
return spanCode, fmt.Sprintf("Invalid HTTP status code %d", code)
|
||||
}
|
||||
category := code / 100
|
||||
if spanKind == trace.SpanKindServer && category == 4 {
|
||||
return codes.Unset, ""
|
||||
}
|
||||
return spanCode, ""
|
||||
}
|
||||
|
||||
// Validates the HTTP status code and returns corresponding span status code.
|
||||
// If the `code` is not a valid HTTP status code, returns span status Error
|
||||
// and false.
|
||||
|
@@ -20,6 +20,8 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
@@ -854,7 +856,7 @@ func TestHTTPAttributesFromHTTPStatusCode(t *testing.T) {
|
||||
|
||||
func TestSpanStatusFromHTTPStatusCode(t *testing.T) {
|
||||
for code := 0; code < 1000; code++ {
|
||||
expected := getExpectedCodeForHTTPCode(code)
|
||||
expected := getExpectedCodeForHTTPCode(code, trace.SpanKindClient)
|
||||
got, msg := SpanStatusFromHTTPStatusCode(code)
|
||||
assert.Equalf(t, expected, got, "%s vs %s", expected, got)
|
||||
|
||||
@@ -867,7 +869,24 @@ func TestSpanStatusFromHTTPStatusCode(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func getExpectedCodeForHTTPCode(code int) codes.Code {
|
||||
func TestSpanStatusFromHTTPStatusCodeAndSpanKind(t *testing.T) {
|
||||
for code := 0; code < 1000; code++ {
|
||||
expected := getExpectedCodeForHTTPCode(code, trace.SpanKindClient)
|
||||
got, msg := SpanStatusFromHTTPStatusCodeAndSpanKind(code, trace.SpanKindClient)
|
||||
assert.Equalf(t, expected, got, "%s vs %s", expected, got)
|
||||
|
||||
_, valid := validateHTTPStatusCode(code)
|
||||
if !valid {
|
||||
assert.NotEmpty(t, msg, "message should be set if error cannot be inferred from code")
|
||||
} else {
|
||||
assert.Empty(t, msg, "message should not be set if error can be inferred from code")
|
||||
}
|
||||
}
|
||||
code, _ := SpanStatusFromHTTPStatusCodeAndSpanKind(400, trace.SpanKindServer)
|
||||
assert.Equalf(t, codes.Unset, code, "message should be set if error cannot be inferred from code")
|
||||
}
|
||||
|
||||
func getExpectedCodeForHTTPCode(code int, spanKind trace.SpanKind) codes.Code {
|
||||
if http.StatusText(code) == "" {
|
||||
return codes.Error
|
||||
}
|
||||
@@ -886,6 +905,9 @@ func getExpectedCodeForHTTPCode(code int) codes.Code {
|
||||
if category > 0 && category < 4 {
|
||||
return codes.Unset
|
||||
}
|
||||
if spanKind == trace.SpanKindServer && category == 4 {
|
||||
return codes.Unset
|
||||
}
|
||||
return codes.Error
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user