1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-07-07 00:35:52 +02:00

Support configurable AggregationTemporality in exporters; add OTLP missing sum point temporality/monotonic fields (#1296)

* Restructure ExportKindSelector helpers; eliminate PassThroughExportKind; add StatelessExportKindSelector()

* WithExportKindSelector(); Additional testing

* Changelog update

* Test the new selectors

* From review feedback

Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
This commit is contained in:
Joshua MacDonald
2020-11-10 07:44:42 -08:00
committed by GitHub
parent 3a06b393b9
commit f9984f2d4e
19 changed files with 341 additions and 168 deletions

View File

@ -50,9 +50,8 @@ func TestProcessor(t *testing.T) {
}
for _, tc := range []exportCase{
{kind: export.PassThroughExporter},
{kind: export.CumulativeExporter},
{kind: export.DeltaExporter},
{kind: export.CumulativeExportKind},
{kind: export.DeltaExportKind},
} {
t.Run(tc.kind.String(), func(t *testing.T) {
for _, ic := range []instrumentCase{
@ -127,7 +126,7 @@ func testProcessor(
labs2 := []label.KeyValue{label.String("L2", "V")}
testBody := func(t *testing.T, hasMemory bool, nAccum, nCheckpoint int) {
processor := basic.New(selector, ekind, basic.WithMemory(hasMemory))
processor := basic.New(selector, export.ConstantExportKindSelector(ekind), basic.WithMemory(hasMemory))
instSuffix := fmt.Sprint(".", strings.ToLower(akind.String()))
@ -159,7 +158,7 @@ func testProcessor(
_, canSub := subr.(export.Subtractor)
// Allow unsupported subraction case only when it is called for.
require.True(t, mkind.PrecomputedSum() && ekind == export.DeltaExporter && !canSub)
require.True(t, mkind.PrecomputedSum() && ekind == export.DeltaExportKind && !canSub)
return
} else if err != nil {
t.Fatal("unexpected FinishCollection error: ", err)
@ -183,7 +182,7 @@ func testProcessor(
// Test the final checkpoint state.
records1 := processorTest.NewOutput(label.DefaultEncoder())
err = checkpointSet.ForEach(ekind, records1.AddRecord)
err = checkpointSet.ForEach(export.ConstantExportKindSelector(ekind), records1.AddRecord)
// Test for an allowed error:
if err != nil && err != aggregation.ErrNoSubtraction {
@ -196,7 +195,7 @@ func testProcessor(
// number of Accumulators, unless LastValue aggregation.
// If a precomputed sum, we expect cumulative inputs.
if mkind.PrecomputedSum() {
if ekind == export.DeltaExporter && akind != aggregation.LastValueKind {
if ekind == export.DeltaExportKind && akind != aggregation.LastValueKind {
multiplier = int64(nAccum)
} else if akind == aggregation.LastValueKind {
multiplier = cumulativeMultiplier
@ -204,7 +203,7 @@ func testProcessor(
multiplier = cumulativeMultiplier * int64(nAccum)
}
} else {
if ekind == export.CumulativeExporter && akind != aggregation.LastValueKind {
if ekind == export.CumulativeExportKind && akind != aggregation.LastValueKind {
multiplier = cumulativeMultiplier * int64(nAccum)
} else if akind == aggregation.LastValueKind {
multiplier = 1
@ -216,7 +215,7 @@ func testProcessor(
// Synchronous accumulate results from multiple accumulators,
// use that number as the baseline multiplier.
multiplier = int64(nAccum)
if ekind == export.CumulativeExporter {
if ekind == export.CumulativeExportKind {
// If a cumulative exporter, include prior checkpoints.
multiplier *= cumulativeMultiplier
}
@ -268,39 +267,39 @@ func (bogusExporter) Export(context.Context, export.CheckpointSet) error {
func TestBasicInconsistent(t *testing.T) {
// Test double-start
b := basic.New(processorTest.AggregatorSelector(), export.PassThroughExporter)
b := basic.New(processorTest.AggregatorSelector(), export.StatelessExportKindSelector())
b.StartCollection()
b.StartCollection()
require.Equal(t, basic.ErrInconsistentState, b.FinishCollection())
// Test finish without start
b = basic.New(processorTest.AggregatorSelector(), export.PassThroughExporter)
b = basic.New(processorTest.AggregatorSelector(), export.StatelessExportKindSelector())
require.Equal(t, basic.ErrInconsistentState, b.FinishCollection())
// Test no finish
b = basic.New(processorTest.AggregatorSelector(), export.PassThroughExporter)
b = basic.New(processorTest.AggregatorSelector(), export.StatelessExportKindSelector())
b.StartCollection()
require.Equal(
t,
basic.ErrInconsistentState,
b.ForEach(
export.PassThroughExporter,
export.StatelessExportKindSelector(),
func(export.Record) error { return nil },
),
)
// Test no start
b = basic.New(processorTest.AggregatorSelector(), export.PassThroughExporter)
b = basic.New(processorTest.AggregatorSelector(), export.StatelessExportKindSelector())
desc := otel.NewDescriptor("inst", otel.CounterInstrumentKind, otel.Int64NumberKind)
accum := export.NewAccumulation(&desc, label.EmptySet(), resource.Empty(), metrictest.NoopAggregator{})
require.Equal(t, basic.ErrInconsistentState, b.Process(accum))
// Test invalid kind:
b = basic.New(processorTest.AggregatorSelector(), export.PassThroughExporter)
b = basic.New(processorTest.AggregatorSelector(), export.StatelessExportKindSelector())
b.StartCollection()
require.NoError(t, b.Process(accum))
require.NoError(t, b.FinishCollection())
@ -309,13 +308,13 @@ func TestBasicInconsistent(t *testing.T) {
bogusExporter{},
func(export.Record) error { return nil },
)
require.True(t, errors.Is(err, basic.ErrInvalidExporterKind))
require.True(t, errors.Is(err, basic.ErrInvalidExportKind))
}
func TestBasicTimestamps(t *testing.T) {
beforeNew := time.Now()
b := basic.New(processorTest.AggregatorSelector(), export.PassThroughExporter)
b := basic.New(processorTest.AggregatorSelector(), export.StatelessExportKindSelector())
afterNew := time.Now()
desc := otel.NewDescriptor("inst", otel.CounterInstrumentKind, otel.Int64NumberKind)
@ -327,7 +326,7 @@ func TestBasicTimestamps(t *testing.T) {
var start1, end1 time.Time
require.NoError(t, b.ForEach(export.PassThroughExporter, func(rec export.Record) error {
require.NoError(t, b.ForEach(export.StatelessExportKindSelector(), func(rec export.Record) error {
start1 = rec.StartTime()
end1 = rec.EndTime()
return nil
@ -344,7 +343,7 @@ func TestBasicTimestamps(t *testing.T) {
var start2, end2 time.Time
require.NoError(t, b.ForEach(export.PassThroughExporter, func(rec export.Record) error {
require.NoError(t, b.ForEach(export.StatelessExportKindSelector(), func(rec export.Record) error {
start2 = rec.StartTime()
end2 = rec.EndTime()
return nil
@ -362,12 +361,12 @@ func TestBasicTimestamps(t *testing.T) {
func TestStatefulNoMemoryCumulative(t *testing.T) {
res := resource.NewWithAttributes(label.String("R", "V"))
ekind := export.CumulativeExporter
ekindSel := export.CumulativeExportKindSelector()
desc := otel.NewDescriptor("inst.sum", otel.CounterInstrumentKind, otel.Int64NumberKind)
selector := processorTest.AggregatorSelector()
processor := basic.New(selector, ekind, basic.WithMemory(false))
processor := basic.New(selector, ekindSel, basic.WithMemory(false))
checkpointSet := processor.CheckpointSet()
for i := 1; i < 3; i++ {
@ -377,7 +376,7 @@ func TestStatefulNoMemoryCumulative(t *testing.T) {
// Verify zero elements
records := processorTest.NewOutput(label.DefaultEncoder())
require.NoError(t, checkpointSet.ForEach(ekind, records.AddRecord))
require.NoError(t, checkpointSet.ForEach(ekindSel, records.AddRecord))
require.EqualValues(t, map[string]float64{}, records.Map())
// Add 10
@ -387,7 +386,7 @@ func TestStatefulNoMemoryCumulative(t *testing.T) {
// Verify one element
records = processorTest.NewOutput(label.DefaultEncoder())
require.NoError(t, checkpointSet.ForEach(ekind, records.AddRecord))
require.NoError(t, checkpointSet.ForEach(ekindSel, records.AddRecord))
require.EqualValues(t, map[string]float64{
"inst.sum/A=B/R=V": float64(i * 10),
}, records.Map())
@ -396,12 +395,12 @@ func TestStatefulNoMemoryCumulative(t *testing.T) {
func TestStatefulNoMemoryDelta(t *testing.T) {
res := resource.NewWithAttributes(label.String("R", "V"))
ekind := export.DeltaExporter
ekindSel := export.DeltaExportKindSelector()
desc := otel.NewDescriptor("inst.sum", otel.SumObserverInstrumentKind, otel.Int64NumberKind)
selector := processorTest.AggregatorSelector()
processor := basic.New(selector, ekind, basic.WithMemory(false))
processor := basic.New(selector, ekindSel, basic.WithMemory(false))
checkpointSet := processor.CheckpointSet()
for i := 1; i < 3; i++ {
@ -411,7 +410,7 @@ func TestStatefulNoMemoryDelta(t *testing.T) {
// Verify zero elements
records := processorTest.NewOutput(label.DefaultEncoder())
require.NoError(t, checkpointSet.ForEach(ekind, records.AddRecord))
require.NoError(t, checkpointSet.ForEach(ekindSel, records.AddRecord))
require.EqualValues(t, map[string]float64{}, records.Map())
// Add 10
@ -421,7 +420,7 @@ func TestStatefulNoMemoryDelta(t *testing.T) {
// Verify one element
records = processorTest.NewOutput(label.DefaultEncoder())
require.NoError(t, checkpointSet.ForEach(ekind, records.AddRecord))
require.NoError(t, checkpointSet.ForEach(ekindSel, records.AddRecord))
require.EqualValues(t, map[string]float64{
"inst.sum/A=B/R=V": 10,
}, records.Map())
@ -429,17 +428,16 @@ func TestStatefulNoMemoryDelta(t *testing.T) {
}
func TestMultiObserverSum(t *testing.T) {
for _, ekind := range []export.ExportKind{
export.PassThroughExporter,
export.CumulativeExporter,
export.DeltaExporter,
for _, ekindSel := range []export.ExportKindSelector{
export.CumulativeExportKindSelector(),
export.DeltaExportKindSelector(),
} {
res := resource.NewWithAttributes(label.String("R", "V"))
desc := otel.NewDescriptor("observe.sum", otel.SumObserverInstrumentKind, otel.Int64NumberKind)
selector := processorTest.AggregatorSelector()
processor := basic.New(selector, ekind, basic.WithMemory(false))
processor := basic.New(selector, ekindSel, basic.WithMemory(false))
checkpointSet := processor.CheckpointSet()
for i := 1; i < 3; i++ {
@ -452,13 +450,13 @@ func TestMultiObserverSum(t *testing.T) {
// Multiplier is 1 for deltas, otherwise i.
multiplier := i
if ekind == export.DeltaExporter {
if ekindSel.ExportKindFor(&desc, aggregation.SumKind) == export.DeltaExportKind {
multiplier = 1
}
// Verify one element
records := processorTest.NewOutput(label.DefaultEncoder())
require.NoError(t, checkpointSet.ForEach(ekind, records.AddRecord))
require.NoError(t, checkpointSet.ForEach(ekindSel, records.AddRecord))
require.EqualValues(t, map[string]float64{
"observe.sum/A=B/R=V": float64(3 * 10 * multiplier),
}, records.Map())