-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use Protobuf-based JSON output for sampling strategies (#4173)
## Which problem is this PR solving? Related to open-telemetry/opentelemetry-specification#3126 ## Short description of the changes - changes the main `/sampling` endpoint to use Protobuf-based JSON marshaling instead of Thrift-based - adds unit tests to validate that the new endpoint is backwards compatible with Thrift-based serialization - opens the path to remove Thrift-based sampling data model throughout the codebase Signed-off-by: Yuri Shkuro <github@ysh.us>
- Loading branch information
1 parent
17eefc5
commit 03e24ab
Showing
7 changed files
with
292 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
{ | ||
"service_strategies": [ | ||
{ | ||
"service": "foo", | ||
"type": "probabilistic", | ||
"param": 0.8, | ||
"operation_strategies": [ | ||
{ | ||
"operation": "op1", | ||
"type": "probabilistic", | ||
"param": 0.2 | ||
}, | ||
{ | ||
"operation": "op2", | ||
"type": "probabilistic", | ||
"param": 0.4 | ||
} | ||
] | ||
}, | ||
{ | ||
"service": "bar", | ||
"type": "ratelimiting", | ||
"param": 5 | ||
} | ||
], | ||
"default_strategy": { | ||
"type": "probabilistic", | ||
"param": 0.5, | ||
"operation_strategies": [ | ||
{ | ||
"operation": "/health", | ||
"type": "probabilistic", | ||
"param": 0.0 | ||
}, | ||
{ | ||
"operation": "/metrics", | ||
"type": "probabilistic", | ||
"param": 0.0 | ||
} | ||
] | ||
} | ||
} | ||
|
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Copyright (c) 2023 The Jaeger Authors. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package json | ||
|
||
import ( | ||
"strings" | ||
|
||
"github.com/gogo/protobuf/jsonpb" | ||
|
||
"github.com/jaegertracing/jaeger/proto-gen/api_v2" | ||
) | ||
|
||
// SamplingStrategyResponseToJSON defines the official way to generate | ||
// a JSON response from /sampling endpoints. | ||
func SamplingStrategyResponseToJSON(protoObj *api_v2.SamplingStrategyResponse) (string, error) { | ||
// For backwards compatibility with Thrift-to-JSON encoding, | ||
// we want the output to include "strategyType":"PROBABILISTIC" when appropriate. | ||
// However, due to design oversight, the enum value for PROBABILISTIC is 0, so | ||
// we need to set EmitDefaults=true. This in turns causes null fields to be emitted too, | ||
// so we take care of them below. | ||
jsonpbMarshaler := jsonpb.Marshaler{ | ||
EmitDefaults: true, | ||
} | ||
|
||
str, err := jsonpbMarshaler.MarshalToString(protoObj) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
// Because we set EmitDefaults, jsonpb will also render null entries, so we remove them here. | ||
str = strings.ReplaceAll(str, `"probabilisticSampling":null,`, "") | ||
str = strings.ReplaceAll(str, `,"rateLimitingSampling":null`, "") | ||
str = strings.ReplaceAll(str, `,"operationSampling":null`, "") | ||
|
||
return str, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
// Copyright (c) 2023 The Jaeger Authors. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package json | ||
|
||
import ( | ||
"encoding/json" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
|
||
thriftconv "github.com/jaegertracing/jaeger/model/converter/thrift/jaeger" | ||
api_v1 "github.com/jaegertracing/jaeger/thrift-gen/sampling" | ||
) | ||
|
||
func TestSamplingStrategyResponseToJSON_Error(t *testing.T) { | ||
_, err := SamplingStrategyResponseToJSON(nil) | ||
assert.Error(t, err) | ||
} | ||
|
||
// TestSamplingStrategyResponseToJSON verifies that the function outputs | ||
// the same string as Thrift-based JSON marshaler. | ||
func TestSamplingStrategyResponseToJSON(t *testing.T) { | ||
t.Run("probabilistic", func(t *testing.T) { | ||
s := &api_v1.SamplingStrategyResponse{ | ||
StrategyType: api_v1.SamplingStrategyType_PROBABILISTIC, | ||
ProbabilisticSampling: &api_v1.ProbabilisticSamplingStrategy{ | ||
SamplingRate: 0.42, | ||
}, | ||
} | ||
compareProtoAndThriftJSON(t, s) | ||
}) | ||
t.Run("rateLimiting", func(t *testing.T) { | ||
s := &api_v1.SamplingStrategyResponse{ | ||
StrategyType: api_v1.SamplingStrategyType_RATE_LIMITING, | ||
RateLimitingSampling: &api_v1.RateLimitingSamplingStrategy{ | ||
MaxTracesPerSecond: 42, | ||
}, | ||
} | ||
compareProtoAndThriftJSON(t, s) | ||
}) | ||
t.Run("operationSampling", func(t *testing.T) { | ||
a := 11.2 // we need a pointer to value | ||
s := &api_v1.SamplingStrategyResponse{ | ||
OperationSampling: &api_v1.PerOperationSamplingStrategies{ | ||
DefaultSamplingProbability: 0.42, | ||
DefaultUpperBoundTracesPerSecond: &a, | ||
DefaultLowerBoundTracesPerSecond: 2, | ||
PerOperationStrategies: []*api_v1.OperationSamplingStrategy{ | ||
{ | ||
Operation: "foo", | ||
ProbabilisticSampling: &api_v1.ProbabilisticSamplingStrategy{ | ||
SamplingRate: 0.42, | ||
}, | ||
}, | ||
{ | ||
Operation: "bar", | ||
ProbabilisticSampling: &api_v1.ProbabilisticSamplingStrategy{ | ||
SamplingRate: 0.42, | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
compareProtoAndThriftJSON(t, s) | ||
}) | ||
} | ||
|
||
func compareProtoAndThriftJSON(t *testing.T, thriftObj *api_v1.SamplingStrategyResponse) { | ||
protoObj, err := thriftconv.ConvertSamplingResponseToDomain(thriftObj) | ||
require.NoError(t, err) | ||
|
||
s1, err := json.Marshal(thriftObj) | ||
require.NoError(t, err) | ||
|
||
s2, err := SamplingStrategyResponseToJSON(protoObj) | ||
require.NoError(t, err) | ||
|
||
assert.Equal(t, string(s1), s2) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.