diff --git a/comp/core/agenttelemetry/fx/go.mod b/comp/core/agenttelemetry/fx/go.mod index ae12c5cee86d..4ef24fe0694a 100644 --- a/comp/core/agenttelemetry/fx/go.mod +++ b/comp/core/agenttelemetry/fx/go.mod @@ -59,7 +59,7 @@ require ( github.com/DataDog/datadog-agent/pkg/version v0.75.4 // indirect github.com/DataDog/go-acl v1.0.1 // indirect github.com/DataDog/viper v1.15.1 // indirect - github.com/DataDog/zstd v1.5.7 // indirect + github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect diff --git a/comp/core/agenttelemetry/fx/go.sum b/comp/core/agenttelemetry/fx/go.sum index 90d8e7a6d620..e928f36ee5d9 100644 --- a/comp/core/agenttelemetry/fx/go.sum +++ b/comp/core/agenttelemetry/fx/go.sum @@ -3,8 +3,8 @@ github.com/DataDog/go-acl v1.0.1 h1:uRbp98YmlVZYqNNyTBFNI3Y6bnziBLyCIR4nRu0bIpU= github.com/DataDog/go-acl v1.0.1/go.mod h1:YJx333qSb3GUqCLIbqKeGaZS2pUYh2IYGI7+FsX18CU= github.com/DataDog/viper v1.15.1 h1:kcdFE+qPndlWkhU4iEf/WpWQMCyVYHTv5HqvVf+SYJs= github.com/DataDog/viper v1.15.1/go.mod h1:rDLDREOPd+gpEbA8y4Y/5wTvyLqvUiCmDXX0jRZy8mw= -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= diff --git a/comp/core/agenttelemetry/impl/go.mod b/comp/core/agenttelemetry/impl/go.mod index f43cf8b1c8b2..a46471776cc3 100644 --- a/comp/core/agenttelemetry/impl/go.mod +++ b/comp/core/agenttelemetry/impl/go.mod @@ -20,7 +20,7 @@ require ( github.com/DataDog/datadog-agent/pkg/util/jsonquery v0.0.0-20251027120702-0e91eee9852f github.com/DataDog/datadog-agent/pkg/util/scrubber v0.75.4 github.com/DataDog/datadog-agent/pkg/version v0.75.4 - github.com/DataDog/zstd v1.5.7 + github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 github.com/prometheus/client_model v0.6.2 github.com/robfig/cron/v3 v3.0.1 github.com/stretchr/testify v1.11.1 diff --git a/comp/core/agenttelemetry/impl/go.sum b/comp/core/agenttelemetry/impl/go.sum index 644ab77c2038..008cac8e6d43 100644 --- a/comp/core/agenttelemetry/impl/go.sum +++ b/comp/core/agenttelemetry/impl/go.sum @@ -3,8 +3,8 @@ github.com/DataDog/go-acl v1.0.1 h1:uRbp98YmlVZYqNNyTBFNI3Y6bnziBLyCIR4nRu0bIpU= github.com/DataDog/go-acl v1.0.1/go.mod h1:YJx333qSb3GUqCLIbqKeGaZS2pUYh2IYGI7+FsX18CU= github.com/DataDog/viper v1.15.1 h1:kcdFE+qPndlWkhU4iEf/WpWQMCyVYHTv5HqvVf+SYJs= github.com/DataDog/viper v1.15.1/go.mod h1:rDLDREOPd+gpEbA8y4Y/5wTvyLqvUiCmDXX0jRZy8mw= -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= diff --git a/comp/logs-library/go.mod b/comp/logs-library/go.mod index 7b1084ba6827..b26988e2f4b5 100644 --- a/comp/logs-library/go.mod +++ b/comp/logs-library/go.mod @@ -72,7 +72,7 @@ require ( github.com/DataDog/datadog-agent/pkg/util/winutil v0.75.4 // indirect github.com/DataDog/go-acl v1.0.1 // indirect github.com/DataDog/viper v1.15.1 // indirect - github.com/DataDog/zstd v1.5.7 // indirect + github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect diff --git a/comp/logs-library/go.sum b/comp/logs-library/go.sum index 8056a5d3b549..10ca27bf9ad7 100644 --- a/comp/logs-library/go.sum +++ b/comp/logs-library/go.sum @@ -5,8 +5,8 @@ github.com/DataDog/go-acl v1.0.1 h1:uRbp98YmlVZYqNNyTBFNI3Y6bnziBLyCIR4nRu0bIpU= github.com/DataDog/go-acl v1.0.1/go.mod h1:YJx333qSb3GUqCLIbqKeGaZS2pUYh2IYGI7+FsX18CU= github.com/DataDog/viper v1.15.1 h1:kcdFE+qPndlWkhU4iEf/WpWQMCyVYHTv5HqvVf+SYJs= github.com/DataDog/viper v1.15.1/go.mod h1:rDLDREOPd+gpEbA8y4Y/5wTvyLqvUiCmDXX0jRZy8mw= -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= diff --git a/comp/otelcol/collector-contrib/impl/go.mod b/comp/otelcol/collector-contrib/impl/go.mod index fb47f7eec93e..aa38b0f75445 100644 --- a/comp/otelcol/collector-contrib/impl/go.mod +++ b/comp/otelcol/collector-contrib/impl/go.mod @@ -145,7 +145,7 @@ require ( github.com/DataDog/mmh3 v0.0.0-20210722141835-012dc69a9e49 // indirect github.com/DataDog/sketches-go v1.4.8 // indirect github.com/DataDog/viper v1.15.1 // indirect - github.com/DataDog/zstd v1.5.7 // indirect + github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 // indirect github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.32.0 // indirect github.com/Masterminds/semver/v3 v3.5.0 // indirect diff --git a/comp/otelcol/collector-contrib/impl/go.sum b/comp/otelcol/collector-contrib/impl/go.sum index 60d53219a9d1..fd34886b9b04 100644 --- a/comp/otelcol/collector-contrib/impl/go.sum +++ b/comp/otelcol/collector-contrib/impl/go.sum @@ -51,8 +51,8 @@ github.com/DataDog/sketches-go v1.4.8 h1:pFk9BNn+Rzv8IMIoPUttoOpOr3bJOqU3P6EP5wK github.com/DataDog/sketches-go v1.4.8/go.mod h1:a/wjRUqzqtGS8qRHRPDCs4EAQfmvPDZGDlMIF5mxXOE= github.com/DataDog/viper v1.15.1 h1:kcdFE+qPndlWkhU4iEf/WpWQMCyVYHTv5HqvVf+SYJs= github.com/DataDog/viper v1.15.1/go.mod h1:rDLDREOPd+gpEbA8y4Y/5wTvyLqvUiCmDXX0jRZy8mw= -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f h1:5Vuo4niPKFkfwW55jV4vY0ih3VQ9RaQqeqY67fvRn8A= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f/go.mod h1:oXfOhM/Kr8OvqS6tVqJwxPBornV0yrx3bc+l0BDr7PQ= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.32.0 h1:rIkQfkCOVKc1OiRCNcSDD8ml5RJlZbH/Xsq7lbpynwc= diff --git a/comp/otelcol/ddflareextension/impl/go.mod b/comp/otelcol/ddflareextension/impl/go.mod index 92f9d3537c32..52cebd88fd5a 100644 --- a/comp/otelcol/ddflareextension/impl/go.mod +++ b/comp/otelcol/ddflareextension/impl/go.mod @@ -235,7 +235,7 @@ require ( github.com/DataDog/mmh3 v0.0.0-20210722141835-012dc69a9e49 // indirect github.com/DataDog/sketches-go v1.4.8 // indirect github.com/DataDog/viper v1.15.1 // indirect - github.com/DataDog/zstd v1.5.7 // indirect + github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 // indirect github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/alecthomas/participle/v2 v2.1.4 // indirect diff --git a/comp/otelcol/ddflareextension/impl/go.sum b/comp/otelcol/ddflareextension/impl/go.sum index eda0e1fc4e00..487720756c54 100644 --- a/comp/otelcol/ddflareextension/impl/go.sum +++ b/comp/otelcol/ddflareextension/impl/go.sum @@ -56,8 +56,8 @@ github.com/DataDog/sketches-go v1.4.8 h1:pFk9BNn+Rzv8IMIoPUttoOpOr3bJOqU3P6EP5wK github.com/DataDog/sketches-go v1.4.8/go.mod h1:a/wjRUqzqtGS8qRHRPDCs4EAQfmvPDZGDlMIF5mxXOE= github.com/DataDog/viper v1.15.1 h1:kcdFE+qPndlWkhU4iEf/WpWQMCyVYHTv5HqvVf+SYJs= github.com/DataDog/viper v1.15.1/go.mod h1:rDLDREOPd+gpEbA8y4Y/5wTvyLqvUiCmDXX0jRZy8mw= -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f h1:5Vuo4niPKFkfwW55jV4vY0ih3VQ9RaQqeqY67fvRn8A= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f/go.mod h1:oXfOhM/Kr8OvqS6tVqJwxPBornV0yrx3bc+l0BDr7PQ= github.com/Masterminds/semver/v3 v3.5.0 h1:kQceYJfbupGfZOKZQg0kou0DgAKhzDg2NZPAwZ/2OOE= diff --git a/comp/otelcol/ddprofilingextension/impl/go.sum b/comp/otelcol/ddprofilingextension/impl/go.sum index 8d3efa63cfd4..2d18cea9df91 100644 --- a/comp/otelcol/ddprofilingextension/impl/go.sum +++ b/comp/otelcol/ddprofilingextension/impl/go.sum @@ -17,8 +17,8 @@ github.com/DataDog/sketches-go v1.4.8 h1:pFk9BNn+Rzv8IMIoPUttoOpOr3bJOqU3P6EP5wK github.com/DataDog/sketches-go v1.4.8/go.mod h1:a/wjRUqzqtGS8qRHRPDCs4EAQfmvPDZGDlMIF5mxXOE= github.com/DataDog/viper v1.15.1 h1:kcdFE+qPndlWkhU4iEf/WpWQMCyVYHTv5HqvVf+SYJs= github.com/DataDog/viper v1.15.1/go.mod h1:rDLDREOPd+gpEbA8y4Y/5wTvyLqvUiCmDXX0jRZy8mw= -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= diff --git a/comp/otelcol/logsagentpipeline/go.mod b/comp/otelcol/logsagentpipeline/go.mod index 8890b5e86bd9..14af13eb333e 100644 --- a/comp/otelcol/logsagentpipeline/go.mod +++ b/comp/otelcol/logsagentpipeline/go.mod @@ -69,7 +69,7 @@ require ( github.com/DataDog/datadog-agent/pkg/util/winutil v0.78.1 // indirect github.com/DataDog/datadog-agent/pkg/version v0.78.1 // indirect github.com/DataDog/viper v1.15.1 // indirect - github.com/DataDog/zstd v1.5.7 // indirect + github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 // indirect ) require ( diff --git a/comp/otelcol/logsagentpipeline/go.sum b/comp/otelcol/logsagentpipeline/go.sum index 8056a5d3b549..10ca27bf9ad7 100644 --- a/comp/otelcol/logsagentpipeline/go.sum +++ b/comp/otelcol/logsagentpipeline/go.sum @@ -5,8 +5,8 @@ github.com/DataDog/go-acl v1.0.1 h1:uRbp98YmlVZYqNNyTBFNI3Y6bnziBLyCIR4nRu0bIpU= github.com/DataDog/go-acl v1.0.1/go.mod h1:YJx333qSb3GUqCLIbqKeGaZS2pUYh2IYGI7+FsX18CU= github.com/DataDog/viper v1.15.1 h1:kcdFE+qPndlWkhU4iEf/WpWQMCyVYHTv5HqvVf+SYJs= github.com/DataDog/viper v1.15.1/go.mod h1:rDLDREOPd+gpEbA8y4Y/5wTvyLqvUiCmDXX0jRZy8mw= -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= diff --git a/comp/otelcol/logsagentpipeline/logsagentpipelineimpl/go.sum b/comp/otelcol/logsagentpipeline/logsagentpipelineimpl/go.sum index 8056a5d3b549..10ca27bf9ad7 100644 --- a/comp/otelcol/logsagentpipeline/logsagentpipelineimpl/go.sum +++ b/comp/otelcol/logsagentpipeline/logsagentpipelineimpl/go.sum @@ -5,8 +5,8 @@ github.com/DataDog/go-acl v1.0.1 h1:uRbp98YmlVZYqNNyTBFNI3Y6bnziBLyCIR4nRu0bIpU= github.com/DataDog/go-acl v1.0.1/go.mod h1:YJx333qSb3GUqCLIbqKeGaZS2pUYh2IYGI7+FsX18CU= github.com/DataDog/viper v1.15.1 h1:kcdFE+qPndlWkhU4iEf/WpWQMCyVYHTv5HqvVf+SYJs= github.com/DataDog/viper v1.15.1/go.mod h1:rDLDREOPd+gpEbA8y4Y/5wTvyLqvUiCmDXX0jRZy8mw= -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= diff --git a/comp/otelcol/otlp/components/exporter/datadogexporter/go.mod b/comp/otelcol/otlp/components/exporter/datadogexporter/go.mod index 4d67c98ae2fd..e4cb191fe094 100644 --- a/comp/otelcol/otlp/components/exporter/datadogexporter/go.mod +++ b/comp/otelcol/otlp/components/exporter/datadogexporter/go.mod @@ -139,7 +139,7 @@ require ( github.com/DataDog/mmh3 v0.0.0-20210722141835-012dc69a9e49 // indirect github.com/DataDog/sketches-go v1.4.8 // indirect github.com/DataDog/viper v1.15.1 // indirect - github.com/DataDog/zstd v1.5.7 // indirect + github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 // indirect github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/benbjohnson/clock v1.3.5 // indirect diff --git a/comp/otelcol/otlp/components/exporter/datadogexporter/go.sum b/comp/otelcol/otlp/components/exporter/datadogexporter/go.sum index 67f7b00a48dc..dd6badb3f446 100644 --- a/comp/otelcol/otlp/components/exporter/datadogexporter/go.sum +++ b/comp/otelcol/otlp/components/exporter/datadogexporter/go.sum @@ -17,8 +17,8 @@ github.com/DataDog/sketches-go v1.4.8 h1:pFk9BNn+Rzv8IMIoPUttoOpOr3bJOqU3P6EP5wK github.com/DataDog/sketches-go v1.4.8/go.mod h1:a/wjRUqzqtGS8qRHRPDCs4EAQfmvPDZGDlMIF5mxXOE= github.com/DataDog/viper v1.15.1 h1:kcdFE+qPndlWkhU4iEf/WpWQMCyVYHTv5HqvVf+SYJs= github.com/DataDog/viper v1.15.1/go.mod h1:rDLDREOPd+gpEbA8y4Y/5wTvyLqvUiCmDXX0jRZy8mw= -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f h1:5Vuo4niPKFkfwW55jV4vY0ih3VQ9RaQqeqY67fvRn8A= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f/go.mod h1:oXfOhM/Kr8OvqS6tVqJwxPBornV0yrx3bc+l0BDr7PQ= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= diff --git a/comp/otelcol/otlp/components/exporter/logsagentexporter/go.mod b/comp/otelcol/otlp/components/exporter/logsagentexporter/go.mod index 0961852573c3..0b7853b8f818 100644 --- a/comp/otelcol/otlp/components/exporter/logsagentexporter/go.mod +++ b/comp/otelcol/otlp/components/exporter/logsagentexporter/go.mod @@ -85,7 +85,7 @@ require ( github.com/DataDog/mmh3 v0.0.0-20210722141835-012dc69a9e49 // indirect github.com/DataDog/sketches-go v1.4.8 // indirect github.com/DataDog/viper v1.15.1 // indirect - github.com/DataDog/zstd v1.5.7 // indirect + github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 // indirect github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/beorn7/perks v1.0.1 // indirect diff --git a/comp/otelcol/otlp/components/exporter/logsagentexporter/go.sum b/comp/otelcol/otlp/components/exporter/logsagentexporter/go.sum index ea6330f92629..c05ae157b0ec 100644 --- a/comp/otelcol/otlp/components/exporter/logsagentexporter/go.sum +++ b/comp/otelcol/otlp/components/exporter/logsagentexporter/go.sum @@ -11,8 +11,8 @@ github.com/DataDog/sketches-go v1.4.8 h1:pFk9BNn+Rzv8IMIoPUttoOpOr3bJOqU3P6EP5wK github.com/DataDog/sketches-go v1.4.8/go.mod h1:a/wjRUqzqtGS8qRHRPDCs4EAQfmvPDZGDlMIF5mxXOE= github.com/DataDog/viper v1.15.1 h1:kcdFE+qPndlWkhU4iEf/WpWQMCyVYHTv5HqvVf+SYJs= github.com/DataDog/viper v1.15.1/go.mod h1:rDLDREOPd+gpEbA8y4Y/5wTvyLqvUiCmDXX0jRZy8mw= -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f h1:5Vuo4niPKFkfwW55jV4vY0ih3VQ9RaQqeqY67fvRn8A= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f/go.mod h1:oXfOhM/Kr8OvqS6tVqJwxPBornV0yrx3bc+l0BDr7PQ= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= diff --git a/comp/otelcol/otlp/components/exporter/serializerexporter/go.mod b/comp/otelcol/otlp/components/exporter/serializerexporter/go.mod index 4b3fd74e0aa4..0b64b428bef9 100644 --- a/comp/otelcol/otlp/components/exporter/serializerexporter/go.mod +++ b/comp/otelcol/otlp/components/exporter/serializerexporter/go.mod @@ -118,7 +118,7 @@ require ( github.com/DataDog/mmh3 v0.0.0-20210722141835-012dc69a9e49 // indirect github.com/DataDog/sketches-go v1.4.8 // indirect github.com/DataDog/viper v1.15.1 // indirect - github.com/DataDog/zstd v1.5.7 // indirect + github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 // indirect github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect diff --git a/comp/otelcol/otlp/components/exporter/serializerexporter/go.sum b/comp/otelcol/otlp/components/exporter/serializerexporter/go.sum index a682e678b4dd..c4467ef4134e 100644 --- a/comp/otelcol/otlp/components/exporter/serializerexporter/go.sum +++ b/comp/otelcol/otlp/components/exporter/serializerexporter/go.sum @@ -9,8 +9,8 @@ github.com/DataDog/sketches-go v1.4.8 h1:pFk9BNn+Rzv8IMIoPUttoOpOr3bJOqU3P6EP5wK github.com/DataDog/sketches-go v1.4.8/go.mod h1:a/wjRUqzqtGS8qRHRPDCs4EAQfmvPDZGDlMIF5mxXOE= github.com/DataDog/viper v1.15.1 h1:kcdFE+qPndlWkhU4iEf/WpWQMCyVYHTv5HqvVf+SYJs= github.com/DataDog/viper v1.15.1/go.mod h1:rDLDREOPd+gpEbA8y4Y/5wTvyLqvUiCmDXX0jRZy8mw= -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f h1:5Vuo4niPKFkfwW55jV4vY0ih3VQ9RaQqeqY67fvRn8A= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f/go.mod h1:oXfOhM/Kr8OvqS6tVqJwxPBornV0yrx3bc+l0BDr7PQ= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= diff --git a/comp/serializer/logscompression/go.mod b/comp/serializer/logscompression/go.mod index 566ce8d58ce6..8b8db63ae414 100644 --- a/comp/serializer/logscompression/go.mod +++ b/comp/serializer/logscompression/go.mod @@ -45,7 +45,7 @@ require ( github.com/DataDog/datadog-agent/pkg/version v0.72.2 // indirect github.com/DataDog/go-acl v1.0.1 // indirect github.com/DataDog/viper v1.15.1 // indirect - github.com/DataDog/zstd v1.5.7 // indirect + github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/ebitengine/purego v0.10.0 // indirect diff --git a/comp/serializer/logscompression/go.sum b/comp/serializer/logscompression/go.sum index ae6459a21146..bbb8bba32b6d 100644 --- a/comp/serializer/logscompression/go.sum +++ b/comp/serializer/logscompression/go.sum @@ -3,8 +3,8 @@ github.com/DataDog/go-acl v1.0.1 h1:uRbp98YmlVZYqNNyTBFNI3Y6bnziBLyCIR4nRu0bIpU= github.com/DataDog/go-acl v1.0.1/go.mod h1:YJx333qSb3GUqCLIbqKeGaZS2pUYh2IYGI7+FsX18CU= github.com/DataDog/viper v1.15.1 h1:kcdFE+qPndlWkhU4iEf/WpWQMCyVYHTv5HqvVf+SYJs= github.com/DataDog/viper v1.15.1/go.mod h1:rDLDREOPd+gpEbA8y4Y/5wTvyLqvUiCmDXX0jRZy8mw= -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= diff --git a/comp/serializer/metricscompression/go.mod b/comp/serializer/metricscompression/go.mod index 40bd5ef0e7e8..c5b2cac8c232 100644 --- a/comp/serializer/metricscompression/go.mod +++ b/comp/serializer/metricscompression/go.mod @@ -45,7 +45,7 @@ require ( github.com/DataDog/datadog-agent/pkg/version v0.72.2 // indirect github.com/DataDog/go-acl v1.0.1 // indirect github.com/DataDog/viper v1.15.1 // indirect - github.com/DataDog/zstd v1.5.7 // indirect + github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/ebitengine/purego v0.10.0 // indirect diff --git a/comp/serializer/metricscompression/go.sum b/comp/serializer/metricscompression/go.sum index ae6459a21146..bbb8bba32b6d 100644 --- a/comp/serializer/metricscompression/go.sum +++ b/comp/serializer/metricscompression/go.sum @@ -3,8 +3,8 @@ github.com/DataDog/go-acl v1.0.1 h1:uRbp98YmlVZYqNNyTBFNI3Y6bnziBLyCIR4nRu0bIpU= github.com/DataDog/go-acl v1.0.1/go.mod h1:YJx333qSb3GUqCLIbqKeGaZS2pUYh2IYGI7+FsX18CU= github.com/DataDog/viper v1.15.1 h1:kcdFE+qPndlWkhU4iEf/WpWQMCyVYHTv5HqvVf+SYJs= github.com/DataDog/viper v1.15.1/go.mod h1:rDLDREOPd+gpEbA8y4Y/5wTvyLqvUiCmDXX0jRZy8mw= -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= diff --git a/comp/trace/compression/impl-zstd/go.mod b/comp/trace/compression/impl-zstd/go.mod index d48d9ed44261..c1a1fe710f43 100644 --- a/comp/trace/compression/impl-zstd/go.mod +++ b/comp/trace/compression/impl-zstd/go.mod @@ -4,7 +4,7 @@ go 1.25.0 require ( github.com/DataDog/datadog-agent/comp/trace/compression/def v0.61.0 - github.com/DataDog/zstd v1.5.7 + github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 ) // This section was automatically added by 'dda inv modules.add-all-replace' command, do not edit manually diff --git a/comp/trace/compression/impl-zstd/go.sum b/comp/trace/compression/impl-zstd/go.sum index f6b646221cf9..4d0abfe5903a 100644 --- a/comp/trace/compression/impl-zstd/go.sum +++ b/comp/trace/compression/impl-zstd/go.sum @@ -1,2 +1,2 @@ -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= diff --git a/go.mod b/go.mod index f542133086f1..7f9e927f7182 100644 --- a/go.mod +++ b/go.mod @@ -174,7 +174,7 @@ require ( github.com/DataDog/viper v1.15.1 // TODO: pin to a WPA released version once there is a release that includes the apis module github.com/DataDog/watermarkpodautoscaler/apis v0.0.0-20250108152814-82e58d0231d1 - github.com/DataDog/zstd v1.5.7 + github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 github.com/Masterminds/semver/v3 v3.5.0 github.com/Masterminds/sprig/v3 v3.3.0 github.com/Microsoft/go-winio v0.6.2 diff --git a/go.sum b/go.sum index 702ba2a1ffe5..4d440ea91892 100644 --- a/go.sum +++ b/go.sum @@ -2605,8 +2605,8 @@ github.com/DataDog/viper v1.15.1 h1:kcdFE+qPndlWkhU4iEf/WpWQMCyVYHTv5HqvVf+SYJs= github.com/DataDog/viper v1.15.1/go.mod h1:rDLDREOPd+gpEbA8y4Y/5wTvyLqvUiCmDXX0jRZy8mw= github.com/DataDog/watermarkpodautoscaler/apis v0.0.0-20250108152814-82e58d0231d1 h1:9hiwoIk8FOsXDkdcdgNJ48iYaPfn+/7bXEwAnnfKjTc= github.com/DataDog/watermarkpodautoscaler/apis v0.0.0-20250108152814-82e58d0231d1/go.mod h1:57ytxiQR5KMYNeDgNqKn9y1LJMoRamBKHj3nvURhAdQ= -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f h1:5Vuo4niPKFkfwW55jV4vY0ih3VQ9RaQqeqY67fvRn8A= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f/go.mod h1:oXfOhM/Kr8OvqS6tVqJwxPBornV0yrx3bc+l0BDr7PQ= github.com/DisposaBoy/JsonConfigReader v0.0.0-20201129172854-99cf318d67e7 h1:AJKJCKcb/psppPl/9CUiQQnTG+Bce0/cIweD5w5Q7aQ= diff --git a/internal/qbranch/anomalydetection-testbench/go.mod b/internal/qbranch/anomalydetection-testbench/go.mod index 5f0bc82e0bfc..379b2569230e 100644 --- a/internal/qbranch/anomalydetection-testbench/go.mod +++ b/internal/qbranch/anomalydetection-testbench/go.mod @@ -89,7 +89,7 @@ require ( github.com/DataDog/go-acl v1.0.1 // indirect github.com/DataDog/go-tuf v1.1.1-0.5.2 // indirect github.com/DataDog/viper v1.15.1 // indirect - github.com/DataDog/zstd v1.5.7 // indirect + github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/acobaugh/osrelease v0.1.0 // indirect github.com/andybalholm/brotli v1.2.1 // indirect diff --git a/internal/qbranch/anomalydetection-testbench/go.sum b/internal/qbranch/anomalydetection-testbench/go.sum index 41eb2ca793f4..f90fae6c9380 100644 --- a/internal/qbranch/anomalydetection-testbench/go.sum +++ b/internal/qbranch/anomalydetection-testbench/go.sum @@ -11,8 +11,8 @@ github.com/DataDog/go-tuf v1.1.1-0.5.2 h1:YWvghV4ZvrQsPcUw8IOUMSDpqc3W5ruOIC+KJx github.com/DataDog/go-tuf v1.1.1-0.5.2/go.mod h1:zBcq6f654iVqmkk8n2Cx81E1JnNTMOAx1UEO/wZR+P0= github.com/DataDog/viper v1.15.1 h1:kcdFE+qPndlWkhU4iEf/WpWQMCyVYHTv5HqvVf+SYJs= github.com/DataDog/viper v1.15.1/go.mod h1:rDLDREOPd+gpEbA8y4Y/5wTvyLqvUiCmDXX0jRZy8mw= -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/acobaugh/osrelease v0.1.0 h1:Yb59HQDGGNhCj4suHaFQQfBps5wyoKLSSX/J/+UifRE= diff --git a/pkg/config/schema/go.mod b/pkg/config/schema/go.mod index 7509b2d1f48f..c9a5f444d950 100644 --- a/pkg/config/schema/go.mod +++ b/pkg/config/schema/go.mod @@ -3,7 +3,7 @@ module github.com/DataDog/datadog-agent/pkg/config/schema go 1.25.0 require ( - github.com/DataDog/zstd v1.5.7 + github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 github.com/stretchr/testify v1.11.1 go.yaml.in/yaml/v3 v3.0.4 diff --git a/pkg/config/schema/go.sum b/pkg/config/schema/go.sum index e8b8adb4ea45..ecb3818d1735 100644 --- a/pkg/config/schema/go.sum +++ b/pkg/config/schema/go.sum @@ -1,5 +1,5 @@ -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/pkg/opentelemetry-mapping-go/otlp/logs/go.mod b/pkg/opentelemetry-mapping-go/otlp/logs/go.mod index aa30a223cbe1..bfe1bd913ab6 100644 --- a/pkg/opentelemetry-mapping-go/otlp/logs/go.mod +++ b/pkg/opentelemetry-mapping-go/otlp/logs/go.mod @@ -32,7 +32,7 @@ require ( github.com/DataDog/datadog-agent/pkg/util/scrubber v0.72.2 // indirect github.com/DataDog/datadog-agent/pkg/version v0.72.2 // indirect github.com/DataDog/mmh3 v0.0.0-20210722141835-012dc69a9e49 // indirect - github.com/DataDog/zstd v1.5.7 // indirect + github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 // indirect github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/go-logr/logr v1.4.3 // indirect diff --git a/pkg/opentelemetry-mapping-go/otlp/logs/go.sum b/pkg/opentelemetry-mapping-go/otlp/logs/go.sum index 366fc193e83d..5f5aae4ffc4c 100644 --- a/pkg/opentelemetry-mapping-go/otlp/logs/go.sum +++ b/pkg/opentelemetry-mapping-go/otlp/logs/go.sum @@ -4,8 +4,8 @@ github.com/DataDog/datadog-api-client-go/v2 v2.60.0 h1:YzEB2H42symyDlHzNo0wcjW1m github.com/DataDog/datadog-api-client-go/v2 v2.60.0/go.mod h1:d3tOEgUd2kfsr9uuHQdY+nXrWp4uikgTgVCPdKNK30U= github.com/DataDog/mmh3 v0.0.0-20210722141835-012dc69a9e49 h1:EbzDX8HPk5uE2FsJYxD74QmMw0/3CqSKhEr6teh0ncQ= github.com/DataDog/mmh3 v0.0.0-20210722141835-012dc69a9e49/go.mod h1:SvsjzyJlSg0rKsqYgdcFxeEVflx3ZNAyFfkUHP0TxXg= -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f h1:5Vuo4niPKFkfwW55jV4vY0ih3VQ9RaQqeqY67fvRn8A= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f/go.mod h1:oXfOhM/Kr8OvqS6tVqJwxPBornV0yrx3bc+l0BDr7PQ= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= diff --git a/pkg/process/util/api/go.mod b/pkg/process/util/api/go.mod index 9a2332e06eaa..46826027fc4f 100644 --- a/pkg/process/util/api/go.mod +++ b/pkg/process/util/api/go.mod @@ -43,7 +43,7 @@ require ( github.com/DataDog/go-acl v1.0.1 // indirect github.com/DataDog/mmh3 v0.0.0-20210722141835-012dc69a9e49 // indirect github.com/DataDog/viper v1.15.1 // indirect - github.com/DataDog/zstd v1.5.7 // indirect + github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 // indirect github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/beorn7/perks v1.0.1 // indirect diff --git a/pkg/process/util/api/go.sum b/pkg/process/util/api/go.sum index d1d714277959..f34aff8800d6 100644 --- a/pkg/process/util/api/go.sum +++ b/pkg/process/util/api/go.sum @@ -7,8 +7,8 @@ github.com/DataDog/mmh3 v0.0.0-20210722141835-012dc69a9e49 h1:EbzDX8HPk5uE2FsJYx github.com/DataDog/mmh3 v0.0.0-20210722141835-012dc69a9e49/go.mod h1:SvsjzyJlSg0rKsqYgdcFxeEVflx3ZNAyFfkUHP0TxXg= github.com/DataDog/viper v1.15.1 h1:kcdFE+qPndlWkhU4iEf/WpWQMCyVYHTv5HqvVf+SYJs= github.com/DataDog/viper v1.15.1/go.mod h1:rDLDREOPd+gpEbA8y4Y/5wTvyLqvUiCmDXX0jRZy8mw= -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f h1:5Vuo4niPKFkfwW55jV4vY0ih3VQ9RaQqeqY67fvRn8A= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f/go.mod h1:oXfOhM/Kr8OvqS6tVqJwxPBornV0yrx3bc+l0BDr7PQ= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= diff --git a/pkg/serializer/go.mod b/pkg/serializer/go.mod index bbc0a254d22a..d0f3165d6174 100644 --- a/pkg/serializer/go.mod +++ b/pkg/serializer/go.mod @@ -82,7 +82,7 @@ require ( github.com/DataDog/mmh3 v0.0.0-20210722141835-012dc69a9e49 // indirect github.com/DataDog/sketches-go v1.4.8 // indirect github.com/DataDog/viper v1.15.1 // indirect - github.com/DataDog/zstd v1.5.7 // indirect + github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 // indirect github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/benbjohnson/clock v1.3.5 // indirect diff --git a/pkg/serializer/go.sum b/pkg/serializer/go.sum index 07107a867ac8..e1ebf26d5eb8 100644 --- a/pkg/serializer/go.sum +++ b/pkg/serializer/go.sum @@ -9,8 +9,8 @@ github.com/DataDog/sketches-go v1.4.8 h1:pFk9BNn+Rzv8IMIoPUttoOpOr3bJOqU3P6EP5wK github.com/DataDog/sketches-go v1.4.8/go.mod h1:a/wjRUqzqtGS8qRHRPDCs4EAQfmvPDZGDlMIF5mxXOE= github.com/DataDog/viper v1.15.1 h1:kcdFE+qPndlWkhU4iEf/WpWQMCyVYHTv5HqvVf+SYJs= github.com/DataDog/viper v1.15.1/go.mod h1:rDLDREOPd+gpEbA8y4Y/5wTvyLqvUiCmDXX0jRZy8mw= -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f h1:5Vuo4niPKFkfwW55jV4vY0ih3VQ9RaQqeqY67fvRn8A= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f/go.mod h1:oXfOhM/Kr8OvqS6tVqJwxPBornV0yrx3bc+l0BDr7PQ= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= diff --git a/pkg/trace/go.mod b/pkg/trace/go.mod index 1309a0ca7106..949bc42090f8 100644 --- a/pkg/trace/go.mod +++ b/pkg/trace/go.mod @@ -80,7 +80,7 @@ require ( github.com/DataDog/go-acl v1.0.1 // indirect github.com/DataDog/go-sqllexer v0.2.2 // indirect github.com/DataDog/go-tuf v1.1.1-0.5.2 // indirect - github.com/DataDog/zstd v1.5.7 // indirect + github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect diff --git a/pkg/trace/go.sum b/pkg/trace/go.sum index ce9baad01d5b..568c0261997d 100644 --- a/pkg/trace/go.sum +++ b/pkg/trace/go.sum @@ -8,8 +8,8 @@ github.com/DataDog/go-tuf v1.1.1-0.5.2 h1:YWvghV4ZvrQsPcUw8IOUMSDpqc3W5ruOIC+KJx github.com/DataDog/go-tuf v1.1.1-0.5.2/go.mod h1:zBcq6f654iVqmkk8n2Cx81E1JnNTMOAx1UEO/wZR+P0= github.com/DataDog/sketches-go v1.4.8 h1:pFk9BNn+Rzv8IMIoPUttoOpOr3bJOqU3P6EP5wK+Lv8= github.com/DataDog/sketches-go v1.4.8/go.mod h1:a/wjRUqzqtGS8qRHRPDCs4EAQfmvPDZGDlMIF5mxXOE= -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= diff --git a/pkg/util/compression/go.mod b/pkg/util/compression/go.mod index 9170bc7ac9a5..063cf92ee6e1 100644 --- a/pkg/util/compression/go.mod +++ b/pkg/util/compression/go.mod @@ -5,7 +5,7 @@ go 1.25.0 require ( github.com/DataDog/datadog-agent/comp/core/config v0.64.0-devel github.com/DataDog/datadog-agent/pkg/util/log v0.73.0-rc.5 - github.com/DataDog/zstd v1.5.7 + github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 github.com/klauspost/compress v1.18.6 ) diff --git a/pkg/util/compression/go.sum b/pkg/util/compression/go.sum index ae6459a21146..bbb8bba32b6d 100644 --- a/pkg/util/compression/go.sum +++ b/pkg/util/compression/go.sum @@ -3,8 +3,8 @@ github.com/DataDog/go-acl v1.0.1 h1:uRbp98YmlVZYqNNyTBFNI3Y6bnziBLyCIR4nRu0bIpU= github.com/DataDog/go-acl v1.0.1/go.mod h1:YJx333qSb3GUqCLIbqKeGaZS2pUYh2IYGI7+FsX18CU= github.com/DataDog/viper v1.15.1 h1:kcdFE+qPndlWkhU4iEf/WpWQMCyVYHTv5HqvVf+SYJs= github.com/DataDog/viper v1.15.1/go.mod h1:rDLDREOPd+gpEbA8y4Y/5wTvyLqvUiCmDXX0jRZy8mw= -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= diff --git a/test/e2e-framework/components/datadog/agentparams/BUILD.bazel b/test/e2e-framework/components/datadog/agentparams/BUILD.bazel index 0cd6d045e6e5..a0bd7f824e84 100644 --- a/test/e2e-framework/components/datadog/agentparams/BUILD.bazel +++ b/test/e2e-framework/components/datadog/agentparams/BUILD.bazel @@ -15,6 +15,7 @@ go_library( "//test/e2e-framework/components/datadog/agentparams/filepermissions", "//test/e2e-framework/components/datadog/fakeintake", "@com_github_pulumi_pulumi_sdk_v3//go/pulumi", + "@in_yaml_go_yaml_v3//:yaml", ], ) diff --git a/test/e2e-framework/components/datadog/agentparams/params.go b/test/e2e-framework/components/datadog/agentparams/params.go index 4207efd5ed00..5a30aa6cc675 100644 --- a/test/e2e-framework/components/datadog/agentparams/params.go +++ b/test/e2e-framework/components/datadog/agentparams/params.go @@ -11,6 +11,7 @@ import ( "strings" "github.com/pulumi/pulumi/sdk/v3/go/pulumi" + "go.yaml.in/yaml/v3" "github.com/DataDog/datadog-agent/pkg/util/option" "github.com/DataDog/datadog-agent/test/e2e-framework/common" @@ -39,6 +40,7 @@ import ( // - [WithLogs] // - [WithAdditionalInstallParameters] // - [WithSkipAPIKeyInConfig] +// - [WithV3MetricsEnabled] // // [Functional options pattern]: https://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis @@ -61,6 +63,10 @@ type Params struct { // parameters like the MSI flags. AdditionalInstallParameters []string SkipAPIKeyInConfig bool + + // intakeURL is set by withIntakeHostname so WithV3MetricsEnabled can inject V3 endpoint + // config without recomposing the URL from its parts. + intakeURL *pulumi.StringOutput } type Option = func(*Params) error @@ -269,6 +275,9 @@ func WithPulumiResourceOptions(resources ...pulumi.ResourceOption) func(*Params) func withIntakeHostname(scheme pulumi.StringInput, hostname pulumi.StringInput, port pulumi.IntInput) func(*Params) error { return func(p *Params) error { + u := pulumi.Sprintf("%s://%s:%d", scheme, hostname, port) + p.intakeURL = &u + extraConfig := pulumi.Sprintf(`dd_url: %[3]s://%[1]s:%[2]d logs_config.logs_dd_url: %[1]s:%[2]d logs_config.logs_no_ssl: true @@ -378,3 +387,34 @@ func WithHostname(hostname string) func(*Params) error { return nil } } + +// WithV3MetricsEnabled opts the agent into the V3 series intake API for its primary fakeintake +// endpoint. It adds serializer_experimental_use_v3_api.series.endpoints pointing at the same URL +// used for dd_url, so the serializer sends to /api/intake/metrics/v3/series instead of +// /api/v2/series. +// +// Only series are redirected; sketches V3 support is not yet implemented in fakeintake. +// +// Must be called after WithFakeintake (or WithIntakeHostname) so the intake URL is known. +func WithV3MetricsEnabled() func(*Params) error { + return func(p *Params) error { + if p.intakeURL == nil { + return fmt.Errorf("WithV3MetricsEnabled must be called after WithFakeintake or WithIntakeHostname") + } + v3Config := (*p.intakeURL).ApplyT(func(url string) (string, error) { + var cfg struct { + V3API struct { + Series struct { + Endpoints []string `yaml:"endpoints"` + } `yaml:"series"` + } `yaml:"serializer_experimental_use_v3_api"` + } + cfg.V3API.Series.Endpoints = []string{url} + out, err := yaml.Marshal(cfg) + return string(out), err + }).(pulumi.StringOutput) + p.ExtraAgentConfig = append(p.ExtraAgentConfig, v3Config) + return nil + } +} + diff --git a/test/e2e-framework/components/datadog/dockeragentparams/params.go b/test/e2e-framework/components/datadog/dockeragentparams/params.go index b5755c9186de..d1d450c81146 100644 --- a/test/e2e-framework/components/datadog/dockeragentparams/params.go +++ b/test/e2e-framework/components/datadog/dockeragentparams/params.go @@ -34,6 +34,7 @@ import ( // - [WithFakeintake] // - [WithLogs] // - [WithExtraComposeManifest] +// - [WithV3MetricsEnabled] // // [Functional options pattern]: https://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis @@ -59,6 +60,10 @@ type Params struct { PulumiDependsOn []pulumi.ResourceOption // FIPS is true if FIPS image is needed. FIPS bool + + // intakeURL is stored by withIntakeHostname so that WithV3MetricsEnabled + // can inject V3 endpoint config after fakeintake wiring. + intakeURL pulumi.StringInput } type Option = func(*Params) error @@ -171,6 +176,7 @@ func WithFakeintake(fakeintake *fakeintake.Fakeintake) func(*Params) error { func withIntakeHostname(url pulumi.StringInput, shouldSkipSSLValidation pulumi.BoolInput) func(*Params) error { return func(p *Params) error { + p.intakeURL = url envVars := pulumi.Map{ "DD_DD_URL": pulumi.Sprintf("%s", url), "DD_PROCESS_CONFIG_PROCESS_DD_URL": pulumi.Sprintf("%s", url), @@ -191,6 +197,26 @@ func withIntakeHostname(url pulumi.StringInput, shouldSkipSSLValidation pulumi.B } } +// WithV3MetricsEnabled opts the Agent into the V3 metrics intake API for its primary +// fakeintake endpoint. It adds serializer_experimental_use_v3_api series endpoints pointing +// at the same URL used for DD_DD_URL, so the serializer sends to /api/intake/metrics/v3/series +// instead of /api/v2/series. +// +// Only series are redirected; sketches V3 support is not yet implemented in fakeintake. +// +// Must be called after WithFakeintake or WithIntake so the intake URL is known. +func WithV3MetricsEnabled() func(*Params) error { + return func(p *Params) error { + if p.intakeURL == nil { + return fmt.Errorf("WithV3MetricsEnabled must be called after WithFakeintake or WithIntake") + } + return WithAgentServiceEnvVariable( + "DD_SERIALIZER_EXPERIMENTAL_USE_V3_API_SERIES_ENDPOINTS", + pulumi.Sprintf("%s", p.intakeURL), + )(p) + } +} + type additionalLogEndpointInput struct { Hostname string `json:"host"` APIKey string `json:"api_key,omitempty"` diff --git a/test/e2e-framework/go.mod b/test/e2e-framework/go.mod index 072916824665..bd02e5232e80 100644 --- a/test/e2e-framework/go.mod +++ b/test/e2e-framework/go.mod @@ -74,7 +74,7 @@ require ( github.com/DataDog/datadog-agent/pkg/tagger/types v0.76.0-rc.4 // indirect github.com/DataDog/datadog-agent/pkg/version v0.76.0-rc.4 // indirect github.com/DataDog/mmh3 v0.0.0-20210722141835-012dc69a9e49 // indirect - github.com/DataDog/zstd v1.5.7 // indirect + github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 // indirect github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect diff --git a/test/e2e-framework/go.sum b/test/e2e-framework/go.sum index ce2cbe84bf19..02282e4d7358 100644 --- a/test/e2e-framework/go.sum +++ b/test/e2e-framework/go.sum @@ -20,8 +20,8 @@ github.com/DataDog/datadog-api-client-go/v2 v2.60.0 h1:YzEB2H42symyDlHzNo0wcjW1m github.com/DataDog/datadog-api-client-go/v2 v2.60.0/go.mod h1:d3tOEgUd2kfsr9uuHQdY+nXrWp4uikgTgVCPdKNK30U= github.com/DataDog/mmh3 v0.0.0-20210722141835-012dc69a9e49 h1:EbzDX8HPk5uE2FsJYxD74QmMw0/3CqSKhEr6teh0ncQ= github.com/DataDog/mmh3 v0.0.0-20210722141835-012dc69a9e49/go.mod h1:SvsjzyJlSg0rKsqYgdcFxeEVflx3ZNAyFfkUHP0TxXg= -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f h1:5Vuo4niPKFkfwW55jV4vY0ih3VQ9RaQqeqY67fvRn8A= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f/go.mod h1:oXfOhM/Kr8OvqS6tVqJwxPBornV0yrx3bc+l0BDr7PQ= github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= diff --git a/test/fakeintake/aggregator/BUILD.bazel b/test/fakeintake/aggregator/BUILD.bazel index 3781c27f569e..84d5a2b175b0 100644 --- a/test/fakeintake/aggregator/BUILD.bazel +++ b/test/fakeintake/aggregator/BUILD.bazel @@ -17,6 +17,7 @@ go_library( "metadataAggregator.go", "metricAggregator.go", "metricAggregatorV1.go", + "metricAggregatorV3.go", "ncmAggregator.go", "ndmAggregator.go", "ndmflowAggregator.go", @@ -36,6 +37,7 @@ go_library( "//pkg/metrics/event", "//pkg/networkpath/payload", "//pkg/proto/pbgo/trace", + "//test/fakeintake/aggregator/internal/apiv3", "//test/fakeintake/api", "@com_github_datadog_agent_payload_v5//contimage", "@com_github_datadog_agent_payload_v5//contlcycle", @@ -65,6 +67,7 @@ go_test( "logAggregator_test.go", "metadataAggregator_test.go", "metricAggregatorV1_test.go", + "metricAggregatorV3_test.go", "metricAggregator_test.go", "ndmAggregator_test.go", "ndmflowAggregator_test.go", @@ -105,13 +108,17 @@ go_test( deps = [ "//pkg/metrics/event", "//pkg/networkpath/payload", + "//test/fakeintake/aggregator/internal/apiv3", "//test/fakeintake/api", "//test/fakeintake/fixtures", "@com_github_datadog_agent_payload_v5//gogen", "@com_github_datadog_agent_payload_v5//healthplatform", "@com_github_datadog_agent_payload_v5//process", + "@com_github_datadog_zstd//:zstd", "@com_github_kr_pretty//:pretty", "@com_github_stretchr_testify//assert", "@com_github_stretchr_testify//require", + "@org_golang_google_protobuf//encoding/protowire", + "@org_golang_google_protobuf//proto", ], ) diff --git a/test/fakeintake/aggregator/internal/apiv3/BUILD.bazel b/test/fakeintake/aggregator/internal/apiv3/BUILD.bazel new file mode 100644 index 000000000000..6dc2d4d8ffe5 --- /dev/null +++ b/test/fakeintake/aggregator/internal/apiv3/BUILD.bazel @@ -0,0 +1,34 @@ +load("@protobuf//bazel:proto_library.bzl", "proto_library") +load("@rules_go//go:def.bzl", "go_library") +load("@rules_go//proto:def.bzl", "go_proto_library") +load("//bazel/rules/write_pb_go:defs.bzl", "write_pb_go") + +go_library( + name = "apiv3", + srcs = ["reader.go"], + embed = [":apiv3_go_proto"], + importpath = "github.com/DataDog/datadog-agent/test/fakeintake/aggregator/internal/apiv3", + visibility = ["//visibility:public"], +) + +proto_library( + name = "apiv3_proto", + srcs = ["payload.proto"], + visibility = ["//test/fakeintake/aggregator:__subpackages__"], +) + +go_proto_library( + name = "apiv3_go_proto", + importpath = "github.com/DataDog/datadog-agent/test/fakeintake/aggregator/internal/apiv3", + proto = ":apiv3_proto", + visibility = ["//test/fakeintake/aggregator:__subpackages__"], +) + +write_pb_go( + name = "write_pb_go", + srcs = { + ":apiv3_go_proto": [ + "payload.pb.go", + ], + }, +) diff --git a/test/fakeintake/aggregator/internal/apiv3/payload.pb.go b/test/fakeintake/aggregator/internal/apiv3/payload.pb.go new file mode 100644 index 000000000000..87420810e121 --- /dev/null +++ b/test/fakeintake/aggregator/internal/apiv3/payload.pb.go @@ -0,0 +1,712 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. +// +// Source: https://github.com/DataDog/agent-payload/blob/master/proto/metrics/intake_v3.proto +// Copied for local Go code generation. Update when agent-payload updates intake_v3.proto. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11-devel +// protoc v7.35.0 +// source: test/fakeintake/aggregator/internal/apiv3/payload.proto + +package apiv3 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type MetricType int32 + +const ( + MetricType_UNUSED MetricType = 0 + MetricType_Count MetricType = 1 + MetricType_Rate MetricType = 2 + MetricType_Gauge MetricType = 3 + MetricType_Sketch MetricType = 4 +) + +// Enum value maps for MetricType. +var ( + MetricType_name = map[int32]string{ + 0: "UNUSED", + 1: "Count", + 2: "Rate", + 3: "Gauge", + 4: "Sketch", + } + MetricType_value = map[string]int32{ + "UNUSED": 0, + "Count": 1, + "Rate": 2, + "Gauge": 3, + "Sketch": 4, + } +) + +func (x MetricType) Enum() *MetricType { + p := new(MetricType) + *p = x + return p +} + +func (x MetricType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (MetricType) Descriptor() protoreflect.EnumDescriptor { + return file_test_fakeintake_aggregator_internal_apiv3_payload_proto_enumTypes[0].Descriptor() +} + +func (MetricType) Type() protoreflect.EnumType { + return &file_test_fakeintake_aggregator_internal_apiv3_payload_proto_enumTypes[0] +} + +func (x MetricType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use MetricType.Descriptor instead. +func (MetricType) EnumDescriptor() ([]byte, []int) { + return file_test_fakeintake_aggregator_internal_apiv3_payload_proto_rawDescGZIP(), []int{0} +} + +type ValueType int32 + +const ( + ValueType_Zero ValueType = 0 // value is zero, not stored explicitly + ValueType_Sint64 ValueType = 16 // value is stored in valsSint64 + ValueType_Float32 ValueType = 32 // value is stored in valsFloat32 + ValueType_Float64 ValueType = 48 // value is stored in valsFloat64 +) + +// Enum value maps for ValueType. +var ( + ValueType_name = map[int32]string{ + 0: "Zero", + 16: "Sint64", + 32: "Float32", + 48: "Float64", + } + ValueType_value = map[string]int32{ + "Zero": 0, + "Sint64": 16, + "Float32": 32, + "Float64": 48, + } +) + +func (x ValueType) Enum() *ValueType { + p := new(ValueType) + *p = x + return p +} + +func (x ValueType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ValueType) Descriptor() protoreflect.EnumDescriptor { + return file_test_fakeintake_aggregator_internal_apiv3_payload_proto_enumTypes[1].Descriptor() +} + +func (ValueType) Type() protoreflect.EnumType { + return &file_test_fakeintake_aggregator_internal_apiv3_payload_proto_enumTypes[1] +} + +func (x ValueType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ValueType.Descriptor instead. +func (ValueType) EnumDescriptor() ([]byte, []int) { + return file_test_fakeintake_aggregator_internal_apiv3_payload_proto_rawDescGZIP(), []int{1} +} + +type MetricFlags int32 + +const ( + MetricFlags_flagNone MetricFlags = 0 + MetricFlags_flagNoIndex MetricFlags = 256 // metric should not be indexed (equivalent to origin metric type == agent_hidden in v2) + MetricFlags_flagHasUnit MetricFlags = 512 // timeseries has a unit in the unitRefs column +) + +// Enum value maps for MetricFlags. +var ( + MetricFlags_name = map[int32]string{ + 0: "flagNone", + 256: "flagNoIndex", + 512: "flagHasUnit", + } + MetricFlags_value = map[string]int32{ + "flagNone": 0, + "flagNoIndex": 256, + "flagHasUnit": 512, + } +) + +func (x MetricFlags) Enum() *MetricFlags { + p := new(MetricFlags) + *p = x + return p +} + +func (x MetricFlags) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (MetricFlags) Descriptor() protoreflect.EnumDescriptor { + return file_test_fakeintake_aggregator_internal_apiv3_payload_proto_enumTypes[2].Descriptor() +} + +func (MetricFlags) Type() protoreflect.EnumType { + return &file_test_fakeintake_aggregator_internal_apiv3_payload_proto_enumTypes[2] +} + +func (x MetricFlags) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use MetricFlags.Descriptor instead. +func (MetricFlags) EnumDescriptor() ([]byte, []int) { + return file_test_fakeintake_aggregator_internal_apiv3_payload_proto_rawDescGZIP(), []int{2} +} + +type Payload struct { + state protoimpl.MessageState `protogen:"open.v1"` + Metadata *Metadata `protobuf:"bytes,2,opt,name=metadata,proto3" json:"metadata,omitempty"` + MetricData *MetricData `protobuf:"bytes,3,opt,name=metricData,proto3" json:"metricData,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Payload) Reset() { + *x = Payload{} + mi := &file_test_fakeintake_aggregator_internal_apiv3_payload_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Payload) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Payload) ProtoMessage() {} + +func (x *Payload) ProtoReflect() protoreflect.Message { + mi := &file_test_fakeintake_aggregator_internal_apiv3_payload_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Payload.ProtoReflect.Descriptor instead. +func (*Payload) Descriptor() ([]byte, []int) { + return file_test_fakeintake_aggregator_internal_apiv3_payload_proto_rawDescGZIP(), []int{0} +} + +func (x *Payload) GetMetadata() *Metadata { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *Payload) GetMetricData() *MetricData { + if x != nil { + return x.MetricData + } + return nil +} + +type Metadata struct { + state protoimpl.MessageState `protogen:"open.v1"` + Tags []string `protobuf:"bytes,1,rep,name=tags,proto3" json:"tags,omitempty"` + Resources []string `protobuf:"bytes,2,rep,name=resources,proto3" json:"resources,omitempty"` // even number of elements, [Type, Name] pairs + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Metadata) Reset() { + *x = Metadata{} + mi := &file_test_fakeintake_aggregator_internal_apiv3_payload_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Metadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Metadata) ProtoMessage() {} + +func (x *Metadata) ProtoReflect() protoreflect.Message { + mi := &file_test_fakeintake_aggregator_internal_apiv3_payload_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Metadata.ProtoReflect.Descriptor instead. +func (*Metadata) Descriptor() ([]byte, []int) { + return file_test_fakeintake_aggregator_internal_apiv3_payload_proto_rawDescGZIP(), []int{1} +} + +func (x *Metadata) GetTags() []string { + if x != nil { + return x.Tags + } + return nil +} + +func (x *Metadata) GetResources() []string { + if x != nil { + return x.Resources + } + return nil +} + +type MetricData struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Dictionaries + // All dictionary indexes are base-1, zero implicitly represents an empty value. + DictNameStr []byte `protobuf:"bytes,1,opt,name=dictNameStr,proto3" json:"dictNameStr,omitempty"` // varint length + value + DictTagStr []byte `protobuf:"bytes,2,opt,name=dictTagStr,proto3" json:"dictTagStr,omitempty"` // varint length + value + DictTagsets []int64 `protobuf:"zigzag64,3,rep,packed,name=dictTagsets,proto3" json:"dictTagsets,omitempty"` // length, delta encoded set of indexes into dictTagsStr + DictResourceStr []byte `protobuf:"bytes,4,opt,name=dictResourceStr,proto3" json:"dictResourceStr,omitempty"` // varint length + value + DictResourceLen []int64 `protobuf:"varint,5,rep,packed,name=dictResourceLen,proto3" json:"dictResourceLen,omitempty"` // number of elements in Type and Name arrays + DictResourceType []int64 `protobuf:"zigzag64,6,rep,packed,name=dictResourceType,proto3" json:"dictResourceType,omitempty"` // delta encoded set of indexes into dictResourceStr + DictResourceName []int64 `protobuf:"zigzag64,7,rep,packed,name=dictResourceName,proto3" json:"dictResourceName,omitempty"` // delta encoded set of indexes into dictResourceStr + DictSourceTypeName []byte `protobuf:"bytes,8,opt,name=dictSourceTypeName,proto3" json:"dictSourceTypeName,omitempty"` // varint length + value + DictOriginInfo []int32 `protobuf:"varint,9,rep,packed,name=dictOriginInfo,proto3" json:"dictOriginInfo,omitempty"` // (product, category, service) tuples + DictUnitStr []byte `protobuf:"bytes,25,opt,name=dictUnitStr,proto3" json:"dictUnitStr,omitempty"` // varint length + value + // One entry per time series + Types []uint64 `protobuf:"varint,10,rep,packed,name=types,proto3" json:"types,omitempty"` // type = metricType | valueType | metricFlags + NameRefs []int64 `protobuf:"zigzag64,11,rep,packed,name=nameRefs,proto3" json:"nameRefs,omitempty"` // index into dictNameStr, entire array is delta encoded + TagsetRefs []int64 `protobuf:"zigzag64,12,rep,packed,name=tagsetRefs,proto3" json:"tagsetRefs,omitempty"` // index into dictTagsets, entire array is delta encoded + ResourcesRefs []int64 `protobuf:"zigzag64,13,rep,packed,name=resourcesRefs,proto3" json:"resourcesRefs,omitempty"` // index into dictResourceLen, entire array is delta encoded + Intervals []uint64 `protobuf:"varint,14,rep,packed,name=intervals,proto3" json:"intervals,omitempty"` + NumPoints []uint64 `protobuf:"varint,15,rep,packed,name=numPoints,proto3" json:"numPoints,omitempty"` + SourceTypeNameRefs []int64 `protobuf:"zigzag64,23,rep,packed,name=sourceTypeNameRefs,proto3" json:"sourceTypeNameRefs,omitempty"` // index into dictSourceTypeName, entire array is delta encoded + OriginInfoRefs []int64 `protobuf:"zigzag64,24,rep,packed,name=originInfoRefs,proto3" json:"originInfoRefs,omitempty"` // index into dictOriginInfo, entire array is delta encoded + UnitRefs []int64 `protobuf:"zigzag64,26,rep,packed,name=unitRefs,proto3" json:"unitRefs,omitempty"` // index into dictUnitStr, value present if flagHasUnit is set, entire array is delta encoded + // each metric has numPoints values in this section + Timestamps []int64 `protobuf:"zigzag64,16,rep,packed,name=timestamps,proto3" json:"timestamps,omitempty"` // entire array delta encoded + ValsSint64 []int64 `protobuf:"zigzag64,17,rep,packed,name=valsSint64,proto3" json:"valsSint64,omitempty"` // or + ValsFloat32 []float32 `protobuf:"fixed32,18,rep,packed,name=valsFloat32,proto3" json:"valsFloat32,omitempty"` // or + ValsFloat64 []float64 `protobuf:"fixed64,19,rep,packed,name=valsFloat64,proto3" json:"valsFloat64,omitempty"` // based on valueType + SketchNumBins []uint64 `protobuf:"varint,20,rep,packed,name=sketchNumBins,proto3" json:"sketchNumBins,omitempty"` + SketchBinKeys []int32 `protobuf:"zigzag32,21,rep,packed,name=sketchBinKeys,proto3" json:"sketchBinKeys,omitempty"` // per-metric sequence is delta encoded + SketchBinCnts []uint32 `protobuf:"varint,22,rep,packed,name=sketchBinCnts,proto3" json:"sketchBinCnts,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MetricData) Reset() { + *x = MetricData{} + mi := &file_test_fakeintake_aggregator_internal_apiv3_payload_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MetricData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MetricData) ProtoMessage() {} + +func (x *MetricData) ProtoReflect() protoreflect.Message { + mi := &file_test_fakeintake_aggregator_internal_apiv3_payload_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MetricData.ProtoReflect.Descriptor instead. +func (*MetricData) Descriptor() ([]byte, []int) { + return file_test_fakeintake_aggregator_internal_apiv3_payload_proto_rawDescGZIP(), []int{2} +} + +func (x *MetricData) GetDictNameStr() []byte { + if x != nil { + return x.DictNameStr + } + return nil +} + +func (x *MetricData) GetDictTagStr() []byte { + if x != nil { + return x.DictTagStr + } + return nil +} + +func (x *MetricData) GetDictTagsets() []int64 { + if x != nil { + return x.DictTagsets + } + return nil +} + +func (x *MetricData) GetDictResourceStr() []byte { + if x != nil { + return x.DictResourceStr + } + return nil +} + +func (x *MetricData) GetDictResourceLen() []int64 { + if x != nil { + return x.DictResourceLen + } + return nil +} + +func (x *MetricData) GetDictResourceType() []int64 { + if x != nil { + return x.DictResourceType + } + return nil +} + +func (x *MetricData) GetDictResourceName() []int64 { + if x != nil { + return x.DictResourceName + } + return nil +} + +func (x *MetricData) GetDictSourceTypeName() []byte { + if x != nil { + return x.DictSourceTypeName + } + return nil +} + +func (x *MetricData) GetDictOriginInfo() []int32 { + if x != nil { + return x.DictOriginInfo + } + return nil +} + +func (x *MetricData) GetDictUnitStr() []byte { + if x != nil { + return x.DictUnitStr + } + return nil +} + +func (x *MetricData) GetTypes() []uint64 { + if x != nil { + return x.Types + } + return nil +} + +func (x *MetricData) GetNameRefs() []int64 { + if x != nil { + return x.NameRefs + } + return nil +} + +func (x *MetricData) GetTagsetRefs() []int64 { + if x != nil { + return x.TagsetRefs + } + return nil +} + +func (x *MetricData) GetResourcesRefs() []int64 { + if x != nil { + return x.ResourcesRefs + } + return nil +} + +func (x *MetricData) GetIntervals() []uint64 { + if x != nil { + return x.Intervals + } + return nil +} + +func (x *MetricData) GetNumPoints() []uint64 { + if x != nil { + return x.NumPoints + } + return nil +} + +func (x *MetricData) GetSourceTypeNameRefs() []int64 { + if x != nil { + return x.SourceTypeNameRefs + } + return nil +} + +func (x *MetricData) GetOriginInfoRefs() []int64 { + if x != nil { + return x.OriginInfoRefs + } + return nil +} + +func (x *MetricData) GetUnitRefs() []int64 { + if x != nil { + return x.UnitRefs + } + return nil +} + +func (x *MetricData) GetTimestamps() []int64 { + if x != nil { + return x.Timestamps + } + return nil +} + +func (x *MetricData) GetValsSint64() []int64 { + if x != nil { + return x.ValsSint64 + } + return nil +} + +func (x *MetricData) GetValsFloat32() []float32 { + if x != nil { + return x.ValsFloat32 + } + return nil +} + +func (x *MetricData) GetValsFloat64() []float64 { + if x != nil { + return x.ValsFloat64 + } + return nil +} + +func (x *MetricData) GetSketchNumBins() []uint64 { + if x != nil { + return x.SketchNumBins + } + return nil +} + +func (x *MetricData) GetSketchBinKeys() []int32 { + if x != nil { + return x.SketchBinKeys + } + return nil +} + +func (x *MetricData) GetSketchBinCnts() []uint32 { + if x != nil { + return x.SketchBinCnts + } + return nil +} + +type Response struct { + state protoimpl.MessageState `protogen:"open.v1"` + Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Response) Reset() { + *x = Response{} + mi := &file_test_fakeintake_aggregator_internal_apiv3_payload_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Response) ProtoMessage() {} + +func (x *Response) ProtoReflect() protoreflect.Message { + mi := &file_test_fakeintake_aggregator_internal_apiv3_payload_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Response.ProtoReflect.Descriptor instead. +func (*Response) Descriptor() ([]byte, []int) { + return file_test_fakeintake_aggregator_internal_apiv3_payload_proto_rawDescGZIP(), []int{3} +} + +func (x *Response) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +var File_test_fakeintake_aggregator_internal_apiv3_payload_proto protoreflect.FileDescriptor + +const file_test_fakeintake_aggregator_internal_apiv3_payload_proto_rawDesc = "" + + "\n" + + "7test/fakeintake/aggregator/internal/apiv3/payload.proto\x12\x18datadoghq.api.metrics.v3\"\x95\x01\n" + + "\aPayload\x12>\n" + + "\bmetadata\x18\x02 \x01(\v2\".datadoghq.api.metrics.v3.MetadataR\bmetadata\x12D\n" + + "\n" + + "metricData\x18\x03 \x01(\v2$.datadoghq.api.metrics.v3.MetricDataR\n" + + "metricDataJ\x04\b\x01\x10\x02\"<\n" + + "\bMetadata\x12\x12\n" + + "\x04tags\x18\x01 \x03(\tR\x04tags\x12\x1c\n" + + "\tresources\x18\x02 \x03(\tR\tresources\"\xb4\a\n" + + "\n" + + "MetricData\x12 \n" + + "\vdictNameStr\x18\x01 \x01(\fR\vdictNameStr\x12\x1e\n" + + "\n" + + "dictTagStr\x18\x02 \x01(\fR\n" + + "dictTagStr\x12 \n" + + "\vdictTagsets\x18\x03 \x03(\x12R\vdictTagsets\x12(\n" + + "\x0fdictResourceStr\x18\x04 \x01(\fR\x0fdictResourceStr\x12(\n" + + "\x0fdictResourceLen\x18\x05 \x03(\x03R\x0fdictResourceLen\x12*\n" + + "\x10dictResourceType\x18\x06 \x03(\x12R\x10dictResourceType\x12*\n" + + "\x10dictResourceName\x18\a \x03(\x12R\x10dictResourceName\x12.\n" + + "\x12dictSourceTypeName\x18\b \x01(\fR\x12dictSourceTypeName\x12&\n" + + "\x0edictOriginInfo\x18\t \x03(\x05R\x0edictOriginInfo\x12 \n" + + "\vdictUnitStr\x18\x19 \x01(\fR\vdictUnitStr\x12\x14\n" + + "\x05types\x18\n" + + " \x03(\x04R\x05types\x12\x1a\n" + + "\bnameRefs\x18\v \x03(\x12R\bnameRefs\x12\x1e\n" + + "\n" + + "tagsetRefs\x18\f \x03(\x12R\n" + + "tagsetRefs\x12$\n" + + "\rresourcesRefs\x18\r \x03(\x12R\rresourcesRefs\x12\x1c\n" + + "\tintervals\x18\x0e \x03(\x04R\tintervals\x12\x1c\n" + + "\tnumPoints\x18\x0f \x03(\x04R\tnumPoints\x12.\n" + + "\x12sourceTypeNameRefs\x18\x17 \x03(\x12R\x12sourceTypeNameRefs\x12&\n" + + "\x0eoriginInfoRefs\x18\x18 \x03(\x12R\x0eoriginInfoRefs\x12\x1a\n" + + "\bunitRefs\x18\x1a \x03(\x12R\bunitRefs\x12\x1e\n" + + "\n" + + "timestamps\x18\x10 \x03(\x12R\n" + + "timestamps\x12\x1e\n" + + "\n" + + "valsSint64\x18\x11 \x03(\x12R\n" + + "valsSint64\x12 \n" + + "\vvalsFloat32\x18\x12 \x03(\x02R\vvalsFloat32\x12 \n" + + "\vvalsFloat64\x18\x13 \x03(\x01R\vvalsFloat64\x12$\n" + + "\rsketchNumBins\x18\x14 \x03(\x04R\rsketchNumBins\x12$\n" + + "\rsketchBinKeys\x18\x15 \x03(\x11R\rsketchBinKeys\x12$\n" + + "\rsketchBinCnts\x18\x16 \x03(\rR\rsketchBinCnts\" \n" + + "\bResponse\x12\x14\n" + + "\x05error\x18\x01 \x01(\tR\x05error*D\n" + + "\n" + + "metricType\x12\n" + + "\n" + + "\x06UNUSED\x10\x00\x12\t\n" + + "\x05Count\x10\x01\x12\b\n" + + "\x04Rate\x10\x02\x12\t\n" + + "\x05Gauge\x10\x03\x12\n" + + "\n" + + "\x06Sketch\x10\x04*;\n" + + "\tvalueType\x12\b\n" + + "\x04Zero\x10\x00\x12\n" + + "\n" + + "\x06Sint64\x10\x10\x12\v\n" + + "\aFloat32\x10 \x12\v\n" + + "\aFloat64\x100*?\n" + + "\vmetricFlags\x12\f\n" + + "\bflagNone\x10\x00\x12\x10\n" + + "\vflagNoIndex\x10\x80\x02\x12\x10\n" + + "\vflagHasUnit\x10\x80\x04BLZJgithub.com/DataDog/datadog-agent/test/fakeintake/aggregator/internal/apiv3b\x06proto3" + +var ( + file_test_fakeintake_aggregator_internal_apiv3_payload_proto_rawDescOnce sync.Once + file_test_fakeintake_aggregator_internal_apiv3_payload_proto_rawDescData []byte +) + +func file_test_fakeintake_aggregator_internal_apiv3_payload_proto_rawDescGZIP() []byte { + file_test_fakeintake_aggregator_internal_apiv3_payload_proto_rawDescOnce.Do(func() { + file_test_fakeintake_aggregator_internal_apiv3_payload_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_test_fakeintake_aggregator_internal_apiv3_payload_proto_rawDesc), len(file_test_fakeintake_aggregator_internal_apiv3_payload_proto_rawDesc))) + }) + return file_test_fakeintake_aggregator_internal_apiv3_payload_proto_rawDescData +} + +var file_test_fakeintake_aggregator_internal_apiv3_payload_proto_enumTypes = make([]protoimpl.EnumInfo, 3) +var file_test_fakeintake_aggregator_internal_apiv3_payload_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_test_fakeintake_aggregator_internal_apiv3_payload_proto_goTypes = []any{ + (MetricType)(0), // 0: datadoghq.api.metrics.v3.metricType + (ValueType)(0), // 1: datadoghq.api.metrics.v3.valueType + (MetricFlags)(0), // 2: datadoghq.api.metrics.v3.metricFlags + (*Payload)(nil), // 3: datadoghq.api.metrics.v3.Payload + (*Metadata)(nil), // 4: datadoghq.api.metrics.v3.Metadata + (*MetricData)(nil), // 5: datadoghq.api.metrics.v3.MetricData + (*Response)(nil), // 6: datadoghq.api.metrics.v3.Response +} +var file_test_fakeintake_aggregator_internal_apiv3_payload_proto_depIdxs = []int32{ + 4, // 0: datadoghq.api.metrics.v3.Payload.metadata:type_name -> datadoghq.api.metrics.v3.Metadata + 5, // 1: datadoghq.api.metrics.v3.Payload.metricData:type_name -> datadoghq.api.metrics.v3.MetricData + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_test_fakeintake_aggregator_internal_apiv3_payload_proto_init() } +func file_test_fakeintake_aggregator_internal_apiv3_payload_proto_init() { + if File_test_fakeintake_aggregator_internal_apiv3_payload_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_test_fakeintake_aggregator_internal_apiv3_payload_proto_rawDesc), len(file_test_fakeintake_aggregator_internal_apiv3_payload_proto_rawDesc)), + NumEnums: 3, + NumMessages: 4, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_test_fakeintake_aggregator_internal_apiv3_payload_proto_goTypes, + DependencyIndexes: file_test_fakeintake_aggregator_internal_apiv3_payload_proto_depIdxs, + EnumInfos: file_test_fakeintake_aggregator_internal_apiv3_payload_proto_enumTypes, + MessageInfos: file_test_fakeintake_aggregator_internal_apiv3_payload_proto_msgTypes, + }.Build() + File_test_fakeintake_aggregator_internal_apiv3_payload_proto = out.File + file_test_fakeintake_aggregator_internal_apiv3_payload_proto_goTypes = nil + file_test_fakeintake_aggregator_internal_apiv3_payload_proto_depIdxs = nil +} diff --git a/test/fakeintake/aggregator/internal/apiv3/payload.proto b/test/fakeintake/aggregator/internal/apiv3/payload.proto new file mode 100644 index 000000000000..d96cb9880a8c --- /dev/null +++ b/test/fakeintake/aggregator/internal/apiv3/payload.proto @@ -0,0 +1,88 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. +// +// Source: https://github.com/DataDog/agent-payload/blob/master/proto/metrics/intake_v3.proto +// Copied for local Go code generation. Update when agent-payload updates intake_v3.proto. +syntax = "proto3"; + +package datadoghq.api.metrics.v3; + +option go_package = "github.com/DataDog/datadog-agent/test/fakeintake/aggregator/internal/apiv3"; + +message Payload { + reserved 1; // for compatibility with agentpayload.MetricPayload.series + Metadata metadata = 2; + MetricData metricData = 3; +} + +message Metadata { + repeated string tags = 1; + repeated string resources = 2; // even number of elements, [Type, Name] pairs +} + +message MetricData { + // Dictionaries + // All dictionary indexes are base-1, zero implicitly represents an empty value. + bytes dictNameStr = 1; // varint length + value + bytes dictTagStr = 2; // varint length + value + repeated sint64 dictTagsets = 3; // length, delta encoded set of indexes into dictTagsStr + + bytes dictResourceStr = 4; // varint length + value + repeated int64 dictResourceLen = 5; // number of elements in Type and Name arrays + repeated sint64 dictResourceType = 6; // delta encoded set of indexes into dictResourceStr + repeated sint64 dictResourceName = 7; // delta encoded set of indexes into dictResourceStr + + bytes dictSourceTypeName = 8; // varint length + value + repeated int32 dictOriginInfo = 9; // (product, category, service) tuples + bytes dictUnitStr = 25; // varint length + value + + // One entry per time series + repeated uint64 types = 10; // type = metricType | valueType | metricFlags + repeated sint64 nameRefs = 11; // index into dictNameStr, entire array is delta encoded + repeated sint64 tagsetRefs = 12; // index into dictTagsets, entire array is delta encoded + repeated sint64 resourcesRefs = 13; // index into dictResourceLen, entire array is delta encoded + repeated uint64 intervals = 14; + repeated uint64 numPoints = 15; + repeated sint64 sourceTypeNameRefs = 23; // index into dictSourceTypeName, entire array is delta encoded + repeated sint64 originInfoRefs = 24; // index into dictOriginInfo, entire array is delta encoded + repeated sint64 unitRefs = 26; // index into dictUnitStr, value present if flagHasUnit is set, entire array is delta encoded + + // each metric has numPoints values in this section + repeated sint64 timestamps = 16; // entire array delta encoded + repeated sint64 valsSint64 = 17; // or + repeated float valsFloat32 = 18; // or + repeated double valsFloat64 = 19; // based on valueType + repeated uint64 sketchNumBins = 20; + repeated sint32 sketchBinKeys = 21; // per-metric sequence is delta encoded + repeated uint32 sketchBinCnts = 22; + // sketch summary Sum, Min, Max are encoded as three consecutive elements in one of vals using valueType + // sketch summary Cnt is always encoded in valInt64 + // sketch summary Avg is reconstructed as Sum/Cnt in the intake +} + +enum metricType { + UNUSED = 0; + Count = 1; + Rate = 2; + Gauge = 3; + Sketch = 4; +} + +enum valueType { + Zero = 0x00; // value is zero, not stored explicitly + Sint64 = 0x10; // value is stored in valsSint64 + Float32 = 0x20; // value is stored in valsFloat32 + Float64 = 0x30; // value is stored in valsFloat64 +} + +enum metricFlags { + flagNone = 0; + flagNoIndex = 0x100; // metric should not be indexed (equivalent to origin metric type == agent_hidden in v2) + flagHasUnit = 0x200; // timeseries has a unit in the unitRefs column +} + +message Response { + string error = 1; +} diff --git a/test/fakeintake/aggregator/internal/apiv3/reader.go b/test/fakeintake/aggregator/internal/apiv3/reader.go new file mode 100644 index 000000000000..170aae3971a0 --- /dev/null +++ b/test/fakeintake/aggregator/internal/apiv3/reader.go @@ -0,0 +1,671 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +// Package apiv3 provides a reader for the V3 metrics intake wire format. +// +// Copied for use in fakeintake. Update when reader.go changes. +package apiv3 + +import ( + "encoding/binary" + "errors" + "fmt" + "math" + "slices" + "strings" + "unicode/utf8" +) + +// Reader is an iterator over data contained in Payload. +// +// Usage: +// +// r := NewReader(payload.Payload) +// if err := r.Initialize(); err != nil { +// return err +// } +// for r.HaveMoreMetrics() { +// if err := r.NextMetric(); err != nil { +// return err +// +// // Accessors for metric entry data can be called. +// for r.HaveMorePoints() { +// if err := r.NextPoint(); err != nil { +// return err +// } +// // Accessors for metric data point can be called. +// } +// } +type Reader struct { + payload *Payload + + // Indexes point the next unconsumed element + metricIdx int + pointIdx int + unitRefIdx int + + valsSint64Idx int + valsFloat32Idx int + valsFloat64Idx int + sketchNumBinsIdx int + sketchBinsIdx int + + pointsRemaining int + + // Accumulators for delta encoded columns + nameRef int64 + tagsRef int64 + resourcesRef int64 + sourceTypeNameRef int64 + originInfoRef int64 + timestamp int64 + unitRef int64 + + // Dicts are pre-loaded with empty element at index zero + dictNameStr []string + dictTagsStr []string + dictUnitStr []string + dictTagsets [][]string + dictResourceStr []string + dictResources [][]*resource + dictSourceTypeName []string + dictOriginInfo []*originInfo +} + +type resource = [2]string +type originInfo = [3]int32 + +// NewReader creates an iterator over the data contained in MetricData +// by wrapping it in a Payload +func NewReader(data *MetricData) *Reader { + return &Reader{ + payload: &Payload{ + MetricData: data, + }, + } +} + +// NewPayloadReader creates an iterator over the data contained in Payload +func NewPayloadReader(payload *Payload) *Reader { + return &Reader{ + payload: payload, + } +} + +// Initialize reads and normalizes payload dictionaries for fast access. +// This method must be called before any other method on the reader. +func (r *Reader) Initialize() error { + if r.payload.MetricData == nil { + return errors.New("metric data must not be nil") + } + + var err error + r.dictNameStr, err = unpackStrDict(r.payload.MetricData.DictNameStr, false) + if err != nil { + return err + } + r.dictTagsStr, err = unpackStrDict(r.payload.MetricData.DictTagStr, true) + if err != nil { + return err + } + r.dictUnitStr, err = unpackStrDict(r.payload.MetricData.DictUnitStr, false) + if err != nil { + return err + } + r.dictTagsets, err = r.unpackTagsetsDict() + if err != nil { + return err + } + r.dictResourceStr, err = unpackStrDict(r.payload.MetricData.DictResourceStr, false) + if err != nil { + return err + } + r.dictResources, err = r.unpackResourcesDict() + if err != nil { + return err + } + r.dictSourceTypeName, err = unpackStrDict(r.payload.MetricData.DictSourceTypeName, false) + if err != nil { + return err + } + r.dictOriginInfo, err = unpackOriginInfoDict(r.payload.MetricData.DictOriginInfo) + if err != nil { + return err + } + return nil +} + +var ( + errUnexpectedEOF = errors.New("unexpected end of column") + errOverflow = errors.New("length field overflow") + errBadReference = errors.New("invalid reference") + errInvalidUTF8 = errors.New("invalid UTF-8 string") +) + +func unpackStrDict(raw []byte, sanitizeInvalidUTF8 bool) ([]string, error) { + dict := []string{""} + + for len(raw) > 0 { + length, n := binary.Uvarint(raw) + if n == 0 { + return nil, errUnexpectedEOF + } + if n < 0 { + return nil, errOverflow + } + if length > uint64(math.MaxInt-n) { + return nil, errOverflow + } + end := n + int(length) + if end > len(raw) { + return nil, errUnexpectedEOF + } + str := string(raw[n:end]) + + if !utf8.ValidString(str) { + if sanitizeInvalidUTF8 { + str = strings.ToValidUTF8(str, string(utf8.RuneError)) + } else { + return nil, errInvalidUTF8 + } + } + + dict = append(dict, str) + raw = raw[end:] + } + return dict, nil +} + +func (r *Reader) unpackTagsetsDict() ([][]string, error) { + packed := r.payload.MetricData.DictTagsets + tagsets := [][]string{nil} + + metadataTags := r.payload.GetMetadata().GetTags() + + for len(packed) > 0 { + size := packed[0] + packed = packed[1:] + if size < 0 || size > int64(len(packed)) { + return nil, errUnexpectedEOF + } + tags := make([]string, 0, int(size)+len(metadataTags)) + + idx := int64(0) + for i := int64(0); i < size; i++ { + idx += packed[i] + + if idx < 0 { + if idx <= -math.MaxInt64 || -idx >= int64(len(tagsets)) { + return nil, errBadReference + } + tags = append(tags, tagsets[-idx]...) + } else { + if idx >= int64(len(r.dictTagsStr)) { + return nil, errBadReference + } + tags = append(tags, r.dictTagsStr[idx]) + } + } + packed = packed[size:] + tagsets = append(tagsets, tags) + } + + // Now do a one-time union of metric tags + metadata tags + if len(metadataTags) == 0 { + return tagsets, nil + } + + metaIndex := make(map[string]int, len(metadataTags)) + for i, mt := range metadataTags { + metaIndex[mt] = i + } + + for i, tags := range tagsets { + if len(tags) == 0 { + // Just append all the metadata tags if the tagset is empty + tagsets[i] = append(tags, metadataTags...) + continue + } + + // Track which metadata tags have already been seen + seen := make([]bool, len(metadataTags)) + + // Mark the metadata tags that have already been seen + for _, t := range tags { + if idx, ok := metaIndex[t]; ok { + seen[idx] = true + } + } + + // Append only the metadata tags that are missing + for idx, mt := range metadataTags { + if !seen[idx] { + tags = append(tags, mt) + } + } + + tagsets[i] = tags + } + + return tagsets, nil +} + +func (r *Reader) unpackResourcesDict() ([][]*resource, error) { + packedLen := r.payload.MetricData.DictResourceLen + packedType := r.payload.MetricData.DictResourceType + packedName := r.payload.MetricData.DictResourceName + resourcesDict := make([][]*resource, 1, len(packedLen)+1) + + metadataResources := r.payload.GetMetadata().GetResources() + + // Decode metadata resources once + var metaResources []*resource + if len(metadataResources) > 0 { + if len(metadataResources)%2 != 0 { + return nil, errors.New("metadata resources must be [Type, Name] pairs") + } + pairs := len(metadataResources) / 2 + metaResources = make([]*resource, pairs) + for i := 0; i < pairs; i++ { + t := metadataResources[2*i] + n := metadataResources[2*i+1] + metaResources[i] = &resource{t, n} + } + } + + start := int64(0) + for _, size := range packedLen { + if size < 0 { + return nil, errUnexpectedEOF + } + if size > math.MaxInt64-start { + return nil, errOverflow + } + end := start + size + if end > int64(len(packedType)) || end > int64(len(packedName)) { + return nil, errBadReference + } + + typeRef := int64(0) + nameRef := int64(0) + resourcesSet := make([]*resource, 0, size+int64(len(metaResources))) + for i := int64(0); i < size; i++ { + typeRef += packedType[start+i] + nameRef += packedName[start+i] + + if typeRef < 0 || typeRef >= int64(len(r.dictResourceStr)) || + nameRef < 0 || nameRef >= int64(len(r.dictResourceStr)) { + return nil, errBadReference + } + + resourcesSet = append(resourcesSet, &resource{r.dictResourceStr[typeRef], r.dictResourceStr[nameRef]}) + } + + if len(metaResources) > 0 { + resourcesSet = append(resourcesSet, metaResources...) + } + + resourcesDict = append(resourcesDict, resourcesSet) + start = end + } + + return resourcesDict, nil +} + +func unpackOriginInfoDict(raw []int32) ([]*originInfo, error) { + nelem := len(raw) / 3 + if len(raw) != nelem*3 { + return nil, errUnexpectedEOF + } + dict := make([]*originInfo, 1, nelem+1) + for i := 0; i < len(raw); i += 3 { + dict = append(dict, &originInfo{int32(raw[i+0]), int32(raw[i+1]), int32(raw[i+2])}) + } + + return dict, nil +} + +// HaveMoreMetrics returns true if there are more metrics to read. +func (r *Reader) HaveMoreMetrics() bool { + return r.metricIdx < len(r.payload.MetricData.Types) +} + +// NextMetric consumes next metric entry and prepares data for access. +// +// If this method returns an error the reader is in an invalid state and calling data access methods may panic. +func (r *Reader) NextMetric() error { + if !r.HaveMoreMetrics() { + return errUnexpectedEOF + } + + if r.metricIdx >= 0 { + for r.HaveMorePoints() { + if err := r.NextPoint(); err != nil { + return err + } + } + } + + r.metricIdx++ + + if r.metricIdx > len(r.payload.MetricData.Types) || + r.metricIdx > len(r.payload.MetricData.NameRefs) || + r.metricIdx > len(r.payload.MetricData.TagsetRefs) || + r.metricIdx > len(r.payload.MetricData.ResourcesRefs) || + r.metricIdx > len(r.payload.MetricData.SourceTypeNameRefs) || + r.metricIdx > len(r.payload.MetricData.OriginInfoRefs) || + r.metricIdx > len(r.payload.MetricData.Intervals) || + r.metricIdx > len(r.payload.MetricData.NumPoints) { + return errUnexpectedEOF + } + + r.pointsRemaining = int(r.NumPoints()) + + r.nameRef += r.payload.MetricData.NameRefs[r.metricIdx-1] + if r.nameRef < 0 || r.nameRef >= int64(len(r.dictNameStr)) { + return errBadReference + } + + r.tagsRef += r.payload.MetricData.TagsetRefs[r.metricIdx-1] + if r.tagsRef < 0 || r.tagsRef >= int64(len(r.dictTagsets)) { + return errBadReference + } + + if r.HasUnit() { + r.unitRefIdx++ + if r.unitRefIdx > len(r.payload.MetricData.UnitRefs) { + return errUnexpectedEOF + } + r.unitRef += r.payload.MetricData.UnitRefs[r.unitRefIdx-1] + if r.unitRef < 0 || r.unitRef >= int64(len(r.dictUnitStr)) { + return errBadReference + } + } + + r.resourcesRef += r.payload.MetricData.ResourcesRefs[r.metricIdx-1] + if r.resourcesRef < 0 || r.resourcesRef >= int64(len(r.dictResources)) { + return errBadReference + } + + r.sourceTypeNameRef += r.payload.MetricData.SourceTypeNameRefs[r.metricIdx-1] + if r.sourceTypeNameRef < 0 || r.sourceTypeNameRef >= int64(len(r.dictSourceTypeName)) { + return errBadReference + } + + r.originInfoRef += r.payload.MetricData.OriginInfoRefs[r.metricIdx-1] + if r.originInfoRef < 0 || r.originInfoRef >= int64(len(r.dictOriginInfo)) { + return errBadReference + } + + return nil +} + +func (r *Reader) packedType() uint64 { + return r.payload.MetricData.Types[r.metricIdx-1] +} + +// Type returns type of current metric entry. +func (r *Reader) Type() MetricType { + return MetricType(r.packedType() & 0xF) +} + +// ValueType returns value type of current metric entry. +func (r *Reader) ValueType() ValueType { + return ValueType(r.packedType() & 0xF0) +} + +// Unit returns unit of current metric entry, or empty string if none. +func (r *Reader) Unit() string { + if r.HasUnit() { + return r.dictUnitStr[r.unitRef] + } + return "" +} + +// Name returns metric name of current metric entry. +func (r *Reader) Name() string { + return r.dictNameStr[r.nameRef] +} + +// Tags returns set of tags for current metric entry. +func (r *Reader) Tags() []string { + return r.dictTagsets[r.tagsRef] +} + +// Resources returns set of resources for current metric entry. +// +//nolint:revive +func (r *Reader) Resources() []*resource { + return r.dictResources[r.resourcesRef] +} + +// SourceTypeName returns source type identifier for current metric entry. +func (r *Reader) SourceTypeName() string { + return r.dictSourceTypeName[r.sourceTypeNameRef] +} + +// Origin returns product origin information for current metric entry. +// +//nolint:revive +func (r *Reader) Origin() *originInfo { + return r.dictOriginInfo[r.originInfoRef] +} + +// Interval returns metric time interval for current metric entry. +func (r *Reader) Interval() uint64 { + return r.payload.MetricData.Intervals[r.metricIdx-1] +} + +// NumPoints returns number of data points contained in the current metric entry. +func (r *Reader) NumPoints() uint64 { + return r.payload.MetricData.NumPoints[r.metricIdx-1] +} + +// NoIndex returns true if the metric should not be indexed. +func (r *Reader) NoIndex() bool { + return r.packedType()&uint64(MetricFlags_flagNoIndex) != 0 +} + +// HaveMorePoints returns true if there are more points to read. +func (r *Reader) HaveMorePoints() bool { + return r.pointsRemaining > 0 +} + +// HasUnit returns true if the current metric entry has a unit. +func (r *Reader) HasUnit() bool { + return r.packedType()&uint64(MetricFlags_flagHasUnit) != 0 +} + +// NextPoint consumes next unread metric data point and prepares data for access. +// +// If this method returns an error the reader is in an invalid state and calling data access methods may panic. +func (r *Reader) NextPoint() error { + if !r.HaveMorePoints() { + return errUnexpectedEOF + } + + r.pointIdx++ + r.pointsRemaining-- + + if r.pointIdx > len(r.payload.MetricData.Timestamps) { + return errUnexpectedEOF + } + + switch r.Type() { + case MetricType_Sketch: + r.sketchNumBinsIdx++ + if r.sketchNumBinsIdx > len(r.payload.MetricData.SketchNumBins) { + return errUnexpectedEOF + } + r.sketchBinsIdx += r.SketchNumBins() + switch r.ValueType() { + case ValueType_Float64: + r.valsFloat64Idx += 3 + r.valsSint64Idx++ + case ValueType_Float32: + r.valsFloat32Idx += 3 + r.valsSint64Idx++ + case ValueType_Sint64: + r.valsSint64Idx += 4 + case ValueType_Zero: + r.valsSint64Idx++ + } + default: + switch r.ValueType() { + case ValueType_Float64: + r.valsFloat64Idx++ + case ValueType_Float32: + r.valsFloat32Idx++ + case ValueType_Sint64: + r.valsSint64Idx++ + } + } + + if r.valsFloat64Idx > len(r.payload.MetricData.ValsFloat64) { + return errUnexpectedEOF + } + if r.valsFloat32Idx > len(r.payload.MetricData.ValsFloat32) { + return errUnexpectedEOF + } + if r.valsSint64Idx > len(r.payload.MetricData.ValsSint64) { + return errUnexpectedEOF + } + if r.sketchBinsIdx > len(r.payload.MetricData.SketchBinKeys) { + return errUnexpectedEOF + } + if r.sketchBinsIdx > len(r.payload.MetricData.SketchBinCnts) { + return errUnexpectedEOF + } + + r.timestamp += r.payload.MetricData.Timestamps[r.pointIdx-1] + + return nil +} + +// Timestamp returns timestamp for current metric data point. +func (r *Reader) Timestamp() int64 { + return r.timestamp +} + +// Value returns metric value for current metric data point. +// +// Only valid to call if r.Type() != MetricType_Sketch, panics otherwise. +func (r *Reader) Value() float64 { + if r.Type() == MetricType_Sketch { + panic("invalid type") + } + switch r.ValueType() { + case ValueType_Float64: + return r.payload.MetricData.ValsFloat64[r.valsFloat64Idx-1] + case ValueType_Float32: + return float64(r.payload.MetricData.ValsFloat32[r.valsFloat32Idx-1]) + case ValueType_Sint64: + return float64(r.payload.MetricData.ValsSint64[r.valsSint64Idx-1]) + default: + return 0 + } +} + +// SketchSummary returns sketch summary for current metric data point. +// +// Only valid if r.Type() == MetricType_Sketch, panics otherwise. +func (r *Reader) SketchSummary() (sum, min, max float64, cnt uint64) { + if r.Type() != MetricType_Sketch { + panic("invalid type") + } + + cnt = uint64(r.payload.MetricData.ValsSint64[r.valsSint64Idx-1]) + + switch r.ValueType() { + case ValueType_Zero: + case ValueType_Sint64: + sum = float64(r.payload.MetricData.ValsSint64[r.valsSint64Idx-4]) + min = float64(r.payload.MetricData.ValsSint64[r.valsSint64Idx-3]) + max = float64(r.payload.MetricData.ValsSint64[r.valsSint64Idx-2]) + // -1 is cnt + case ValueType_Float32: + sum = float64(r.payload.MetricData.ValsFloat32[r.valsFloat32Idx-3]) + min = float64(r.payload.MetricData.ValsFloat32[r.valsFloat32Idx-2]) + max = float64(r.payload.MetricData.ValsFloat32[r.valsFloat32Idx-1]) + case ValueType_Float64: + sum = r.payload.MetricData.ValsFloat64[r.valsFloat64Idx-3] + min = r.payload.MetricData.ValsFloat64[r.valsFloat64Idx-2] + max = r.payload.MetricData.ValsFloat64[r.valsFloat64Idx-1] + } + + return +} + +// SketchNumBins returns number of sketch bins for the current metric data point. +// +// Only valid if r.Type() == MetricType_Sketch, panics otherwise. +func (r *Reader) SketchNumBins() int { + if r.Type() != MetricType_Sketch { + panic("invalid type") + } + return int(r.payload.MetricData.SketchNumBins[r.sketchNumBinsIdx-1]) +} + +// SketchCols returns sketch data columns for the current metric data +// point. +// +// Only valid if r.Type() == MetricType_Sketch, panics otherwise. +func (r *Reader) SketchCols() (k []int32, n []uint32) { + if r.Type() != MetricType_Sketch { + panic("invalid type") + } + size := r.SketchNumBins() + start := r.sketchBinsIdx - size + k = slices.Clone(r.payload.MetricData.SketchBinKeys[start:][:size]) + n = slices.Clone(r.payload.MetricData.SketchBinCnts[start:][:size]) + deltaDecode(k) + return +} + +func deltaDecode(s []int32) { + for i := 1; i < len(s); i++ { + s[i] += s[i-1] + } +} + +func (r *Reader) Debug() { + fmt.Printf(`-- + metricIdx %d + pointIdx %d + valsSint64Idx %d + valsFloat32Idx %d + valsFloat64Idx %d + + sketchNumBinsIdx %d + sketchBinsIdx %d + + pointsRemaining %d + + nameRef %d + tagsRef %d + resourcesRef %d + sourceTypeNameRef %d + originInfoRef %d + timestamp %d +`, + r.metricIdx, + r.pointIdx, + r.valsSint64Idx, + r.valsFloat32Idx, + r.valsFloat64Idx, + r.sketchNumBinsIdx, + r.sketchBinsIdx, + + r.pointsRemaining, + + r.nameRef, + r.tagsRef, + r.resourcesRef, + r.sourceTypeNameRef, + r.originInfoRef, + r.timestamp, + ) + +} diff --git a/test/fakeintake/aggregator/metricAggregatorV3.go b/test/fakeintake/aggregator/metricAggregatorV3.go new file mode 100644 index 000000000000..537890aa8699 --- /dev/null +++ b/test/fakeintake/aggregator/metricAggregatorV3.go @@ -0,0 +1,106 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +package aggregator + +import ( + "bytes" + "fmt" + + metricspb "github.com/DataDog/agent-payload/v5/gogen" + "google.golang.org/protobuf/proto" + + apiv3 "github.com/DataDog/datadog-agent/test/fakeintake/aggregator/internal/apiv3" + "github.com/DataDog/datadog-agent/test/fakeintake/api" +) + +// ParseMetricSeriesV3 decodes a /api/intake/metrics/v3/series payload (compressed protobuf) +// into []*MetricSeries — the same type used for /api/v2/series — so FilterMetrics() works +// transparently regardless of which wire format the agent uses. +// +// V3 is a column-oriented protobuf encoding described in +// test/fakeintake/aggregator/internal/apiv3/payload.proto. The MetricType numeric values are identical +// to MetricPayload_MetricType (COUNT=1, RATE=2, GAUGE=3), making the cast safe. +func ParseMetricSeriesV3(payload api.Payload) ([]*MetricSeries, error) { + if len(payload.Data) == 0 || bytes.Equal(payload.Data, []byte("{}")) { + return []*MetricSeries{}, nil + } + + inflated, err := inflate(payload.Data, payload.Encoding) + if err != nil { + return nil, fmt.Errorf("v3 payload inflate: %w", err) + } + if len(inflated) == 0 || bytes.Equal(inflated, []byte("{}")) { + return []*MetricSeries{}, nil + } + + var p apiv3.Payload + if err := proto.Unmarshal(inflated, &p); err != nil { + return nil, fmt.Errorf("v3 payload unmarshal: %w", err) + } + if p.MetricData == nil { + return []*MetricSeries{}, nil + } + + r := apiv3.NewReader(p.MetricData) + if err := r.Initialize(); err != nil { + return nil, fmt.Errorf("v3 reader init: %w", err) + } + + var series []*MetricSeries + for r.HaveMoreMetrics() { + if err := r.NextMetric(); err != nil { + return nil, fmt.Errorf("v3 next metric: %w", err) + } + + metricType := r.Type() + if metricType == apiv3.MetricType_Sketch { + return nil, fmt.Errorf("unexpected sketch metric %q in V3 series payload", r.Name()) + } + + ms := &metricspb.MetricPayload_MetricSeries{ + Metric: r.Name(), + Tags: append([]string{}, r.Tags()...), + // MetricType numeric values are identical between the two proto packages. + Type: metricspb.MetricPayload_MetricType(metricType), + Unit: r.Unit(), + } + for _, res := range r.Resources() { + if res == nil { + continue + } + ms.Resources = append(ms.Resources, &metricspb.MetricPayload_Resource{ + Type: res[0], + Name: res[1], + }) + } + + for r.HaveMorePoints() { + if err := r.NextPoint(); err != nil { + return nil, fmt.Errorf("v3 next point: %w", err) + } + ms.Points = append(ms.Points, &metricspb.MetricPayload_MetricPoint{ + Timestamp: r.Timestamp(), + Value: r.Value(), + }) + } + + series = append(series, &MetricSeries{ + MetricPayload_MetricSeries: *ms, + collectedTime: payload.Timestamp, + }) + } + + return series, nil +} + +// NewMetricAggregatorV3 returns a MetricAggregator wired to the V3 series parser. +// The returned type is identical to NewMetricAggregator(); callers can merge results +// from both aggregators and pass them to FilterMetrics without type conversion. +func NewMetricAggregatorV3() MetricAggregator { + return MetricAggregator{ + Aggregator: newAggregator(ParseMetricSeriesV3), + } +} diff --git a/test/fakeintake/aggregator/metricAggregatorV3_test.go b/test/fakeintake/aggregator/metricAggregatorV3_test.go new file mode 100644 index 000000000000..18aabdb7dfeb --- /dev/null +++ b/test/fakeintake/aggregator/metricAggregatorV3_test.go @@ -0,0 +1,263 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +package aggregator + +import ( + "testing" + "time" + + "github.com/DataDog/zstd" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/encoding/protowire" + "google.golang.org/protobuf/proto" + + metricspb "github.com/DataDog/agent-payload/v5/gogen" + apiv3 "github.com/DataDog/datadog-agent/test/fakeintake/aggregator/internal/apiv3" + + "github.com/DataDog/datadog-agent/test/fakeintake/api" +) + +// buildMinimalV3Payload constructs an apiv3.Payload containing a single gauge metric +// "test.gauge" with tag "env:test", timestamp 1000, and value 42.0. +// +// Wire encoding of the column-oriented MetricData: +// - DictNameStr: varint(10) + "test.gauge" +// - DictTagStr: varint(8) + "env:test" +// - DictTagsets: [1, 1] — one tagset of size 1, pointing to dictTagStr[1] +// - Types: [3|48] = [51] — MetricType_Gauge | ValueType_Float64 +// - NameRefs: [1] — delta-encoded index → dictNameStr[1] +// - TagsetRefs: [1] — delta-encoded index → dictTagsets[1] +// - DictResourceStr: varint(4) + "host" + varint(6) + "node-a" +// - DictResourceLen: [1] — one resource set with one resource +// - DictResourceType: [1] — type → dictResourceStr[1] ("host") +// - DictResourceName: [2] — name → dictResourceStr[2] ("node-a") +// - ResourcesRefs: [1] — resource set → dictResources[1] +// - SourceTypeNameRefs: [0] +// - OriginInfoRefs: [0] +// - Intervals: [0] +// - NumPoints: [1] +// - Timestamps: [1000] — delta-encoded +// - ValsFloat64: [42.0] +func buildMinimalV3Payload() *apiv3.Payload { + nameStr := append([]byte{10}, []byte("test.gauge")...) // varint(10) + "test.gauge" + tagStr := append([]byte{8}, []byte("env:test")...) // varint(8) + "env:test" + resourceStr := append([]byte{4}, []byte("host")...) // varint(4) + "host" + resourceStr = append(resourceStr, byte(6)) + resourceStr = append(resourceStr, []byte("node-a")...) + + return &apiv3.Payload{ + MetricData: &apiv3.MetricData{ + DictNameStr: nameStr, + DictTagStr: tagStr, + DictTagsets: []int64{1, 1}, // size=1, ref=1 + DictResourceStr: resourceStr, + DictResourceLen: []int64{1}, + DictResourceType: []int64{1}, + DictResourceName: []int64{2}, + Types: []uint64{uint64(apiv3.MetricType_Gauge) | uint64(apiv3.ValueType_Float64)}, + NameRefs: []int64{1}, + TagsetRefs: []int64{1}, + ResourcesRefs: []int64{1}, + SourceTypeNameRefs: []int64{0}, + OriginInfoRefs: []int64{0}, + Intervals: []uint64{0}, + NumPoints: []uint64{1}, + Timestamps: []int64{1000}, + ValsFloat64: []float64{42.0}, + }, + } +} + +func buildV3PayloadWithUnit(unit string) *apiv3.Payload { + p := buildMinimalV3Payload() + p.MetricData.Types[0] |= uint64(apiv3.MetricFlags_flagHasUnit) + + unitStr := append([]byte{byte(len(unit))}, []byte(unit)...) + p.MetricData.DictUnitStr = unitStr + p.MetricData.UnitRefs = []int64{1} + + return p +} + +func TestParseMetricSeriesV3_SingleGauge(t *testing.T) { + p := buildMinimalV3Payload() + + raw, err := proto.Marshal(p) + require.NoError(t, err) + + payload := api.Payload{ + Data: raw, + Encoding: encodingEmpty, // no compression + ContentType: "application/x-protobuf", + Timestamp: time.Unix(999, 0), + } + + series, err := ParseMetricSeriesV3(payload) + require.NoError(t, err) + require.Len(t, series, 1) + + s := series[0] + assert.Equal(t, "test.gauge", s.Metric) + assert.Equal(t, []string{"env:test"}, s.Tags) + require.Len(t, s.Resources, 1) + assert.Equal(t, "host", s.Resources[0].Type) + assert.Equal(t, "node-a", s.Resources[0].Name) + assert.Equal(t, metricspb.MetricPayload_GAUGE, s.Type) + assert.Empty(t, s.Unit) + require.Len(t, s.Points, 1) + assert.Equal(t, int64(1000), s.Points[0].Timestamp) + assert.Equal(t, 42.0, s.Points[0].Value) + assert.Equal(t, time.Unix(999, 0), s.GetCollectedTime()) +} + +func TestParseMetricSeriesV3_Unit(t *testing.T) { + p := buildV3PayloadWithUnit("millisecond") + + raw, err := proto.Marshal(p) + require.NoError(t, err) + + payload := api.Payload{ + Data: raw, + Encoding: encodingEmpty, // no compression + ContentType: "application/x-protobuf", + Timestamp: time.Unix(999, 0), + } + + series, err := ParseMetricSeriesV3(payload) + require.NoError(t, err) + require.Len(t, series, 1) + assert.Equal(t, "millisecond", series[0].Unit) +} + +func TestParseMetricSeriesV3_CompressedColumnPayload(t *testing.T) { + p := buildMinimalV3Payload() + raw, err := proto.Marshal(p) + require.NoError(t, err) + + compressed := buildCompressedV3Payload(t, raw) + inflated, err := inflate(compressed, encodingZstd) + require.NoError(t, err) + require.Equal(t, raw, inflated) + + payload := api.Payload{ + Data: compressed, + Encoding: encodingZstd, + ContentType: "application/x-protobuf", + Timestamp: time.Unix(999, 0), + } + + series, err := ParseMetricSeriesV3(payload) + require.NoError(t, err) + require.Len(t, series, 1) + assert.Equal(t, "test.gauge", series[0].Metric) +} + +func TestParseMetricSeriesV3_EmptyPayload(t *testing.T) { + p := &apiv3.Payload{MetricData: nil} + raw, err := proto.Marshal(p) + require.NoError(t, err) + + payload := api.Payload{Data: raw, Encoding: encodingEmpty, Timestamp: time.Now()} + series, err := ParseMetricSeriesV3(payload) + require.NoError(t, err) + assert.Empty(t, series) +} + +func buildCompressedV3Payload(t *testing.T, raw []byte) []byte { + t.Helper() + + fieldNum, typ, n := protowire.ConsumeTag(raw) + require.Greater(t, n, 0) + require.Equal(t, protowire.Number(3), fieldNum) + require.Equal(t, protowire.BytesType, typ) + metricData, m := protowire.ConsumeBytes(raw[n:]) + require.Greater(t, m, 0) + require.Equal(t, len(raw), n+m) + + out := zstdCompress(t, raw[:len(raw)-len(metricData)]) + for len(metricData) > 0 { + _, fieldType, fieldHeaderLen := protowire.ConsumeTag(metricData) + require.Greater(t, fieldHeaderLen, 0) + require.Equal(t, protowire.BytesType, fieldType) + fieldValue, fieldValueLen := protowire.ConsumeBytes(metricData[fieldHeaderLen:]) + require.Greater(t, fieldValueLen, 0) + headerLen := fieldHeaderLen + fieldValueLen - len(fieldValue) + out = append(out, zstdCompress(t, metricData[:headerLen])...) + out = append(out, zstdCompress(t, fieldValue)...) + metricData = metricData[headerLen+len(fieldValue):] + } + return out +} + +func zstdCompress(t *testing.T, raw []byte) []byte { + t.Helper() + compressed, err := zstd.CompressLevel(nil, raw, 1) + require.NoError(t, err) + return compressed +} + +func TestParseMetricSeriesV3_EmptyBody(t *testing.T) { + for _, payload := range []api.Payload{ + {Data: nil, Encoding: encodingEmpty, Timestamp: time.Now()}, + {Data: []byte("{}"), Encoding: encodingEmpty, Timestamp: time.Now()}, + {Data: nil, Encoding: encodingZstd, Timestamp: time.Now()}, + } { + series, err := ParseMetricSeriesV3(payload) + require.NoError(t, err) + assert.Empty(t, series) + } +} + +func TestParseMetricSeriesV3_SketchInSeriesPayloadErrors(t *testing.T) { + // A sketch entry in a /api/intake/metrics/v3/series payload is a serious agent bug; + // the parser must return an error rather than silently skip it. + nameStr := append([]byte{10}, []byte("test.dist1")...) + p := &apiv3.Payload{ + MetricData: &apiv3.MetricData{ + DictNameStr: nameStr, + DictTagStr: nil, + DictTagsets: []int64{0}, + Types: []uint64{uint64(apiv3.MetricType_Sketch) | uint64(apiv3.ValueType_Zero)}, + NameRefs: []int64{1}, + TagsetRefs: []int64{0}, + ResourcesRefs: []int64{0}, + SourceTypeNameRefs: []int64{0}, + OriginInfoRefs: []int64{0}, + Intervals: []uint64{0}, + NumPoints: []uint64{1}, + Timestamps: []int64{1000}, + SketchNumBins: []uint64{0}, + ValsSint64: []int64{0}, + }, + } + + raw, err := proto.Marshal(p) + require.NoError(t, err) + + payload := api.Payload{Data: raw, Encoding: encodingEmpty, Timestamp: time.Now()} + _, err = ParseMetricSeriesV3(payload) + require.Error(t, err) + assert.Contains(t, err.Error(), "unexpected sketch metric") +} + +func TestParseMetricSeriesV3_Aggregator(t *testing.T) { + // End-to-end: parse through the aggregator so GetPayloadsByName works. + p := buildMinimalV3Payload() + raw, err := proto.Marshal(p) + require.NoError(t, err) + + agg := NewMetricAggregatorV3() + err = agg.UnmarshallPayloads([]api.Payload{ + {Data: raw, Encoding: encodingEmpty, Timestamp: time.Now()}, + }) + require.NoError(t, err) + + byName := agg.GetPayloadsByName("test.gauge") + require.Len(t, byName, 1) + assert.Equal(t, "test.gauge", byName[0].Metric) + assert.Equal(t, []string{"env:test"}, byName[0].Tags) +} diff --git a/test/fakeintake/client/client.go b/test/fakeintake/client/client.go index 149a6eed9ad3..41d5cf5d7033 100644 --- a/test/fakeintake/client/client.go +++ b/test/fakeintake/client/client.go @@ -66,6 +66,7 @@ import ( const ( fakeintakeIDHeader = "Fakeintake-ID" metricsEndpoint = "/api/v2/series" + metricsV3Endpoint = "/api/intake/metrics/v3/series" sketchesEndpoint = "/api/beta/sketches" intakeEndpoint = "/intake/" checkRunsEndpoint = "/api/v1/check_run" @@ -130,6 +131,7 @@ type Client struct { getBackoffDelay time.Duration metricAggregator aggregator.MetricAggregator + metricAggregatorV3 aggregator.MetricAggregator sketchAggregator aggregator.SketchAggregator checkRunAggregator aggregator.CheckRunAggregator eventAggregator aggregator.EventAggregator @@ -164,6 +166,7 @@ func NewClient(fakeIntakeURL string, opts ...Option) *Client { getBackoffDelay: 5 * time.Second, fakeIntakeURL: strings.TrimSuffix(fakeIntakeURL, "/"), metricAggregator: aggregator.NewMetricAggregator(), + metricAggregatorV3: aggregator.NewMetricAggregatorV3(), sketchAggregator: aggregator.NewSketchAggregator(), checkRunAggregator: aggregator.NewCheckRunAggregator(), eventAggregator: aggregator.NewEventAggregator(), @@ -377,8 +380,9 @@ func (c *Client) getAgentHealth() error { return c.agentHealthAggregator.UnmarshallPayloads(payloads) } -// FilterMetrics fetches fakeintake on `/api/v2/series` endpoint and returns -// metrics matching `name` and any [MatchOpt](#MatchOpt) options +// FilterMetrics fetches fakeintake on both `/api/v2/series` and `/api/intake/metrics/v3/series` +// and returns metrics matching `name` and any [MatchOpt](#MatchOpt) options. +// Results from both endpoints are merged. func (c *Client) FilterMetrics(name string, options ...MatchOpt[*aggregator.MetricSeries]) ([]*aggregator.MetricSeries, error) { metrics, err := c.getMetric(name) if err != nil { @@ -397,6 +401,14 @@ func (c *Client) FilterSketches(name string, options ...MatchOpt[*aggregator.Ske return filterPayload(c.sketchAggregator.GetPayloadsByName(name), options...) } +func (c *Client) getMetricsV3() error { + payloads, err := c.getFakePayloads(metricsV3Endpoint) + if err != nil { + return err + } + return c.metricAggregatorV3.UnmarshallPayloads(payloads) +} + // FilterCheckRuns fetches fakeintake on `/api/v1/check_run` endpoint and returns // metrics matching `name` and any [MatchOpt](#MatchOpt) options func (c *Client) FilterCheckRuns(name string, options ...MatchOpt[*aggregator.CheckRun]) ([]*aggregator.CheckRun, error) { @@ -518,24 +530,39 @@ func (c *Client) GetLastAPIKey() (string, error) { } func (c *Client) getMetric(name string) ([]*aggregator.MetricSeries, error) { - err := c.getMetrics() - if err != nil { + if err := c.getMetrics(); err != nil { return nil, err } - return c.metricAggregator.GetPayloadsByName(name), nil + if err := c.getMetricsV3(); err != nil { + return nil, err + } + return append( + c.metricAggregator.GetPayloadsByName(name), + c.metricAggregatorV3.GetPayloadsByName(name)..., + ), nil } // A MatchOpt to filter fakeintake payloads type MatchOpt[P aggregator.PayloadItem] func(payload P) (bool, error) -// GetMetricNames fetches fakeintake on `/api/v2/series` endpoint and returns -// all received metric names +// GetMetricNames fetches fakeintake on both `/api/v2/series` and `/api/intake/metrics/v3/series` +// and returns all received metric names. func (c *Client) GetMetricNames() ([]string, error) { - err := c.getMetrics() - if err != nil { + if err := c.getMetrics(); err != nil { return nil, err } - return c.metricAggregator.GetNames(), nil + if err := c.getMetricsV3(); err != nil { + return nil, err + } + seen := map[string]struct{}{} + for _, name := range append(c.metricAggregator.GetNames(), c.metricAggregatorV3.GetNames()...) { + seen[name] = struct{}{} + } + names := make([]string, 0, len(seen)) + for name := range seen { + names = append(names, name) + } + return names, nil } // GetSketchNames fetches fakeintake on `/api/beta/sketches` and returns every @@ -710,6 +737,7 @@ func (c *Client) FlushServerAndResetAggregators() error { c.checkRunAggregator.Reset() c.connectionAggregator.Reset() c.metricAggregator.Reset() + c.metricAggregatorV3.Reset() c.sketchAggregator.Reset() c.logAggregator.Reset() c.apmStatsAggregator.Reset() diff --git a/test/fakeintake/go.mod b/test/fakeintake/go.mod index 1bcce3c004a5..902f41d85eee 100644 --- a/test/fakeintake/go.mod +++ b/test/fakeintake/go.mod @@ -10,10 +10,11 @@ require ( github.com/DataDog/datadog-agent/pkg/metrics v0.64.0 github.com/DataDog/datadog-agent/pkg/networkpath/payload v0.0.0-20250128160050-7ac9ccd58c07 github.com/DataDog/datadog-agent/pkg/proto v0.64.0-devel - github.com/DataDog/zstd v1.5.7 + github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 github.com/benbjohnson/clock v1.3.5 github.com/cenkalti/backoff/v5 v5.0.3 github.com/google/uuid v1.6.0 + github.com/klauspost/compress v1.18.6 // indirect github.com/kr/pretty v0.3.1 github.com/prometheus/client_golang v1.23.3-0.20251103151724-a5ae20370e5e github.com/samber/lo v1.52.0 @@ -36,7 +37,6 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/klauspost/compress v1.18.6 // indirect github.com/kr/text v0.2.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/philhofer/fwd v1.2.0 // indirect diff --git a/test/fakeintake/go.sum b/test/fakeintake/go.sum index de5d11151ff0..bef21c5d7a77 100644 --- a/test/fakeintake/go.sum +++ b/test/fakeintake/go.sum @@ -2,8 +2,8 @@ github.com/DataDog/agent-payload/v5 v5.0.198 h1:i6OuIo88zLZW+S/XcDFHddu5p5f+5BYv github.com/DataDog/agent-payload/v5 v5.0.198/go.mod h1:GyA1vuCeRywrNNCbYeR0cOYKE8QkOVNAFDqsH8VNF5M= github.com/DataDog/mmh3 v0.0.0-20210722141835-012dc69a9e49 h1:EbzDX8HPk5uE2FsJYxD74QmMw0/3CqSKhEr6teh0ncQ= github.com/DataDog/mmh3 v0.0.0-20210722141835-012dc69a9e49/go.mod h1:SvsjzyJlSg0rKsqYgdcFxeEVflx3ZNAyFfkUHP0TxXg= -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f h1:5Vuo4niPKFkfwW55jV4vY0ih3VQ9RaQqeqY67fvRn8A= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f/go.mod h1:oXfOhM/Kr8OvqS6tVqJwxPBornV0yrx3bc+l0BDr7PQ= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= diff --git a/test/fakeintake/server/serverstore/parser.go b/test/fakeintake/server/serverstore/parser.go index bcbd1b86a744..f9f8de4dfb4c 100644 --- a/test/fakeintake/server/serverstore/parser.go +++ b/test/fakeintake/server/serverstore/parser.go @@ -13,12 +13,13 @@ import ( type parserFunc func(api.Payload) (interface{}, error) var parserMap = map[string]parserFunc{ - "/api/v2/logs": getLogPayLoadJSON, - "/api/v2/series": getMetricPayLoadJSON, - "/api/v1/series": getV1MetricPayLoadJSON, - "/api/v1/check_run": getCheckRunPayLoadJSON, - "/api/v1/connections": getConnectionsPayLoadProtobuf, - "/api/beta/sketches": getSketchPayloadProtobuf, + "/api/v2/logs": getLogPayLoadJSON, + "/api/v2/series": getMetricPayLoadJSON, + "/api/v1/series": getV1MetricPayLoadJSON, + "/api/v1/check_run": getCheckRunPayLoadJSON, + "/api/v1/connections": getConnectionsPayLoadProtobuf, + "/api/beta/sketches": getSketchPayloadProtobuf, + "/api/intake/metrics/v3/series": getMetricV3SeriesPayload, } func getLogPayLoadJSON(payload api.Payload) (interface{}, error) { @@ -45,6 +46,10 @@ func getSketchPayloadProtobuf(payload api.Payload) (interface{}, error) { return aggregator.ParseSketches(payload) } +func getMetricV3SeriesPayload(payload api.Payload) (interface{}, error) { + return aggregator.ParseMetricSeriesV3(payload) +} + // IsRouteHandled checks if a route is handled by the Datadog parsed store func IsRouteHandled(route string) bool { _, ok := parserMap[route] diff --git a/test/new-e2e/go.mod b/test/new-e2e/go.mod index 414ba93cb96f..24dee389bab2 100644 --- a/test/new-e2e/go.mod +++ b/test/new-e2e/go.mod @@ -47,7 +47,7 @@ require ( github.com/DataDog/datadog-agent/comp/netflow/payload v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/proto v0.77.0 github.com/DataDog/mmh3 v0.0.0-20210722141835-012dc69a9e49 // indirect - github.com/DataDog/zstd v1.5.7 // indirect + github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 // indirect github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect diff --git a/test/new-e2e/go.sum b/test/new-e2e/go.sum index 2fe5c691a33a..cbd139a5d01f 100644 --- a/test/new-e2e/go.sum +++ b/test/new-e2e/go.sum @@ -41,8 +41,8 @@ github.com/DataDog/sketches-go v1.4.8 h1:pFk9BNn+Rzv8IMIoPUttoOpOr3bJOqU3P6EP5wK github.com/DataDog/sketches-go v1.4.8/go.mod h1:a/wjRUqzqtGS8qRHRPDCs4EAQfmvPDZGDlMIF5mxXOE= github.com/DataDog/viper v1.15.1 h1:kcdFE+qPndlWkhU4iEf/WpWQMCyVYHTv5HqvVf+SYJs= github.com/DataDog/viper v1.15.1/go.mod h1:rDLDREOPd+gpEbA8y4Y/5wTvyLqvUiCmDXX0jRZy8mw= -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f h1:5Vuo4niPKFkfwW55jV4vY0ih3VQ9RaQqeqY67fvRn8A= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f/go.mod h1:oXfOhM/Kr8OvqS6tVqJwxPBornV0yrx3bc+l0BDr7PQ= github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= diff --git a/test/new-e2e/tests/agent-metric-pipelines/dogstatsd-unit/dogstatsd_unit_nix_test.go b/test/new-e2e/tests/agent-metric-pipelines/dogstatsd-unit/dogstatsd_unit_nix_test.go index f8dd03df0fe3..e8e09ada9431 100644 --- a/test/new-e2e/tests/agent-metric-pipelines/dogstatsd-unit/dogstatsd_unit_nix_test.go +++ b/test/new-e2e/tests/agent-metric-pipelines/dogstatsd-unit/dogstatsd_unit_nix_test.go @@ -38,15 +38,19 @@ const ( // expectedTimingUnit is the Datadog API unit name for millisecond timing metrics. expectedTimingUnit = "millisecond" + + metricsV2Endpoint = "/api/v2/series" + metricsV3Endpoint = "/api/intake/metrics/v3/series" ) type dogstatsdUnitSuite struct { e2e.BaseSuite[environments.Host] adpEnabled bool + v3Enabled bool } -func testDogstatsdMetricUnit(t *testing.T, adpEnabled bool) { +func testDogstatsdMetricUnit(t *testing.T, adpEnabled, v3Enabled bool) { t.Parallel() agentOptions := []agentparams.Option{ @@ -62,13 +66,21 @@ histogram_percentiles: if adpEnabled { agentOptions = append(agentOptions, common.WithADPEnabled()) } + if v3Enabled { + // WithV3MetricsEnabled must come after WithFakeintake, which the provisioner + // prepends automatically, so this ordering is correct. + agentOptions = append(agentOptions, agentparams.WithV3MetricsEnabled()) + } stackName := "dogstatsdmetricunit" if adpEnabled { stackName += "-adp" } + if v3Enabled { + stackName += "-v3" + } - e2e.Run(t, &dogstatsdUnitSuite{adpEnabled: adpEnabled}, + e2e.Run(t, &dogstatsdUnitSuite{adpEnabled: adpEnabled, v3Enabled: v3Enabled}, e2e.WithProvisioner( awshost.Provisioner( awshost.WithRunOptions( @@ -82,12 +94,19 @@ histogram_percentiles: // TestDogstatsdMetricUnit runs the DogStatsD unit e2e test on Linux. func TestDogstatsdMetricUnit(t *testing.T) { - testDogstatsdMetricUnit(t, false) + testDogstatsdMetricUnit(t, false, false) } // TestDogstatsdMetricUnitADP runs the DogStatsD unit e2e test with ADP serving DogStatsD traffic. func TestDogstatsdMetricUnitADP(t *testing.T) { - testDogstatsdMetricUnit(t, true) + testDogstatsdMetricUnit(t, true, false) +} + +// TestDogstatsdMetricUnitV3 runs the DogStatsD unit e2e test with the V3 metrics intake API enabled. +// It verifies that the same unit semantics hold over the V3 wire format, and that payloads are +// routed to /api/intake/metrics/v3/series rather than /api/v2/series. +func TestDogstatsdMetricUnitV3(t *testing.T) { + testDogstatsdMetricUnit(t, false, true) } // sendMetric sends a single DogStatsD metric over UDP to the local Agent. @@ -96,8 +115,10 @@ func (s *dogstatsdUnitSuite) sendMetric(name string, value float32, metricType s s.Env().RemoteHost.MustExecute(cmd) } -// TestDogstatsdUnitOnlyOnTimingMetrics sends a counter, a histogram, and a timing -// metric in parallel and verifies that only the timing metric carries a unit. +// TestDogstatsdUnitOnlyOnTimingMetrics sends a counter, a histogram, and a timing metric in +// parallel and verifies that only the timing metric carries a unit. The test runs for both V2 +// (default) and V3 intake protocols; in both cases it asserts that payloads were routed +// exclusively to the expected endpoint. func (s *dogstatsdUnitSuite) TestDogstatsdUnitOnlyOnTimingMetrics() { if s.adpEnabled { common.AssertADPRunning(s.T(), s.Env().RemoteHost) @@ -161,4 +182,20 @@ func (s *dogstatsdUnitSuite) TestDogstatsdUnitOnlyOnTimingMetrics() { "timing metric %q must carry unit %q, got %q", m.Metric, expectedTimingUnit, m.Unit) fmt.Printf("metric %q carries unit %q\n", m.Metric, m.Unit) } + + // Phase 3: verify routing. Each mode must use exactly its intended endpoint and + // send nothing to the other. + routeStats, err := s.Env().FakeIntake.Client().RouteStats() + require.NoError(s.T(), err) + if s.v3Enabled { + assert.Greater(s.T(), routeStats[metricsV3Endpoint], 0, + "expected payloads on %s when V3 is enabled", metricsV3Endpoint) + assert.Zero(s.T(), routeStats[metricsV2Endpoint], + "expected no payloads on %s when V3 is enabled", metricsV2Endpoint) + } else { + assert.Greater(s.T(), routeStats[metricsV2Endpoint], 0, + "expected payloads on %s when V3 is not enabled", metricsV2Endpoint) + assert.Zero(s.T(), routeStats[metricsV3Endpoint], + "expected no payloads on %s when V3 is not enabled", metricsV3Endpoint) + } } diff --git a/test/new-e2e/tests/otel/otlp-ingest/docker_pipelines_test.go b/test/new-e2e/tests/otel/otlp-ingest/docker_pipelines_test.go index 69de6d2e686d..14f7fb1209d2 100644 --- a/test/new-e2e/tests/otel/otlp-ingest/docker_pipelines_test.go +++ b/test/new-e2e/tests/otel/otlp-ingest/docker_pipelines_test.go @@ -10,6 +10,9 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/DataDog/datadog-agent/test/e2e-framework/components/datadog/apps" "github.com/DataDog/datadog-agent/test/e2e-framework/components/datadog/dockeragentparams" "github.com/pulumi/pulumi/sdk/v3/go/pulumi" @@ -21,36 +24,67 @@ import ( "github.com/DataDog/datadog-agent/test/new-e2e/tests/otel/utils" ) +const ( + otlpMetricsV2Endpoint = "/api/v2/series" + otlpMetricsV3Endpoint = "/api/intake/metrics/v3/series" +) + type otlpIngestDockerTestSuite struct { e2e.BaseSuite[environments.DockerHost] + + v3Enabled bool } //go:embed compose/otlp_ingest_compose.yaml var otlpIngestCompose string -func TestOTLPIngestDocker(t *testing.T) { +func testOTLPIngestDocker(t *testing.T, v3Enabled bool) { t.Parallel() + + agentOptions := []dockeragentparams.Option{ + dockeragentparams.WithLogs(), + dockeragentparams.WithAgentServiceEnvVariable("DD_OTLP_CONFIG_RECEIVER_PROTOCOLS_GRPC_ENDPOINT", pulumi.StringPtr("0.0.0.0:4317")), + dockeragentparams.WithAgentServiceEnvVariable("DD_OTLP_CONFIG_RECEIVER_PROTOCOLS_HTTP_ENDPOINT", pulumi.StringPtr("0.0.0.0:4318")), + dockeragentparams.WithAgentServiceEnvVariable("DD_LOGS_ENABLED", pulumi.StringPtr("true")), + dockeragentparams.WithAgentServiceEnvVariable("DD_OTLP_CONFIG_LOGS_ENABLED", pulumi.StringPtr("true")), + dockeragentparams.WithAgentServiceEnvVariable("DD_LOGS_CONFIG_CONTAINER_COLLECT_ALL", pulumi.StringPtr("false")), + dockeragentparams.WithAgentServiceEnvVariable("DD_OTLP_CONFIG_METRICS_RESOURCE_ATTRIBUTES_AS_TAGS", pulumi.StringPtr("true")), + dockeragentparams.WithExtraComposeManifest("calendar-rest-go", pulumi.String(strings.ReplaceAll(otlpIngestCompose, "{APPS_VERSION}", apps.Version))), + } + if v3Enabled { + agentOptions = append(agentOptions, dockeragentparams.WithV3MetricsEnabled()) + } + + stackName := "otlpingestdocker" + if v3Enabled { + stackName += "-v3" + } + e2e.Run(t, - &otlpIngestDockerTestSuite{}, + &otlpIngestDockerTestSuite{v3Enabled: v3Enabled}, e2e.WithProvisioner( awsdocker.Provisioner( awsdocker.WithRunOptions( - ec2docker.WithAgentOptions( - dockeragentparams.WithLogs(), - dockeragentparams.WithAgentServiceEnvVariable("DD_OTLP_CONFIG_RECEIVER_PROTOCOLS_GRPC_ENDPOINT", pulumi.StringPtr("0.0.0.0:4317")), - dockeragentparams.WithAgentServiceEnvVariable("DD_OTLP_CONFIG_RECEIVER_PROTOCOLS_HTTP_ENDPOINT", pulumi.StringPtr("0.0.0.0:4318")), - dockeragentparams.WithAgentServiceEnvVariable("DD_LOGS_ENABLED", pulumi.StringPtr("true")), - dockeragentparams.WithAgentServiceEnvVariable("DD_OTLP_CONFIG_LOGS_ENABLED", pulumi.StringPtr("true")), - dockeragentparams.WithAgentServiceEnvVariable("DD_LOGS_CONFIG_CONTAINER_COLLECT_ALL", pulumi.StringPtr("false")), - dockeragentparams.WithAgentServiceEnvVariable("DD_OTLP_CONFIG_METRICS_RESOURCE_ATTRIBUTES_AS_TAGS", pulumi.StringPtr("true")), - dockeragentparams.WithExtraComposeManifest("calendar-rest-go", pulumi.String(strings.ReplaceAll(otlpIngestCompose, "{APPS_VERSION}", apps.Version))), - ), + ec2docker.WithAgentOptions(agentOptions...), ), ), ), + e2e.WithStackName(stackName), ) } +// TestOTLPIngestDocker runs the OTLP ingest Docker e2e test with the default V2 metrics endpoint. +func TestOTLPIngestDocker(t *testing.T) { + testOTLPIngestDocker(t, false) +} + +// TestOTLPIngestDockerV3 runs the OTLP ingest Docker e2e test with the V3 metrics intake API +// enabled. Metric assertions are identical to the V2 variant; the test additionally verifies +// that payloads were routed to /api/intake/metrics/v3/series and not /api/v2/series. +func TestOTLPIngestDockerV3(t *testing.T) { + testOTLPIngestDocker(t, true) +} + func (s *otlpIngestDockerTestSuite) SetupSuite() { s.BaseSuite.SetupSuite() // SetupSuite needs to defer CleanupOnSetupFailure() if what comes after BaseSuite.SetupSuite() can fail. @@ -65,6 +99,21 @@ func (s *otlpIngestDockerTestSuite) TestOTLPTraces() { func (s *otlpIngestDockerTestSuite) TestOTLPMetrics() { utils.TestMetricsDocker(s) + + // Verify routing: each mode must use exactly its intended series endpoint. + routeStats, err := s.Env().FakeIntake.Client().RouteStats() + require.NoError(s.T(), err) + if s.v3Enabled { + assert.Greater(s.T(), routeStats[otlpMetricsV3Endpoint], 0, + "expected payloads on %s when V3 is enabled", otlpMetricsV3Endpoint) + assert.Zero(s.T(), routeStats[otlpMetricsV2Endpoint], + "expected no payloads on %s when V3 is enabled", otlpMetricsV2Endpoint) + } else { + assert.Greater(s.T(), routeStats[otlpMetricsV2Endpoint], 0, + "expected payloads on %s when V3 is not enabled", otlpMetricsV2Endpoint) + assert.Zero(s.T(), routeStats[otlpMetricsV3Endpoint], + "expected no payloads on %s when V3 is not enabled", otlpMetricsV3Endpoint) + } } func (s *otlpIngestDockerTestSuite) TestOTLPLogs() { diff --git a/test/otel/go.mod b/test/otel/go.mod index 9ef3ddea21b2..40a2096b31cd 100644 --- a/test/otel/go.mod +++ b/test/otel/go.mod @@ -148,7 +148,7 @@ require ( github.com/DataDog/go-sqllexer v0.2.2 // indirect github.com/DataDog/sketches-go v1.4.8 // indirect github.com/DataDog/viper v1.15.1 // indirect - github.com/DataDog/zstd v1.5.7 // indirect + github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect diff --git a/test/otel/go.sum b/test/otel/go.sum index 6500f3076fa9..dcfef89bd9fb 100644 --- a/test/otel/go.sum +++ b/test/otel/go.sum @@ -17,8 +17,8 @@ github.com/DataDog/sketches-go v1.4.8 h1:pFk9BNn+Rzv8IMIoPUttoOpOr3bJOqU3P6EP5wK github.com/DataDog/sketches-go v1.4.8/go.mod h1:a/wjRUqzqtGS8qRHRPDCs4EAQfmvPDZGDlMIF5mxXOE= github.com/DataDog/viper v1.15.1 h1:kcdFE+qPndlWkhU4iEf/WpWQMCyVYHTv5HqvVf+SYJs= github.com/DataDog/viper v1.15.1/go.mod h1:rDLDREOPd+gpEbA8y4Y/5wTvyLqvUiCmDXX0jRZy8mw= -github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= -github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571 h1:zDAogP70WYpLD6MiIjQ9tHZYmkfbFcsfGb26CMf99To= +github.com/DataDog/zstd v1.5.8-0.20260421145859-31a7e515a571/go.mod h1:oyU0k4j1rV2Cxqy/hdGZzmVg3nJtHahZBImIK9ejcDA= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f h1:5Vuo4niPKFkfwW55jV4vY0ih3VQ9RaQqeqY67fvRn8A= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f/go.mod h1:oXfOhM/Kr8OvqS6tVqJwxPBornV0yrx3bc+l0BDr7PQ= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=