077a755fe8
* Move hcp client to subpackage hcpclient (#16800) * [HCP Observability] New MetricsClient (#17100) * Client configured with TLS using HCP config and retry/throttle * Add tests and godoc for metrics client * close body after request * run go mod tidy * Remove one abstraction to use the config from deps * Address PR feedback * remove clone * Extract CloudConfig and mock for future PR * Switch to hclog.FromContext * [HCP Observability] OTELExporter (#17128) * Client configured with TLS using HCP config and retry/throttle * run go mod tidy * Remove one abstraction to use the config from deps * Address PR feedback * Client configured with TLS using HCP config and retry/throttle * run go mod tidy * Create new OTELExporter which uses the MetricsClient Add transform because the conversion is in an /internal package * Fix lint error * early return when there are no metrics * Add NewOTELExporter() function * Downgrade to metrics SDK version: v1.15.0-rc.1 * Fix imports * fix small nits with comments and url.URL * Fix tests by asserting actual error for context cancellation, fix parallel, and make mock more versatile * Cleanup error handling and clarify empty metrics case * Fix input/expected naming in otel_transform_test.go * add comment for metric tracking * Add a general isEmpty method * Add clear error types * update to latest version 1.15.0 of OTEL * [HCP Observability] OTELSink (#17159) * Client configured with TLS using HCP config and retry/throttle * run go mod tidy * Remove one abstraction to use the config from deps * Address PR feedback * Client configured with TLS using HCP config and retry/throttle * run go mod tidy * Create new OTELExporter which uses the MetricsClient Add transform because the conversion is in an /internal package * Fix lint error * early return when there are no metrics * Add NewOTELExporter() function * Downgrade to metrics SDK version: v1.15.0-rc.1 * Fix imports * fix small nits with comments and url.URL * Fix tests by asserting actual error for context cancellation, fix parallel, and make mock more versatile * Cleanup error handling and clarify empty metrics case * Fix input/expected naming in otel_transform_test.go * add comment for metric tracking * Add a general isEmpty method * Add clear error types * update to latest version 1.15.0 of OTEL * Client configured with TLS using HCP config and retry/throttle * run go mod tidy * Remove one abstraction to use the config from deps * Address PR feedback * Initialize OTELSink with sync.Map for all the instrument stores. * Moved PeriodicReader init to NewOtelReader function. This allows us to use a ManualReader for tests. * Switch to mutex instead of sync.Map to avoid type assertion * Add gauge store * Clarify comments * return concrete sink type * Fix lint errors * Move gauge store to be within sink * Use context.TODO,rebase and clenaup opts handling * Rebase onto otl exporter to downgrade metrics API to v1.15.0-rc.1 * Fix imports * Update to latest stable version by rebasing on cc-4933, fix import, remove mutex init, fix opts error messages and use logger from ctx * Add lots of documentation to the OTELSink * Fix gauge store comment and check ok * Add select and ctx.Done() check to gauge callback * use require.Equal for attributes * Fixed import naming * Remove float64 calls and add a NewGaugeStore method * Change name Store to Set in gaugeStore, add concurrency tests in both OTELSink and gauge store * Generate 100 gauge operations * Seperate the labels into goroutines in sink test * Generate kv store for the test case keys to avoid using uuid * Added a race test with 300 samples for OTELSink * Do not pass in waitgroup and use error channel instead. * Using SHA 7dea2225a218872e86d2f580e82c089b321617b0 to avoid build failures in otel * Fix nits * [HCP Observability] Init OTELSink in Telemetry (#17162) * Move hcp client to subpackage hcpclient (#16800) * [HCP Observability] New MetricsClient (#17100) * Client configured with TLS using HCP config and retry/throttle * Add tests and godoc for metrics client * close body after request * run go mod tidy * Remove one abstraction to use the config from deps * Address PR feedback * remove clone * Extract CloudConfig and mock for future PR * Switch to hclog.FromContext * [HCP Observability] New MetricsClient (#17100) * Client configured with TLS using HCP config and retry/throttle * Add tests and godoc for metrics client * close body after request * run go mod tidy * Remove one abstraction to use the config from deps * Address PR feedback * remove clone * Extract CloudConfig and mock for future PR * Switch to hclog.FromContext * [HCP Observability] New MetricsClient (#17100) * Client configured with TLS using HCP config and retry/throttle * Add tests and godoc for metrics client * close body after request * run go mod tidy * Remove one abstraction to use the config from deps * Address PR feedback * remove clone * Extract CloudConfig and mock for future PR * Switch to hclog.FromContext * Client configured with TLS using HCP config and retry/throttle * run go mod tidy * Remove one abstraction to use the config from deps * Address PR feedback * Client configured with TLS using HCP config and retry/throttle * run go mod tidy * Create new OTELExporter which uses the MetricsClient Add transform because the conversion is in an /internal package * Fix lint error * early return when there are no metrics * Add NewOTELExporter() function * Downgrade to metrics SDK version: v1.15.0-rc.1 * Fix imports * fix small nits with comments and url.URL * Fix tests by asserting actual error for context cancellation, fix parallel, and make mock more versatile * Cleanup error handling and clarify empty metrics case * Fix input/expected naming in otel_transform_test.go * add comment for metric tracking * Add a general isEmpty method * Add clear error types * update to latest version 1.15.0 of OTEL * Client configured with TLS using HCP config and retry/throttle * run go mod tidy * Remove one abstraction to use the config from deps * Address PR feedback * Initialize OTELSink with sync.Map for all the instrument stores. * Moved PeriodicReader init to NewOtelReader function. This allows us to use a ManualReader for tests. * Switch to mutex instead of sync.Map to avoid type assertion * Add gauge store * Clarify comments * return concrete sink type * Fix lint errors * Move gauge store to be within sink * Use context.TODO,rebase and clenaup opts handling * Rebase onto otl exporter to downgrade metrics API to v1.15.0-rc.1 * Fix imports * Update to latest stable version by rebasing on cc-4933, fix import, remove mutex init, fix opts error messages and use logger from ctx * Add lots of documentation to the OTELSink * Fix gauge store comment and check ok * Add select and ctx.Done() check to gauge callback * use require.Equal for attributes * Fixed import naming * Remove float64 calls and add a NewGaugeStore method * Change name Store to Set in gaugeStore, add concurrency tests in both OTELSink and gauge store * Generate 100 gauge operations * Seperate the labels into goroutines in sink test * Generate kv store for the test case keys to avoid using uuid * Added a race test with 300 samples for OTELSink * [HCP Observability] OTELExporter (#17128) * Client configured with TLS using HCP config and retry/throttle * run go mod tidy * Remove one abstraction to use the config from deps * Address PR feedback * Client configured with TLS using HCP config and retry/throttle * run go mod tidy * Create new OTELExporter which uses the MetricsClient Add transform because the conversion is in an /internal package * Fix lint error * early return when there are no metrics * Add NewOTELExporter() function * Downgrade to metrics SDK version: v1.15.0-rc.1 * Fix imports * fix small nits with comments and url.URL * Fix tests by asserting actual error for context cancellation, fix parallel, and make mock more versatile * Cleanup error handling and clarify empty metrics case * Fix input/expected naming in otel_transform_test.go * add comment for metric tracking * Add a general isEmpty method * Add clear error types * update to latest version 1.15.0 of OTEL * Do not pass in waitgroup and use error channel instead. * Using SHA 7dea2225a218872e86d2f580e82c089b321617b0 to avoid build failures in otel * Rebase onto otl exporter to downgrade metrics API to v1.15.0-rc.1 * Initialize OTELSink with sync.Map for all the instrument stores. * Added telemetry agent to client and init sink in deps * Fixed client * Initalize sink in deps * init sink in telemetry library * Init deps before telemetry * Use concrete telemetry.OtelSink type * add /v1/metrics * Avoid returning err for telemetry init * move sink init within the IsCloudEnabled() * Use HCPSinkOpts in deps instead * update golden test for configuration file * Switch to using extra sinks in the telemetry library * keep name MetricsConfig * fix log in verifyCCMRegistration * Set logger in context * pass around MetricSink in deps * Fix imports * Rebased onto otel sink pr * Fix URL in test * [HCP Observability] OTELSink (#17159) * Client configured with TLS using HCP config and retry/throttle * run go mod tidy * Remove one abstraction to use the config from deps * Address PR feedback * Client configured with TLS using HCP config and retry/throttle * run go mod tidy * Create new OTELExporter which uses the MetricsClient Add transform because the conversion is in an /internal package * Fix lint error * early return when there are no metrics * Add NewOTELExporter() function * Downgrade to metrics SDK version: v1.15.0-rc.1 * Fix imports * fix small nits with comments and url.URL * Fix tests by asserting actual error for context cancellation, fix parallel, and make mock more versatile * Cleanup error handling and clarify empty metrics case * Fix input/expected naming in otel_transform_test.go * add comment for metric tracking * Add a general isEmpty method * Add clear error types * update to latest version 1.15.0 of OTEL * Client configured with TLS using HCP config and retry/throttle * run go mod tidy * Remove one abstraction to use the config from deps * Address PR feedback * Initialize OTELSink with sync.Map for all the instrument stores. * Moved PeriodicReader init to NewOtelReader function. This allows us to use a ManualReader for tests. * Switch to mutex instead of sync.Map to avoid type assertion * Add gauge store * Clarify comments * return concrete sink type * Fix lint errors * Move gauge store to be within sink * Use context.TODO,rebase and clenaup opts handling * Rebase onto otl exporter to downgrade metrics API to v1.15.0-rc.1 * Fix imports * Update to latest stable version by rebasing on cc-4933, fix import, remove mutex init, fix opts error messages and use logger from ctx * Add lots of documentation to the OTELSink * Fix gauge store comment and check ok * Add select and ctx.Done() check to gauge callback * use require.Equal for attributes * Fixed import naming * Remove float64 calls and add a NewGaugeStore method * Change name Store to Set in gaugeStore, add concurrency tests in both OTELSink and gauge store * Generate 100 gauge operations * Seperate the labels into goroutines in sink test * Generate kv store for the test case keys to avoid using uuid * Added a race test with 300 samples for OTELSink * Do not pass in waitgroup and use error channel instead. * Using SHA 7dea2225a218872e86d2f580e82c089b321617b0 to avoid build failures in otel * Fix nits * pass extraSinks as function param instead * Add default interval as package export * remove verifyCCM func * Add clusterID * Fix import and add t.Parallel() for missing tests * Kick Vercel CI * Remove scheme from endpoint path, and fix error logging * return metrics.MetricSink for sink method * Update SDK * [HCP Observability] Metrics filtering and Labels in Go Metrics sink (#17184) * Move hcp client to subpackage hcpclient (#16800) * [HCP Observability] New MetricsClient (#17100) * Client configured with TLS using HCP config and retry/throttle * Add tests and godoc for metrics client * close body after request * run go mod tidy * Remove one abstraction to use the config from deps * Address PR feedback * remove clone * Extract CloudConfig and mock for future PR * Switch to hclog.FromContext * [HCP Observability] New MetricsClient (#17100) * Client configured with TLS using HCP config and retry/throttle * Add tests and godoc for metrics client * close body after request * run go mod tidy * Remove one abstraction to use the config from deps * Address PR feedback * remove clone * Extract CloudConfig and mock for future PR * Switch to hclog.FromContext * [HCP Observability] New MetricsClient (#17100) * Client configured with TLS using HCP config and retry/throttle * Add tests and godoc for metrics client * close body after request * run go mod tidy * Remove one abstraction to use the config from deps * Address PR feedback * remove clone * Extract CloudConfig and mock for future PR * Switch to hclog.FromContext * Client configured with TLS using HCP config and retry/throttle * run go mod tidy * Remove one abstraction to use the config from deps * Address PR feedback * Client configured with TLS using HCP config and retry/throttle * run go mod tidy * Create new OTELExporter which uses the MetricsClient Add transform because the conversion is in an /internal package * Fix lint error * early return when there are no metrics * Add NewOTELExporter() function * Downgrade to metrics SDK version: v1.15.0-rc.1 * Fix imports * fix small nits with comments and url.URL * Fix tests by asserting actual error for context cancellation, fix parallel, and make mock more versatile * Cleanup error handling and clarify empty metrics case * Fix input/expected naming in otel_transform_test.go * add comment for metric tracking * Add a general isEmpty method * Add clear error types * update to latest version 1.15.0 of OTEL * Client configured with TLS using HCP config and retry/throttle * run go mod tidy * Remove one abstraction to use the config from deps * Address PR feedback * Initialize OTELSink with sync.Map for all the instrument stores. * Moved PeriodicReader init to NewOtelReader function. This allows us to use a ManualReader for tests. * Switch to mutex instead of sync.Map to avoid type assertion * Add gauge store * Clarify comments * return concrete sink type * Fix lint errors * Move gauge store to be within sink * Use context.TODO,rebase and clenaup opts handling * Rebase onto otl exporter to downgrade metrics API to v1.15.0-rc.1 * Fix imports * Update to latest stable version by rebasing on cc-4933, fix import, remove mutex init, fix opts error messages and use logger from ctx * Add lots of documentation to the OTELSink * Fix gauge store comment and check ok * Add select and ctx.Done() check to gauge callback * use require.Equal for attributes * Fixed import naming * Remove float64 calls and add a NewGaugeStore method * Change name Store to Set in gaugeStore, add concurrency tests in both OTELSink and gauge store * Generate 100 gauge operations * Seperate the labels into goroutines in sink test * Generate kv store for the test case keys to avoid using uuid * Added a race test with 300 samples for OTELSink * [HCP Observability] OTELExporter (#17128) * Client configured with TLS using HCP config and retry/throttle * run go mod tidy * Remove one abstraction to use the config from deps * Address PR feedback * Client configured with TLS using HCP config and retry/throttle * run go mod tidy * Create new OTELExporter which uses the MetricsClient Add transform because the conversion is in an /internal package * Fix lint error * early return when there are no metrics * Add NewOTELExporter() function * Downgrade to metrics SDK version: v1.15.0-rc.1 * Fix imports * fix small nits with comments and url.URL * Fix tests by asserting actual error for context cancellation, fix parallel, and make mock more versatile * Cleanup error handling and clarify empty metrics case * Fix input/expected naming in otel_transform_test.go * add comment for metric tracking * Add a general isEmpty method * Add clear error types * update to latest version 1.15.0 of OTEL * Do not pass in waitgroup and use error channel instead. * Using SHA 7dea2225a218872e86d2f580e82c089b321617b0 to avoid build failures in otel * Rebase onto otl exporter to downgrade metrics API to v1.15.0-rc.1 * Initialize OTELSink with sync.Map for all the instrument stores. * Added telemetry agent to client and init sink in deps * Fixed client * Initalize sink in deps * init sink in telemetry library * Init deps before telemetry * Use concrete telemetry.OtelSink type * add /v1/metrics * Avoid returning err for telemetry init * move sink init within the IsCloudEnabled() * Use HCPSinkOpts in deps instead * update golden test for configuration file * Switch to using extra sinks in the telemetry library * keep name MetricsConfig * fix log in verifyCCMRegistration * Set logger in context * pass around MetricSink in deps * Fix imports * Rebased onto otel sink pr * Fix URL in test * [HCP Observability] OTELSink (#17159) * Client configured with TLS using HCP config and retry/throttle * run go mod tidy * Remove one abstraction to use the config from deps * Address PR feedback * Client configured with TLS using HCP config and retry/throttle * run go mod tidy * Create new OTELExporter which uses the MetricsClient Add transform because the conversion is in an /internal package * Fix lint error * early return when there are no metrics * Add NewOTELExporter() function * Downgrade to metrics SDK version: v1.15.0-rc.1 * Fix imports * fix small nits with comments and url.URL * Fix tests by asserting actual error for context cancellation, fix parallel, and make mock more versatile * Cleanup error handling and clarify empty metrics case * Fix input/expected naming in otel_transform_test.go * add comment for metric tracking * Add a general isEmpty method * Add clear error types * update to latest version 1.15.0 of OTEL * Client configured with TLS using HCP config and retry/throttle * run go mod tidy * Remove one abstraction to use the config from deps * Address PR feedback * Initialize OTELSink with sync.Map for all the instrument stores. * Moved PeriodicReader init to NewOtelReader function. This allows us to use a ManualReader for tests. * Switch to mutex instead of sync.Map to avoid type assertion * Add gauge store * Clarify comments * return concrete sink type * Fix lint errors * Move gauge store to be within sink * Use context.TODO,rebase and clenaup opts handling * Rebase onto otl exporter to downgrade metrics API to v1.15.0-rc.1 * Fix imports * Update to latest stable version by rebasing on cc-4933, fix import, remove mutex init, fix opts error messages and use logger from ctx * Add lots of documentation to the OTELSink * Fix gauge store comment and check ok * Add select and ctx.Done() check to gauge callback * use require.Equal for attributes * Fixed import naming * Remove float64 calls and add a NewGaugeStore method * Change name Store to Set in gaugeStore, add concurrency tests in both OTELSink and gauge store * Generate 100 gauge operations * Seperate the labels into goroutines in sink test * Generate kv store for the test case keys to avoid using uuid * Added a race test with 300 samples for OTELSink * Do not pass in waitgroup and use error channel instead. * Using SHA 7dea2225a218872e86d2f580e82c089b321617b0 to avoid build failures in otel * Fix nits * pass extraSinks as function param instead * Add default interval as package export * remove verifyCCM func * Add clusterID * Fix import and add t.Parallel() for missing tests * Kick Vercel CI * Remove scheme from endpoint path, and fix error logging * return metrics.MetricSink for sink method * Update SDK * Added telemetry agent to client and init sink in deps * Add node_id and __replica__ default labels * add function for default labels and set x-hcp-resource-id * Fix labels tests * Commit suggestion for getDefaultLabels Co-authored-by: Joshua Timmons <joshua.timmons1@gmail.com> * Fixed server.id, and t.Parallel() * Make defaultLabels a method on the TelemetryConfig object * Rename FilterList to lowercase filterList * Cleanup filter implemetation by combining regex into a single one, and making the type lowercase * Fix append * use regex directly for filters * Fix x-resource-id test to use mocked value * Fix log.Error formats * Forgot the len(opts.Label) optimization) * Use cfg.NodeID instead --------- Co-authored-by: Joshua Timmons <joshua.timmons1@gmail.com> * remove replic tag (#17484) * [HCP Observability] Add custom metrics for OTEL sink, improve logging, upgrade modules and cleanup metrics client (#17455) * Add custom metrics for Exporter and transform operations * Improve deps logging Run go mod tidy * Upgrade SDK and OTEL * Remove the partial success implemetation and check for HTTP status code in metrics client * Add x-channel * cleanup logs in deps.go based on PR feedback * Change to debug log and lowercase * address test operation feedback * use GetHumanVersion on version * Fix error wrapping * Fix metric names * [HCP Observability] Turn off retries for now until dynamically configurable (#17496) * Remove retries for now until dynamic configuration is possible * Clarify comment * Update changelog * improve changelog --------- Co-authored-by: Joshua Timmons <joshua.timmons1@gmail.com>
343 lines
9.5 KiB
Go
343 lines
9.5 KiB
Go
package telemetry
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/armon/go-metrics"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"go.opentelemetry.io/otel/attribute"
|
|
"go.opentelemetry.io/otel/sdk/instrumentation"
|
|
"go.opentelemetry.io/otel/sdk/metric/metricdata"
|
|
"go.opentelemetry.io/otel/sdk/resource"
|
|
semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
|
|
cpb "go.opentelemetry.io/proto/otlp/common/v1"
|
|
mpb "go.opentelemetry.io/proto/otlp/metrics/v1"
|
|
rpb "go.opentelemetry.io/proto/otlp/resource/v1"
|
|
)
|
|
|
|
var (
|
|
// Common attributes for test cases.
|
|
start = time.Date(2000, time.January, 01, 0, 0, 0, 0, time.FixedZone("GMT", 0))
|
|
end = start.Add(30 * time.Second)
|
|
|
|
alice = attribute.NewSet(attribute.String("user", "alice"))
|
|
bob = attribute.NewSet(attribute.String("user", "bob"))
|
|
|
|
pbAlice = &cpb.KeyValue{Key: "user", Value: &cpb.AnyValue{
|
|
Value: &cpb.AnyValue_StringValue{StringValue: "alice"},
|
|
}}
|
|
pbBob = &cpb.KeyValue{Key: "user", Value: &cpb.AnyValue{
|
|
Value: &cpb.AnyValue_StringValue{StringValue: "bob"},
|
|
}}
|
|
|
|
// DataPoint test case : Histogram Datapoints (Histogram)
|
|
minA, maxA, sumA = 2.0, 4.0, 90.0
|
|
minB, maxB, sumB = 4.0, 150.0, 234.0
|
|
inputHDP = []metricdata.HistogramDataPoint[float64]{{
|
|
Attributes: alice,
|
|
StartTime: start,
|
|
Time: end,
|
|
Count: 30,
|
|
Bounds: []float64{1, 5},
|
|
BucketCounts: []uint64{0, 30, 0},
|
|
Min: metricdata.NewExtrema(minA),
|
|
Max: metricdata.NewExtrema(maxA),
|
|
Sum: sumA,
|
|
}, {
|
|
Attributes: bob,
|
|
StartTime: start,
|
|
Time: end,
|
|
Count: 3,
|
|
Bounds: []float64{1, 5},
|
|
BucketCounts: []uint64{0, 1, 2},
|
|
Min: metricdata.NewExtrema(minB),
|
|
Max: metricdata.NewExtrema(maxB),
|
|
Sum: sumB,
|
|
}}
|
|
|
|
expectedHDP = []*mpb.HistogramDataPoint{{
|
|
Attributes: []*cpb.KeyValue{pbAlice},
|
|
StartTimeUnixNano: uint64(start.UnixNano()),
|
|
TimeUnixNano: uint64(end.UnixNano()),
|
|
Count: 30,
|
|
Sum: &sumA,
|
|
ExplicitBounds: []float64{1, 5},
|
|
BucketCounts: []uint64{0, 30, 0},
|
|
Min: &minA,
|
|
Max: &maxA,
|
|
}, {
|
|
Attributes: []*cpb.KeyValue{pbBob},
|
|
StartTimeUnixNano: uint64(start.UnixNano()),
|
|
TimeUnixNano: uint64(end.UnixNano()),
|
|
Count: 3,
|
|
Sum: &sumB,
|
|
ExplicitBounds: []float64{1, 5},
|
|
BucketCounts: []uint64{0, 1, 2},
|
|
Min: &minB,
|
|
Max: &maxB,
|
|
}}
|
|
// DataPoint test case : Number Datapoints (Gauge / Counter)
|
|
inputDP = []metricdata.DataPoint[float64]{
|
|
{Attributes: alice, StartTime: start, Time: end, Value: 1.0},
|
|
{Attributes: bob, StartTime: start, Time: end, Value: 2.0},
|
|
}
|
|
|
|
expectedDP = []*mpb.NumberDataPoint{
|
|
{
|
|
Attributes: []*cpb.KeyValue{pbAlice},
|
|
StartTimeUnixNano: uint64(start.UnixNano()),
|
|
TimeUnixNano: uint64(end.UnixNano()),
|
|
Value: &mpb.NumberDataPoint_AsDouble{AsDouble: 1.0},
|
|
},
|
|
{
|
|
Attributes: []*cpb.KeyValue{pbBob},
|
|
StartTimeUnixNano: uint64(start.UnixNano()),
|
|
TimeUnixNano: uint64(end.UnixNano()),
|
|
Value: &mpb.NumberDataPoint_AsDouble{AsDouble: 2.0},
|
|
},
|
|
}
|
|
|
|
invalidSumTemporality = metricdata.Metrics{
|
|
Name: "invalid-sum",
|
|
Description: "Sum with invalid temporality",
|
|
Unit: "1",
|
|
Data: metricdata.Sum[float64]{
|
|
Temporality: metricdata.DeltaTemporality,
|
|
IsMonotonic: false,
|
|
DataPoints: inputDP,
|
|
},
|
|
}
|
|
|
|
invalidSumAgg = metricdata.Metrics{
|
|
Name: "unknown",
|
|
Description: "Unknown aggregation",
|
|
Unit: "1",
|
|
Data: metricdata.Sum[int64]{},
|
|
}
|
|
|
|
invalidHistTemporality = metricdata.Metrics{
|
|
Name: "invalid-histogram",
|
|
Description: "Invalid histogram",
|
|
Unit: "1",
|
|
Data: metricdata.Histogram[float64]{
|
|
Temporality: metricdata.DeltaTemporality,
|
|
DataPoints: inputHDP,
|
|
},
|
|
}
|
|
|
|
validFloat64Gauge = metricdata.Metrics{
|
|
Name: "float64-gauge",
|
|
Description: "Gauge with float64 values",
|
|
Unit: "1",
|
|
Data: metricdata.Gauge[float64]{DataPoints: inputDP},
|
|
}
|
|
|
|
validFloat64Sum = metricdata.Metrics{
|
|
Name: "float64-sum",
|
|
Description: "Sum with float64 values",
|
|
Unit: "1",
|
|
Data: metricdata.Sum[float64]{
|
|
Temporality: metricdata.CumulativeTemporality,
|
|
IsMonotonic: false,
|
|
DataPoints: inputDP,
|
|
},
|
|
}
|
|
|
|
validFloat64Hist = metricdata.Metrics{
|
|
Name: "float64-histogram",
|
|
Description: "Histogram",
|
|
Unit: "1",
|
|
Data: metricdata.Histogram[float64]{
|
|
Temporality: metricdata.CumulativeTemporality,
|
|
DataPoints: inputHDP,
|
|
},
|
|
}
|
|
|
|
// Metrics Test Case
|
|
// - 3 invalid metrics and 3 Valid to test filtering
|
|
// - 1 invalid metric type
|
|
// - 2 invalid cummulative temporalities (only cummulative supported)
|
|
// - 3 types (Gauge, Counter, and Histogram) supported
|
|
inputMetrics = []metricdata.Metrics{
|
|
validFloat64Gauge,
|
|
validFloat64Sum,
|
|
validFloat64Hist,
|
|
invalidSumTemporality,
|
|
invalidHistTemporality,
|
|
invalidSumAgg,
|
|
}
|
|
|
|
expectedMetrics = []*mpb.Metric{
|
|
{
|
|
Name: "float64-gauge",
|
|
Description: "Gauge with float64 values",
|
|
Unit: "1",
|
|
Data: &mpb.Metric_Gauge{Gauge: &mpb.Gauge{DataPoints: expectedDP}},
|
|
},
|
|
{
|
|
Name: "float64-sum",
|
|
Description: "Sum with float64 values",
|
|
Unit: "1",
|
|
Data: &mpb.Metric_Sum{Sum: &mpb.Sum{
|
|
AggregationTemporality: mpb.AggregationTemporality_AGGREGATION_TEMPORALITY_CUMULATIVE,
|
|
IsMonotonic: false,
|
|
DataPoints: expectedDP,
|
|
}},
|
|
},
|
|
{
|
|
Name: "float64-histogram",
|
|
Description: "Histogram",
|
|
Unit: "1",
|
|
Data: &mpb.Metric_Histogram{Histogram: &mpb.Histogram{
|
|
AggregationTemporality: mpb.AggregationTemporality_AGGREGATION_TEMPORALITY_CUMULATIVE,
|
|
DataPoints: expectedHDP,
|
|
}},
|
|
},
|
|
}
|
|
|
|
// ScopeMetrics Test Cases
|
|
inputScopeMetrics = []metricdata.ScopeMetrics{{
|
|
Scope: instrumentation.Scope{
|
|
Name: "test/code/path",
|
|
Version: "v0.1.0",
|
|
},
|
|
Metrics: inputMetrics,
|
|
}}
|
|
|
|
expectedScopeMetrics = []*mpb.ScopeMetrics{{
|
|
Scope: &cpb.InstrumentationScope{
|
|
Name: "test/code/path",
|
|
Version: "v0.1.0",
|
|
},
|
|
Metrics: expectedMetrics,
|
|
}}
|
|
|
|
// ResourceMetrics Test Cases
|
|
inputResourceMetrics = &metricdata.ResourceMetrics{
|
|
Resource: resource.NewSchemaless(
|
|
semconv.ServiceName("test server"),
|
|
semconv.ServiceVersion("v0.1.0"),
|
|
),
|
|
ScopeMetrics: inputScopeMetrics,
|
|
}
|
|
|
|
expectedResourceMetrics = &mpb.ResourceMetrics{
|
|
Resource: &rpb.Resource{
|
|
Attributes: []*cpb.KeyValue{
|
|
{
|
|
Key: "service.name",
|
|
Value: &cpb.AnyValue{
|
|
Value: &cpb.AnyValue_StringValue{StringValue: "test server"},
|
|
},
|
|
},
|
|
{
|
|
Key: "service.version",
|
|
Value: &cpb.AnyValue{
|
|
Value: &cpb.AnyValue_StringValue{StringValue: "v0.1.0"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ScopeMetrics: expectedScopeMetrics,
|
|
}
|
|
)
|
|
|
|
// TestTransformOTLP runs tests from the "bottom-up" of the metricdata data types.
|
|
func TestTransformOTLP(t *testing.T) {
|
|
t.Parallel()
|
|
// Histogram DataPoint Test Case (Histograms)
|
|
assert.Equal(t, expectedHDP, histogramDataPointsToPB(inputHDP))
|
|
|
|
// Number DataPoint Test Case (Counters / Gauges)
|
|
require.Equal(t, expectedDP, dataPointsToPB(inputDP))
|
|
|
|
// MetricType Error Test Cases
|
|
_, err := metricTypeToPB(invalidHistTemporality)
|
|
require.Error(t, err)
|
|
require.ErrorIs(t, err, temporalityErr)
|
|
|
|
_, err = metricTypeToPB(invalidSumTemporality)
|
|
require.Error(t, err)
|
|
require.ErrorIs(t, err, temporalityErr)
|
|
|
|
_, err = metricTypeToPB(invalidSumAgg)
|
|
require.Error(t, err)
|
|
require.ErrorIs(t, err, aggregationErr)
|
|
|
|
// Metrics Test Case
|
|
m := metricsToPB(inputMetrics)
|
|
require.Equal(t, expectedMetrics, m)
|
|
require.Equal(t, len(expectedMetrics), 3)
|
|
|
|
// Scope Metrics Test Case
|
|
sm := scopeMetricsToPB(inputScopeMetrics)
|
|
require.Equal(t, expectedScopeMetrics, sm)
|
|
|
|
// // Resource Metrics Test Case
|
|
rm := transformOTLP(inputResourceMetrics)
|
|
require.Equal(t, expectedResourceMetrics, rm)
|
|
}
|
|
|
|
// TestTransformOTLP_CustomMetrics tests that a custom metric (hcp.otel.transform.failure) is emitted
|
|
// when transform fails. This test cannot be run in parallel as the metrics.NewGlobal()
|
|
// sets a shared global sink.
|
|
func TestTransformOTLP_CustomMetrics(t *testing.T) {
|
|
for name, tc := range map[string]struct {
|
|
inputRM *metricdata.ResourceMetrics
|
|
expectedMetricCount int
|
|
}{
|
|
"successNoMetric": {
|
|
inputRM: &metricdata.ResourceMetrics{
|
|
// 3 valid metrics.
|
|
ScopeMetrics: []metricdata.ScopeMetrics{
|
|
{
|
|
Metrics: []metricdata.Metrics{
|
|
validFloat64Gauge,
|
|
validFloat64Hist,
|
|
validFloat64Sum,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"failureEmitsMetric": {
|
|
// inputScopeMetrics contains 3 bad metrics.
|
|
inputRM: inputResourceMetrics,
|
|
expectedMetricCount: 3,
|
|
},
|
|
} {
|
|
tc := tc
|
|
t.Run(name, func(t *testing.T) {
|
|
// Init global sink.
|
|
serviceName := "test.transform"
|
|
cfg := metrics.DefaultConfig(serviceName)
|
|
cfg.EnableHostname = false
|
|
|
|
sink := metrics.NewInmemSink(10*time.Second, 10*time.Second)
|
|
metrics.NewGlobal(cfg, sink)
|
|
|
|
// Perform operation that emits metric.
|
|
transformOTLP(tc.inputRM)
|
|
|
|
// Collect sink metrics.
|
|
intervals := sink.Data()
|
|
require.Len(t, intervals, 1)
|
|
key := serviceName + "." + strings.Join(internalMetricTransformFailure, ".")
|
|
sv := intervals[0].Counters[key]
|
|
|
|
if tc.expectedMetricCount == 0 {
|
|
require.Empty(t, sv)
|
|
return
|
|
}
|
|
|
|
// Verify count for transform failure metric.
|
|
require.NotNil(t, sv)
|
|
require.NotNil(t, sv.AggregateSample)
|
|
require.Equal(t, 3, sv.AggregateSample.Count)
|
|
})
|
|
}
|
|
}
|