From 33a5a495a45f872cccb7c2ddf437eecb8c77cfce Mon Sep 17 00:00:00 2001 From: Chester Cheung Date: Tue, 1 Mar 2022 23:48:37 +0800 Subject: [PATCH 01/29] Replace master with specific jaeger tag version in otel-collector (#2622) * replace master with specific jaeger tag version in otel-collector * change version * update jeager-operator version in makefile --- example/otel-collector/Makefile | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/example/otel-collector/Makefile b/example/otel-collector/Makefile index 606e8f86ef4..47c560b34c8 100644 --- a/example/otel-collector/Makefile +++ b/example/otel-collector/Makefile @@ -3,15 +3,7 @@ namespace-k8s: jaeger-operator-k8s: # Create the jaeger operator and necessary artifacts in ns observability - kubectl create -n observability -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/crds/jaegertracing.io_jaegers_crd.yaml - kubectl create -n observability -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/service_account.yaml - kubectl create -n observability -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/role.yaml - kubectl create -n observability -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/role_binding.yaml - kubectl create -n observability -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/operator.yaml - - # Create the cluster role & bindings - kubectl create -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/cluster_role.yaml - kubectl create -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/cluster_role_binding.yaml + kubectl create -n observability -f https://github.com/jaegertracing/jaeger-operator/releases/download/v1.31.0/jaeger-operator.yaml jaeger-k8s: kubectl apply -f k8s/jaeger.yaml @@ -31,11 +23,4 @@ clean-k8s: - kubectl delete -f k8s/jaeger.yaml - - kubectl delete -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/cluster_role.yaml - - kubectl delete -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/cluster_role_binding.yaml - - - kubectl delete -n observability -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/crds/jaegertracing.io_jaegers_crd.yaml - - kubectl delete -n observability -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/service_account.yaml - - kubectl delete -n observability -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/role.yaml - - kubectl delete -n observability -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/role_binding.yaml - - kubectl delete -n observability -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/operator.yaml + - kubectl delete -n observability -f https://github.com/jaegertracing/jaeger-operator/releases/download/v1.31.0/jaeger-operator.yaml From 79f6bc1208be88374bddbd5b285ba21c1d3068fc Mon Sep 17 00:00:00 2001 From: Chester Cheung Date: Wed, 2 Mar 2022 04:09:51 +0800 Subject: [PATCH 02/29] remove old prom-collector depandence (#2643) --- .gitignore | 1 - bridge/opencensus/go.mod | 2 -- bridge/opentracing/go.mod | 2 -- example/jaeger/go.mod | 2 -- example/namedtracer/go.mod | 2 -- example/opencensus/go.mod | 2 -- example/otel-collector/go.mod | 2 -- example/passthrough/go.mod | 2 -- example/prometheus/go.mod | 2 -- example/zipkin/go.mod | 2 -- exporters/jaeger/go.mod | 2 -- exporters/otlp/otlpmetric/otlpmetricgrpc/go.mod | 2 -- exporters/otlp/otlpmetric/otlpmetrichttp/go.mod | 8 -------- exporters/otlp/otlptrace/go.mod | 2 -- exporters/otlp/otlptrace/otlptracegrpc/go.mod | 2 -- exporters/otlp/otlptrace/otlptracehttp/go.mod | 2 -- exporters/prometheus/go.mod | 2 -- exporters/stdout/stdoutmetric/go.mod | 2 -- exporters/stdout/stdouttrace/go.mod | 2 -- exporters/zipkin/go.mod | 2 -- go.mod | 2 -- internal/metric/go.mod | 2 -- metric/go.mod | 2 -- sdk/export/metric/go.mod | 2 -- sdk/go.mod | 2 -- sdk/metric/go.mod | 2 -- trace/go.mod | 2 -- 27 files changed, 59 deletions(-) diff --git a/.gitignore b/.gitignore index 759cf53e002..99230bae28b 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,5 @@ gen/ /example/opencensus/opencensus /example/passthrough/passthrough /example/prometheus/prometheus -/example/prom-collector/prom-collector /example/zipkin/zipkin /example/otel-collector/otel-collector diff --git a/bridge/opencensus/go.mod b/bridge/opencensus/go.mod index c275b1ac003..db2733fc484 100644 --- a/bridge/opencensus/go.mod +++ b/bridge/opencensus/go.mod @@ -25,8 +25,6 @@ replace go.opentelemetry.io/otel/example/opencensus => ../../example/opencensus replace go.opentelemetry.io/otel/example/otel-collector => ../../example/otel-collector -replace go.opentelemetry.io/otel/example/prom-collector => ../../example/prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ../../example/prometheus replace go.opentelemetry.io/otel/example/zipkin => ../../example/zipkin diff --git a/bridge/opentracing/go.mod b/bridge/opentracing/go.mod index 8bea859d6f1..6a36fde8822 100644 --- a/bridge/opentracing/go.mod +++ b/bridge/opentracing/go.mod @@ -22,8 +22,6 @@ replace go.opentelemetry.io/otel/example/opencensus => ../../example/opencensus replace go.opentelemetry.io/otel/example/otel-collector => ../../example/otel-collector -replace go.opentelemetry.io/otel/example/prom-collector => ../../example/prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ../../example/prometheus replace go.opentelemetry.io/otel/example/zipkin => ../../example/zipkin diff --git a/example/jaeger/go.mod b/example/jaeger/go.mod index 89e704f77ef..c67a139299d 100644 --- a/example/jaeger/go.mod +++ b/example/jaeger/go.mod @@ -26,8 +26,6 @@ replace go.opentelemetry.io/otel/example/opencensus => ../opencensus replace go.opentelemetry.io/otel/example/otel-collector => ../otel-collector -replace go.opentelemetry.io/otel/example/prom-collector => ../prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ../prometheus replace go.opentelemetry.io/otel/example/zipkin => ../zipkin diff --git a/example/namedtracer/go.mod b/example/namedtracer/go.mod index eb1052a5c34..3873edf2951 100644 --- a/example/namedtracer/go.mod +++ b/example/namedtracer/go.mod @@ -27,8 +27,6 @@ replace go.opentelemetry.io/otel/example/opencensus => ../opencensus replace go.opentelemetry.io/otel/example/otel-collector => ../otel-collector -replace go.opentelemetry.io/otel/example/prom-collector => ../prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ../prometheus replace go.opentelemetry.io/otel/example/zipkin => ../zipkin diff --git a/example/opencensus/go.mod b/example/opencensus/go.mod index bac77c24e0f..ba0fa9db3de 100644 --- a/example/opencensus/go.mod +++ b/example/opencensus/go.mod @@ -28,8 +28,6 @@ replace go.opentelemetry.io/otel/example/opencensus => ./ replace go.opentelemetry.io/otel/example/otel-collector => ../otel-collector -replace go.opentelemetry.io/otel/example/prom-collector => ../prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ../prometheus replace go.opentelemetry.io/otel/example/zipkin => ../zipkin diff --git a/example/otel-collector/go.mod b/example/otel-collector/go.mod index e353ef0ef1c..bc705fd9bac 100644 --- a/example/otel-collector/go.mod +++ b/example/otel-collector/go.mod @@ -27,8 +27,6 @@ replace go.opentelemetry.io/otel/example/opencensus => ../opencensus replace go.opentelemetry.io/otel/example/otel-collector => ./ -replace go.opentelemetry.io/otel/example/prom-collector => ../prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ../prometheus replace go.opentelemetry.io/otel/example/zipkin => ../zipkin diff --git a/example/passthrough/go.mod b/example/passthrough/go.mod index 0bab8c3ca85..b738a24061b 100644 --- a/example/passthrough/go.mod +++ b/example/passthrough/go.mod @@ -29,8 +29,6 @@ replace go.opentelemetry.io/otel/example/otel-collector => ../otel-collector replace go.opentelemetry.io/otel/example/passthrough => ./ -replace go.opentelemetry.io/otel/example/prom-collector => ../prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ../prometheus replace go.opentelemetry.io/otel/example/zipkin => ../zipkin diff --git a/example/prometheus/go.mod b/example/prometheus/go.mod index 510707da899..b30c60e547f 100644 --- a/example/prometheus/go.mod +++ b/example/prometheus/go.mod @@ -27,8 +27,6 @@ replace go.opentelemetry.io/otel/example/opencensus => ../opencensus replace go.opentelemetry.io/otel/example/otel-collector => ../otel-collector -replace go.opentelemetry.io/otel/example/prom-collector => ../prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ./ replace go.opentelemetry.io/otel/example/zipkin => ../zipkin diff --git a/example/zipkin/go.mod b/example/zipkin/go.mod index 3a09af7e14f..c47de71dfda 100644 --- a/example/zipkin/go.mod +++ b/example/zipkin/go.mod @@ -27,8 +27,6 @@ replace go.opentelemetry.io/otel/example/opencensus => ../opencensus replace go.opentelemetry.io/otel/example/otel-collector => ../otel-collector -replace go.opentelemetry.io/otel/example/prom-collector => ../prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ../prometheus replace go.opentelemetry.io/otel/example/zipkin => ./ diff --git a/exporters/jaeger/go.mod b/exporters/jaeger/go.mod index 165ded9b2e3..265bbc92eb3 100644 --- a/exporters/jaeger/go.mod +++ b/exporters/jaeger/go.mod @@ -22,8 +22,6 @@ replace go.opentelemetry.io/otel/example/opencensus => ../../example/opencensus replace go.opentelemetry.io/otel/example/otel-collector => ../../example/otel-collector -replace go.opentelemetry.io/otel/example/prom-collector => ../../example/prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ../../example/prometheus replace go.opentelemetry.io/otel/example/zipkin => ../../example/zipkin diff --git a/exporters/otlp/otlpmetric/otlpmetricgrpc/go.mod b/exporters/otlp/otlpmetric/otlpmetricgrpc/go.mod index 9023dc3014f..cba505c7944 100644 --- a/exporters/otlp/otlpmetric/otlpmetricgrpc/go.mod +++ b/exporters/otlp/otlpmetric/otlpmetricgrpc/go.mod @@ -42,8 +42,6 @@ replace go.opentelemetry.io/otel/example/otel-collector => ../../../../example/o replace go.opentelemetry.io/otel/example/passthrough => ../../../../example/passthrough -replace go.opentelemetry.io/otel/example/prom-collector => ../../../../example/prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ../../../../example/prometheus replace go.opentelemetry.io/otel/example/zipkin => ../../../../example/zipkin diff --git a/exporters/otlp/otlpmetric/otlpmetrichttp/go.mod b/exporters/otlp/otlpmetric/otlpmetrichttp/go.mod index 8fe02304d3c..a91939eff01 100644 --- a/exporters/otlp/otlpmetric/otlpmetrichttp/go.mod +++ b/exporters/otlp/otlpmetric/otlpmetrichttp/go.mod @@ -37,14 +37,10 @@ replace go.opentelemetry.io/otel/example/otel-collector => ../../../../example/o replace go.opentelemetry.io/otel/example/passthrough => ../../../../example/passthrough -replace go.opentelemetry.io/otel/example/prom-collector => ../../../../example/prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ../../../../example/prometheus replace go.opentelemetry.io/otel/example/zipkin => ../../../../example/zipkin -replace go.opentelemetry.io/otel/exporters/metric/prometheus => ../../../metric/prometheus - replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp => ./ replace go.opentelemetry.io/otel/exporters/otlp/otlptrace => ../../otlptrace @@ -53,10 +49,6 @@ replace go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc => ../.. replace go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp => ../../otlptrace/otlptracehttp -replace go.opentelemetry.io/otel/exporters/trace/jaeger => ../../../trace/jaeger - -replace go.opentelemetry.io/otel/exporters/trace/zipkin => ../../../trace/zipkin - replace go.opentelemetry.io/otel/internal/tools => ../../../../internal/tools replace go.opentelemetry.io/otel/sdk/export/metric => ../../../../sdk/export/metric diff --git a/exporters/otlp/otlptrace/go.mod b/exporters/otlp/otlptrace/go.mod index a722bfb6969..dd9eb1815aa 100644 --- a/exporters/otlp/otlptrace/go.mod +++ b/exporters/otlp/otlptrace/go.mod @@ -34,8 +34,6 @@ replace go.opentelemetry.io/otel/example/opencensus => ../../../example/opencens replace go.opentelemetry.io/otel/example/otel-collector => ../../../example/otel-collector -replace go.opentelemetry.io/otel/example/prom-collector => ../../../example/prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ../../../example/prometheus replace go.opentelemetry.io/otel/example/zipkin => ../../../example/zipkin diff --git a/exporters/otlp/otlptrace/otlptracegrpc/go.mod b/exporters/otlp/otlptrace/otlptracegrpc/go.mod index bbff4b4ab34..024bd30407c 100644 --- a/exporters/otlp/otlptrace/otlptracegrpc/go.mod +++ b/exporters/otlp/otlptrace/otlptracegrpc/go.mod @@ -37,8 +37,6 @@ replace go.opentelemetry.io/otel/example/opencensus => ../../../../example/openc replace go.opentelemetry.io/otel/example/otel-collector => ../../../../example/otel-collector -replace go.opentelemetry.io/otel/example/prom-collector => ../../../../example/prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ../../../../example/prometheus replace go.opentelemetry.io/otel/example/zipkin => ../../../../example/zipkin diff --git a/exporters/otlp/otlptrace/otlptracehttp/go.mod b/exporters/otlp/otlptrace/otlptracehttp/go.mod index 9a522d90550..fb3ca1c3429 100644 --- a/exporters/otlp/otlptrace/otlptracehttp/go.mod +++ b/exporters/otlp/otlptrace/otlptracehttp/go.mod @@ -31,8 +31,6 @@ replace go.opentelemetry.io/otel/example/otel-collector => ../../../../example/o replace go.opentelemetry.io/otel/example/passthrough => ../../../../example/passthrough -replace go.opentelemetry.io/otel/example/prom-collector => ../../../../example/prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ../../../../example/prometheus replace go.opentelemetry.io/otel/example/zipkin => ../../../../example/zipkin diff --git a/exporters/prometheus/go.mod b/exporters/prometheus/go.mod index 77519e04d3f..3d02af45d5f 100644 --- a/exporters/prometheus/go.mod +++ b/exporters/prometheus/go.mod @@ -27,8 +27,6 @@ replace go.opentelemetry.io/otel/example/otel-collector => ../../example/otel-co replace go.opentelemetry.io/otel/example/passthrough => ../../example/passthrough -replace go.opentelemetry.io/otel/example/prom-collector => ../../example/prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ../../example/prometheus replace go.opentelemetry.io/otel/example/zipkin => ../../example/zipkin diff --git a/exporters/stdout/stdoutmetric/go.mod b/exporters/stdout/stdoutmetric/go.mod index de0b27d97c7..07989e72e67 100644 --- a/exporters/stdout/stdoutmetric/go.mod +++ b/exporters/stdout/stdoutmetric/go.mod @@ -27,8 +27,6 @@ replace go.opentelemetry.io/otel/example/opencensus => ../../../example/opencens replace go.opentelemetry.io/otel/example/otel-collector => ../../../example/otel-collector -replace go.opentelemetry.io/otel/example/prom-collector => ../../example/prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ../../../example/prometheus replace go.opentelemetry.io/otel/example/zipkin => ../../../example/zipkin diff --git a/exporters/stdout/stdouttrace/go.mod b/exporters/stdout/stdouttrace/go.mod index 1848b11100f..88d59d2d605 100644 --- a/exporters/stdout/stdouttrace/go.mod +++ b/exporters/stdout/stdouttrace/go.mod @@ -26,8 +26,6 @@ replace go.opentelemetry.io/otel/example/opencensus => ../../../example/opencens replace go.opentelemetry.io/otel/example/otel-collector => ../../../example/otel-collector -replace go.opentelemetry.io/otel/example/prom-collector => ../../example/prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ../../../example/prometheus replace go.opentelemetry.io/otel/example/zipkin => ../../../example/zipkin diff --git a/exporters/zipkin/go.mod b/exporters/zipkin/go.mod index 2d5e28d19ef..c9d56ed8d03 100644 --- a/exporters/zipkin/go.mod +++ b/exporters/zipkin/go.mod @@ -23,8 +23,6 @@ replace go.opentelemetry.io/otel/example/opencensus => ../../example/opencensus replace go.opentelemetry.io/otel/example/otel-collector => ../../example/otel-collector -replace go.opentelemetry.io/otel/example/prom-collector => ../../example/prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ../../example/prometheus replace go.opentelemetry.io/otel/example/zipkin => ../../example/zipkin diff --git a/go.mod b/go.mod index 0065f9e3e0c..f37c9bf371a 100644 --- a/go.mod +++ b/go.mod @@ -24,8 +24,6 @@ replace go.opentelemetry.io/otel/example/opencensus => ./example/opencensus replace go.opentelemetry.io/otel/example/otel-collector => ./example/otel-collector -replace go.opentelemetry.io/otel/example/prom-collector => ./example/prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ./example/prometheus replace go.opentelemetry.io/otel/example/zipkin => ./example/zipkin diff --git a/internal/metric/go.mod b/internal/metric/go.mod index 1b8af6b8d15..7e92e2dcb10 100644 --- a/internal/metric/go.mod +++ b/internal/metric/go.mod @@ -28,8 +28,6 @@ replace go.opentelemetry.io/otel/example/otel-collector => ../../example/otel-co replace go.opentelemetry.io/otel/example/passthrough => ../../example/passthrough -replace go.opentelemetry.io/otel/example/prom-collector => ../../example/prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ../../example/prometheus replace go.opentelemetry.io/otel/example/zipkin => ../../example/zipkin diff --git a/metric/go.mod b/metric/go.mod index 839b03b4c98..17780384f4c 100644 --- a/metric/go.mod +++ b/metric/go.mod @@ -16,8 +16,6 @@ replace go.opentelemetry.io/otel/example/opencensus => ../example/opencensus replace go.opentelemetry.io/otel/example/otel-collector => ../example/otel-collector -replace go.opentelemetry.io/otel/example/prom-collector => ../example/prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ../example/prometheus replace go.opentelemetry.io/otel/example/zipkin => ../example/zipkin diff --git a/sdk/export/metric/go.mod b/sdk/export/metric/go.mod index 6affa3e5e5e..8f728464774 100644 --- a/sdk/export/metric/go.mod +++ b/sdk/export/metric/go.mod @@ -17,8 +17,6 @@ replace go.opentelemetry.io/otel/example/opencensus => ../../../example/opencens replace go.opentelemetry.io/otel/example/otel-collector => ../../../example/otel-collector -replace go.opentelemetry.io/otel/example/prom-collector => ../../../example/prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ../../../example/prometheus replace go.opentelemetry.io/otel/example/zipkin => ../../../example/zipkin diff --git a/sdk/go.mod b/sdk/go.mod index 403cc024da0..bad9bd0c41c 100644 --- a/sdk/go.mod +++ b/sdk/go.mod @@ -25,8 +25,6 @@ replace go.opentelemetry.io/otel/example/opencensus => ../example/opencensus replace go.opentelemetry.io/otel/example/otel-collector => ../example/otel-collector -replace go.opentelemetry.io/otel/example/prom-collector => ../example/prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ../example/prometheus replace go.opentelemetry.io/otel/example/zipkin => ../example/zipkin diff --git a/sdk/metric/go.mod b/sdk/metric/go.mod index a027704356f..fc70fcf873e 100644 --- a/sdk/metric/go.mod +++ b/sdk/metric/go.mod @@ -16,8 +16,6 @@ replace go.opentelemetry.io/otel/example/opencensus => ../../example/opencensus replace go.opentelemetry.io/otel/example/otel-collector => ../../example/otel-collector -replace go.opentelemetry.io/otel/example/prom-collector => ../../example/prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ../../example/prometheus replace go.opentelemetry.io/otel/example/zipkin => ../../example/zipkin diff --git a/trace/go.mod b/trace/go.mod index 90174c5c617..e7a32932464 100644 --- a/trace/go.mod +++ b/trace/go.mod @@ -16,8 +16,6 @@ replace go.opentelemetry.io/otel/example/opencensus => ../example/opencensus replace go.opentelemetry.io/otel/example/otel-collector => ../example/otel-collector -replace go.opentelemetry.io/otel/example/prom-collector => ../example/prom-collector - replace go.opentelemetry.io/otel/example/prometheus => ../example/prometheus replace go.opentelemetry.io/otel/example/zipkin => ../example/zipkin From b66c9027776ed667c7a21f187a9a15416876225f Mon Sep 17 00:00:00 2001 From: Chester Cheung Date: Wed, 2 Mar 2022 23:13:43 +0800 Subject: [PATCH 03/29] Unify OTLP path parsing/default Logic (#2639) * unify otlp path parsing/default logic * add changelog * add license and unit test * remove else branch * increase unitt test coverage * add vanity import * Update exporters/otlp/internal/config.go Co-authored-by: Tyler Yahn * Update exporters/otlp/internal/config.go Co-authored-by: Tyler Yahn * Update exporters/otlp/internal/config.go Co-authored-by: Tyler Yahn * Update CHANGELOG.md Co-authored-by: Tyler Yahn * Update exporters/otlp/internal/config_test.go Co-authored-by: Tyler Yahn * Update exporters/otlp/internal/config_test.go Co-authored-by: Tyler Yahn * format the config_test.go * Update exporters/otlp/internal/config_test.go Co-authored-by: Sam Xie * Update exporters/otlp/internal/config_test.go Co-authored-by: Sam Xie * Update exporters/otlp/internal/config_test.go Co-authored-by: Sam Xie * Update exporters/otlp/internal/config_test.go Co-authored-by: Sam Xie * Update exporters/otlp/internal/config.go Co-authored-by: Sam Xie * Update exporters/otlp/internal/config.go Co-authored-by: Sam Xie * change URLPath to urlPath Co-authored-by: Tyler Yahn Co-authored-by: Sam Xie --- CHANGELOG.md | 1 + exporters/otlp/internal/config.go | 34 ++++++++ exporters/otlp/internal/config_test.go | 83 +++++++++++++++++++ .../otlpmetric/internal/otlpconfig/options.go | 15 +--- .../otlptrace/internal/otlpconfig/options.go | 15 +--- 5 files changed, 122 insertions(+), 26 deletions(-) create mode 100644 exporters/otlp/internal/config.go create mode 100644 exporters/otlp/internal/config_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 99f62c59cb6..73e1f723a65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - For tracestate's members, prepend the new element and remove the oldest one, which is over capacity (#2592) - Add event and link drop counts to the exported data from the `oltptrace` exporter. (#2601) +- Unify path cleaning functionally in the `otlpmetric` and `otlptrace` config. (#2639) - Change the debug message from the `sdk/trace.BatchSpanProcessor` to reflect the count is cumulative. (#2640) ### Fixed diff --git a/exporters/otlp/internal/config.go b/exporters/otlp/internal/config.go new file mode 100644 index 00000000000..b3fd45d9d31 --- /dev/null +++ b/exporters/otlp/internal/config.go @@ -0,0 +1,34 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package internal contains common functionality for all OTLP exporters. +package internal // import "go.opentelemetry.io/otel/exporters/otlp/internal" + +import ( + "fmt" + "path" + "strings" +) + +// CleanPath returns a path with all spaces trimmed and all redundancies removed. If urlPath is empty or cleaning it results in an empty string, defaultPath is returned instead. +func CleanPath(urlPath string, defaultPath string) string { + tmp := path.Clean(strings.TrimSpace(urlPath)) + if tmp == "." { + return defaultPath + } + if !path.IsAbs(tmp) { + tmp = fmt.Sprintf("/%s", tmp) + } + return tmp +} diff --git a/exporters/otlp/internal/config_test.go b/exporters/otlp/internal/config_test.go new file mode 100644 index 00000000000..92a819a1f2b --- /dev/null +++ b/exporters/otlp/internal/config_test.go @@ -0,0 +1,83 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package internal + +import "testing" + +func TestCleanPath(t *testing.T) { + type args struct { + urlPath string + defaultPath string + } + tests := []struct { + name string + args args + want string + }{ + { + name: "clean empty path", + args: args{ + urlPath: "", + defaultPath: "DefaultPath", + }, + want: "DefaultPath", + }, + { + name: "clean metrics path", + args: args{ + urlPath: "/prefix/v1/metrics", + defaultPath: "DefaultMetricsPath", + }, + want: "/prefix/v1/metrics", + }, + { + name: "clean traces path", + args: args{ + urlPath: "https://env_endpoint", + defaultPath: "DefaultTracesPath", + }, + want: "/https:/env_endpoint", + }, + { + name: "spaces trimmed", + args: args{ + urlPath: " /dir", + }, + want: "/dir", + }, + { + name: "clean path empty", + args: args{ + urlPath: "dir/..", + defaultPath: "DefaultTracesPath", + }, + want: "DefaultTracesPath", + }, + { + name: "make absolute", + args: args{ + urlPath: "dir/a", + }, + want: "/dir/a", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := CleanPath(tt.args.urlPath, tt.args.defaultPath); got != tt.want { + t.Errorf("CleanPath() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/exporters/otlp/otlpmetric/internal/otlpconfig/options.go b/exporters/otlp/otlpmetric/internal/otlpconfig/options.go index c2f442f998f..f2c8ee5d21a 100644 --- a/exporters/otlp/otlpmetric/internal/otlpconfig/options.go +++ b/exporters/otlp/otlpmetric/internal/otlpconfig/options.go @@ -17,8 +17,6 @@ package otlpconfig // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric import ( "crypto/tls" "fmt" - "path" - "strings" "time" "google.golang.org/grpc" @@ -27,6 +25,7 @@ import ( "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/encoding/gzip" + "go.opentelemetry.io/otel/exporters/otlp/internal" "go.opentelemetry.io/otel/exporters/otlp/internal/retry" ) @@ -90,17 +89,7 @@ func NewHTTPConfig(opts ...HTTPOption) Config { for _, opt := range opts { cfg = opt.ApplyHTTPOption(cfg) } - - tmp := strings.TrimSpace(cfg.Metrics.URLPath) - if tmp == "" { - tmp = DefaultMetricsPath - } else { - tmp = path.Clean(tmp) - if !path.IsAbs(tmp) { - tmp = fmt.Sprintf("/%s", tmp) - } - } - cfg.Metrics.URLPath = tmp + cfg.Metrics.URLPath = internal.CleanPath(cfg.Metrics.URLPath, DefaultMetricsPath) return cfg } diff --git a/exporters/otlp/otlptrace/internal/otlpconfig/options.go b/exporters/otlp/otlptrace/internal/otlpconfig/options.go index f874c146e25..56e83b85334 100644 --- a/exporters/otlp/otlptrace/internal/otlpconfig/options.go +++ b/exporters/otlp/otlptrace/internal/otlpconfig/options.go @@ -17,8 +17,6 @@ package otlpconfig // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/ import ( "crypto/tls" "fmt" - "path" - "strings" "time" "google.golang.org/grpc" @@ -27,6 +25,7 @@ import ( "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/encoding/gzip" + "go.opentelemetry.io/otel/exporters/otlp/internal" "go.opentelemetry.io/otel/exporters/otlp/internal/retry" ) @@ -83,17 +82,7 @@ func NewHTTPConfig(opts ...HTTPOption) Config { for _, opt := range opts { cfg = opt.ApplyHTTPOption(cfg) } - - tmp := strings.TrimSpace(cfg.Traces.URLPath) - if tmp == "" { - tmp = DefaultTracesPath - } else { - tmp = path.Clean(tmp) - if !path.IsAbs(tmp) { - tmp = fmt.Sprintf("/%s", tmp) - } - } - cfg.Traces.URLPath = tmp + cfg.Traces.URLPath = internal.CleanPath(cfg.Traces.URLPath, DefaultTracesPath) return cfg } From 18f4cb85ece82b12cb9bd9af02efe2a47bd8f76e Mon Sep 17 00:00:00 2001 From: Aaron Clawson Date: Wed, 2 Mar 2022 09:50:29 -0600 Subject: [PATCH 04/29] [API EPIC 4/4] Fix tests and examples (#2587) * Empty All of the metrics dir * Add instrument api with documentation * Add a NoOp implementation. * Updated to the new config standard * Address PR comments * This change moves components to sdk/metrics The Moved components are: - metric/metrictest - metric/number - metric/internal/registry - metric/sdkapi * The SDK changes necessary to satasify the new api * This fixes the remaing tests. * Update changelog * refactor the Noop meter and instruments into one package. * Renamed pkg.Instruments to pkg.InstrumentProvider Co-authored-by: Aaron Clawson --- .github/dependabot.yml | 9 - CHANGELOG.md | 5 + bridge/opencensus/aggregation.go | 2 +- bridge/opencensus/exporter.go | 18 +- bridge/opencensus/exporter_test.go | 24 +- example/prometheus/main.go | 62 +- exporters/otlp/otlpmetric/exporter.go | 2 +- exporters/otlp/otlpmetric/exporter_test.go | 6 +- .../internal/metrictransform/metric.go | 2 +- .../internal/metrictransform/metric_test.go | 6 +- .../internal/otlpmetrictest/data.go | 6 +- .../internal/otlpmetrictest/otlptest.go | 35 +- .../otlpmetric/otlpmetricgrpc/example_test.go | 52 +- exporters/prometheus/prometheus.go | 4 +- exporters/prometheus/prometheus_test.go | 41 +- exporters/stdout/stdoutmetric/example_test.go | 31 +- exporters/stdout/stdoutmetric/metric.go | 2 +- exporters/stdout/stdoutmetric/metric_test.go | 18 +- internal/metric/async.go | 149 ----- internal/metric/global/benchmark_test.go | 41 -- internal/metric/global/internal_test.go | 40 -- internal/metric/global/meter.go | 287 ---------- internal/metric/global/meter_test.go | 253 -------- internal/metric/global/metric.go | 66 --- internal/metric/global/registry_test.go | 131 ----- internal/metric/global/state_test.go | 45 -- internal/metric/go.mod | 73 --- internal/metric/go.sum | 18 - metric/config.go | 65 +-- metric/doc.go | 44 -- metric/example_test.go | 116 ++++ metric/global/metric.go | 49 -- metric/global/metric_test.go | 42 -- metric/go.mod | 11 +- metric/go.sum | 4 - .../instrument/asyncfloat64/asyncfloat64.go | 70 +++ metric/instrument/asyncint64/asyncint64.go | 70 +++ metric/instrument/config.go | 69 +++ .../instrument.go} | 28 +- metric/instrument/syncfloat64/syncfloat64.go | 56 ++ metric/instrument/syncint64/syncint64.go | 56 ++ metric/meter.go | 60 ++ metric/metric.go | 538 ------------------ metric/metric_instrument.go | 464 --------------- metric/metric_test.go | 497 ---------------- metric/metrictest/meter.go | 290 ---------- metric/nonrecording/instruments.go | 138 +++++ metric/nonrecording/meter.go | 64 +++ metric/noop.go | 30 - sdk/export/metric/aggregation/aggregation.go | 2 +- sdk/export/metric/go.mod | 1 - sdk/export/metric/metric.go | 2 +- sdk/metric/aggregator/aggregator.go | 4 +- sdk/metric/aggregator/aggregator_test.go | 6 +- sdk/metric/aggregator/aggregatortest/test.go | 6 +- .../aggregator/histogram/benchmark_test.go | 4 +- sdk/metric/aggregator/histogram/histogram.go | 4 +- .../aggregator/histogram/histogram_test.go | 4 +- sdk/metric/aggregator/lastvalue/lastvalue.go | 4 +- .../aggregator/lastvalue/lastvalue_test.go | 4 +- sdk/metric/aggregator/sum/sum.go | 4 +- sdk/metric/aggregator/sum/sum_test.go | 4 +- sdk/metric/benchmark_test.go | 116 ++-- sdk/metric/controller/basic/controller.go | 7 +- .../controller/basic/controller_test.go | 100 ++-- sdk/metric/controller/basic/pull_test.go | 7 +- sdk/metric/controller/basic/push_test.go | 10 +- sdk/metric/correct_test.go | 329 ++++++----- sdk/metric/export/aggregation/aggregation.go | 2 +- sdk/metric/export/aggregation/temporality.go | 2 +- .../export/aggregation/temporality_test.go | 6 +- sdk/metric/export/metric.go | 2 +- sdk/metric/go.mod | 3 - sdk/metric/histogram_stress_test.go | 6 +- .../metric}/metrictest/alignment_test.go | 0 sdk/metric/metrictest/meter.go | 56 ++ {metric => sdk/metric}/number/doc.go | 2 +- {metric => sdk/metric}/number/kind_string.go | 0 {metric => sdk/metric}/number/number.go | 2 +- {metric => sdk/metric}/number/number_test.go | 0 sdk/metric/processor/basic/basic.go | 2 +- sdk/metric/processor/basic/basic_test.go | 23 +- sdk/metric/processor/processortest/test.go | 2 +- .../processor/processortest/test_test.go | 28 +- sdk/metric/processor/reducer/reducer.go | 2 +- sdk/metric/processor/reducer/reducer_test.go | 31 +- {internal => sdk}/metric/registry/doc.go | 2 +- {internal => sdk}/metric/registry/registry.go | 25 +- .../metric/registry/registry_test.go | 41 +- sdk/metric/sdk.go | 328 ++++------- {metric => sdk/metric}/sdkapi/descriptor.go | 4 +- .../metric}/sdkapi/descriptor_test.go | 2 +- .../metric}/sdkapi/instrumentkind.go | 2 +- .../metric}/sdkapi/instrumentkind_string.go | 0 .../metric}/sdkapi/instrumentkind_test.go | 2 +- {metric => sdk/metric}/sdkapi/noop.go | 31 +- {metric => sdk/metric}/sdkapi/sdkapi.go | 21 +- {metric => sdk/metric}/sdkapi/sdkapi_test.go | 2 +- sdk/metric/sdkapi/wrap.go | 181 ++++++ sdk/metric/selector/simple/simple.go | 2 +- sdk/metric/selector/simple/simple_test.go | 6 +- sdk/metric/stress_test.go | 502 ---------------- 102 files changed, 1722 insertions(+), 4405 deletions(-) delete mode 100644 internal/metric/async.go delete mode 100644 internal/metric/global/benchmark_test.go delete mode 100644 internal/metric/global/internal_test.go delete mode 100644 internal/metric/global/meter.go delete mode 100644 internal/metric/global/meter_test.go delete mode 100644 internal/metric/global/metric.go delete mode 100644 internal/metric/global/registry_test.go delete mode 100644 internal/metric/global/state_test.go delete mode 100644 internal/metric/go.mod delete mode 100644 internal/metric/go.sum create mode 100644 metric/example_test.go delete mode 100644 metric/global/metric.go delete mode 100644 metric/global/metric_test.go create mode 100644 metric/instrument/asyncfloat64/asyncfloat64.go create mode 100644 metric/instrument/asyncint64/asyncint64.go create mode 100644 metric/instrument/config.go rename metric/{noop_test.go => instrument/instrument.go} (54%) create mode 100644 metric/instrument/syncfloat64/syncfloat64.go create mode 100644 metric/instrument/syncint64/syncint64.go create mode 100644 metric/meter.go delete mode 100644 metric/metric.go delete mode 100644 metric/metric_instrument.go delete mode 100644 metric/metric_test.go delete mode 100644 metric/metrictest/meter.go create mode 100644 metric/nonrecording/instruments.go create mode 100644 metric/nonrecording/meter.go delete mode 100644 metric/noop.go rename {metric => sdk/metric}/metrictest/alignment_test.go (100%) create mode 100644 sdk/metric/metrictest/meter.go rename {metric => sdk/metric}/number/doc.go (92%) rename {metric => sdk/metric}/number/kind_string.go (100%) rename {metric => sdk/metric}/number/number.go (99%) rename {metric => sdk/metric}/number/number_test.go (100%) rename {internal => sdk}/metric/registry/doc.go (92%) rename {internal => sdk}/metric/registry/registry.go (86%) rename {internal => sdk}/metric/registry/registry_test.go (71%) rename {metric => sdk/metric}/sdkapi/descriptor.go (94%) rename {metric => sdk/metric}/sdkapi/descriptor_test.go (96%) rename {metric => sdk/metric}/sdkapi/instrumentkind.go (97%) rename {metric => sdk/metric}/sdkapi/instrumentkind_string.go (100%) rename {metric => sdk/metric}/sdkapi/instrumentkind_test.go (96%) rename {metric => sdk/metric}/sdkapi/noop.go (71%) rename {metric => sdk/metric}/sdkapi/sdkapi.go (90%) rename {metric => sdk/metric}/sdkapi/sdkapi_test.go (96%) create mode 100644 sdk/metric/sdkapi/wrap.go delete mode 100644 sdk/metric/stress_test.go diff --git a/.github/dependabot.yml b/.github/dependabot.yml index ca2daee0cbd..5e4fc315deb 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -227,15 +227,6 @@ updates: schedule: day: sunday interval: weekly - - package-ecosystem: gomod - directory: /internal/metric - labels: - - dependencies - - go - - "Skip Changelog" - schedule: - day: sunday - interval: weekly - package-ecosystem: gomod directory: /internal/tools labels: diff --git a/CHANGELOG.md b/CHANGELOG.md index 73e1f723a65..30b4333441d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased] +### ⚠️ Notice ⚠️ + +This update is a breaking change of the unstable Metrics API. Code instrumented with the `go.opentelemetry.io/otel/metric` <= v0.27.0 will need to be modified. + ### Added - Added support to configure the span limits with environment variables. @@ -24,6 +28,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - For tracestate's members, prepend the new element and remove the oldest one, which is over capacity (#2592) - Add event and link drop counts to the exported data from the `oltptrace` exporter. (#2601) +- The metrics API has been significantly changed. (#2587) - Unify path cleaning functionally in the `otlpmetric` and `otlptrace` config. (#2639) - Change the debug message from the `sdk/trace.BatchSpanProcessor` to reflect the count is cumulative. (#2640) diff --git a/bridge/opencensus/aggregation.go b/bridge/opencensus/aggregation.go index 3d88f7589a4..99d2b07afad 100644 --- a/bridge/opencensus/aggregation.go +++ b/bridge/opencensus/aggregation.go @@ -21,8 +21,8 @@ import ( "go.opencensus.io/metric/metricdata" - "go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/number" ) var ( diff --git a/bridge/opencensus/exporter.go b/bridge/opencensus/exporter.go index bdc22eced73..d40ddc9d665 100644 --- a/bridge/opencensus/exporter.go +++ b/bridge/opencensus/exporter.go @@ -27,13 +27,13 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" + "go.opentelemetry.io/otel/metric/instrument" "go.opentelemetry.io/otel/metric/unit" "go.opentelemetry.io/otel/sdk/instrumentation" "go.opentelemetry.io/otel/sdk/metric/export" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/number" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" "go.opentelemetry.io/otel/sdk/resource" ) @@ -170,17 +170,17 @@ func convertDescriptor(ocDescriptor metricdata.Descriptor) (sdkapi.Descriptor, e // Includes TypeGaugeDistribution, TypeCumulativeDistribution, TypeSummary return sdkapi.Descriptor{}, fmt.Errorf("%w; descriptor type: %v", errConversion, ocDescriptor.Type) } - opts := []metric.InstrumentOption{ - metric.WithDescription(ocDescriptor.Description), + opts := []instrument.Option{ + instrument.WithDescription(ocDescriptor.Description), } switch ocDescriptor.Unit { case metricdata.UnitDimensionless: - opts = append(opts, metric.WithUnit(unit.Dimensionless)) + opts = append(opts, instrument.WithUnit(unit.Dimensionless)) case metricdata.UnitBytes: - opts = append(opts, metric.WithUnit(unit.Bytes)) + opts = append(opts, instrument.WithUnit(unit.Bytes)) case metricdata.UnitMilliseconds: - opts = append(opts, metric.WithUnit(unit.Milliseconds)) + opts = append(opts, instrument.WithUnit(unit.Milliseconds)) } - cfg := metric.NewInstrumentConfig(opts...) + cfg := instrument.NewConfig(opts...) return sdkapi.NewDescriptor(ocDescriptor.Name, ikind, nkind, cfg.Description(), cfg.Unit()), nil } diff --git a/bridge/opencensus/exporter_test.go b/bridge/opencensus/exporter_test.go index 8fe6893477e..79e195c1f6c 100644 --- a/bridge/opencensus/exporter_test.go +++ b/bridge/opencensus/exporter_test.go @@ -26,15 +26,15 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/metrictest" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" + "go.opentelemetry.io/otel/metric/instrument" "go.opentelemetry.io/otel/metric/unit" "go.opentelemetry.io/otel/sdk/instrumentation" "go.opentelemetry.io/otel/sdk/metric/controller/controllertest" "go.opentelemetry.io/otel/sdk/metric/export" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/metrictest" + "go.opentelemetry.io/otel/sdk/metric/number" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" "go.opentelemetry.io/otel/sdk/resource" ) @@ -400,8 +400,8 @@ func TestConvertDescriptor(t *testing.T) { "foo", sdkapi.GaugeObserverInstrumentKind, number.Int64Kind, - metric.WithDescription("bar"), - metric.WithUnit(unit.Bytes), + instrument.WithDescription("bar"), + instrument.WithUnit(unit.Bytes), ), }, { @@ -416,8 +416,8 @@ func TestConvertDescriptor(t *testing.T) { "foo", sdkapi.GaugeObserverInstrumentKind, number.Float64Kind, - metric.WithDescription("bar"), - metric.WithUnit(unit.Milliseconds), + instrument.WithDescription("bar"), + instrument.WithUnit(unit.Milliseconds), ), }, { @@ -432,8 +432,8 @@ func TestConvertDescriptor(t *testing.T) { "foo", sdkapi.CounterObserverInstrumentKind, number.Int64Kind, - metric.WithDescription("bar"), - metric.WithUnit(unit.Dimensionless), + instrument.WithDescription("bar"), + instrument.WithUnit(unit.Dimensionless), ), }, { @@ -448,8 +448,8 @@ func TestConvertDescriptor(t *testing.T) { "foo", sdkapi.CounterObserverInstrumentKind, number.Float64Kind, - metric.WithDescription("bar"), - metric.WithUnit(unit.Dimensionless), + instrument.WithDescription("bar"), + instrument.WithUnit(unit.Dimensionless), ), }, { diff --git a/example/prometheus/main.go b/example/prometheus/main.go index 8a1248a358e..12148d2595f 100644 --- a/example/prometheus/main.go +++ b/example/prometheus/main.go @@ -25,7 +25,7 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/exporters/prometheus" "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/global" + "go.opentelemetry.io/otel/metric/instrument" "go.opentelemetry.io/otel/sdk/metric/aggregator/histogram" controller "go.opentelemetry.io/otel/sdk/metric/controller/basic" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" @@ -35,6 +35,9 @@ import ( var ( lemonsKey = attribute.Key("ex.com/lemons") + + // TODO Bring back Global package + meterProvider metric.MeterProvider ) func initMeter() { @@ -54,7 +57,9 @@ func initMeter() { if err != nil { log.Panicf("failed to initialize prometheus exporter %v", err) } - global.SetMeterProvider(exporter.MeterProvider()) + // TODO Bring back Global package + // global.SetMeterProvider(exporter.MeterProvider()) + meterProvider = exporter.MeterProvider() http.HandleFunc("/", exporter.ServeHTTP) go func() { @@ -67,23 +72,33 @@ func initMeter() { func main() { initMeter() - meter := global.Meter("ex.com/basic") + // TODO Bring back Global package + // meter := global.Meter("ex.com/basic") + meter := meterProvider.Meter("ex.com/basic") observerLock := new(sync.RWMutex) observerValueToReport := new(float64) observerLabelsToReport := new([]attribute.KeyValue) - cb := func(_ context.Context, result metric.Float64ObserverResult) { + + gaugeObserver, err := meter.AsyncFloat64().Gauge("ex.com.one") + if err != nil { + log.Panicf("failed to initialize instrument: %v", err) + } + _ = meter.RegisterCallback([]instrument.Asynchronous{gaugeObserver}, func(ctx context.Context) { (*observerLock).RLock() value := *observerValueToReport labels := *observerLabelsToReport (*observerLock).RUnlock() - result.Observe(value, labels...) - } - _ = metric.Must(meter).NewFloat64GaugeObserver("ex.com.one", cb, - metric.WithDescription("A GaugeObserver set to 1.0"), - ) + gaugeObserver.Observe(ctx, value, labels...) + }) - histogram := metric.Must(meter).NewFloat64Histogram("ex.com.two") - counter := metric.Must(meter).NewFloat64Counter("ex.com.three") + histogram, err := meter.SyncFloat64().Histogram("ex.com.two") + if err != nil { + log.Panicf("failed to initialize instrument: %v", err) + } + counter, err := meter.SyncFloat64().Counter("ex.com.three") + if err != nil { + log.Panicf("failed to initialize instrument: %v", err) + } commonLabels := []attribute.KeyValue{lemonsKey.Int(10), attribute.String("A", "1"), attribute.String("B", "2"), attribute.String("C", "3")} notSoCommonLabels := []attribute.KeyValue{lemonsKey.Int(13)} @@ -94,12 +109,9 @@ func main() { *observerValueToReport = 1.0 *observerLabelsToReport = commonLabels (*observerLock).Unlock() - meter.RecordBatch( - ctx, - commonLabels, - histogram.Measurement(2.0), - counter.Measurement(12.0), - ) + + histogram.Record(ctx, 2.0, commonLabels...) + counter.Add(ctx, 12.0, commonLabels...) time.Sleep(5 * time.Second) @@ -107,12 +119,8 @@ func main() { *observerValueToReport = 1.0 *observerLabelsToReport = notSoCommonLabels (*observerLock).Unlock() - meter.RecordBatch( - ctx, - notSoCommonLabels, - histogram.Measurement(2.0), - counter.Measurement(22.0), - ) + histogram.Record(ctx, 2.0, notSoCommonLabels...) + counter.Add(ctx, 22.0, notSoCommonLabels...) time.Sleep(5 * time.Second) @@ -120,12 +128,8 @@ func main() { *observerValueToReport = 13.0 *observerLabelsToReport = commonLabels (*observerLock).Unlock() - meter.RecordBatch( - ctx, - commonLabels, - histogram.Measurement(12.0), - counter.Measurement(13.0), - ) + histogram.Record(ctx, 12.0, commonLabels...) + counter.Add(ctx, 13.0, commonLabels...) fmt.Println("Example finished updating, please visit :2222") diff --git a/exporters/otlp/otlpmetric/exporter.go b/exporters/otlp/otlpmetric/exporter.go index 36c41cce762..caf21eaf2a3 100644 --- a/exporters/otlp/otlpmetric/exporter.go +++ b/exporters/otlp/otlpmetric/exporter.go @@ -20,9 +20,9 @@ import ( "sync" "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal/metrictransform" - "go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/sdk/metric/export" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" "go.opentelemetry.io/otel/sdk/resource" ) diff --git a/exporters/otlp/otlpmetric/exporter_test.go b/exporters/otlp/otlpmetric/exporter_test.go index 31e3f3e6848..b8ba3dce95e 100644 --- a/exporters/otlp/otlpmetric/exporter_test.go +++ b/exporters/otlp/otlpmetric/exporter_test.go @@ -29,16 +29,16 @@ import ( "go.opentelemetry.io/otel/exporters/otlp/otlpmetric" "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal/metrictransform" "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/metrictest" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/sdk/instrumentation" "go.opentelemetry.io/otel/sdk/metric/aggregator" "go.opentelemetry.io/otel/sdk/metric/aggregator/histogram" "go.opentelemetry.io/otel/sdk/metric/aggregator/sum" "go.opentelemetry.io/otel/sdk/metric/export" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/metrictest" + "go.opentelemetry.io/otel/sdk/metric/number" "go.opentelemetry.io/otel/sdk/metric/processor/processortest" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" "go.opentelemetry.io/otel/sdk/resource" commonpb "go.opentelemetry.io/proto/otlp/common/v1" metricpb "go.opentelemetry.io/proto/otlp/metrics/v1" diff --git a/exporters/otlp/otlpmetric/internal/metrictransform/metric.go b/exporters/otlp/otlpmetric/internal/metrictransform/metric.go index e1ba26dccd0..002bb64a997 100644 --- a/exporters/otlp/otlpmetric/internal/metrictransform/metric.go +++ b/exporters/otlp/otlpmetric/internal/metrictransform/metric.go @@ -24,10 +24,10 @@ import ( "sync" "time" - "go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/sdk/instrumentation" "go.opentelemetry.io/otel/sdk/metric/export" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/number" "go.opentelemetry.io/otel/sdk/resource" commonpb "go.opentelemetry.io/proto/otlp/common/v1" metricpb "go.opentelemetry.io/proto/otlp/metrics/v1" diff --git a/exporters/otlp/otlpmetric/internal/metrictransform/metric_test.go b/exporters/otlp/otlpmetric/internal/metrictransform/metric_test.go index 7b5b801eb6b..d8f2a1c8b62 100644 --- a/exporters/otlp/otlpmetric/internal/metrictransform/metric_test.go +++ b/exporters/otlp/otlpmetric/internal/metrictransform/metric_test.go @@ -25,14 +25,14 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric/metrictest" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/sdk/metric/aggregator" "go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue" "go.opentelemetry.io/otel/sdk/metric/aggregator/sum" "go.opentelemetry.io/otel/sdk/metric/export" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/metrictest" + "go.opentelemetry.io/otel/sdk/metric/number" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" commonpb "go.opentelemetry.io/proto/otlp/common/v1" metricpb "go.opentelemetry.io/proto/otlp/metrics/v1" ) diff --git a/exporters/otlp/otlpmetric/internal/otlpmetrictest/data.go b/exporters/otlp/otlpmetric/internal/otlpmetrictest/data.go index cc3f7871598..2da921f142c 100644 --- a/exporters/otlp/otlpmetric/internal/otlpmetrictest/data.go +++ b/exporters/otlp/otlpmetric/internal/otlpmetrictest/data.go @@ -20,13 +20,13 @@ import ( "time" "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric/metrictest" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/sdk/instrumentation" "go.opentelemetry.io/otel/sdk/metric/aggregator/sum" "go.opentelemetry.io/otel/sdk/metric/export" + "go.opentelemetry.io/otel/sdk/metric/metrictest" + "go.opentelemetry.io/otel/sdk/metric/number" "go.opentelemetry.io/otel/sdk/metric/processor/processortest" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" ) // OneRecordReader is a Reader that returns just one diff --git a/exporters/otlp/otlpmetric/internal/otlpmetrictest/otlptest.go b/exporters/otlp/otlpmetric/internal/otlpmetrictest/otlptest.go index 53af9d5565a..524cb774588 100644 --- a/exporters/otlp/otlpmetric/internal/otlpmetrictest/otlptest.go +++ b/exporters/otlp/otlpmetric/internal/otlpmetrictest/otlptest.go @@ -25,12 +25,12 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/exporters/otlp/otlpmetric" - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" + "go.opentelemetry.io/otel/metric/instrument" controller "go.opentelemetry.io/otel/sdk/metric/controller/basic" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/number" processor "go.opentelemetry.io/otel/sdk/metric/processor/basic" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" "go.opentelemetry.io/otel/sdk/metric/selector/simple" metricpb "go.opentelemetry.io/proto/otlp/metrics/v1" ) @@ -63,34 +63,37 @@ func RunEndToEndTest(ctx context.Context, t *testing.T, exp *otlpmetric.Exporter case sdkapi.CounterInstrumentKind: switch data.nKind { case number.Int64Kind: - metric.Must(meter).NewInt64Counter(name).Add(ctx, data.val, labels...) + c, _ := meter.SyncInt64().Counter(name) + c.Add(ctx, data.val, labels...) case number.Float64Kind: - metric.Must(meter).NewFloat64Counter(name).Add(ctx, float64(data.val), labels...) + c, _ := meter.SyncFloat64().Counter(name) + c.Add(ctx, float64(data.val), labels...) default: assert.Failf(t, "unsupported number testing kind", data.nKind.String()) } case sdkapi.HistogramInstrumentKind: switch data.nKind { case number.Int64Kind: - metric.Must(meter).NewInt64Histogram(name).Record(ctx, data.val, labels...) + c, _ := meter.SyncInt64().Histogram(name) + c.Record(ctx, data.val, labels...) case number.Float64Kind: - metric.Must(meter).NewFloat64Histogram(name).Record(ctx, float64(data.val), labels...) + c, _ := meter.SyncFloat64().Histogram(name) + c.Record(ctx, float64(data.val), labels...) default: assert.Failf(t, "unsupported number testing kind", data.nKind.String()) } case sdkapi.GaugeObserverInstrumentKind: switch data.nKind { case number.Int64Kind: - metric.Must(meter).NewInt64GaugeObserver(name, - func(_ context.Context, result metric.Int64ObserverResult) { - result.Observe(data.val, labels...) - }, - ) + g, _ := meter.AsyncInt64().Gauge(name) + _ = meter.RegisterCallback([]instrument.Asynchronous{g}, func(ctx context.Context) { + g.Observe(ctx, data.val, labels...) + }) case number.Float64Kind: - callback := func(v float64) metric.Float64ObserverFunc { - return metric.Float64ObserverFunc(func(_ context.Context, result metric.Float64ObserverResult) { result.Observe(v, labels...) }) - }(float64(data.val)) - metric.Must(meter).NewFloat64GaugeObserver(name, callback) + g, _ := meter.AsyncFloat64().Gauge(name) + _ = meter.RegisterCallback([]instrument.Asynchronous{g}, func(ctx context.Context) { + g.Observe(ctx, float64(data.val), labels...) + }) default: assert.Failf(t, "unsupported number testing kind", data.nKind.String()) } diff --git a/exporters/otlp/otlpmetric/otlpmetricgrpc/example_test.go b/exporters/otlp/otlpmetric/otlpmetricgrpc/example_test.go index f37c39095f7..fe0866b7af5 100644 --- a/exporters/otlp/otlpmetric/otlpmetricgrpc/example_test.go +++ b/exporters/otlp/otlpmetric/otlpmetricgrpc/example_test.go @@ -24,8 +24,7 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/exporters/otlp/otlpmetric" "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc" - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/global" + "go.opentelemetry.io/otel/metric/instrument" controller "go.opentelemetry.io/otel/sdk/metric/controller/basic" processor "go.opentelemetry.io/otel/sdk/metric/processor/basic" "go.opentelemetry.io/otel/sdk/metric/selector/simple" @@ -54,7 +53,8 @@ func Example_insecure() { controller.WithExporter(exp), controller.WithCollectPeriod(2*time.Second), ) - global.SetMeterProvider(pusher) + // TODO Bring back Global package + // global.SetMeterProvider(pusher) if err := pusher.Start(ctx); err != nil { log.Fatalf("could not start metric controoler: %v", err) @@ -68,14 +68,16 @@ func Example_insecure() { } }() - meter := global.Meter("test-meter") + // TODO Bring Back Global package + // meter := global.Meter("go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc_test") + meter := pusher.Meter("go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc_test") // Recorder metric example - counter := metric.Must(meter). - NewFloat64Counter( - "an_important_metric", - metric.WithDescription("Measures the cumulative epicness of the app"), - ) + + counter, err := meter.SyncFloat64().Counter("an_important_metric", instrument.WithDescription("Measures the cumulative epicness of the app")) + if err != nil { + log.Fatalf("Failed to create the instrument: %v", err) + } for i := 0; i < 10; i++ { log.Printf("Doing really hard work (%d / 10)\n", i+1) @@ -113,7 +115,8 @@ func Example_withTLS() { controller.WithExporter(exp), controller.WithCollectPeriod(2*time.Second), ) - global.SetMeterProvider(pusher) + // TODO Bring back Global package + // global.SetMeterProvider(pusher) if err := pusher.Start(ctx); err != nil { log.Fatalf("could not start metric controoler: %v", err) @@ -128,14 +131,15 @@ func Example_withTLS() { } }() - meter := global.Meter("test-meter") + // TODO Bring back Global package + // meter := global.Meter("go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc_test") + meter := pusher.Meter("go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc_test") // Recorder metric example - counter := metric.Must(meter). - NewFloat64Counter( - "an_important_metric", - metric.WithDescription("Measures the cumulative epicness of the app"), - ) + counter, err := meter.SyncFloat64().Counter("an_important_metric", instrument.WithDescription("Measures the cumulative epicness of the app")) + if err != nil { + log.Fatalf("Failed to create the instrument: %v", err) + } for i := 0; i < 10; i++ { log.Printf("Doing really hard work (%d / 10)\n", i+1) @@ -170,7 +174,8 @@ func Example_withDifferentSignalCollectors() { controller.WithExporter(exp), controller.WithCollectPeriod(2*time.Second), ) - global.SetMeterProvider(pusher) + // TODO Bring back Global package + // global.SetMeterProvider(pusher) if err := pusher.Start(ctx); err != nil { log.Fatalf("could not start metric controoler: %v", err) @@ -184,14 +189,15 @@ func Example_withDifferentSignalCollectors() { } }() - meter := global.Meter("test-meter") + // TODO Bring back Global package + // meter := global.Meter("go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc_test") + meter := pusher.Meter("go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc_test") // Recorder metric example - counter := metric.Must(meter). - NewFloat64Counter( - "an_important_metric", - metric.WithDescription("Measures the cumulative epicness of the app"), - ) + counter, err := meter.SyncFloat64().Counter("an_important_metric", instrument.WithDescription("Measures the cumulative epicness of the app")) + if err != nil { + log.Fatalf("Failed to create the instrument: %v", err) + } for i := 0; i < 10; i++ { log.Printf("Doing really hard work (%d / 10)\n", i+1) diff --git a/exporters/prometheus/prometheus.go b/exporters/prometheus/prometheus.go index 08595526263..7d31514fb5f 100644 --- a/exporters/prometheus/prometheus.go +++ b/exporters/prometheus/prometheus.go @@ -29,12 +29,12 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/sdk/instrumentation" controller "go.opentelemetry.io/otel/sdk/metric/controller/basic" "go.opentelemetry.io/otel/sdk/metric/export" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/number" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" "go.opentelemetry.io/otel/sdk/resource" ) diff --git a/exporters/prometheus/prometheus_test.go b/exporters/prometheus/prometheus_test.go index b05d9232117..587c8633e78 100644 --- a/exporters/prometheus/prometheus_test.go +++ b/exporters/prometheus/prometheus_test.go @@ -26,7 +26,7 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/exporters/prometheus" - "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/metric/instrument" "go.opentelemetry.io/otel/sdk/metric/aggregator/histogram" controller "go.opentelemetry.io/otel/sdk/metric/controller/basic" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" @@ -107,9 +107,12 @@ func TestPrometheusExporter(t *testing.T) { require.NoError(t, err) meter := exporter.MeterProvider().Meter("test") - upDownCounter := metric.Must(meter).NewFloat64UpDownCounter("updowncounter") - counter := metric.Must(meter).NewFloat64Counter("counter") - histogram := metric.Must(meter).NewFloat64Histogram("histogram") + upDownCounter, err := meter.SyncFloat64().UpDownCounter("updowncounter") + require.NoError(t, err) + counter, err := meter.SyncFloat64().Counter("counter") + require.NoError(t, err) + histogram, err := meter.SyncFloat64().Histogram("histogram") + require.NoError(t, err) labels := []attribute.KeyValue{ attribute.Key("A").String("B"), @@ -124,9 +127,13 @@ func TestPrometheusExporter(t *testing.T) { expected = append(expected, expectCounter("counter", `counter{A="B",C="D",R="V"} 15.3`)) - _ = metric.Must(meter).NewInt64GaugeObserver("intgaugeobserver", func(_ context.Context, result metric.Int64ObserverResult) { - result.Observe(1, labels...) + gaugeObserver, err := meter.AsyncInt64().Gauge("intgaugeobserver") + require.NoError(t, err) + + err = meter.RegisterCallback([]instrument.Asynchronous{gaugeObserver}, func(ctx context.Context) { + gaugeObserver.Observe(ctx, 1, labels...) }) + require.NoError(t, err) expected = append(expected, expectGauge("intgaugeobserver", `intgaugeobserver{A="B",C="D",R="V"} 1`)) @@ -148,15 +155,23 @@ func TestPrometheusExporter(t *testing.T) { expected = append(expected, expectGauge("updowncounter", `updowncounter{A="B",C="D",R="V"} 6.8`)) - _ = metric.Must(meter).NewFloat64CounterObserver("floatcounterobserver", func(_ context.Context, result metric.Float64ObserverResult) { - result.Observe(7.7, labels...) + counterObserver, err := meter.AsyncFloat64().Counter("floatcounterobserver") + require.NoError(t, err) + + err = meter.RegisterCallback([]instrument.Asynchronous{counterObserver}, func(ctx context.Context) { + counterObserver.Observe(ctx, 7.7, labels...) }) + require.NoError(t, err) expected = append(expected, expectCounter("floatcounterobserver", `floatcounterobserver{A="B",C="D",R="V"} 7.7`)) - _ = metric.Must(meter).NewFloat64UpDownCounterObserver("floatupdowncounterobserver", func(_ context.Context, result metric.Float64ObserverResult) { - result.Observe(-7.7, labels...) + upDownCounterObserver, err := meter.AsyncFloat64().UpDownCounter("floatupdowncounterobserver") + require.NoError(t, err) + + err = meter.RegisterCallback([]instrument.Asynchronous{upDownCounterObserver}, func(ctx context.Context) { + upDownCounterObserver.Observe(ctx, -7.7, labels...) }) + require.NoError(t, err) expected = append(expected, expectGauge("floatupdowncounterobserver", `floatupdowncounterobserver{A="B",C="D",R="V"} -7.7`)) @@ -196,10 +211,8 @@ func TestPrometheusStatefulness(t *testing.T) { ctx := context.Background() - counter := metric.Must(meter).NewInt64Counter( - "a.counter", - metric.WithDescription("Counts things"), - ) + counter, err := meter.SyncInt64().Counter("a.counter", instrument.WithDescription("Counts things")) + require.NoError(t, err) counter.Add(ctx, 100, attribute.String("key", "value")) diff --git a/exporters/stdout/stdoutmetric/example_test.go b/exporters/stdout/stdoutmetric/example_test.go index c367b767040..1250a463a8c 100644 --- a/exporters/stdout/stdoutmetric/example_test.go +++ b/exporters/stdout/stdoutmetric/example_test.go @@ -21,7 +21,7 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/exporters/stdout/stdoutmetric" "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/global" + "go.opentelemetry.io/otel/metric/instrument/syncint64" controller "go.opentelemetry.io/otel/sdk/metric/controller/basic" processor "go.opentelemetry.io/otel/sdk/metric/processor/basic" "go.opentelemetry.io/otel/sdk/metric/selector/simple" @@ -33,13 +33,15 @@ const ( ) var ( - meter = global.GetMeterProvider().Meter( - instrumentationName, - metric.WithInstrumentationVersion(instrumentationVersion), - ) + // TODO Bring back Global package + // meter = global.GetMeterProvider().Meter( + // instrumentationName, + // metric.WithInstrumentationVersion(instrumentationVersion), + // ) + meter metric.Meter - loopCounter = metric.Must(meter).NewInt64Counter("function.loops") - paramValue = metric.Must(meter).NewInt64Histogram("function.param") + loopCounter syncint64.Counter + paramValue syncint64.Histogram nameKey = attribute.Key("function.name") ) @@ -80,7 +82,18 @@ func InstallExportPipeline(ctx context.Context) func() { if err = pusher.Start(ctx); err != nil { log.Fatalf("starting push controller: %v", err) } - global.SetMeterProvider(pusher) + // TODO Bring back Global package + // global.SetMeterProvider(pusher) + meter = pusher.Meter(instrumentationName, metric.WithInstrumentationVersion(instrumentationVersion)) + + loopCounter, err = meter.SyncInt64().Counter("function.loops") + if err != nil { + log.Fatalf("creating instrument: %v", err) + } + paramValue, err = meter.SyncInt64().Histogram("function.param") + if err != nil { + log.Fatalf("creating instrument: %v", err) + } return func() { if err := pusher.Stop(ctx); err != nil { @@ -92,7 +105,7 @@ func InstallExportPipeline(ctx context.Context) func() { func Example() { ctx := context.Background() - // Registers a meter Provider globally. + // TODO: Registers a meter Provider globally. cleanup := InstallExportPipeline(ctx) defer cleanup() diff --git a/exporters/stdout/stdoutmetric/metric.go b/exporters/stdout/stdoutmetric/metric.go index 56e449de20d..c816c035b1c 100644 --- a/exporters/stdout/stdoutmetric/metric.go +++ b/exporters/stdout/stdoutmetric/metric.go @@ -22,10 +22,10 @@ import ( "time" "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/sdk/instrumentation" "go.opentelemetry.io/otel/sdk/metric/export" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" "go.opentelemetry.io/otel/sdk/resource" ) diff --git a/exporters/stdout/stdoutmetric/metric_test.go b/exporters/stdout/stdoutmetric/metric_test.go index e9153fcfd0a..33e2831dbd7 100644 --- a/exporters/stdout/stdoutmetric/metric_test.go +++ b/exporters/stdout/stdoutmetric/metric_test.go @@ -101,7 +101,8 @@ func TestStdoutTimestamp(t *testing.T) { require.NoError(t, cont.Start(ctx)) meter := cont.Meter("test") - counter := metric.Must(meter).NewInt64Counter("name.lastvalue") + counter, err := meter.SyncInt64().Counter("name.lastvalue") + require.NoError(t, err) before := time.Now() // Ensure the timestamp is after before. @@ -137,7 +138,8 @@ func TestStdoutTimestamp(t *testing.T) { func TestStdoutCounterFormat(t *testing.T) { fix := newFixture(t) - counter := metric.Must(fix.meter).NewInt64Counter("name.sum") + counter, err := fix.meter.SyncInt64().Counter("name.sum") + require.NoError(t, err) counter.Add(fix.ctx, 123, attribute.String("A", "B"), attribute.String("C", "D")) require.NoError(t, fix.cont.Stop(fix.ctx)) @@ -148,7 +150,8 @@ func TestStdoutCounterFormat(t *testing.T) { func TestStdoutLastValueFormat(t *testing.T) { fix := newFixture(t) - counter := metric.Must(fix.meter).NewFloat64Counter("name.lastvalue") + counter, err := fix.meter.SyncFloat64().Counter("name.lastvalue") + require.NoError(t, err) counter.Add(fix.ctx, 123.456, attribute.String("A", "B"), attribute.String("C", "D")) require.NoError(t, fix.cont.Stop(fix.ctx)) @@ -159,7 +162,8 @@ func TestStdoutLastValueFormat(t *testing.T) { func TestStdoutHistogramFormat(t *testing.T) { fix := newFixture(t, stdoutmetric.WithPrettyPrint()) - inst := metric.Must(fix.meter).NewFloat64Histogram("name.histogram") + inst, err := fix.meter.SyncFloat64().Histogram("name.histogram") + require.NoError(t, err) for i := 0; i < 1000; i++ { inst.Record(fix.ctx, float64(i)+0.5, attribute.String("A", "B"), attribute.String("C", "D")) @@ -181,7 +185,8 @@ func TestStdoutNoData(t *testing.T) { t.Parallel() fix := newFixture(t) - _ = metric.Must(fix.meter).NewFloat64Counter(fmt.Sprint("name.", aggName)) + _, err := fix.meter.SyncFloat64().Counter(fmt.Sprint("name.", aggName)) + require.NoError(t, err) require.NoError(t, fix.cont.Stop(fix.ctx)) require.Equal(t, "", fix.Output()) @@ -243,7 +248,8 @@ func TestStdoutResource(t *testing.T) { ctx := context.Background() fix := newFixtureWithResource(t, tc.res) - counter := metric.Must(fix.meter).NewFloat64Counter("name.lastvalue") + counter, err := fix.meter.SyncFloat64().Counter("name.lastvalue") + require.NoError(t, err) counter.Add(ctx, 123.456, tc.attrs...) require.NoError(t, fix.cont.Stop(fix.ctx)) diff --git a/internal/metric/async.go b/internal/metric/async.go deleted file mode 100644 index 94801b7ff3c..00000000000 --- a/internal/metric/async.go +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package metric // import "go.opentelemetry.io/otel/internal/metric" - -import ( - "context" - "errors" - "fmt" - "sync" - - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric/sdkapi" -) - -//nolint:revive // ignoring missing comments for exported error in an internal package -var ErrInvalidAsyncRunner = errors.New("unknown async runner type") - -// AsyncCollector is an interface used between the MeterImpl and the -// AsyncInstrumentState helper below. This interface is implemented by -// the SDK to provide support for running observer callbacks. -type AsyncCollector interface { - // CollectAsync passes a batch of observations to the MeterImpl. - CollectAsync(labels []attribute.KeyValue, observation ...sdkapi.Observation) -} - -// AsyncInstrumentState manages an ordered set of asynchronous -// instruments and the distinct runners, taking into account batch -// observer callbacks. -type AsyncInstrumentState struct { - lock sync.Mutex - - // errorOnce will use the otel.Handler to report an error - // once in case of an invalid runner attempting to run. - errorOnce sync.Once - - // runnerMap keeps the set of runners that will run each - // collection interval. Singletons are entered with a real - // instrument each, batch observers are entered with a nil - // instrument, ensuring that when a singleton callback is used - // repeatedly, it is executed repeatedly in the interval, while - // when a batch callback is used repeatedly, it only executes - // once per interval. - runnerMap map[asyncRunnerPair]struct{} - - // runners maintains the set of runners in the order they were - // registered. - runners []asyncRunnerPair - - // instruments maintains the set of instruments in the order - // they were registered. - instruments []sdkapi.AsyncImpl -} - -// asyncRunnerPair is a map entry for Observer callback runners. -type asyncRunnerPair struct { - // runner is used as a map key here. The API ensures - // that all callbacks are pointers for this reason. - runner sdkapi.AsyncRunner - - // inst refers to a non-nil instrument when `runner` is a - // AsyncSingleRunner. - inst sdkapi.AsyncImpl -} - -// NewAsyncInstrumentState returns a new *AsyncInstrumentState, for -// use by MeterImpl to manage running the set of observer callbacks in -// the correct order. -func NewAsyncInstrumentState() *AsyncInstrumentState { - return &AsyncInstrumentState{ - runnerMap: map[asyncRunnerPair]struct{}{}, - } -} - -// Instruments returns the asynchronous instruments managed by this -// object, the set that should be checkpointed after observers are -// run. -func (a *AsyncInstrumentState) Instruments() []sdkapi.AsyncImpl { - a.lock.Lock() - defer a.lock.Unlock() - return a.instruments -} - -// Register adds a new asynchronous instrument to by managed by this -// object. This should be called during NewAsyncInstrument() and -// assumes that errors (e.g., duplicate registration) have already -// been checked. -func (a *AsyncInstrumentState) Register(inst sdkapi.AsyncImpl, runner sdkapi.AsyncRunner) { - a.lock.Lock() - defer a.lock.Unlock() - - a.instruments = append(a.instruments, inst) - - // asyncRunnerPair reflects this callback in the asyncRunners - // list. If this is a batch runner, the instrument is nil. - // If this is a single-Observer runner, the instrument is - // included. This ensures that batch callbacks are called - // once and single callbacks are called once per instrument. - rp := asyncRunnerPair{ - runner: runner, - } - if _, ok := runner.(sdkapi.AsyncSingleRunner); ok { - rp.inst = inst - } - - if _, ok := a.runnerMap[rp]; !ok { - a.runnerMap[rp] = struct{}{} - a.runners = append(a.runners, rp) - } -} - -// Run executes the complete set of observer callbacks. -func (a *AsyncInstrumentState) Run(ctx context.Context, collector AsyncCollector) { - a.lock.Lock() - runners := a.runners - a.lock.Unlock() - - for _, rp := range runners { - // The runner must be a single or batch runner, no - // other implementations are possible because the - // interface has un-exported methods. - - if singleRunner, ok := rp.runner.(sdkapi.AsyncSingleRunner); ok { - singleRunner.Run(ctx, rp.inst, collector.CollectAsync) - continue - } - - if multiRunner, ok := rp.runner.(sdkapi.AsyncBatchRunner); ok { - multiRunner.Run(ctx, collector.CollectAsync) - continue - } - - a.errorOnce.Do(func() { - otel.Handle(fmt.Errorf("%w: type %T (reported once)", ErrInvalidAsyncRunner, rp)) - }) - } -} diff --git a/internal/metric/global/benchmark_test.go b/internal/metric/global/benchmark_test.go deleted file mode 100644 index 05cab62d2dc..00000000000 --- a/internal/metric/global/benchmark_test.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package global_test - -import ( - "context" - "testing" - - "go.opentelemetry.io/otel/attribute" - internalglobal "go.opentelemetry.io/otel/internal/metric/global" - metricglobal "go.opentelemetry.io/otel/metric/global" -) - -func BenchmarkGlobalInt64CounterAddNoSDK(b *testing.B) { - // Compare with BenchmarkGlobalInt64CounterAddWithSDK() in - // ../../sdk/metric/benchmark_test.go to see the overhead of the - // global no-op system against a registered SDK. - internalglobal.ResetForTest() - ctx := context.Background() - sdk := metricglobal.Meter("test") - labs := []attribute.KeyValue{attribute.String("A", "B")} - cnt := Must(sdk).NewInt64Counter("int64.counter") - - b.ResetTimer() - - for i := 0; i < b.N; i++ { - cnt.Add(ctx, 1, labs...) - } -} diff --git a/internal/metric/global/internal_test.go b/internal/metric/global/internal_test.go deleted file mode 100644 index 44e1904aefe..00000000000 --- a/internal/metric/global/internal_test.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package global_test - -import ( - "os" - "testing" - - ottest "go.opentelemetry.io/otel/internal/internaltest" - "go.opentelemetry.io/otel/internal/metric/global" -) - -// Ensure struct alignment prior to running tests. -func TestMain(m *testing.M) { - fieldsMap := global.AtomicFieldOffsets() - fields := make([]ottest.FieldOffset, 0, len(fieldsMap)) - for name, offset := range fieldsMap { - fields = append(fields, ottest.FieldOffset{ - Name: name, - Offset: offset, - }) - } - if !ottest.Aligned8Byte(fields, os.Stderr) { - os.Exit(1) - } - - os.Exit(m.Run()) -} diff --git a/internal/metric/global/meter.go b/internal/metric/global/meter.go deleted file mode 100644 index 77781ead118..00000000000 --- a/internal/metric/global/meter.go +++ /dev/null @@ -1,287 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package global // import "go.opentelemetry.io/otel/internal/metric/global" - -import ( - "context" - "sync" - "sync/atomic" - "unsafe" - - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/internal/metric/registry" - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" -) - -// This file contains the forwarding implementation of MeterProvider used as -// the default global instance. Metric events using instruments provided by -// this implementation are no-ops until the first Meter implementation is set -// as the global provider. -// -// The implementation here uses Mutexes to maintain a list of active Meters in -// the MeterProvider and Instruments in each Meter, under the assumption that -// these interfaces are not performance-critical. -// -// We have the invariant that setDelegate() will be called before a new -// MeterProvider implementation is registered as the global provider. Mutexes -// in the MeterProvider and Meters ensure that each instrument has a delegate -// before the global provider is set. -// -// Metric uniqueness checking is implemented by calling the exported -// methods of the api/metric/registry package. - -type meterKey struct { - InstrumentationName string - InstrumentationVersion string - SchemaURL string -} - -type meterProvider struct { - delegate metric.MeterProvider - - // lock protects `delegate` and `meters`. - lock sync.Mutex - - // meters maintains a unique entry for every named Meter - // that has been registered through the global instance. - meters map[meterKey]*meterEntry -} - -type meterImpl struct { - delegate unsafe.Pointer // (*metric.MeterImpl) - - lock sync.Mutex - syncInsts []*syncImpl - asyncInsts []*asyncImpl -} - -type meterEntry struct { - unique sdkapi.MeterImpl - impl meterImpl -} - -type instrument struct { - descriptor sdkapi.Descriptor -} - -type syncImpl struct { - delegate unsafe.Pointer // (*sdkapi.SyncImpl) - - instrument -} - -type asyncImpl struct { - delegate unsafe.Pointer // (*sdkapi.AsyncImpl) - - instrument - - runner sdkapi.AsyncRunner -} - -var _ metric.MeterProvider = &meterProvider{} -var _ sdkapi.MeterImpl = &meterImpl{} -var _ sdkapi.InstrumentImpl = &syncImpl{} -var _ sdkapi.AsyncImpl = &asyncImpl{} - -func (inst *instrument) Descriptor() sdkapi.Descriptor { - return inst.descriptor -} - -// MeterProvider interface and delegation - -func newMeterProvider() *meterProvider { - return &meterProvider{ - meters: map[meterKey]*meterEntry{}, - } -} - -func (p *meterProvider) setDelegate(provider metric.MeterProvider) { - p.lock.Lock() - defer p.lock.Unlock() - - p.delegate = provider - for key, entry := range p.meters { - entry.impl.setDelegate(key, provider) - } - p.meters = nil -} - -func (p *meterProvider) Meter(instrumentationName string, opts ...metric.MeterOption) metric.Meter { - p.lock.Lock() - defer p.lock.Unlock() - - if p.delegate != nil { - return p.delegate.Meter(instrumentationName, opts...) - } - - cfg := metric.NewMeterConfig(opts...) - key := meterKey{ - InstrumentationName: instrumentationName, - InstrumentationVersion: cfg.InstrumentationVersion(), - SchemaURL: cfg.SchemaURL(), - } - entry, ok := p.meters[key] - if !ok { - entry = &meterEntry{} - // Note: This code implements its own MeterProvider - // name-uniqueness logic because there is - // synchronization required at the moment of - // delegation. We use the same instrument-uniqueness - // checking the real SDK uses here: - entry.unique = registry.NewUniqueInstrumentMeterImpl(&entry.impl) - p.meters[key] = entry - } - return metric.WrapMeterImpl(entry.unique) -} - -// Meter interface and delegation - -func (m *meterImpl) setDelegate(key meterKey, provider metric.MeterProvider) { - m.lock.Lock() - defer m.lock.Unlock() - - d := new(sdkapi.MeterImpl) - *d = provider.Meter( - key.InstrumentationName, - metric.WithInstrumentationVersion(key.InstrumentationVersion), - metric.WithSchemaURL(key.SchemaURL), - ).MeterImpl() - m.delegate = unsafe.Pointer(d) - - for _, inst := range m.syncInsts { - inst.setDelegate(*d) - } - m.syncInsts = nil - for _, obs := range m.asyncInsts { - obs.setDelegate(*d) - } - m.asyncInsts = nil -} - -func (m *meterImpl) NewSyncInstrument(desc sdkapi.Descriptor) (sdkapi.SyncImpl, error) { - m.lock.Lock() - defer m.lock.Unlock() - - if meterPtr := (*sdkapi.MeterImpl)(atomic.LoadPointer(&m.delegate)); meterPtr != nil { - return (*meterPtr).NewSyncInstrument(desc) - } - - inst := &syncImpl{ - instrument: instrument{ - descriptor: desc, - }, - } - m.syncInsts = append(m.syncInsts, inst) - return inst, nil -} - -// Synchronous delegation - -func (inst *syncImpl) setDelegate(d sdkapi.MeterImpl) { - implPtr := new(sdkapi.SyncImpl) - - var err error - *implPtr, err = d.NewSyncInstrument(inst.descriptor) - - if err != nil { - // TODO: There is no standard way to deliver this error to the user. - // See https://github.com/open-telemetry/opentelemetry-go/issues/514 - // Note that the default SDK will not generate any errors yet, this is - // only for added safety. - panic(err) - } - - atomic.StorePointer(&inst.delegate, unsafe.Pointer(implPtr)) -} - -func (inst *syncImpl) Implementation() interface{} { - if implPtr := (*sdkapi.SyncImpl)(atomic.LoadPointer(&inst.delegate)); implPtr != nil { - return (*implPtr).Implementation() - } - return inst -} - -// Async delegation - -func (m *meterImpl) NewAsyncInstrument( - desc sdkapi.Descriptor, - runner sdkapi.AsyncRunner, -) (sdkapi.AsyncImpl, error) { - - m.lock.Lock() - defer m.lock.Unlock() - - if meterPtr := (*sdkapi.MeterImpl)(atomic.LoadPointer(&m.delegate)); meterPtr != nil { - return (*meterPtr).NewAsyncInstrument(desc, runner) - } - - inst := &asyncImpl{ - instrument: instrument{ - descriptor: desc, - }, - runner: runner, - } - m.asyncInsts = append(m.asyncInsts, inst) - return inst, nil -} - -func (obs *asyncImpl) Implementation() interface{} { - if implPtr := (*sdkapi.AsyncImpl)(atomic.LoadPointer(&obs.delegate)); implPtr != nil { - return (*implPtr).Implementation() - } - return obs -} - -func (obs *asyncImpl) setDelegate(d sdkapi.MeterImpl) { - implPtr := new(sdkapi.AsyncImpl) - - var err error - *implPtr, err = d.NewAsyncInstrument(obs.descriptor, obs.runner) - - if err != nil { - // TODO: There is no standard way to deliver this error to the user. - // See https://github.com/open-telemetry/opentelemetry-go/issues/514 - // Note that the default SDK will not generate any errors yet, this is - // only for added safety. - panic(err) - } - - atomic.StorePointer(&obs.delegate, unsafe.Pointer(implPtr)) -} - -// Metric updates - -func (m *meterImpl) RecordBatch(ctx context.Context, labels []attribute.KeyValue, measurements ...sdkapi.Measurement) { - if delegatePtr := (*sdkapi.MeterImpl)(atomic.LoadPointer(&m.delegate)); delegatePtr != nil { - (*delegatePtr).RecordBatch(ctx, labels, measurements...) - } -} - -func (inst *syncImpl) RecordOne(ctx context.Context, number number.Number, labels []attribute.KeyValue) { - if instPtr := (*sdkapi.SyncImpl)(atomic.LoadPointer(&inst.delegate)); instPtr != nil { - (*instPtr).RecordOne(ctx, number, labels) - } -} - -func AtomicFieldOffsets() map[string]uintptr { - return map[string]uintptr{ - "meterProvider.delegate": unsafe.Offsetof(meterProvider{}.delegate), - "meterImpl.delegate": unsafe.Offsetof(meterImpl{}.delegate), - "syncImpl.delegate": unsafe.Offsetof(syncImpl{}.delegate), - "asyncImpl.delegate": unsafe.Offsetof(asyncImpl{}.delegate), - } -} diff --git a/internal/metric/global/meter_test.go b/internal/metric/global/meter_test.go deleted file mode 100644 index 2062ecf8b07..00000000000 --- a/internal/metric/global/meter_test.go +++ /dev/null @@ -1,253 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package global_test - -import ( - "context" - "errors" - "testing" - - "github.com/stretchr/testify/require" - - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/internal/metric/global" - "go.opentelemetry.io/otel/metric" - metricglobal "go.opentelemetry.io/otel/metric/global" - "go.opentelemetry.io/otel/metric/metrictest" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" -) - -var Must = metric.Must - -var asInt = number.NewInt64Number -var asFloat = number.NewFloat64Number - -func TestDirect(t *testing.T) { - global.ResetForTest() - - ctx := context.Background() - meter1 := metricglobal.Meter("test1", metric.WithInstrumentationVersion("semver:v1.0.0")) - meter2 := metricglobal.Meter("test2", metric.WithSchemaURL("hello")) - - library1 := metrictest.Library{ - InstrumentationName: "test1", - InstrumentationVersion: "semver:v1.0.0", - } - library2 := metrictest.Library{ - InstrumentationName: "test2", - SchemaURL: "hello", - } - - labels1 := []attribute.KeyValue{attribute.String("A", "B")} - labels2 := []attribute.KeyValue{attribute.String("C", "D")} - labels3 := []attribute.KeyValue{attribute.String("E", "F")} - - counter := Must(meter1).NewInt64Counter("test.counter") - counter.Add(ctx, 1, labels1...) - counter.Add(ctx, 1, labels1...) - - histogram := Must(meter1).NewFloat64Histogram("test.histogram") - histogram.Record(ctx, 1, labels1...) - histogram.Record(ctx, 2, labels1...) - - _ = Must(meter1).NewFloat64GaugeObserver("test.gauge.float", func(_ context.Context, result metric.Float64ObserverResult) { - result.Observe(1., labels1...) - result.Observe(2., labels2...) - }) - - _ = Must(meter1).NewInt64GaugeObserver("test.gauge.int", func(_ context.Context, result metric.Int64ObserverResult) { - result.Observe(1, labels1...) - result.Observe(2, labels2...) - }) - - second := Must(meter2).NewFloat64Histogram("test.second") - second.Record(ctx, 1, labels3...) - second.Record(ctx, 2, labels3...) - - provider := metrictest.NewMeterProvider() - metricglobal.SetMeterProvider(provider) - - counter.Add(ctx, 1, labels1...) - histogram.Record(ctx, 3, labels1...) - second.Record(ctx, 3, labels3...) - - provider.RunAsyncInstruments() - - measurements := metrictest.AsStructs(provider.MeasurementBatches) - - require.EqualValues(t, - []metrictest.Measured{ - { - Name: "test.counter", - Library: library1, - Labels: metrictest.LabelsToMap(labels1...), - Number: asInt(1), - }, - { - Name: "test.histogram", - Library: library1, - Labels: metrictest.LabelsToMap(labels1...), - Number: asFloat(3), - }, - { - Name: "test.second", - Library: library2, - Labels: metrictest.LabelsToMap(labels3...), - Number: asFloat(3), - }, - { - Name: "test.gauge.float", - Library: library1, - Labels: metrictest.LabelsToMap(labels1...), - Number: asFloat(1), - }, - { - Name: "test.gauge.float", - Library: library1, - Labels: metrictest.LabelsToMap(labels2...), - Number: asFloat(2), - }, - { - Name: "test.gauge.int", - Library: library1, - Labels: metrictest.LabelsToMap(labels1...), - Number: asInt(1), - }, - { - Name: "test.gauge.int", - Library: library1, - Labels: metrictest.LabelsToMap(labels2...), - Number: asInt(2), - }, - }, - measurements, - ) -} - -type meterProviderWithConstructorError struct { - metric.MeterProvider -} - -type meterWithConstructorError struct { - sdkapi.MeterImpl -} - -func (m *meterProviderWithConstructorError) Meter(iName string, opts ...metric.MeterOption) metric.Meter { - return metric.WrapMeterImpl(&meterWithConstructorError{m.MeterProvider.Meter(iName, opts...).MeterImpl()}) -} - -func (m *meterWithConstructorError) NewSyncInstrument(_ sdkapi.Descriptor) (sdkapi.SyncImpl, error) { - return sdkapi.NewNoopSyncInstrument(), errors.New("constructor error") -} - -func TestErrorInDeferredConstructor(t *testing.T) { - global.ResetForTest() - - ctx := context.Background() - meter := metricglobal.GetMeterProvider().Meter("builtin") - - c1 := Must(meter).NewInt64Counter("test") - c2 := Must(meter).NewInt64Counter("test") - - provider := metrictest.NewMeterProvider() - sdk := &meterProviderWithConstructorError{provider} - - require.Panics(t, func() { - metricglobal.SetMeterProvider(sdk) - }) - - c1.Add(ctx, 1) - c2.Add(ctx, 2) -} - -func TestImplementationIndirection(t *testing.T) { - global.ResetForTest() - - // Test that Implementation() does the proper indirection, i.e., - // returns the implementation interface not the global, after - // registered. - - meter1 := metricglobal.Meter("test1") - - // Sync: no SDK yet - counter := Must(meter1).NewInt64Counter("interface.counter") - - ival := counter.Measurement(1).SyncImpl().Implementation() - require.NotNil(t, ival) - - _, ok := ival.(*metrictest.Sync) - require.False(t, ok) - - // Async: no SDK yet - gauge := Must(meter1).NewFloat64GaugeObserver( - "interface.gauge", - func(_ context.Context, result metric.Float64ObserverResult) {}, - ) - - ival = gauge.AsyncImpl().Implementation() - require.NotNil(t, ival) - - _, ok = ival.(*metrictest.Async) - require.False(t, ok) - - // Register the SDK - provider := metrictest.NewMeterProvider() - metricglobal.SetMeterProvider(provider) - - // Repeat the above tests - - // Sync - ival = counter.Measurement(1).SyncImpl().Implementation() - require.NotNil(t, ival) - - _, ok = ival.(*metrictest.Sync) - require.True(t, ok) - - // Async - ival = gauge.AsyncImpl().Implementation() - require.NotNil(t, ival) - - _, ok = ival.(*metrictest.Async) - require.True(t, ok) -} - -func TestRecordBatchMock(t *testing.T) { - global.ResetForTest() - - meter := metricglobal.GetMeterProvider().Meter("builtin") - - counter := Must(meter).NewInt64Counter("test.counter") - - meter.RecordBatch(context.Background(), nil, counter.Measurement(1)) - - provider := metrictest.NewMeterProvider() - metricglobal.SetMeterProvider(provider) - - meter.RecordBatch(context.Background(), nil, counter.Measurement(1)) - - require.EqualValues(t, - []metrictest.Measured{ - { - Name: "test.counter", - Library: metrictest.Library{ - InstrumentationName: "builtin", - }, - Labels: metrictest.LabelsToMap(), - Number: asInt(1), - }, - }, - metrictest.AsStructs(provider.MeasurementBatches)) -} diff --git a/internal/metric/global/metric.go b/internal/metric/global/metric.go deleted file mode 100644 index 896c6dd1c30..00000000000 --- a/internal/metric/global/metric.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package global // import "go.opentelemetry.io/otel/internal/metric/global" - -import ( - "sync" - "sync/atomic" - - "go.opentelemetry.io/otel/metric" -) - -type meterProviderHolder struct { - mp metric.MeterProvider -} - -var ( - globalMeter = defaultMeterValue() - - delegateMeterOnce sync.Once -) - -// MeterProvider is the internal implementation for global.MeterProvider. -func MeterProvider() metric.MeterProvider { - return globalMeter.Load().(meterProviderHolder).mp -} - -// SetMeterProvider is the internal implementation for global.SetMeterProvider. -func SetMeterProvider(mp metric.MeterProvider) { - delegateMeterOnce.Do(func() { - current := MeterProvider() - - if current == mp { - // Setting the provider to the prior default is nonsense, panic. - // Panic is acceptable because we are likely still early in the - // process lifetime. - panic("invalid MeterProvider, the global instance cannot be reinstalled") - } else if def, ok := current.(*meterProvider); ok { - def.setDelegate(mp) - } - }) - globalMeter.Store(meterProviderHolder{mp: mp}) -} - -func defaultMeterValue() *atomic.Value { - v := &atomic.Value{} - v.Store(meterProviderHolder{mp: newMeterProvider()}) - return v -} - -// ResetForTest restores the initial global state, for testing purposes. -func ResetForTest() { - globalMeter = defaultMeterValue() - delegateMeterOnce = sync.Once{} -} diff --git a/internal/metric/global/registry_test.go b/internal/metric/global/registry_test.go deleted file mode 100644 index 0d92c044ef1..00000000000 --- a/internal/metric/global/registry_test.go +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package global - -import ( - "context" - "errors" - "testing" - - "github.com/stretchr/testify/require" - - "go.opentelemetry.io/otel/internal/metric/registry" - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/metrictest" - "go.opentelemetry.io/otel/metric/sdkapi" -) - -type ( - newFunc func(name, libraryName string) (sdkapi.InstrumentImpl, error) -) - -var ( - allNew = map[string]newFunc{ - "counter.int64": func(name, libraryName string) (sdkapi.InstrumentImpl, error) { - return unwrap(MeterProvider().Meter(libraryName).NewInt64Counter(name)) - }, - "counter.float64": func(name, libraryName string) (sdkapi.InstrumentImpl, error) { - return unwrap(MeterProvider().Meter(libraryName).NewFloat64Counter(name)) - }, - "histogram.int64": func(name, libraryName string) (sdkapi.InstrumentImpl, error) { - return unwrap(MeterProvider().Meter(libraryName).NewInt64Histogram(name)) - }, - "histogram.float64": func(name, libraryName string) (sdkapi.InstrumentImpl, error) { - return unwrap(MeterProvider().Meter(libraryName).NewFloat64Histogram(name)) - }, - "gauge.int64": func(name, libraryName string) (sdkapi.InstrumentImpl, error) { - return unwrap(MeterProvider().Meter(libraryName).NewInt64GaugeObserver(name, func(context.Context, metric.Int64ObserverResult) {})) - }, - "gauge.float64": func(name, libraryName string) (sdkapi.InstrumentImpl, error) { - return unwrap(MeterProvider().Meter(libraryName).NewFloat64GaugeObserver(name, func(context.Context, metric.Float64ObserverResult) {})) - }, - } -) - -func unwrap(impl interface{}, err error) (sdkapi.InstrumentImpl, error) { - if impl == nil { - return nil, err - } - if s, ok := impl.(interface { - SyncImpl() sdkapi.SyncImpl - }); ok { - return s.SyncImpl(), err - } - if a, ok := impl.(interface { - AsyncImpl() sdkapi.AsyncImpl - }); ok { - return a.AsyncImpl(), err - } - return nil, err -} - -func TestRegistrySameInstruments(t *testing.T) { - for _, nf := range allNew { - ResetForTest() - inst1, err1 := nf("this", "meter") - inst2, err2 := nf("this", "meter") - - require.NoError(t, err1) - require.NoError(t, err2) - require.Equal(t, inst1, inst2) - - SetMeterProvider(metrictest.NewMeterProvider()) - - require.Equal(t, inst1, inst2) - } -} - -func TestRegistryDifferentNamespace(t *testing.T) { - for _, nf := range allNew { - ResetForTest() - inst1, err1 := nf("this", "meter1") - inst2, err2 := nf("this", "meter2") - - require.NoError(t, err1) - require.NoError(t, err2) - - if inst1.Descriptor().InstrumentKind().Synchronous() { - // They're equal because of a `nil` pointer at this point. - // (Only for synchronous instruments, which lack callacks.) - require.EqualValues(t, inst1, inst2) - } - - SetMeterProvider(metrictest.NewMeterProvider()) - - // They're different after the deferred setup. - require.NotEqual(t, inst1, inst2) - } -} - -func TestRegistryDiffInstruments(t *testing.T) { - for origName, origf := range allNew { - ResetForTest() - - _, err := origf("this", "super") - require.NoError(t, err) - - for newName, nf := range allNew { - if newName == origName { - continue - } - - other, err := nf("this", "super") - require.Error(t, err) - require.NotNil(t, other) - require.True(t, errors.Is(err, registry.ErrMetricKindMismatch)) - require.Contains(t, err.Error(), "by this name with another kind or number type") - } - } -} diff --git a/internal/metric/global/state_test.go b/internal/metric/global/state_test.go deleted file mode 100644 index 526eac7fa69..00000000000 --- a/internal/metric/global/state_test.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package global_test - -import ( - "testing" - - internalglobal "go.opentelemetry.io/otel/internal/metric/global" - metricglobal "go.opentelemetry.io/otel/metric/global" -) - -func TestResetsOfGlobalsPanic(t *testing.T) { - internalglobal.ResetForTest() - tests := map[string]func(){ - "SetMeterProvider": func() { - metricglobal.SetMeterProvider(metricglobal.GetMeterProvider()) - }, - } - - for name, test := range tests { - shouldPanic(t, name, test) - } -} - -func shouldPanic(t *testing.T, name string, f func()) { - defer func() { - if r := recover(); r == nil { - t.Errorf("calling %s with default global did not panic", name) - } - }() - - f() -} diff --git a/internal/metric/go.mod b/internal/metric/go.mod deleted file mode 100644 index 7e92e2dcb10..00000000000 --- a/internal/metric/go.mod +++ /dev/null @@ -1,73 +0,0 @@ -module go.opentelemetry.io/otel/internal/metric - -go 1.16 - -require ( - github.com/stretchr/testify v1.7.0 - go.opentelemetry.io/otel v1.4.1 - go.opentelemetry.io/otel/metric v0.27.0 -) - -replace go.opentelemetry.io/otel => ../.. - -replace go.opentelemetry.io/otel/metric => ../../metric - -replace go.opentelemetry.io/otel/internal/metric => ./ - -replace go.opentelemetry.io/otel/bridge/opencensus => ../../bridge/opencensus - -replace go.opentelemetry.io/otel/bridge/opentracing => ../../bridge/opentracing - -replace go.opentelemetry.io/otel/example/jaeger => ../../example/jaeger - -replace go.opentelemetry.io/otel/example/namedtracer => ../../example/namedtracer - -replace go.opentelemetry.io/otel/example/opencensus => ../../example/opencensus - -replace go.opentelemetry.io/otel/example/otel-collector => ../../example/otel-collector - -replace go.opentelemetry.io/otel/example/passthrough => ../../example/passthrough - -replace go.opentelemetry.io/otel/example/prometheus => ../../example/prometheus - -replace go.opentelemetry.io/otel/example/zipkin => ../../example/zipkin - -replace go.opentelemetry.io/otel/exporters/prometheus => ../../exporters/prometheus - -replace go.opentelemetry.io/otel/exporters/otlp/otlptrace => ../../exporters/otlp/otlptrace - -replace go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc => ../../exporters/otlp/otlptrace/otlptracegrpc - -replace go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp => ../../exporters/otlp/otlptrace/otlptracehttp - -replace go.opentelemetry.io/otel/exporters/jaeger => ../../exporters/jaeger - -replace go.opentelemetry.io/otel/exporters/zipkin => ../../exporters/zipkin - -replace go.opentelemetry.io/otel/internal/tools => ../tools - -replace go.opentelemetry.io/otel/sdk => ../../sdk - -replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric - -replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric - -replace go.opentelemetry.io/otel/trace => ../../trace - -replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric => ../../exporters/otlp/otlpmetric - -replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc => ../../exporters/otlp/otlpmetric/otlpmetricgrpc - -replace go.opentelemetry.io/otel/exporters/stdout/stdoutmetric => ../../exporters/stdout/stdoutmetric - -replace go.opentelemetry.io/otel/exporters/stdout/stdouttrace => ../../exporters/stdout/stdouttrace - -replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp => ../../exporters/otlp/otlpmetric/otlpmetrichttp - -replace go.opentelemetry.io/otel/bridge/opencensus/test => ../../bridge/opencensus/test - -replace go.opentelemetry.io/otel/example/fib => ../../example/fib - -replace go.opentelemetry.io/otel/schema => ../../schema - -replace go.opentelemetry.io/otel/exporters/otlp/internal/retry => ../../exporters/otlp/internal/retry diff --git a/internal/metric/go.sum b/internal/metric/go.sum deleted file mode 100644 index 4f1776cd92b..00000000000 --- a/internal/metric/go.sum +++ /dev/null @@ -1,18 +0,0 @@ -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/metric/config.go b/metric/config.go index 3f722344fa7..621e4c5fcb8 100644 --- a/metric/config.go +++ b/metric/config.go @@ -14,65 +14,6 @@ package metric // import "go.opentelemetry.io/otel/metric" -import ( - "go.opentelemetry.io/otel/metric/unit" -) - -// InstrumentConfig contains options for metric instrument descriptors. -type InstrumentConfig struct { - description string - unit unit.Unit -} - -// Description describes the instrument in human-readable terms. -func (cfg *InstrumentConfig) Description() string { - return cfg.description -} - -// Unit describes the measurement unit for a instrument. -func (cfg *InstrumentConfig) Unit() unit.Unit { - return cfg.unit -} - -// InstrumentOption is an interface for applying metric instrument options. -type InstrumentOption interface { - // ApplyMeter is used to set a InstrumentOption value of a - // InstrumentConfig. - applyInstrument(InstrumentConfig) InstrumentConfig -} - -// NewInstrumentConfig creates a new InstrumentConfig -// and applies all the given options. -func NewInstrumentConfig(opts ...InstrumentOption) InstrumentConfig { - var config InstrumentConfig - for _, o := range opts { - config = o.applyInstrument(config) - } - return config -} - -type instrumentOptionFunc func(InstrumentConfig) InstrumentConfig - -func (fn instrumentOptionFunc) applyInstrument(cfg InstrumentConfig) InstrumentConfig { - return fn(cfg) -} - -// WithDescription applies provided description. -func WithDescription(desc string) InstrumentOption { - return instrumentOptionFunc(func(cfg InstrumentConfig) InstrumentConfig { - cfg.description = desc - return cfg - }) -} - -// WithUnit applies provided unit. -func WithUnit(unit unit.Unit) InstrumentOption { - return instrumentOptionFunc(func(cfg InstrumentConfig) InstrumentConfig { - cfg.unit = unit - return cfg - }) -} - // MeterConfig contains options for Meters. type MeterConfig struct { instrumentationVersion string @@ -80,18 +21,18 @@ type MeterConfig struct { } // InstrumentationVersion is the version of the library providing instrumentation. -func (cfg *MeterConfig) InstrumentationVersion() string { +func (cfg MeterConfig) InstrumentationVersion() string { return cfg.instrumentationVersion } // SchemaURL is the schema_url of the library providing instrumentation. -func (cfg *MeterConfig) SchemaURL() string { +func (cfg MeterConfig) SchemaURL() string { return cfg.schemaURL } // MeterOption is an interface for applying Meter options. type MeterOption interface { - // ApplyMeter is used to set a MeterOption value of a MeterConfig. + // applyMeter is used to set a MeterOption value of a MeterConfig. applyMeter(MeterConfig) MeterConfig } diff --git a/metric/doc.go b/metric/doc.go index 4baf0719fcc..bd6f4343720 100644 --- a/metric/doc.go +++ b/metric/doc.go @@ -19,49 +19,5 @@ OpenTelemetry API. This package is currently in a pre-GA phase. Backwards incompatible changes may be introduced in subsequent minor version releases as we work to track the evolving OpenTelemetry specification and user feedback. - -Measurements can be made about an operation being performed or the state of a -system in general. These measurements can be crucial to the reliable operation -of code and provide valuable insights about the inner workings of a system. - -Measurements are made using instruments provided by this package. The type of -instrument used will depend on the type of measurement being made and of what -part of a system is being measured. - -Instruments are categorized as Synchronous or Asynchronous and independently -as Adding or Grouping. Synchronous instruments are called by the user with a -Context. Asynchronous instruments are called by the SDK during collection. -Adding instruments are semantically intended for capturing a sum. Grouping -instruments are intended for capturing a distribution. - -Adding instruments may be monotonic, in which case they are non-decreasing -and naturally define a rate. - -The synchronous instrument names are: - - Counter: adding, monotonic - UpDownCounter: adding - Histogram: grouping - -and the asynchronous instruments are: - - CounterObserver: adding, monotonic - UpDownCounterObserver: adding - GaugeObserver: grouping - -All instruments are provided with support for either float64 or int64 input -values. - -An instrument is created using a Meter. Additionally, a Meter is used to -record batches of synchronous measurements or asynchronous observations. A -Meter is obtained using a MeterProvider. A Meter, like a Tracer, is unique to -the instrumentation it instruments and must be named and versioned when -created with a MeterProvider with the name and version of the instrumentation -library. - -Instrumentation should be designed to accept a MeterProvider from which it can -create its own unique Meter. Alternatively, the registered global -MeterProvider from the go.opentelemetry.io/otel package can be used as a -default. */ package metric // import "go.opentelemetry.io/otel/metric" diff --git a/metric/example_test.go b/metric/example_test.go new file mode 100644 index 00000000000..92e0e2cd958 --- /dev/null +++ b/metric/example_test.go @@ -0,0 +1,116 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metric_test + +import ( + "context" + "fmt" + "runtime" + "time" + + "go.opentelemetry.io/otel/metric/instrument" + "go.opentelemetry.io/otel/metric/instrument/syncfloat64" + "go.opentelemetry.io/otel/metric/nonrecording" + "go.opentelemetry.io/otel/metric/unit" +) + +//nolint:govet // Meter doesn't register for go vet +func ExampleMeter_synchronous() { + // In a library or program this would be provided by otel.GetMeterProvider(). + meterProvider := nonrecording.NewNoopMeterProvider() + + workDuration, err := meterProvider.Meter("go.opentelemetry.io/otel/metric#SyncExample").SyncInt64().Histogram( + "workDuration", + instrument.WithUnit(unit.Milliseconds)) + if err != nil { + fmt.Println("Failed to register instrument") + panic(err) + } + + startTime := time.Now() + ctx := context.Background() + // Do work + // ... + workDuration.Record(ctx, time.Since(startTime).Milliseconds()) + +} + +//nolint:govet // Meter doesn't register for go vet +func ExampleMeter_asynchronous_single() { + // In a library or program this would be provided by otel.GetMeterProvider(). + meterProvider := nonrecording.NewNoopMeterProvider() + meter := meterProvider.Meter("go.opentelemetry.io/otel/metric#AsyncExample") + + memoryUsage, err := meter.AsyncInt64().Gauge( + "MemoryUsage", + instrument.WithUnit(unit.Bytes), + ) + if err != nil { + fmt.Println("Failed to register instrument") + panic(err) + } + + err = meter.RegisterCallback([]instrument.Asynchronous{memoryUsage}, + func(ctx context.Context) { + // instrument.WithCallbackFunc(func(ctx context.Context) { + //Do Work to get the real memoryUsage + // mem := GatherMemory(ctx) + mem := 75000 + + memoryUsage.Observe(ctx, int64(mem)) + }) + if err != nil { + fmt.Println("Failed to register callback") + panic(err) + } +} + +//nolint:govet // Meter doesn't register for go vet +func ExampleMeter_asynchronous_multiple() { + meterProvider := nonrecording.NewNoopMeterProvider() + meter := meterProvider.Meter("go.opentelemetry.io/otel/metric#MultiAsyncExample") + + // This is just a sample of memory stats to record from the Memstats + heapAlloc, _ := meter.AsyncInt64().UpDownCounter("heapAllocs") + gcCount, _ := meter.AsyncInt64().Counter("gcCount") + gcPause, _ := meter.SyncFloat64().Histogram("gcPause") + + err := meter.RegisterCallback([]instrument.Asynchronous{ + heapAlloc, + gcCount, + }, + func(ctx context.Context) { + memStats := &runtime.MemStats{} + // This call does work + runtime.ReadMemStats(memStats) + + heapAlloc.Observe(ctx, int64(memStats.HeapAlloc)) + gcCount.Observe(ctx, int64(memStats.NumGC)) + + // This function synchronously records the pauses + computeGCPauses(ctx, gcPause, memStats.PauseNs[:]) + }, + ) + + if err != nil { + fmt.Println("Failed to register callback") + panic(err) + } +} + +//This is just an example, see the the contrib runtime instrumentation for real implementation +func computeGCPauses(ctx context.Context, recorder syncfloat64.Histogram, pauseBuff []uint64) { + +} diff --git a/metric/global/metric.go b/metric/global/metric.go deleted file mode 100644 index 14ba862002a..00000000000 --- a/metric/global/metric.go +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package global // import "go.opentelemetry.io/otel/metric/global" - -import ( - "go.opentelemetry.io/otel/internal/metric/global" - "go.opentelemetry.io/otel/metric" -) - -// Meter creates an implementation of the Meter interface from the global -// MeterProvider. The instrumentationName must be the name of the library -// providing instrumentation. This name may be the same as the instrumented -// code only if that code provides built-in instrumentation. If the -// instrumentationName is empty, then a implementation defined default name -// will be used instead. -// -// This is short for MeterProvider().Meter(name) -func Meter(instrumentationName string, opts ...metric.MeterOption) metric.Meter { - return GetMeterProvider().Meter(instrumentationName, opts...) -} - -// GetMeterProvider returns the registered global meter provider. If -// none is registered then a default meter provider is returned that -// forwards the Meter interface to the first registered Meter. -// -// Use the meter provider to create a named meter. E.g. -// meter := global.MeterProvider().Meter("example.com/foo") -// or -// meter := global.Meter("example.com/foo") -func GetMeterProvider() metric.MeterProvider { - return global.MeterProvider() -} - -// SetMeterProvider registers `mp` as the global meter provider. -func SetMeterProvider(mp metric.MeterProvider) { - global.SetMeterProvider(mp) -} diff --git a/metric/global/metric_test.go b/metric/global/metric_test.go deleted file mode 100644 index dc4d9370a92..00000000000 --- a/metric/global/metric_test.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package global - -import ( - "testing" - - "go.opentelemetry.io/otel/metric" -) - -type testMeterProvider struct{} - -var _ metric.MeterProvider = &testMeterProvider{} - -func (*testMeterProvider) Meter(_ string, _ ...metric.MeterOption) metric.Meter { - return metric.Meter{} -} - -func TestMultipleGlobalMeterProvider(t *testing.T) { - p1 := testMeterProvider{} - p2 := metric.NewNoopMeterProvider() - SetMeterProvider(&p1) - SetMeterProvider(p2) - - got := GetMeterProvider() - want := p2 - if got != want { - t.Fatalf("MeterProvider: got %p, want %p\n", got, want) - } -} diff --git a/metric/go.mod b/metric/go.mod index 17780384f4c..7d510be1f32 100644 --- a/metric/go.mod +++ b/metric/go.mod @@ -2,6 +2,8 @@ module go.opentelemetry.io/otel/metric go 1.16 +require go.opentelemetry.io/otel v1.4.1 + replace go.opentelemetry.io/otel => ../ replace go.opentelemetry.io/otel/bridge/opencensus => ../bridge/opencensus @@ -38,13 +40,6 @@ replace go.opentelemetry.io/otel/sdk/metric => ../sdk/metric replace go.opentelemetry.io/otel/trace => ../trace -require ( - github.com/google/go-cmp v0.5.7 - github.com/stretchr/testify v1.7.0 - go.opentelemetry.io/otel v1.4.1 - go.opentelemetry.io/otel/internal/metric v0.27.0 -) - replace go.opentelemetry.io/otel/example/passthrough => ../example/passthrough replace go.opentelemetry.io/otel/exporters/otlp/otlptrace => ../exporters/otlp/otlptrace @@ -53,8 +48,6 @@ replace go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc => ../ex replace go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp => ../exporters/otlp/otlptrace/otlptracehttp -replace go.opentelemetry.io/otel/internal/metric => ../internal/metric - replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric => ../exporters/otlp/otlpmetric replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc => ../exporters/otlp/otlpmetric/otlpmetricgrpc diff --git a/metric/go.sum b/metric/go.sum index 531cae722ed..5457c7626c5 100644 --- a/metric/go.sum +++ b/metric/go.sum @@ -1,8 +1,6 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= @@ -11,9 +9,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/metric/instrument/asyncfloat64/asyncfloat64.go b/metric/instrument/asyncfloat64/asyncfloat64.go new file mode 100644 index 00000000000..91c034fb2a0 --- /dev/null +++ b/metric/instrument/asyncfloat64/asyncfloat64.go @@ -0,0 +1,70 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package asyncfloat64 // import "go.opentelemetry.io/otel/metric/instrument/asyncfloat64" + +import ( + "context" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric/instrument" +) + +// InstrumentProvider provides access to individual instruments. +type InstrumentProvider interface { + // Counter creates an instrument for recording increasing values. + Counter(name string, opts ...instrument.Option) (Counter, error) + + // UpDownCounter creates an instrument for recording changes of a value. + UpDownCounter(name string, opts ...instrument.Option) (UpDownCounter, error) + + // Gauge creates an instrument for recording the current value. + Gauge(name string, opts ...instrument.Option) (Gauge, error) +} + +// Counter is an instrument that records increasing values. +type Counter interface { + // Observe records the state of the instrument. + // + // It is only valid to call this within a callback. If called outside of the + // registered callback it should have no effect on the instrument, and an + // error will be reported via the error handler. + Observe(ctx context.Context, x float64, attrs ...attribute.KeyValue) + + instrument.Asynchronous +} + +// UpDownCounter is an instrument that records increasing or decresing values. +type UpDownCounter interface { + // Observe records the state of the instrument. + // + // It is only valid to call this within a callback. If called outside of the + // registered callback it should have no effect on the instrument, and an + // error will be reported via the error handler. + Observe(ctx context.Context, x float64, attrs ...attribute.KeyValue) + + instrument.Asynchronous +} + +// Gauge is an instrument that records independent readings. +type Gauge interface { + // Observe records the state of the instrument. + // + // It is only valid to call this within a callback. If called outside of the + // registered callback it should have no effect on the instrument, and an + // error will be reported via the error handler. + Observe(ctx context.Context, x float64, attrs ...attribute.KeyValue) + + instrument.Asynchronous +} diff --git a/metric/instrument/asyncint64/asyncint64.go b/metric/instrument/asyncint64/asyncint64.go new file mode 100644 index 00000000000..9dfba553d78 --- /dev/null +++ b/metric/instrument/asyncint64/asyncint64.go @@ -0,0 +1,70 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package asyncint64 // import "go.opentelemetry.io/otel/metric/instrument/asyncint64" + +import ( + "context" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric/instrument" +) + +// InstrumentProvider provides access to individual instruments. +type InstrumentProvider interface { + // Counter creates an instrument for recording increasing values. + Counter(name string, opts ...instrument.Option) (Counter, error) + + // UpDownCounter creates an instrument for recording changes of a value. + UpDownCounter(name string, opts ...instrument.Option) (UpDownCounter, error) + + // Gauge creates an instrument for recording the current value. + Gauge(name string, opts ...instrument.Option) (Gauge, error) +} + +// Counter is an instrument that records increasing values. +type Counter interface { + // Observe records the state of the instrument. + // + // It is only valid to call this within a callback. If called outside of the + // registered callback it should have no effect on the instrument, and an + // error will be reported via the error handler. + Observe(ctx context.Context, x int64, attrs ...attribute.KeyValue) + + instrument.Asynchronous +} + +// UpDownCounter is an instrument that records increasing or decresing values. +type UpDownCounter interface { + // Observe records the state of the instrument. + // + // It is only valid to call this within a callback. If called outside of the + // registered callback it should have no effect on the instrument, and an + // error will be reported via the error handler. + Observe(ctx context.Context, x int64, attrs ...attribute.KeyValue) + + instrument.Asynchronous +} + +// Gauge is an instrument that records independent readings. +type Gauge interface { + // Observe records the state of the instrument. + // + // It is only valid to call this within a callback. If called outside of the + // registered callback it should have no effect on the instrument, and an + // error will be reported via the error handler. + Observe(ctx context.Context, x int64, attrs ...attribute.KeyValue) + + instrument.Asynchronous +} diff --git a/metric/instrument/config.go b/metric/instrument/config.go new file mode 100644 index 00000000000..d6ea25a8da2 --- /dev/null +++ b/metric/instrument/config.go @@ -0,0 +1,69 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package instrument // import "go.opentelemetry.io/otel/metric/instrument" + +import "go.opentelemetry.io/otel/metric/unit" + +// Config contains options for metric instrument descriptors. +type Config struct { + description string + unit unit.Unit +} + +// Description describes the instrument in human-readable terms. +func (cfg Config) Description() string { + return cfg.description +} + +// Unit describes the measurement unit for a instrument. +func (cfg Config) Unit() unit.Unit { + return cfg.unit +} + +// Option is an interface for applying metric instrument options. +type Option interface { + applyInstrument(Config) Config +} + +// NewConfig creates a new Config and applies all the given options. +func NewConfig(opts ...Option) Config { + var config Config + for _, o := range opts { + config = o.applyInstrument(config) + } + return config +} + +type optionFunc func(Config) Config + +func (fn optionFunc) applyInstrument(cfg Config) Config { + return fn(cfg) +} + +// WithDescription applies provided description. +func WithDescription(desc string) Option { + return optionFunc(func(cfg Config) Config { + cfg.description = desc + return cfg + }) +} + +// WithUnit applies provided unit. +func WithUnit(unit unit.Unit) Option { + return optionFunc(func(cfg Config) Config { + cfg.unit = unit + return cfg + }) +} diff --git a/metric/noop_test.go b/metric/instrument/instrument.go similarity index 54% rename from metric/noop_test.go rename to metric/instrument/instrument.go index e5a7528a217..e1bbb850d76 100644 --- a/metric/noop_test.go +++ b/metric/instrument/instrument.go @@ -12,23 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -package metric +package instrument // import "go.opentelemetry.io/otel/metric/instrument" -import ( - "testing" -) - -func TestNewNoopMeterProvider(t *testing.T) { - got, want := NewNoopMeterProvider(), noopMeterProvider{} - if got != want { - t.Errorf("NewNoopMeterProvider() returned %#v, want %#v", got, want) - } +// Asynchronous instruments are instruments that are updated within a Callback. +// If an instrument is observed outside of it's callback it should be an error. +// +// This interface is used as a grouping mechanism. +type Asynchronous interface { + asynchronous() } -func TestNoopMeterProviderMeter(t *testing.T) { - mp := NewNoopMeterProvider() - got, want := mp.Meter(""), Meter{} - if got != want { - t.Errorf("noopMeterProvider.Meter() returned %#v, want %#v", got, want) - } +// Synchronous instruments are updated in line with application code. +// +// This interface is used as a grouping mechanism. +type Synchronous interface { + synchronous() } diff --git a/metric/instrument/syncfloat64/syncfloat64.go b/metric/instrument/syncfloat64/syncfloat64.go new file mode 100644 index 00000000000..1989292ecf8 --- /dev/null +++ b/metric/instrument/syncfloat64/syncfloat64.go @@ -0,0 +1,56 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package syncfloat64 // import "go.opentelemetry.io/otel/metric/instrument/syncfloat64" + +import ( + "context" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric/instrument" +) + +// InstrumentProvider provides access to individual instruments. +type InstrumentProvider interface { + // Counter creates an instrument for recording increasing values. + Counter(name string, opts ...instrument.Option) (Counter, error) + // UpDownCounter creates an instrument for recording changes of a value. + UpDownCounter(name string, opts ...instrument.Option) (UpDownCounter, error) + // Histogram creates an instrument for recording a distribution of values. + Histogram(name string, opts ...instrument.Option) (Histogram, error) +} + +// Counter is an instrument that records increasing values. +type Counter interface { + // Add records a change to the counter. + Add(ctx context.Context, incr float64, attrs ...attribute.KeyValue) + + instrument.Synchronous +} + +// UpDownCounter is an instrument that records increasing or decresing values. +type UpDownCounter interface { + // Add records a change to the counter. + Add(ctx context.Context, incr float64, attrs ...attribute.KeyValue) + + instrument.Synchronous +} + +// Histogram is an instrument that records a distribution of values. +type Histogram interface { + // Record adds an additional value to the distribution. + Record(ctx context.Context, incr float64, attrs ...attribute.KeyValue) + + instrument.Synchronous +} diff --git a/metric/instrument/syncint64/syncint64.go b/metric/instrument/syncint64/syncint64.go new file mode 100644 index 00000000000..ee882bcd922 --- /dev/null +++ b/metric/instrument/syncint64/syncint64.go @@ -0,0 +1,56 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package syncint64 // import "go.opentelemetry.io/otel/metric/instrument/syncint64" + +import ( + "context" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric/instrument" +) + +// InstrumentProvider provides access to individual instruments. +type InstrumentProvider interface { + // Counter creates an instrument for recording increasing values. + Counter(name string, opts ...instrument.Option) (Counter, error) + // UpDownCounter creates an instrument for recording changes of a value. + UpDownCounter(name string, opts ...instrument.Option) (UpDownCounter, error) + // Histogram creates an instrument for recording a distribution of values. + Histogram(name string, opts ...instrument.Option) (Histogram, error) +} + +// Counter is an instrument that records increasing values. +type Counter interface { + // Add records a change to the counter. + Add(ctx context.Context, incr int64, attrs ...attribute.KeyValue) + + instrument.Synchronous +} + +// UpDownCounter is an instrument that records increasing or decresing values. +type UpDownCounter interface { + // Add records a change to the counter. + Add(ctx context.Context, incr int64, attrs ...attribute.KeyValue) + + instrument.Synchronous +} + +// Histogram is an instrument that records a distribution of values. +type Histogram interface { + // Record adds an additional value to the distribution. + Record(ctx context.Context, incr int64, attrs ...attribute.KeyValue) + + instrument.Synchronous +} diff --git a/metric/meter.go b/metric/meter.go new file mode 100644 index 00000000000..21fc1c499fb --- /dev/null +++ b/metric/meter.go @@ -0,0 +1,60 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metric // import "go.opentelemetry.io/otel/metric" + +import ( + "context" + + "go.opentelemetry.io/otel/metric/instrument" + "go.opentelemetry.io/otel/metric/instrument/asyncfloat64" + "go.opentelemetry.io/otel/metric/instrument/asyncint64" + "go.opentelemetry.io/otel/metric/instrument/syncfloat64" + "go.opentelemetry.io/otel/metric/instrument/syncint64" +) + +// MeterProvider provides access to named Meter instances, for instrumenting +// an application or library. +type MeterProvider interface { + // Meter creates an instance of a `Meter` interface. The instrumentationName + // must be the name of the library providing instrumentation. This name may + // be the same as the instrumented code only if that code provides built-in + // instrumentation. If the instrumentationName is empty, then a + // implementation defined default name will be used instead. + Meter(instrumentationName string, opts ...MeterOption) Meter +} + +// Meter provides access to instrument instances for recording metrics. +type Meter interface { + // AsyncInt64 is the namespace for the Asynchronous Integer instruments. + // + // To Observe data with instruments it must be registered in a callback. + AsyncInt64() asyncint64.InstrumentProvider + + // AsyncFloat64 is the namespace for the Asynchronous Float instruments + // + // To Observe data with instruments it must be registered in a callback. + AsyncFloat64() asyncfloat64.InstrumentProvider + + // RegisterCallback captures the function that will be called during Collect. + // + // It is only valid to call Observe within the scope of the passed function, + // and only on the instruments that were registered with this call. + RegisterCallback(insts []instrument.Asynchronous, function func(context.Context)) error + + // SyncInt64 is the namespace for the Synchronous Integer instruments + SyncInt64() syncint64.InstrumentProvider + // SyncFloat64 is the namespace for the Synchronous Float instruments + SyncFloat64() syncfloat64.InstrumentProvider +} diff --git a/metric/metric.go b/metric/metric.go deleted file mode 100644 index d8c5a6b3f35..00000000000 --- a/metric/metric.go +++ /dev/null @@ -1,538 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package metric // import "go.opentelemetry.io/otel/metric" - -import ( - "context" - - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" -) - -// MeterProvider supports named Meter instances. -type MeterProvider interface { - // Meter creates an implementation of the Meter interface. - // The instrumentationName must be the name of the library providing - // instrumentation. This name may be the same as the instrumented code - // only if that code provides built-in instrumentation. If the - // instrumentationName is empty, then a implementation defined default - // name will be used instead. - Meter(instrumentationName string, opts ...MeterOption) Meter -} - -// Meter is the creator of metric instruments. -// -// An uninitialized Meter is a no-op implementation. -type Meter struct { - impl sdkapi.MeterImpl -} - -// WrapMeterImpl constructs a `Meter` implementation from a -// `MeterImpl` implementation. -func WrapMeterImpl(impl sdkapi.MeterImpl) Meter { - return Meter{ - impl: impl, - } -} - -// Measurement is used for reporting a synchronous batch of metric -// values. Instances of this type should be created by synchronous -// instruments (e.g., Int64Counter.Measurement()). -// -// Note: This is an alias because it is a first-class member of the -// API but is also part of the lower-level sdkapi interface. -type Measurement = sdkapi.Measurement - -// Observation is used for reporting an asynchronous batch of metric -// values. Instances of this type should be created by asynchronous -// instruments (e.g., Int64GaugeObserver.Observation()). -// -// Note: This is an alias because it is a first-class member of the -// API but is also part of the lower-level sdkapi interface. -type Observation = sdkapi.Observation - -// RecordBatch atomically records a batch of measurements. -func (m Meter) RecordBatch(ctx context.Context, ls []attribute.KeyValue, ms ...Measurement) { - if m.impl == nil { - return - } - m.impl.RecordBatch(ctx, ls, ms...) -} - -// NewBatchObserver creates a new BatchObserver that supports -// making batches of observations for multiple instruments. -func (m Meter) NewBatchObserver(callback BatchObserverFunc) BatchObserver { - return BatchObserver{ - meter: m, - runner: newBatchAsyncRunner(callback), - } -} - -// NewInt64Counter creates a new integer Counter instrument with the -// given name, customized with options. May return an error if the -// name is invalid (e.g., empty) or improperly registered (e.g., -// duplicate registration). -func (m Meter) NewInt64Counter(name string, options ...InstrumentOption) (Int64Counter, error) { - return wrapInt64CounterInstrument( - m.newSync(name, sdkapi.CounterInstrumentKind, number.Int64Kind, options)) -} - -// NewFloat64Counter creates a new floating point Counter with the -// given name, customized with options. May return an error if the -// name is invalid (e.g., empty) or improperly registered (e.g., -// duplicate registration). -func (m Meter) NewFloat64Counter(name string, options ...InstrumentOption) (Float64Counter, error) { - return wrapFloat64CounterInstrument( - m.newSync(name, sdkapi.CounterInstrumentKind, number.Float64Kind, options)) -} - -// NewInt64UpDownCounter creates a new integer UpDownCounter instrument with the -// given name, customized with options. May return an error if the -// name is invalid (e.g., empty) or improperly registered (e.g., -// duplicate registration). -func (m Meter) NewInt64UpDownCounter(name string, options ...InstrumentOption) (Int64UpDownCounter, error) { - return wrapInt64UpDownCounterInstrument( - m.newSync(name, sdkapi.UpDownCounterInstrumentKind, number.Int64Kind, options)) -} - -// NewFloat64UpDownCounter creates a new floating point UpDownCounter with the -// given name, customized with options. May return an error if the -// name is invalid (e.g., empty) or improperly registered (e.g., -// duplicate registration). -func (m Meter) NewFloat64UpDownCounter(name string, options ...InstrumentOption) (Float64UpDownCounter, error) { - return wrapFloat64UpDownCounterInstrument( - m.newSync(name, sdkapi.UpDownCounterInstrumentKind, number.Float64Kind, options)) -} - -// NewInt64Histogram creates a new integer Histogram instrument with the -// given name, customized with options. May return an error if the -// name is invalid (e.g., empty) or improperly registered (e.g., -// duplicate registration). -func (m Meter) NewInt64Histogram(name string, opts ...InstrumentOption) (Int64Histogram, error) { - return wrapInt64HistogramInstrument( - m.newSync(name, sdkapi.HistogramInstrumentKind, number.Int64Kind, opts)) -} - -// NewFloat64Histogram creates a new floating point Histogram with the -// given name, customized with options. May return an error if the -// name is invalid (e.g., empty) or improperly registered (e.g., -// duplicate registration). -func (m Meter) NewFloat64Histogram(name string, opts ...InstrumentOption) (Float64Histogram, error) { - return wrapFloat64HistogramInstrument( - m.newSync(name, sdkapi.HistogramInstrumentKind, number.Float64Kind, opts)) -} - -// NewInt64GaugeObserver creates a new integer GaugeObserver instrument -// with the given name, running a given callback, and customized with -// options. May return an error if the name is invalid (e.g., empty) -// or improperly registered (e.g., duplicate registration). -func (m Meter) NewInt64GaugeObserver(name string, callback Int64ObserverFunc, opts ...InstrumentOption) (Int64GaugeObserver, error) { - if callback == nil { - return wrapInt64GaugeObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil) - } - return wrapInt64GaugeObserverInstrument( - m.newAsync(name, sdkapi.GaugeObserverInstrumentKind, number.Int64Kind, opts, - newInt64AsyncRunner(callback))) -} - -// NewFloat64GaugeObserver creates a new floating point GaugeObserver with -// the given name, running a given callback, and customized with -// options. May return an error if the name is invalid (e.g., empty) -// or improperly registered (e.g., duplicate registration). -func (m Meter) NewFloat64GaugeObserver(name string, callback Float64ObserverFunc, opts ...InstrumentOption) (Float64GaugeObserver, error) { - if callback == nil { - return wrapFloat64GaugeObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil) - } - return wrapFloat64GaugeObserverInstrument( - m.newAsync(name, sdkapi.GaugeObserverInstrumentKind, number.Float64Kind, opts, - newFloat64AsyncRunner(callback))) -} - -// NewInt64CounterObserver creates a new integer CounterObserver instrument -// with the given name, running a given callback, and customized with -// options. May return an error if the name is invalid (e.g., empty) -// or improperly registered (e.g., duplicate registration). -func (m Meter) NewInt64CounterObserver(name string, callback Int64ObserverFunc, opts ...InstrumentOption) (Int64CounterObserver, error) { - if callback == nil { - return wrapInt64CounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil) - } - return wrapInt64CounterObserverInstrument( - m.newAsync(name, sdkapi.CounterObserverInstrumentKind, number.Int64Kind, opts, - newInt64AsyncRunner(callback))) -} - -// NewFloat64CounterObserver creates a new floating point CounterObserver with -// the given name, running a given callback, and customized with -// options. May return an error if the name is invalid (e.g., empty) -// or improperly registered (e.g., duplicate registration). -func (m Meter) NewFloat64CounterObserver(name string, callback Float64ObserverFunc, opts ...InstrumentOption) (Float64CounterObserver, error) { - if callback == nil { - return wrapFloat64CounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil) - } - return wrapFloat64CounterObserverInstrument( - m.newAsync(name, sdkapi.CounterObserverInstrumentKind, number.Float64Kind, opts, - newFloat64AsyncRunner(callback))) -} - -// NewInt64UpDownCounterObserver creates a new integer UpDownCounterObserver instrument -// with the given name, running a given callback, and customized with -// options. May return an error if the name is invalid (e.g., empty) -// or improperly registered (e.g., duplicate registration). -func (m Meter) NewInt64UpDownCounterObserver(name string, callback Int64ObserverFunc, opts ...InstrumentOption) (Int64UpDownCounterObserver, error) { - if callback == nil { - return wrapInt64UpDownCounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil) - } - return wrapInt64UpDownCounterObserverInstrument( - m.newAsync(name, sdkapi.UpDownCounterObserverInstrumentKind, number.Int64Kind, opts, - newInt64AsyncRunner(callback))) -} - -// NewFloat64UpDownCounterObserver creates a new floating point UpDownCounterObserver with -// the given name, running a given callback, and customized with -// options. May return an error if the name is invalid (e.g., empty) -// or improperly registered (e.g., duplicate registration). -func (m Meter) NewFloat64UpDownCounterObserver(name string, callback Float64ObserverFunc, opts ...InstrumentOption) (Float64UpDownCounterObserver, error) { - if callback == nil { - return wrapFloat64UpDownCounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil) - } - return wrapFloat64UpDownCounterObserverInstrument( - m.newAsync(name, sdkapi.UpDownCounterObserverInstrumentKind, number.Float64Kind, opts, - newFloat64AsyncRunner(callback))) -} - -// NewInt64GaugeObserver creates a new integer GaugeObserver instrument -// with the given name, running in a batch callback, and customized with -// options. May return an error if the name is invalid (e.g., empty) -// or improperly registered (e.g., duplicate registration). -func (b BatchObserver) NewInt64GaugeObserver(name string, opts ...InstrumentOption) (Int64GaugeObserver, error) { - if b.runner == nil { - return wrapInt64GaugeObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil) - } - return wrapInt64GaugeObserverInstrument( - b.meter.newAsync(name, sdkapi.GaugeObserverInstrumentKind, number.Int64Kind, opts, b.runner)) -} - -// NewFloat64GaugeObserver creates a new floating point GaugeObserver with -// the given name, running in a batch callback, and customized with -// options. May return an error if the name is invalid (e.g., empty) -// or improperly registered (e.g., duplicate registration). -func (b BatchObserver) NewFloat64GaugeObserver(name string, opts ...InstrumentOption) (Float64GaugeObserver, error) { - if b.runner == nil { - return wrapFloat64GaugeObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil) - } - return wrapFloat64GaugeObserverInstrument( - b.meter.newAsync(name, sdkapi.GaugeObserverInstrumentKind, number.Float64Kind, opts, - b.runner)) -} - -// NewInt64CounterObserver creates a new integer CounterObserver instrument -// with the given name, running in a batch callback, and customized with -// options. May return an error if the name is invalid (e.g., empty) -// or improperly registered (e.g., duplicate registration). -func (b BatchObserver) NewInt64CounterObserver(name string, opts ...InstrumentOption) (Int64CounterObserver, error) { - if b.runner == nil { - return wrapInt64CounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil) - } - return wrapInt64CounterObserverInstrument( - b.meter.newAsync(name, sdkapi.CounterObserverInstrumentKind, number.Int64Kind, opts, b.runner)) -} - -// NewFloat64CounterObserver creates a new floating point CounterObserver with -// the given name, running in a batch callback, and customized with -// options. May return an error if the name is invalid (e.g., empty) -// or improperly registered (e.g., duplicate registration). -func (b BatchObserver) NewFloat64CounterObserver(name string, opts ...InstrumentOption) (Float64CounterObserver, error) { - if b.runner == nil { - return wrapFloat64CounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil) - } - return wrapFloat64CounterObserverInstrument( - b.meter.newAsync(name, sdkapi.CounterObserverInstrumentKind, number.Float64Kind, opts, - b.runner)) -} - -// NewInt64UpDownCounterObserver creates a new integer UpDownCounterObserver instrument -// with the given name, running in a batch callback, and customized with -// options. May return an error if the name is invalid (e.g., empty) -// or improperly registered (e.g., duplicate registration). -func (b BatchObserver) NewInt64UpDownCounterObserver(name string, opts ...InstrumentOption) (Int64UpDownCounterObserver, error) { - if b.runner == nil { - return wrapInt64UpDownCounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil) - } - return wrapInt64UpDownCounterObserverInstrument( - b.meter.newAsync(name, sdkapi.UpDownCounterObserverInstrumentKind, number.Int64Kind, opts, b.runner)) -} - -// NewFloat64UpDownCounterObserver creates a new floating point UpDownCounterObserver with -// the given name, running in a batch callback, and customized with -// options. May return an error if the name is invalid (e.g., empty) -// or improperly registered (e.g., duplicate registration). -func (b BatchObserver) NewFloat64UpDownCounterObserver(name string, opts ...InstrumentOption) (Float64UpDownCounterObserver, error) { - if b.runner == nil { - return wrapFloat64UpDownCounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil) - } - return wrapFloat64UpDownCounterObserverInstrument( - b.meter.newAsync(name, sdkapi.UpDownCounterObserverInstrumentKind, number.Float64Kind, opts, - b.runner)) -} - -// MeterImpl returns the underlying MeterImpl of this Meter. -func (m Meter) MeterImpl() sdkapi.MeterImpl { - return m.impl -} - -// newAsync constructs one new asynchronous instrument. -func (m Meter) newAsync( - name string, - mkind sdkapi.InstrumentKind, - nkind number.Kind, - opts []InstrumentOption, - runner sdkapi.AsyncRunner, -) ( - sdkapi.AsyncImpl, - error, -) { - if m.impl == nil { - return sdkapi.NewNoopAsyncInstrument(), nil - } - cfg := NewInstrumentConfig(opts...) - desc := sdkapi.NewDescriptor(name, mkind, nkind, cfg.description, cfg.unit) - return m.impl.NewAsyncInstrument(desc, runner) -} - -// newSync constructs one new synchronous instrument. -func (m Meter) newSync( - name string, - metricKind sdkapi.InstrumentKind, - numberKind number.Kind, - opts []InstrumentOption, -) ( - sdkapi.SyncImpl, - error, -) { - if m.impl == nil { - return sdkapi.NewNoopSyncInstrument(), nil - } - cfg := NewInstrumentConfig(opts...) - desc := sdkapi.NewDescriptor(name, metricKind, numberKind, cfg.description, cfg.unit) - return m.impl.NewSyncInstrument(desc) -} - -// MeterMust is a wrapper for Meter interfaces that panics when any -// instrument constructor encounters an error. -type MeterMust struct { - meter Meter -} - -// BatchObserverMust is a wrapper for BatchObserver that panics when -// any instrument constructor encounters an error. -type BatchObserverMust struct { - batch BatchObserver -} - -// Must constructs a MeterMust implementation from a Meter, allowing -// the application to panic when any instrument constructor yields an -// error. -func Must(meter Meter) MeterMust { - return MeterMust{meter: meter} -} - -// NewInt64Counter calls `Meter.NewInt64Counter` and returns the -// instrument, panicking if it encounters an error. -func (mm MeterMust) NewInt64Counter(name string, cos ...InstrumentOption) Int64Counter { - if inst, err := mm.meter.NewInt64Counter(name, cos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewFloat64Counter calls `Meter.NewFloat64Counter` and returns the -// instrument, panicking if it encounters an error. -func (mm MeterMust) NewFloat64Counter(name string, cos ...InstrumentOption) Float64Counter { - if inst, err := mm.meter.NewFloat64Counter(name, cos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewInt64UpDownCounter calls `Meter.NewInt64UpDownCounter` and returns the -// instrument, panicking if it encounters an error. -func (mm MeterMust) NewInt64UpDownCounter(name string, cos ...InstrumentOption) Int64UpDownCounter { - if inst, err := mm.meter.NewInt64UpDownCounter(name, cos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewFloat64UpDownCounter calls `Meter.NewFloat64UpDownCounter` and returns the -// instrument, panicking if it encounters an error. -func (mm MeterMust) NewFloat64UpDownCounter(name string, cos ...InstrumentOption) Float64UpDownCounter { - if inst, err := mm.meter.NewFloat64UpDownCounter(name, cos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewInt64Histogram calls `Meter.NewInt64Histogram` and returns the -// instrument, panicking if it encounters an error. -func (mm MeterMust) NewInt64Histogram(name string, mos ...InstrumentOption) Int64Histogram { - if inst, err := mm.meter.NewInt64Histogram(name, mos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewFloat64Histogram calls `Meter.NewFloat64Histogram` and returns the -// instrument, panicking if it encounters an error. -func (mm MeterMust) NewFloat64Histogram(name string, mos ...InstrumentOption) Float64Histogram { - if inst, err := mm.meter.NewFloat64Histogram(name, mos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewInt64GaugeObserver calls `Meter.NewInt64GaugeObserver` and -// returns the instrument, panicking if it encounters an error. -func (mm MeterMust) NewInt64GaugeObserver(name string, callback Int64ObserverFunc, oos ...InstrumentOption) Int64GaugeObserver { - if inst, err := mm.meter.NewInt64GaugeObserver(name, callback, oos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewFloat64GaugeObserver calls `Meter.NewFloat64GaugeObserver` and -// returns the instrument, panicking if it encounters an error. -func (mm MeterMust) NewFloat64GaugeObserver(name string, callback Float64ObserverFunc, oos ...InstrumentOption) Float64GaugeObserver { - if inst, err := mm.meter.NewFloat64GaugeObserver(name, callback, oos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewInt64CounterObserver calls `Meter.NewInt64CounterObserver` and -// returns the instrument, panicking if it encounters an error. -func (mm MeterMust) NewInt64CounterObserver(name string, callback Int64ObserverFunc, oos ...InstrumentOption) Int64CounterObserver { - if inst, err := mm.meter.NewInt64CounterObserver(name, callback, oos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewFloat64CounterObserver calls `Meter.NewFloat64CounterObserver` and -// returns the instrument, panicking if it encounters an error. -func (mm MeterMust) NewFloat64CounterObserver(name string, callback Float64ObserverFunc, oos ...InstrumentOption) Float64CounterObserver { - if inst, err := mm.meter.NewFloat64CounterObserver(name, callback, oos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewInt64UpDownCounterObserver calls `Meter.NewInt64UpDownCounterObserver` and -// returns the instrument, panicking if it encounters an error. -func (mm MeterMust) NewInt64UpDownCounterObserver(name string, callback Int64ObserverFunc, oos ...InstrumentOption) Int64UpDownCounterObserver { - if inst, err := mm.meter.NewInt64UpDownCounterObserver(name, callback, oos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewFloat64UpDownCounterObserver calls `Meter.NewFloat64UpDownCounterObserver` and -// returns the instrument, panicking if it encounters an error. -func (mm MeterMust) NewFloat64UpDownCounterObserver(name string, callback Float64ObserverFunc, oos ...InstrumentOption) Float64UpDownCounterObserver { - if inst, err := mm.meter.NewFloat64UpDownCounterObserver(name, callback, oos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewBatchObserver returns a wrapper around BatchObserver that panics -// when any instrument constructor returns an error. -func (mm MeterMust) NewBatchObserver(callback BatchObserverFunc) BatchObserverMust { - return BatchObserverMust{ - batch: mm.meter.NewBatchObserver(callback), - } -} - -// NewInt64GaugeObserver calls `BatchObserver.NewInt64GaugeObserver` and -// returns the instrument, panicking if it encounters an error. -func (bm BatchObserverMust) NewInt64GaugeObserver(name string, oos ...InstrumentOption) Int64GaugeObserver { - if inst, err := bm.batch.NewInt64GaugeObserver(name, oos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewFloat64GaugeObserver calls `BatchObserver.NewFloat64GaugeObserver` and -// returns the instrument, panicking if it encounters an error. -func (bm BatchObserverMust) NewFloat64GaugeObserver(name string, oos ...InstrumentOption) Float64GaugeObserver { - if inst, err := bm.batch.NewFloat64GaugeObserver(name, oos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewInt64CounterObserver calls `BatchObserver.NewInt64CounterObserver` and -// returns the instrument, panicking if it encounters an error. -func (bm BatchObserverMust) NewInt64CounterObserver(name string, oos ...InstrumentOption) Int64CounterObserver { - if inst, err := bm.batch.NewInt64CounterObserver(name, oos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewFloat64CounterObserver calls `BatchObserver.NewFloat64CounterObserver` and -// returns the instrument, panicking if it encounters an error. -func (bm BatchObserverMust) NewFloat64CounterObserver(name string, oos ...InstrumentOption) Float64CounterObserver { - if inst, err := bm.batch.NewFloat64CounterObserver(name, oos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewInt64UpDownCounterObserver calls `BatchObserver.NewInt64UpDownCounterObserver` and -// returns the instrument, panicking if it encounters an error. -func (bm BatchObserverMust) NewInt64UpDownCounterObserver(name string, oos ...InstrumentOption) Int64UpDownCounterObserver { - if inst, err := bm.batch.NewInt64UpDownCounterObserver(name, oos...); err != nil { - panic(err) - } else { - return inst - } -} - -// NewFloat64UpDownCounterObserver calls `BatchObserver.NewFloat64UpDownCounterObserver` and -// returns the instrument, panicking if it encounters an error. -func (bm BatchObserverMust) NewFloat64UpDownCounterObserver(name string, oos ...InstrumentOption) Float64UpDownCounterObserver { - if inst, err := bm.batch.NewFloat64UpDownCounterObserver(name, oos...); err != nil { - panic(err) - } else { - return inst - } -} diff --git a/metric/metric_instrument.go b/metric/metric_instrument.go deleted file mode 100644 index 2da24c8f211..00000000000 --- a/metric/metric_instrument.go +++ /dev/null @@ -1,464 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package metric // import "go.opentelemetry.io/otel/metric" - -import ( - "context" - "errors" - - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" -) - -// ErrSDKReturnedNilImpl is returned when a new `MeterImpl` returns nil. -var ErrSDKReturnedNilImpl = errors.New("SDK returned a nil implementation") - -// Int64ObserverFunc is a type of callback that integral -// observers run. -type Int64ObserverFunc func(context.Context, Int64ObserverResult) - -// Float64ObserverFunc is a type of callback that floating point -// observers run. -type Float64ObserverFunc func(context.Context, Float64ObserverResult) - -// BatchObserverFunc is a callback argument for use with any -// Observer instrument that will be reported as a batch of -// observations. -type BatchObserverFunc func(context.Context, BatchObserverResult) - -// Int64ObserverResult is passed to an observer callback to capture -// observations for one asynchronous integer metric instrument. -type Int64ObserverResult struct { - instrument sdkapi.AsyncImpl - function func([]attribute.KeyValue, ...Observation) -} - -// Float64ObserverResult is passed to an observer callback to capture -// observations for one asynchronous floating point metric instrument. -type Float64ObserverResult struct { - instrument sdkapi.AsyncImpl - function func([]attribute.KeyValue, ...Observation) -} - -// BatchObserverResult is passed to a batch observer callback to -// capture observations for multiple asynchronous instruments. -type BatchObserverResult struct { - function func([]attribute.KeyValue, ...Observation) -} - -// Observe captures a single integer value from the associated -// instrument callback, with the given labels. -func (ir Int64ObserverResult) Observe(value int64, labels ...attribute.KeyValue) { - ir.function(labels, sdkapi.NewObservation(ir.instrument, number.NewInt64Number(value))) -} - -// Observe captures a single floating point value from the associated -// instrument callback, with the given labels. -func (fr Float64ObserverResult) Observe(value float64, labels ...attribute.KeyValue) { - fr.function(labels, sdkapi.NewObservation(fr.instrument, number.NewFloat64Number(value))) -} - -// Observe captures a multiple observations from the associated batch -// instrument callback, with the given labels. -func (br BatchObserverResult) Observe(labels []attribute.KeyValue, obs ...Observation) { - br.function(labels, obs...) -} - -var _ sdkapi.AsyncSingleRunner = (*Int64ObserverFunc)(nil) -var _ sdkapi.AsyncSingleRunner = (*Float64ObserverFunc)(nil) -var _ sdkapi.AsyncBatchRunner = (*BatchObserverFunc)(nil) - -// newInt64AsyncRunner returns a single-observer callback for integer Observer instruments. -func newInt64AsyncRunner(c Int64ObserverFunc) sdkapi.AsyncSingleRunner { - return &c -} - -// newFloat64AsyncRunner returns a single-observer callback for floating point Observer instruments. -func newFloat64AsyncRunner(c Float64ObserverFunc) sdkapi.AsyncSingleRunner { - return &c -} - -// newBatchAsyncRunner returns a batch-observer callback use with multiple Observer instruments. -func newBatchAsyncRunner(c BatchObserverFunc) sdkapi.AsyncBatchRunner { - return &c -} - -// AnyRunner implements AsyncRunner. -func (*Int64ObserverFunc) AnyRunner() {} - -// AnyRunner implements AsyncRunner. -func (*Float64ObserverFunc) AnyRunner() {} - -// AnyRunner implements AsyncRunner. -func (*BatchObserverFunc) AnyRunner() {} - -// Run implements AsyncSingleRunner. -func (i *Int64ObserverFunc) Run(ctx context.Context, impl sdkapi.AsyncImpl, function func([]attribute.KeyValue, ...Observation)) { - (*i)(ctx, Int64ObserverResult{ - instrument: impl, - function: function, - }) -} - -// Run implements AsyncSingleRunner. -func (f *Float64ObserverFunc) Run(ctx context.Context, impl sdkapi.AsyncImpl, function func([]attribute.KeyValue, ...Observation)) { - (*f)(ctx, Float64ObserverResult{ - instrument: impl, - function: function, - }) -} - -// Run implements AsyncBatchRunner. -func (b *BatchObserverFunc) Run(ctx context.Context, function func([]attribute.KeyValue, ...Observation)) { - (*b)(ctx, BatchObserverResult{ - function: function, - }) -} - -// wrapInt64GaugeObserverInstrument converts an AsyncImpl into Int64GaugeObserver. -func wrapInt64GaugeObserverInstrument(asyncInst sdkapi.AsyncImpl, err error) (Int64GaugeObserver, error) { - common, err := checkNewAsync(asyncInst, err) - return Int64GaugeObserver{asyncInstrument: common}, err -} - -// wrapFloat64GaugeObserverInstrument converts an AsyncImpl into Float64GaugeObserver. -func wrapFloat64GaugeObserverInstrument(asyncInst sdkapi.AsyncImpl, err error) (Float64GaugeObserver, error) { - common, err := checkNewAsync(asyncInst, err) - return Float64GaugeObserver{asyncInstrument: common}, err -} - -// wrapInt64CounterObserverInstrument converts an AsyncImpl into Int64CounterObserver. -func wrapInt64CounterObserverInstrument(asyncInst sdkapi.AsyncImpl, err error) (Int64CounterObserver, error) { - common, err := checkNewAsync(asyncInst, err) - return Int64CounterObserver{asyncInstrument: common}, err -} - -// wrapFloat64CounterObserverInstrument converts an AsyncImpl into Float64CounterObserver. -func wrapFloat64CounterObserverInstrument(asyncInst sdkapi.AsyncImpl, err error) (Float64CounterObserver, error) { - common, err := checkNewAsync(asyncInst, err) - return Float64CounterObserver{asyncInstrument: common}, err -} - -// wrapInt64UpDownCounterObserverInstrument converts an AsyncImpl into Int64UpDownCounterObserver. -func wrapInt64UpDownCounterObserverInstrument(asyncInst sdkapi.AsyncImpl, err error) (Int64UpDownCounterObserver, error) { - common, err := checkNewAsync(asyncInst, err) - return Int64UpDownCounterObserver{asyncInstrument: common}, err -} - -// wrapFloat64UpDownCounterObserverInstrument converts an AsyncImpl into Float64UpDownCounterObserver. -func wrapFloat64UpDownCounterObserverInstrument(asyncInst sdkapi.AsyncImpl, err error) (Float64UpDownCounterObserver, error) { - common, err := checkNewAsync(asyncInst, err) - return Float64UpDownCounterObserver{asyncInstrument: common}, err -} - -// BatchObserver represents an Observer callback that can report -// observations for multiple instruments. -type BatchObserver struct { - meter Meter - runner sdkapi.AsyncBatchRunner -} - -// Int64GaugeObserver is a metric that captures a set of int64 values at a -// point in time. -type Int64GaugeObserver struct { - asyncInstrument -} - -// Float64GaugeObserver is a metric that captures a set of float64 values -// at a point in time. -type Float64GaugeObserver struct { - asyncInstrument -} - -// Int64CounterObserver is a metric that captures a precomputed sum of -// int64 values at a point in time. -type Int64CounterObserver struct { - asyncInstrument -} - -// Float64CounterObserver is a metric that captures a precomputed sum of -// float64 values at a point in time. -type Float64CounterObserver struct { - asyncInstrument -} - -// Int64UpDownCounterObserver is a metric that captures a precomputed sum of -// int64 values at a point in time. -type Int64UpDownCounterObserver struct { - asyncInstrument -} - -// Float64UpDownCounterObserver is a metric that captures a precomputed sum of -// float64 values at a point in time. -type Float64UpDownCounterObserver struct { - asyncInstrument -} - -// Observation returns an Observation, a BatchObserverFunc -// argument, for an asynchronous integer instrument. -// This returns an implementation-level object for use by the SDK, -// users should not refer to this. -func (i Int64GaugeObserver) Observation(v int64) Observation { - return sdkapi.NewObservation(i.instrument, number.NewInt64Number(v)) -} - -// Observation returns an Observation, a BatchObserverFunc -// argument, for an asynchronous integer instrument. -// This returns an implementation-level object for use by the SDK, -// users should not refer to this. -func (f Float64GaugeObserver) Observation(v float64) Observation { - return sdkapi.NewObservation(f.instrument, number.NewFloat64Number(v)) -} - -// Observation returns an Observation, a BatchObserverFunc -// argument, for an asynchronous integer instrument. -// This returns an implementation-level object for use by the SDK, -// users should not refer to this. -func (i Int64CounterObserver) Observation(v int64) Observation { - return sdkapi.NewObservation(i.instrument, number.NewInt64Number(v)) -} - -// Observation returns an Observation, a BatchObserverFunc -// argument, for an asynchronous integer instrument. -// This returns an implementation-level object for use by the SDK, -// users should not refer to this. -func (f Float64CounterObserver) Observation(v float64) Observation { - return sdkapi.NewObservation(f.instrument, number.NewFloat64Number(v)) -} - -// Observation returns an Observation, a BatchObserverFunc -// argument, for an asynchronous integer instrument. -// This returns an implementation-level object for use by the SDK, -// users should not refer to this. -func (i Int64UpDownCounterObserver) Observation(v int64) Observation { - return sdkapi.NewObservation(i.instrument, number.NewInt64Number(v)) -} - -// Observation returns an Observation, a BatchObserverFunc -// argument, for an asynchronous integer instrument. -// This returns an implementation-level object for use by the SDK, -// users should not refer to this. -func (f Float64UpDownCounterObserver) Observation(v float64) Observation { - return sdkapi.NewObservation(f.instrument, number.NewFloat64Number(v)) -} - -// syncInstrument contains a SyncImpl. -type syncInstrument struct { - instrument sdkapi.SyncImpl -} - -// asyncInstrument contains a AsyncImpl. -type asyncInstrument struct { - instrument sdkapi.AsyncImpl -} - -// AsyncImpl implements AsyncImpl. -func (a asyncInstrument) AsyncImpl() sdkapi.AsyncImpl { - return a.instrument -} - -// SyncImpl returns the implementation object for synchronous instruments. -func (s syncInstrument) SyncImpl() sdkapi.SyncImpl { - return s.instrument -} - -func (s syncInstrument) float64Measurement(value float64) Measurement { - return sdkapi.NewMeasurement(s.instrument, number.NewFloat64Number(value)) -} - -func (s syncInstrument) int64Measurement(value int64) Measurement { - return sdkapi.NewMeasurement(s.instrument, number.NewInt64Number(value)) -} - -func (s syncInstrument) directRecord(ctx context.Context, number number.Number, labels []attribute.KeyValue) { - s.instrument.RecordOne(ctx, number, labels) -} - -// checkNewAsync receives an AsyncImpl and potential -// error, and returns the same types, checking for and ensuring that -// the returned interface is not nil. -func checkNewAsync(instrument sdkapi.AsyncImpl, err error) (asyncInstrument, error) { - if instrument == nil { - if err == nil { - err = ErrSDKReturnedNilImpl - } - instrument = sdkapi.NewNoopAsyncInstrument() - } - return asyncInstrument{ - instrument: instrument, - }, err -} - -// checkNewSync receives an SyncImpl and potential -// error, and returns the same types, checking for and ensuring that -// the returned interface is not nil. -func checkNewSync(instrument sdkapi.SyncImpl, err error) (syncInstrument, error) { - if instrument == nil { - if err == nil { - err = ErrSDKReturnedNilImpl - } - // Note: an alternate behavior would be to synthesize a new name - // or group all duplicately-named instruments of a certain type - // together and use a tag for the original name, e.g., - // name = 'invalid.counter.int64' - // label = 'original-name=duplicate-counter-name' - instrument = sdkapi.NewNoopSyncInstrument() - } - return syncInstrument{ - instrument: instrument, - }, err -} - -// wrapInt64CounterInstrument converts a SyncImpl into Int64Counter. -func wrapInt64CounterInstrument(syncInst sdkapi.SyncImpl, err error) (Int64Counter, error) { - common, err := checkNewSync(syncInst, err) - return Int64Counter{syncInstrument: common}, err -} - -// wrapFloat64CounterInstrument converts a SyncImpl into Float64Counter. -func wrapFloat64CounterInstrument(syncInst sdkapi.SyncImpl, err error) (Float64Counter, error) { - common, err := checkNewSync(syncInst, err) - return Float64Counter{syncInstrument: common}, err -} - -// wrapInt64UpDownCounterInstrument converts a SyncImpl into Int64UpDownCounter. -func wrapInt64UpDownCounterInstrument(syncInst sdkapi.SyncImpl, err error) (Int64UpDownCounter, error) { - common, err := checkNewSync(syncInst, err) - return Int64UpDownCounter{syncInstrument: common}, err -} - -// wrapFloat64UpDownCounterInstrument converts a SyncImpl into Float64UpDownCounter. -func wrapFloat64UpDownCounterInstrument(syncInst sdkapi.SyncImpl, err error) (Float64UpDownCounter, error) { - common, err := checkNewSync(syncInst, err) - return Float64UpDownCounter{syncInstrument: common}, err -} - -// wrapInt64HistogramInstrument converts a SyncImpl into Int64Histogram. -func wrapInt64HistogramInstrument(syncInst sdkapi.SyncImpl, err error) (Int64Histogram, error) { - common, err := checkNewSync(syncInst, err) - return Int64Histogram{syncInstrument: common}, err -} - -// wrapFloat64HistogramInstrument converts a SyncImpl into Float64Histogram. -func wrapFloat64HistogramInstrument(syncInst sdkapi.SyncImpl, err error) (Float64Histogram, error) { - common, err := checkNewSync(syncInst, err) - return Float64Histogram{syncInstrument: common}, err -} - -// Float64Counter is a metric that accumulates float64 values. -type Float64Counter struct { - syncInstrument -} - -// Int64Counter is a metric that accumulates int64 values. -type Int64Counter struct { - syncInstrument -} - -// Measurement creates a Measurement object to use with batch -// recording. -func (c Float64Counter) Measurement(value float64) Measurement { - return c.float64Measurement(value) -} - -// Measurement creates a Measurement object to use with batch -// recording. -func (c Int64Counter) Measurement(value int64) Measurement { - return c.int64Measurement(value) -} - -// Add adds the value to the counter's sum. The labels should contain -// the keys and values to be associated with this value. -func (c Float64Counter) Add(ctx context.Context, value float64, labels ...attribute.KeyValue) { - c.directRecord(ctx, number.NewFloat64Number(value), labels) -} - -// Add adds the value to the counter's sum. The labels should contain -// the keys and values to be associated with this value. -func (c Int64Counter) Add(ctx context.Context, value int64, labels ...attribute.KeyValue) { - c.directRecord(ctx, number.NewInt64Number(value), labels) -} - -// Float64UpDownCounter is a metric instrument that sums floating -// point values. -type Float64UpDownCounter struct { - syncInstrument -} - -// Int64UpDownCounter is a metric instrument that sums integer values. -type Int64UpDownCounter struct { - syncInstrument -} - -// Measurement creates a Measurement object to use with batch -// recording. -func (c Float64UpDownCounter) Measurement(value float64) Measurement { - return c.float64Measurement(value) -} - -// Measurement creates a Measurement object to use with batch -// recording. -func (c Int64UpDownCounter) Measurement(value int64) Measurement { - return c.int64Measurement(value) -} - -// Add adds the value to the counter's sum. The labels should contain -// the keys and values to be associated with this value. -func (c Float64UpDownCounter) Add(ctx context.Context, value float64, labels ...attribute.KeyValue) { - c.directRecord(ctx, number.NewFloat64Number(value), labels) -} - -// Add adds the value to the counter's sum. The labels should contain -// the keys and values to be associated with this value. -func (c Int64UpDownCounter) Add(ctx context.Context, value int64, labels ...attribute.KeyValue) { - c.directRecord(ctx, number.NewInt64Number(value), labels) -} - -// Float64Histogram is a metric that records float64 values. -type Float64Histogram struct { - syncInstrument -} - -// Int64Histogram is a metric that records int64 values. -type Int64Histogram struct { - syncInstrument -} - -// Measurement creates a Measurement object to use with batch -// recording. -func (c Float64Histogram) Measurement(value float64) Measurement { - return c.float64Measurement(value) -} - -// Measurement creates a Measurement object to use with batch -// recording. -func (c Int64Histogram) Measurement(value int64) Measurement { - return c.int64Measurement(value) -} - -// Record adds a new value to the list of Histogram's records. The -// labels should contain the keys and values to be associated with -// this value. -func (c Float64Histogram) Record(ctx context.Context, value float64, labels ...attribute.KeyValue) { - c.directRecord(ctx, number.NewFloat64Number(value), labels) -} - -// Record adds a new value to the Histogram's distribution. The -// labels should contain the keys and values to be associated with -// this value. -func (c Int64Histogram) Record(ctx context.Context, value int64, labels ...attribute.KeyValue) { - c.directRecord(ctx, number.NewInt64Number(value), labels) -} diff --git a/metric/metric_test.go b/metric/metric_test.go deleted file mode 100644 index ab8e916b829..00000000000 --- a/metric/metric_test.go +++ /dev/null @@ -1,497 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package metric_test - -import ( - "context" - "errors" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/metrictest" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" - "go.opentelemetry.io/otel/metric/unit" -) - -var Must = metric.Must - -var ( - syncKinds = []sdkapi.InstrumentKind{ - sdkapi.HistogramInstrumentKind, - sdkapi.CounterInstrumentKind, - sdkapi.UpDownCounterInstrumentKind, - } - asyncKinds = []sdkapi.InstrumentKind{ - sdkapi.GaugeObserverInstrumentKind, - sdkapi.CounterObserverInstrumentKind, - sdkapi.UpDownCounterObserverInstrumentKind, - } - addingKinds = []sdkapi.InstrumentKind{ - sdkapi.CounterInstrumentKind, - sdkapi.UpDownCounterInstrumentKind, - sdkapi.CounterObserverInstrumentKind, - sdkapi.UpDownCounterObserverInstrumentKind, - } - groupingKinds = []sdkapi.InstrumentKind{ - sdkapi.HistogramInstrumentKind, - sdkapi.GaugeObserverInstrumentKind, - } - - monotonicKinds = []sdkapi.InstrumentKind{ - sdkapi.CounterInstrumentKind, - sdkapi.CounterObserverInstrumentKind, - } - - nonMonotonicKinds = []sdkapi.InstrumentKind{ - sdkapi.UpDownCounterInstrumentKind, - sdkapi.UpDownCounterObserverInstrumentKind, - sdkapi.HistogramInstrumentKind, - sdkapi.GaugeObserverInstrumentKind, - } - - precomputedSumKinds = []sdkapi.InstrumentKind{ - sdkapi.CounterObserverInstrumentKind, - sdkapi.UpDownCounterObserverInstrumentKind, - } - - nonPrecomputedSumKinds = []sdkapi.InstrumentKind{ - sdkapi.CounterInstrumentKind, - sdkapi.UpDownCounterInstrumentKind, - sdkapi.HistogramInstrumentKind, - sdkapi.GaugeObserverInstrumentKind, - } -) - -func TestSynchronous(t *testing.T) { - for _, k := range syncKinds { - require.True(t, k.Synchronous()) - require.False(t, k.Asynchronous()) - } - for _, k := range asyncKinds { - require.True(t, k.Asynchronous()) - require.False(t, k.Synchronous()) - } -} - -func TestGrouping(t *testing.T) { - for _, k := range groupingKinds { - require.True(t, k.Grouping()) - require.False(t, k.Adding()) - } - for _, k := range addingKinds { - require.True(t, k.Adding()) - require.False(t, k.Grouping()) - } -} - -func TestMonotonic(t *testing.T) { - for _, k := range monotonicKinds { - require.True(t, k.Monotonic()) - } - for _, k := range nonMonotonicKinds { - require.False(t, k.Monotonic()) - } -} - -func TestPrecomputedSum(t *testing.T) { - for _, k := range precomputedSumKinds { - require.True(t, k.PrecomputedSum()) - } - for _, k := range nonPrecomputedSumKinds { - require.False(t, k.PrecomputedSum()) - } -} - -func checkSyncBatches(ctx context.Context, t *testing.T, labels []attribute.KeyValue, provider *metrictest.MeterProvider, nkind number.Kind, mkind sdkapi.InstrumentKind, instrument sdkapi.InstrumentImpl, expected ...float64) { - t.Helper() - - batchesCount := len(provider.MeasurementBatches) - if len(provider.MeasurementBatches) != len(expected) { - t.Errorf("Expected %d recorded measurement batches, got %d", batchesCount, len(provider.MeasurementBatches)) - } - recorded := metrictest.AsStructs(provider.MeasurementBatches) - - for i, batch := range provider.MeasurementBatches { - if len(batch.Measurements) != 1 { - t.Errorf("Expected 1 measurement in batch %d, got %d", i, len(batch.Measurements)) - } - - measurement := batch.Measurements[0] - descriptor := measurement.Instrument.Descriptor() - - expected := metrictest.Measured{ - Name: descriptor.Name(), - Library: metrictest.Library{ - InstrumentationName: "apitest", - }, - Labels: metrictest.LabelsToMap(labels...), - Number: metrictest.ResolveNumberByKind(t, nkind, expected[i]), - } - require.Equal(t, expected, recorded[i]) - } -} - -func TestOptions(t *testing.T) { - type testcase struct { - name string - opts []metric.InstrumentOption - desc string - unit unit.Unit - } - testcases := []testcase{ - { - name: "no opts", - opts: nil, - desc: "", - unit: "", - }, - { - name: "description", - opts: []metric.InstrumentOption{ - metric.WithDescription("stuff"), - }, - desc: "stuff", - unit: "", - }, - { - name: "description override", - opts: []metric.InstrumentOption{ - metric.WithDescription("stuff"), - metric.WithDescription("things"), - }, - desc: "things", - unit: "", - }, - { - name: "unit", - opts: []metric.InstrumentOption{ - metric.WithUnit("s"), - }, - desc: "", - unit: "s", - }, - { - name: "description override", - opts: []metric.InstrumentOption{ - metric.WithDescription("stuff"), - metric.WithDescription("things"), - }, - desc: "things", - unit: "", - }, - { - name: "unit", - opts: []metric.InstrumentOption{ - metric.WithUnit("s"), - }, - desc: "", - unit: "s", - }, - - { - name: "unit override", - opts: []metric.InstrumentOption{ - metric.WithUnit("s"), - metric.WithUnit("h"), - }, - desc: "", - unit: "h", - }, - { - name: "all", - opts: []metric.InstrumentOption{ - metric.WithDescription("stuff"), - metric.WithUnit("s"), - }, - desc: "stuff", - unit: "s", - }, - } - for idx, tt := range testcases { - t.Logf("Testing counter case %s (%d)", tt.name, idx) - cfg := metric.NewInstrumentConfig(tt.opts...) - if diff := cmp.Diff(cfg.Description(), tt.desc); diff != "" { - t.Errorf("Compare Description: -got +want %s", diff) - } - if diff := cmp.Diff(cfg.Unit(), tt.unit); diff != "" { - t.Errorf("Compare Unit: -got +want %s", diff) - } - } -} -func testPair() (*metrictest.MeterProvider, metric.Meter) { - provider := metrictest.NewMeterProvider() - return provider, provider.Meter("apitest") -} - -func TestCounter(t *testing.T) { - // N.B. the API does not check for negative - // values, that's the SDK's responsibility. - t.Run("float64 counter", func(t *testing.T) { - provider, meter := testPair() - c := Must(meter).NewFloat64Counter("test.counter.float") - ctx := context.Background() - labels := []attribute.KeyValue{attribute.String("A", "B")} - c.Add(ctx, 1994.1, labels...) - meter.RecordBatch(ctx, labels, c.Measurement(42)) - checkSyncBatches(ctx, t, labels, provider, number.Float64Kind, sdkapi.CounterInstrumentKind, c.SyncImpl(), - 1994.1, 42, - ) - }) - t.Run("int64 counter", func(t *testing.T) { - provider, meter := testPair() - c := Must(meter).NewInt64Counter("test.counter.int") - ctx := context.Background() - labels := []attribute.KeyValue{attribute.String("A", "B"), attribute.String("C", "D")} - c.Add(ctx, 42, labels...) - meter.RecordBatch(ctx, labels, c.Measurement(420000)) - checkSyncBatches(ctx, t, labels, provider, number.Int64Kind, sdkapi.CounterInstrumentKind, c.SyncImpl(), - 42, 420000, - ) - - }) - t.Run("int64 updowncounter", func(t *testing.T) { - provider, meter := testPair() - c := Must(meter).NewInt64UpDownCounter("test.updowncounter.int") - ctx := context.Background() - labels := []attribute.KeyValue{attribute.String("A", "B"), attribute.String("C", "D")} - c.Add(ctx, 100, labels...) - meter.RecordBatch(ctx, labels, c.Measurement(42)) - checkSyncBatches(ctx, t, labels, provider, number.Int64Kind, sdkapi.UpDownCounterInstrumentKind, c.SyncImpl(), - 100, 42, - ) - }) - t.Run("float64 updowncounter", func(t *testing.T) { - provider, meter := testPair() - c := Must(meter).NewFloat64UpDownCounter("test.updowncounter.float") - ctx := context.Background() - labels := []attribute.KeyValue{attribute.String("A", "B"), attribute.String("C", "D")} - c.Add(ctx, 100.1, labels...) - meter.RecordBatch(ctx, labels, c.Measurement(-100.1)) - checkSyncBatches(ctx, t, labels, provider, number.Float64Kind, sdkapi.UpDownCounterInstrumentKind, c.SyncImpl(), - 100.1, -100.1, - ) - }) -} - -func TestHistogram(t *testing.T) { - t.Run("float64 histogram", func(t *testing.T) { - provider, meter := testPair() - m := Must(meter).NewFloat64Histogram("test.histogram.float") - ctx := context.Background() - labels := []attribute.KeyValue{} - m.Record(ctx, 42, labels...) - meter.RecordBatch(ctx, labels, m.Measurement(-100.5)) - checkSyncBatches(ctx, t, labels, provider, number.Float64Kind, sdkapi.HistogramInstrumentKind, m.SyncImpl(), - 42, -100.5, - ) - }) - t.Run("int64 histogram", func(t *testing.T) { - provider, meter := testPair() - m := Must(meter).NewInt64Histogram("test.histogram.int") - ctx := context.Background() - labels := []attribute.KeyValue{attribute.Int("I", 1)} - m.Record(ctx, 173, labels...) - meter.RecordBatch(ctx, labels, m.Measurement(0)) - checkSyncBatches(ctx, t, labels, provider, number.Int64Kind, sdkapi.HistogramInstrumentKind, m.SyncImpl(), - 173, 0, - ) - }) -} - -func TestObserverInstruments(t *testing.T) { - t.Run("float gauge", func(t *testing.T) { - labels := []attribute.KeyValue{attribute.String("O", "P")} - provider, meter := testPair() - o := Must(meter).NewFloat64GaugeObserver("test.gauge.float", func(_ context.Context, result metric.Float64ObserverResult) { - result.Observe(42.1, labels...) - }) - provider.RunAsyncInstruments() - checkObserverBatch(t, labels, provider, number.Float64Kind, sdkapi.GaugeObserverInstrumentKind, o.AsyncImpl(), - 42.1, - ) - }) - t.Run("int gauge", func(t *testing.T) { - labels := []attribute.KeyValue{} - provider, meter := testPair() - o := Must(meter).NewInt64GaugeObserver("test.gauge.int", func(_ context.Context, result metric.Int64ObserverResult) { - result.Observe(-142, labels...) - }) - provider.RunAsyncInstruments() - checkObserverBatch(t, labels, provider, number.Int64Kind, sdkapi.GaugeObserverInstrumentKind, o.AsyncImpl(), - -142, - ) - }) - t.Run("float counterobserver", func(t *testing.T) { - labels := []attribute.KeyValue{attribute.String("O", "P")} - provider, meter := testPair() - o := Must(meter).NewFloat64CounterObserver("test.counter.float", func(_ context.Context, result metric.Float64ObserverResult) { - result.Observe(42.1, labels...) - }) - provider.RunAsyncInstruments() - checkObserverBatch(t, labels, provider, number.Float64Kind, sdkapi.CounterObserverInstrumentKind, o.AsyncImpl(), - 42.1, - ) - }) - t.Run("int counterobserver", func(t *testing.T) { - labels := []attribute.KeyValue{} - provider, meter := testPair() - o := Must(meter).NewInt64CounterObserver("test.counter.int", func(_ context.Context, result metric.Int64ObserverResult) { - result.Observe(-142, labels...) - }) - provider.RunAsyncInstruments() - checkObserverBatch(t, labels, provider, number.Int64Kind, sdkapi.CounterObserverInstrumentKind, o.AsyncImpl(), - -142, - ) - }) - t.Run("float updowncounterobserver", func(t *testing.T) { - labels := []attribute.KeyValue{attribute.String("O", "P")} - provider, meter := testPair() - o := Must(meter).NewFloat64UpDownCounterObserver("test.updowncounter.float", func(_ context.Context, result metric.Float64ObserverResult) { - result.Observe(42.1, labels...) - }) - provider.RunAsyncInstruments() - checkObserverBatch(t, labels, provider, number.Float64Kind, sdkapi.UpDownCounterObserverInstrumentKind, o.AsyncImpl(), - 42.1, - ) - }) - t.Run("int updowncounterobserver", func(t *testing.T) { - labels := []attribute.KeyValue{} - provider, meter := testPair() - o := Must(meter).NewInt64UpDownCounterObserver("test..int", func(_ context.Context, result metric.Int64ObserverResult) { - result.Observe(-142, labels...) - }) - provider.RunAsyncInstruments() - checkObserverBatch(t, labels, provider, number.Int64Kind, sdkapi.UpDownCounterObserverInstrumentKind, o.AsyncImpl(), - -142, - ) - }) -} - -func TestBatchObserverInstruments(t *testing.T) { - provider, meter := testPair() - - var obs1 metric.Int64GaugeObserver - var obs2 metric.Float64GaugeObserver - - labels := []attribute.KeyValue{ - attribute.String("A", "B"), - attribute.String("C", "D"), - } - - cb := Must(meter).NewBatchObserver( - func(_ context.Context, result metric.BatchObserverResult) { - result.Observe(labels, - obs1.Observation(42), - obs2.Observation(42.0), - ) - }, - ) - obs1 = cb.NewInt64GaugeObserver("test.gauge.int") - obs2 = cb.NewFloat64GaugeObserver("test.gauge.float") - - provider.RunAsyncInstruments() - - require.Len(t, provider.MeasurementBatches, 1) - - impl1 := obs1.AsyncImpl().Implementation().(*metrictest.Async) - impl2 := obs2.AsyncImpl().Implementation().(*metrictest.Async) - - require.NotNil(t, impl1) - require.NotNil(t, impl2) - - got := provider.MeasurementBatches[0] - require.Equal(t, labels, got.Labels) - require.Len(t, got.Measurements, 2) - - m1 := got.Measurements[0] - require.Equal(t, impl1, m1.Instrument.Implementation().(*metrictest.Async)) - require.Equal(t, 0, m1.Number.CompareNumber(number.Int64Kind, metrictest.ResolveNumberByKind(t, number.Int64Kind, 42))) - - m2 := got.Measurements[1] - require.Equal(t, impl2, m2.Instrument.Implementation().(*metrictest.Async)) - require.Equal(t, 0, m2.Number.CompareNumber(number.Float64Kind, metrictest.ResolveNumberByKind(t, number.Float64Kind, 42))) -} - -func checkObserverBatch(t *testing.T, labels []attribute.KeyValue, provider *metrictest.MeterProvider, nkind number.Kind, mkind sdkapi.InstrumentKind, observer sdkapi.AsyncImpl, expected float64) { - t.Helper() - assert.Len(t, provider.MeasurementBatches, 1) - if len(provider.MeasurementBatches) < 1 { - return - } - o := observer.Implementation().(*metrictest.Async) - if !assert.NotNil(t, o) { - return - } - got := provider.MeasurementBatches[0] - assert.Equal(t, labels, got.Labels) - assert.Len(t, got.Measurements, 1) - if len(got.Measurements) < 1 { - return - } - measurement := got.Measurements[0] - require.Equal(t, mkind, measurement.Instrument.Descriptor().InstrumentKind()) - assert.Equal(t, o, measurement.Instrument.Implementation().(*metrictest.Async)) - ft := metrictest.ResolveNumberByKind(t, nkind, expected) - assert.Equal(t, 0, measurement.Number.CompareNumber(nkind, ft)) -} - -type testWrappedMeter struct { -} - -var _ sdkapi.MeterImpl = testWrappedMeter{} - -func (testWrappedMeter) RecordBatch(context.Context, []attribute.KeyValue, ...sdkapi.Measurement) { -} - -func (testWrappedMeter) NewSyncInstrument(_ sdkapi.Descriptor) (sdkapi.SyncImpl, error) { - return nil, nil -} - -func (testWrappedMeter) NewAsyncInstrument(_ sdkapi.Descriptor, _ sdkapi.AsyncRunner) (sdkapi.AsyncImpl, error) { - return nil, errors.New("Test wrap error") -} - -func TestWrappedInstrumentError(t *testing.T) { - impl := &testWrappedMeter{} - meter := metric.WrapMeterImpl(impl) - - histogram, err := meter.NewInt64Histogram("test.histogram") - - require.Equal(t, err, metric.ErrSDKReturnedNilImpl) - require.NotNil(t, histogram.SyncImpl()) - - observer, err := meter.NewInt64GaugeObserver("test.observer", func(_ context.Context, result metric.Int64ObserverResult) {}) - - require.NotNil(t, err) - require.NotNil(t, observer.AsyncImpl()) -} - -func TestNilCallbackObserverNoop(t *testing.T) { - // Tests that a nil callback yields a no-op observer without error. - _, meter := testPair() - - observer := Must(meter).NewInt64GaugeObserver("test.observer", nil) - - impl := observer.AsyncImpl().Implementation() - desc := observer.AsyncImpl().Descriptor() - require.Equal(t, nil, impl) - require.Equal(t, "", desc.Name()) -} diff --git a/metric/metrictest/meter.go b/metric/metrictest/meter.go deleted file mode 100644 index 759bb04baec..00000000000 --- a/metric/metrictest/meter.go +++ /dev/null @@ -1,290 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package metrictest // import "go.opentelemetry.io/otel/metric/metrictest" - -import ( - "context" - "sync" - "testing" - - "go.opentelemetry.io/otel/attribute" - internalmetric "go.opentelemetry.io/otel/internal/metric" - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" -) - -type ( - Handle struct { - Instrument *Sync - Labels []attribute.KeyValue - } - - // Library is the same as "sdk/instrumentation".Library but there is - // a package cycle to use it. - Library struct { - InstrumentationName string - InstrumentationVersion string - SchemaURL string - } - - Batch struct { - // Measurement needs to be aligned for 64-bit atomic operations. - Measurements []Measurement - Ctx context.Context - Labels []attribute.KeyValue - Library Library - } - - // MeterImpl is an OpenTelemetry Meter implementation used for testing. - MeterImpl struct { - library Library - provider *MeterProvider - asyncInstruments *internalmetric.AsyncInstrumentState - } - - // MeterProvider is a collection of named MeterImpls used for testing. - MeterProvider struct { - lock sync.Mutex - - MeasurementBatches []Batch - impls []*MeterImpl - } - - Measurement struct { - // Number needs to be aligned for 64-bit atomic operations. - Number number.Number - Instrument sdkapi.InstrumentImpl - } - - Instrument struct { - meter *MeterImpl - descriptor sdkapi.Descriptor - } - - Async struct { - Instrument - - runner sdkapi.AsyncRunner - } - - Sync struct { - Instrument - } -) - -var ( - _ sdkapi.SyncImpl = &Sync{} - _ sdkapi.MeterImpl = &MeterImpl{} - _ sdkapi.AsyncImpl = &Async{} -) - -// NewDescriptor is a test helper for constructing test metric -// descriptors using standard options. -func NewDescriptor(name string, ikind sdkapi.InstrumentKind, nkind number.Kind, opts ...metric.InstrumentOption) sdkapi.Descriptor { - cfg := metric.NewInstrumentConfig(opts...) - return sdkapi.NewDescriptor(name, ikind, nkind, cfg.Description(), cfg.Unit()) -} - -func (i Instrument) Descriptor() sdkapi.Descriptor { - return i.descriptor -} - -func (a *Async) Implementation() interface{} { - return a -} - -func (s *Sync) Implementation() interface{} { - return s -} - -func (s *Sync) RecordOne(ctx context.Context, number number.Number, labels []attribute.KeyValue) { - s.meter.doRecordSingle(ctx, labels, s, number) -} - -func (h *Handle) RecordOne(ctx context.Context, number number.Number) { - h.Instrument.meter.doRecordSingle(ctx, h.Labels, h.Instrument, number) -} - -func (h *Handle) Unbind() { -} - -func (m *MeterImpl) doRecordSingle(ctx context.Context, labels []attribute.KeyValue, instrument sdkapi.InstrumentImpl, number number.Number) { - m.collect(ctx, labels, []Measurement{{ - Instrument: instrument, - Number: number, - }}) -} - -// NewMeterProvider returns a MeterProvider suitable for testing. -// When the test is complete, consult MeterProvider.MeasurementBatches. -func NewMeterProvider() *MeterProvider { - return &MeterProvider{} -} - -// Meter implements metric.MeterProvider. -func (p *MeterProvider) Meter(name string, opts ...metric.MeterOption) metric.Meter { - p.lock.Lock() - defer p.lock.Unlock() - cfg := metric.NewMeterConfig(opts...) - impl := &MeterImpl{ - library: Library{ - InstrumentationName: name, - InstrumentationVersion: cfg.InstrumentationVersion(), - SchemaURL: cfg.SchemaURL(), - }, - provider: p, - asyncInstruments: internalmetric.NewAsyncInstrumentState(), - } - p.impls = append(p.impls, impl) - return metric.WrapMeterImpl(impl) -} - -// NewSyncInstrument implements sdkapi.MeterImpl. -func (m *MeterImpl) NewSyncInstrument(descriptor sdkapi.Descriptor) (sdkapi.SyncImpl, error) { - return &Sync{ - Instrument{ - descriptor: descriptor, - meter: m, - }, - }, nil -} - -// NewAsyncInstrument implements sdkapi.MeterImpl. -func (m *MeterImpl) NewAsyncInstrument(descriptor sdkapi.Descriptor, runner sdkapi.AsyncRunner) (sdkapi.AsyncImpl, error) { - a := &Async{ - Instrument: Instrument{ - descriptor: descriptor, - meter: m, - }, - runner: runner, - } - m.provider.registerAsyncInstrument(a, m, runner) - return a, nil -} - -// RecordBatch implements sdkapi.MeterImpl. -func (m *MeterImpl) RecordBatch(ctx context.Context, labels []attribute.KeyValue, measurements ...sdkapi.Measurement) { - mm := make([]Measurement, len(measurements)) - for i := 0; i < len(measurements); i++ { - m := measurements[i] - mm[i] = Measurement{ - Instrument: m.SyncImpl().Implementation().(*Sync), - Number: m.Number(), - } - } - m.collect(ctx, labels, mm) -} - -// CollectAsync is called from asyncInstruments.Run() with the lock held. -func (m *MeterImpl) CollectAsync(labels []attribute.KeyValue, obs ...sdkapi.Observation) { - mm := make([]Measurement, len(obs)) - for i := 0; i < len(obs); i++ { - o := obs[i] - mm[i] = Measurement{ - Instrument: o.AsyncImpl(), - Number: o.Number(), - } - } - m.collect(context.Background(), labels, mm) -} - -// collect is called from CollectAsync() or RecordBatch() with the lock held. -func (m *MeterImpl) collect(ctx context.Context, labels []attribute.KeyValue, measurements []Measurement) { - m.provider.addMeasurement(Batch{ - Ctx: ctx, - Labels: labels, - Measurements: measurements, - Library: m.library, - }) -} - -// registerAsyncInstrument locks the provider and registers the new Async instrument. -func (p *MeterProvider) registerAsyncInstrument(a *Async, m *MeterImpl, runner sdkapi.AsyncRunner) { - p.lock.Lock() - defer p.lock.Unlock() - - m.asyncInstruments.Register(a, runner) -} - -// addMeasurement locks the provider and adds the new measurement batch. -func (p *MeterProvider) addMeasurement(b Batch) { - p.lock.Lock() - defer p.lock.Unlock() - p.MeasurementBatches = append(p.MeasurementBatches, b) -} - -// copyImpls locks the provider and copies the current list of *MeterImpls. -func (p *MeterProvider) copyImpls() []*MeterImpl { - p.lock.Lock() - defer p.lock.Unlock() - cpy := make([]*MeterImpl, len(p.impls)) - copy(cpy, p.impls) - return cpy -} - -// RunAsyncInstruments is used in tests to trigger collection from -// asynchronous instruments. -func (p *MeterProvider) RunAsyncInstruments() { - for _, impl := range p.copyImpls() { - impl.asyncInstruments.Run(context.Background(), impl) - } -} - -// Measured is the helper struct which provides flat representation of recorded measurements -// to simplify testing -type Measured struct { - Name string - Labels map[attribute.Key]attribute.Value - Number number.Number - Library Library -} - -// LabelsToMap converts label set to keyValue map, to be easily used in tests -func LabelsToMap(kvs ...attribute.KeyValue) map[attribute.Key]attribute.Value { - m := map[attribute.Key]attribute.Value{} - for _, label := range kvs { - m[label.Key] = label.Value - } - return m -} - -// AsStructs converts recorded batches to array of flat, readable Measured helper structures -func AsStructs(batches []Batch) []Measured { - var r []Measured - for _, batch := range batches { - for _, m := range batch.Measurements { - r = append(r, Measured{ - Name: m.Instrument.Descriptor().Name(), - Labels: LabelsToMap(batch.Labels...), - Number: m.Number, - Library: batch.Library, - }) - } - } - return r -} - -// ResolveNumberByKind takes defined metric descriptor creates a concrete typed metric number -func ResolveNumberByKind(t *testing.T, kind number.Kind, value float64) number.Number { - t.Helper() - switch kind { - case number.Int64Kind: - return number.NewInt64Number(int64(value)) - case number.Float64Kind: - return number.NewFloat64Number(value) - } - panic("invalid number kind") -} diff --git a/metric/nonrecording/instruments.go b/metric/nonrecording/instruments.go new file mode 100644 index 00000000000..84a6aa89c31 --- /dev/null +++ b/metric/nonrecording/instruments.go @@ -0,0 +1,138 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package nonrecording // import "go.opentelemetry.io/otel/metric/nonrecording" + +import ( + "context" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric/instrument" + "go.opentelemetry.io/otel/metric/instrument/asyncfloat64" + "go.opentelemetry.io/otel/metric/instrument/asyncint64" + "go.opentelemetry.io/otel/metric/instrument/syncfloat64" + "go.opentelemetry.io/otel/metric/instrument/syncint64" +) + +type nonrecordingAsyncFloat64Instrument struct { + instrument.Asynchronous +} + +var ( + _ asyncfloat64.InstrumentProvider = nonrecordingAsyncFloat64Instrument{} + _ asyncfloat64.Counter = nonrecordingAsyncFloat64Instrument{} + _ asyncfloat64.UpDownCounter = nonrecordingAsyncFloat64Instrument{} + _ asyncfloat64.Gauge = nonrecordingAsyncFloat64Instrument{} +) + +func (n nonrecordingAsyncFloat64Instrument) Counter(name string, opts ...instrument.Option) (asyncfloat64.Counter, error) { + return n, nil +} + +func (n nonrecordingAsyncFloat64Instrument) UpDownCounter(name string, opts ...instrument.Option) (asyncfloat64.UpDownCounter, error) { + return n, nil +} + +func (n nonrecordingAsyncFloat64Instrument) Gauge(name string, opts ...instrument.Option) (asyncfloat64.Gauge, error) { + return n, nil +} + +func (nonrecordingAsyncFloat64Instrument) Observe(context.Context, float64, ...attribute.KeyValue) { + +} + +type nonrecordingAsyncInt64Instrument struct { + instrument.Asynchronous +} + +var ( + _ asyncint64.InstrumentProvider = nonrecordingAsyncInt64Instrument{} + _ asyncint64.Counter = nonrecordingAsyncInt64Instrument{} + _ asyncint64.UpDownCounter = nonrecordingAsyncInt64Instrument{} + _ asyncint64.Gauge = nonrecordingAsyncInt64Instrument{} +) + +func (n nonrecordingAsyncInt64Instrument) Counter(name string, opts ...instrument.Option) (asyncint64.Counter, error) { + return n, nil +} + +func (n nonrecordingAsyncInt64Instrument) UpDownCounter(name string, opts ...instrument.Option) (asyncint64.UpDownCounter, error) { + return n, nil +} + +func (n nonrecordingAsyncInt64Instrument) Gauge(name string, opts ...instrument.Option) (asyncint64.Gauge, error) { + return n, nil +} + +func (nonrecordingAsyncInt64Instrument) Observe(context.Context, int64, ...attribute.KeyValue) { +} + +type nonrecordingSyncFloat64Instrument struct { + instrument.Synchronous +} + +var ( + _ syncfloat64.InstrumentProvider = nonrecordingSyncFloat64Instrument{} + _ syncfloat64.Counter = nonrecordingSyncFloat64Instrument{} + _ syncfloat64.UpDownCounter = nonrecordingSyncFloat64Instrument{} + _ syncfloat64.Histogram = nonrecordingSyncFloat64Instrument{} +) + +func (n nonrecordingSyncFloat64Instrument) Counter(name string, opts ...instrument.Option) (syncfloat64.Counter, error) { + return n, nil +} + +func (n nonrecordingSyncFloat64Instrument) UpDownCounter(name string, opts ...instrument.Option) (syncfloat64.UpDownCounter, error) { + return n, nil +} + +func (n nonrecordingSyncFloat64Instrument) Histogram(name string, opts ...instrument.Option) (syncfloat64.Histogram, error) { + return n, nil +} + +func (nonrecordingSyncFloat64Instrument) Add(context.Context, float64, ...attribute.KeyValue) { + +} + +func (nonrecordingSyncFloat64Instrument) Record(context.Context, float64, ...attribute.KeyValue) { + +} + +type nonrecordingSyncInt64Instrument struct { + instrument.Synchronous +} + +var ( + _ syncint64.InstrumentProvider = nonrecordingSyncInt64Instrument{} + _ syncint64.Counter = nonrecordingSyncInt64Instrument{} + _ syncint64.UpDownCounter = nonrecordingSyncInt64Instrument{} + _ syncint64.Histogram = nonrecordingSyncInt64Instrument{} +) + +func (n nonrecordingSyncInt64Instrument) Counter(name string, opts ...instrument.Option) (syncint64.Counter, error) { + return n, nil +} + +func (n nonrecordingSyncInt64Instrument) UpDownCounter(name string, opts ...instrument.Option) (syncint64.UpDownCounter, error) { + return n, nil +} + +func (n nonrecordingSyncInt64Instrument) Histogram(name string, opts ...instrument.Option) (syncint64.Histogram, error) { + return n, nil +} + +func (nonrecordingSyncInt64Instrument) Add(context.Context, int64, ...attribute.KeyValue) { +} +func (nonrecordingSyncInt64Instrument) Record(context.Context, int64, ...attribute.KeyValue) { +} diff --git a/metric/nonrecording/meter.go b/metric/nonrecording/meter.go new file mode 100644 index 00000000000..2acea49d8a1 --- /dev/null +++ b/metric/nonrecording/meter.go @@ -0,0 +1,64 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package nonrecording // import "go.opentelemetry.io/otel/metric/nonrecording" + +import ( + "context" + + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/metric/instrument" + "go.opentelemetry.io/otel/metric/instrument/asyncfloat64" + "go.opentelemetry.io/otel/metric/instrument/asyncint64" + "go.opentelemetry.io/otel/metric/instrument/syncfloat64" + "go.opentelemetry.io/otel/metric/instrument/syncint64" +) + +// NewNoopMeterProvider creates a MeterProvider that does not record any metrics. +func NewNoopMeterProvider() metric.MeterProvider { + return noopMeterProvider{} +} + +type noopMeterProvider struct{} + +var _ metric.MeterProvider = noopMeterProvider{} + +func (noopMeterProvider) Meter(instrumentationName string, opts ...metric.MeterOption) metric.Meter { + return noopMeter{} +} + +// NewNoopMeter creates a Meter that does not record any metrics. +func NewNoopMeter() metric.Meter { + return noopMeter{} +} + +type noopMeter struct{} + +var _ metric.Meter = noopMeter{} + +func (noopMeter) AsyncInt64() asyncint64.InstrumentProvider { + return nonrecordingAsyncInt64Instrument{} +} +func (noopMeter) AsyncFloat64() asyncfloat64.InstrumentProvider { + return nonrecordingAsyncFloat64Instrument{} +} +func (noopMeter) SyncInt64() syncint64.InstrumentProvider { + return nonrecordingSyncInt64Instrument{} +} +func (noopMeter) SyncFloat64() syncfloat64.InstrumentProvider { + return nonrecordingSyncFloat64Instrument{} +} +func (noopMeter) RegisterCallback([]instrument.Asynchronous, func(context.Context)) error { + return nil +} diff --git a/metric/noop.go b/metric/noop.go deleted file mode 100644 index 37c653f51a1..00000000000 --- a/metric/noop.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package metric // import "go.opentelemetry.io/otel/metric" - -type noopMeterProvider struct{} - -// NewNoopMeterProvider returns an implementation of MeterProvider that -// performs no operations. The Meter and Instrument created from the returned -// MeterProvider also perform no operations. -func NewNoopMeterProvider() MeterProvider { - return noopMeterProvider{} -} - -var _ MeterProvider = noopMeterProvider{} - -func (noopMeterProvider) Meter(instrumentationName string, opts ...MeterOption) Meter { - return Meter{} -} diff --git a/sdk/export/metric/aggregation/aggregation.go b/sdk/export/metric/aggregation/aggregation.go index 09b20306051..702c5b2bc82 100644 --- a/sdk/export/metric/aggregation/aggregation.go +++ b/sdk/export/metric/aggregation/aggregation.go @@ -15,8 +15,8 @@ package aggregation // import "go.opentelemetry.io/otel/sdk/export/metric/aggregation" import ( - "go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/number" ) // Deprecated: use module "go.opentelemetry.io/otel/sdk/metric/export/aggregation" diff --git a/sdk/export/metric/go.mod b/sdk/export/metric/go.mod index 8f728464774..415e71a87f9 100644 --- a/sdk/export/metric/go.mod +++ b/sdk/export/metric/go.mod @@ -41,7 +41,6 @@ replace go.opentelemetry.io/otel/trace => ../../../trace require ( go.opentelemetry.io/otel v1.4.1 - go.opentelemetry.io/otel/metric v0.27.0 go.opentelemetry.io/otel/sdk/metric v0.27.0 ) diff --git a/sdk/export/metric/metric.go b/sdk/export/metric/metric.go index 00d3f67b3bc..b3dccccd9dc 100644 --- a/sdk/export/metric/metric.go +++ b/sdk/export/metric/metric.go @@ -18,10 +18,10 @@ import ( "time" "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/sdk/metric/aggregator" "go.opentelemetry.io/otel/sdk/metric/export" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" ) // Deprecated: use module "go.opentelemetry.io/otel/sdk/metric/export" diff --git a/sdk/metric/aggregator/aggregator.go b/sdk/metric/aggregator/aggregator.go index 85d2b3fbdb3..59d42b1a80a 100644 --- a/sdk/metric/aggregator/aggregator.go +++ b/sdk/metric/aggregator/aggregator.go @@ -19,9 +19,9 @@ import ( "fmt" "math" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/number" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" ) // Aggregator implements a specific aggregation behavior, e.g., a diff --git a/sdk/metric/aggregator/aggregator_test.go b/sdk/metric/aggregator/aggregator_test.go index bf405b5c3f8..aab8393c932 100644 --- a/sdk/metric/aggregator/aggregator_test.go +++ b/sdk/metric/aggregator/aggregator_test.go @@ -21,13 +21,13 @@ import ( "github.com/stretchr/testify/require" - "go.opentelemetry.io/otel/metric/metrictest" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/sdk/metric/aggregator" "go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue" "go.opentelemetry.io/otel/sdk/metric/aggregator/sum" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/metrictest" + "go.opentelemetry.io/otel/sdk/metric/number" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" ) func TestInconsistentAggregatorErr(t *testing.T) { diff --git a/sdk/metric/aggregator/aggregatortest/test.go b/sdk/metric/aggregator/aggregatortest/test.go index 2d2a197e635..b9ea62da9bd 100644 --- a/sdk/metric/aggregator/aggregatortest/test.go +++ b/sdk/metric/aggregator/aggregatortest/test.go @@ -26,11 +26,11 @@ import ( "github.com/stretchr/testify/require" ottest "go.opentelemetry.io/otel/internal/internaltest" - "go.opentelemetry.io/otel/metric/metrictest" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/sdk/metric/aggregator" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/metrictest" + "go.opentelemetry.io/otel/sdk/metric/number" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" ) const Magnitude = 1000 diff --git a/sdk/metric/aggregator/histogram/benchmark_test.go b/sdk/metric/aggregator/histogram/benchmark_test.go index 4902c11b7e5..597af3eb714 100644 --- a/sdk/metric/aggregator/histogram/benchmark_test.go +++ b/sdk/metric/aggregator/histogram/benchmark_test.go @@ -19,10 +19,10 @@ import ( "math/rand" "testing" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/sdk/metric/aggregator/aggregatortest" "go.opentelemetry.io/otel/sdk/metric/aggregator/histogram" + "go.opentelemetry.io/otel/sdk/metric/number" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" ) const inputRange = 1e6 diff --git a/sdk/metric/aggregator/histogram/histogram.go b/sdk/metric/aggregator/histogram/histogram.go index 142ca24ebef..f4d94b38c5e 100644 --- a/sdk/metric/aggregator/histogram/histogram.go +++ b/sdk/metric/aggregator/histogram/histogram.go @@ -19,10 +19,10 @@ import ( "sort" "sync" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/sdk/metric/aggregator" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/number" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" ) // Note: This code uses a Mutex to govern access to the exclusive diff --git a/sdk/metric/aggregator/histogram/histogram_test.go b/sdk/metric/aggregator/histogram/histogram_test.go index 00acf2e772d..b22bd149e5e 100644 --- a/sdk/metric/aggregator/histogram/histogram_test.go +++ b/sdk/metric/aggregator/histogram/histogram_test.go @@ -23,11 +23,11 @@ import ( "github.com/stretchr/testify/require" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/sdk/metric/aggregator" "go.opentelemetry.io/otel/sdk/metric/aggregator/aggregatortest" "go.opentelemetry.io/otel/sdk/metric/aggregator/histogram" + "go.opentelemetry.io/otel/sdk/metric/number" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" ) const count = 100 diff --git a/sdk/metric/aggregator/lastvalue/lastvalue.go b/sdk/metric/aggregator/lastvalue/lastvalue.go index 59a7ac8236a..7e88f6b8db3 100644 --- a/sdk/metric/aggregator/lastvalue/lastvalue.go +++ b/sdk/metric/aggregator/lastvalue/lastvalue.go @@ -20,10 +20,10 @@ import ( "time" "unsafe" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/sdk/metric/aggregator" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/number" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" ) type ( diff --git a/sdk/metric/aggregator/lastvalue/lastvalue_test.go b/sdk/metric/aggregator/lastvalue/lastvalue_test.go index 3d105a75cd2..16f9614c25a 100644 --- a/sdk/metric/aggregator/lastvalue/lastvalue_test.go +++ b/sdk/metric/aggregator/lastvalue/lastvalue_test.go @@ -25,11 +25,11 @@ import ( "github.com/stretchr/testify/require" ottest "go.opentelemetry.io/otel/internal/internaltest" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/sdk/metric/aggregator" "go.opentelemetry.io/otel/sdk/metric/aggregator/aggregatortest" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/number" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" ) const count = 100 diff --git a/sdk/metric/aggregator/sum/sum.go b/sdk/metric/aggregator/sum/sum.go index be3c6dfff89..d5c70e59bdf 100644 --- a/sdk/metric/aggregator/sum/sum.go +++ b/sdk/metric/aggregator/sum/sum.go @@ -17,10 +17,10 @@ package sum // import "go.opentelemetry.io/otel/sdk/metric/aggregator/sum" import ( "context" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/sdk/metric/aggregator" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/number" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" ) // Aggregator aggregates counter events. diff --git a/sdk/metric/aggregator/sum/sum_test.go b/sdk/metric/aggregator/sum/sum_test.go index 59480e2c8cc..c92594a460c 100644 --- a/sdk/metric/aggregator/sum/sum_test.go +++ b/sdk/metric/aggregator/sum/sum_test.go @@ -22,10 +22,10 @@ import ( "github.com/stretchr/testify/require" ottest "go.opentelemetry.io/otel/internal/internaltest" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/sdk/metric/aggregator" "go.opentelemetry.io/otel/sdk/metric/aggregator/aggregatortest" + "go.opentelemetry.io/otel/sdk/metric/number" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" ) const count = 100 diff --git a/sdk/metric/benchmark_test.go b/sdk/metric/benchmark_test.go index c4ecf306293..fd5f49bd1ef 100644 --- a/sdk/metric/benchmark_test.go +++ b/sdk/metric/benchmark_test.go @@ -22,11 +22,13 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/global" - "go.opentelemetry.io/otel/metric/sdkapi" + "go.opentelemetry.io/otel/metric/instrument" + "go.opentelemetry.io/otel/metric/instrument/syncfloat64" + "go.opentelemetry.io/otel/metric/instrument/syncint64" sdk "go.opentelemetry.io/otel/sdk/metric" "go.opentelemetry.io/otel/sdk/metric/export" "go.opentelemetry.io/otel/sdk/metric/processor/processortest" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" ) type benchFixture struct { @@ -44,7 +46,7 @@ func newFixture(b *testing.B) *benchFixture { } bf.accumulator = sdk.NewAccumulator(bf) - bf.meter = metric.WrapMeterImpl(bf.accumulator) + bf.meter = sdkapi.WrapMeterImpl(bf.accumulator) return bf } @@ -56,8 +58,33 @@ func (f *benchFixture) Meter(_ string, _ ...metric.MeterOption) metric.Meter { return f.meter } -func (f *benchFixture) meterMust() metric.MeterMust { - return metric.Must(f.meter) +func (f *benchFixture) iCounter(name string) syncint64.Counter { + ctr, err := f.meter.SyncInt64().Counter(name) + if err != nil { + f.B.Error(err) + } + return ctr +} +func (f *benchFixture) fCounter(name string) syncfloat64.Counter { + ctr, err := f.meter.SyncFloat64().Counter(name) + if err != nil { + f.B.Error(err) + } + return ctr +} +func (f *benchFixture) iHistogram(name string) syncint64.Histogram { + ctr, err := f.meter.SyncInt64().Histogram(name) + if err != nil { + f.B.Error(err) + } + return ctr +} +func (f *benchFixture) fHistogram(name string) syncfloat64.Histogram { + ctr, err := f.meter.SyncFloat64().Histogram(name) + if err != nil { + f.B.Error(err) + } + return ctr } func makeLabels(n int) []attribute.KeyValue { @@ -81,7 +108,7 @@ func benchmarkLabels(b *testing.B, n int) { ctx := context.Background() fix := newFixture(b) labs := makeLabels(n) - cnt := fix.meterMust().NewInt64Counter("int64.sum") + cnt := fix.iCounter("int64.sum") b.ResetTimer() @@ -154,31 +181,33 @@ func BenchmarkIterator_16(b *testing.B) { // Counters -func BenchmarkGlobalInt64CounterAddWithSDK(b *testing.B) { - // Compare with BenchmarkInt64CounterAdd() to see overhead of global - // package. This is in the SDK to avoid the API from depending on the - // SDK. - ctx := context.Background() - fix := newFixture(b) +// TODO readd global - sdk := global.Meter("test") - global.SetMeterProvider(fix) +// func BenchmarkGlobalInt64CounterAddWithSDK(b *testing.B) { +// // Compare with BenchmarkInt64CounterAdd() to see overhead of global +// // package. This is in the SDK to avoid the API from depending on the +// // SDK. +// ctx := context.Background() +// fix := newFixture(b) - labs := []attribute.KeyValue{attribute.String("A", "B")} - cnt := Must(sdk).NewInt64Counter("int64.sum") +// sdk := global.Meter("test") +// global.SetMeterProvider(fix) - b.ResetTimer() +// labs := []attribute.KeyValue{attribute.String("A", "B")} +// cnt := Must(sdk).NewInt64Counter("int64.sum") - for i := 0; i < b.N; i++ { - cnt.Add(ctx, 1, labs...) - } -} +// b.ResetTimer() + +// for i := 0; i < b.N; i++ { +// cnt.Add(ctx, 1, labs...) +// } +// } func BenchmarkInt64CounterAdd(b *testing.B) { ctx := context.Background() fix := newFixture(b) labs := makeLabels(1) - cnt := fix.meterMust().NewInt64Counter("int64.sum") + cnt := fix.iCounter("int64.sum") b.ResetTimer() @@ -191,7 +220,7 @@ func BenchmarkFloat64CounterAdd(b *testing.B) { ctx := context.Background() fix := newFixture(b) labs := makeLabels(1) - cnt := fix.meterMust().NewFloat64Counter("float64.sum") + cnt := fix.fCounter("float64.sum") b.ResetTimer() @@ -206,7 +235,7 @@ func BenchmarkInt64LastValueAdd(b *testing.B) { ctx := context.Background() fix := newFixture(b) labs := makeLabels(1) - mea := fix.meterMust().NewInt64Histogram("int64.lastvalue") + mea := fix.iHistogram("int64.lastvalue") b.ResetTimer() @@ -219,7 +248,7 @@ func BenchmarkFloat64LastValueAdd(b *testing.B) { ctx := context.Background() fix := newFixture(b) labs := makeLabels(1) - mea := fix.meterMust().NewFloat64Histogram("float64.lastvalue") + mea := fix.fHistogram("float64.lastvalue") b.ResetTimer() @@ -234,7 +263,7 @@ func BenchmarkInt64HistogramAdd(b *testing.B) { ctx := context.Background() fix := newFixture(b) labs := makeLabels(1) - mea := fix.meterMust().NewInt64Histogram("int64.histogram") + mea := fix.iHistogram("int64.histogram") b.ResetTimer() @@ -247,7 +276,7 @@ func BenchmarkFloat64HistogramAdd(b *testing.B) { ctx := context.Background() fix := newFixture(b) labs := makeLabels(1) - mea := fix.meterMust().NewFloat64Histogram("float64.histogram") + mea := fix.fHistogram("float64.histogram") b.ResetTimer() @@ -264,12 +293,12 @@ func BenchmarkObserverRegistration(b *testing.B) { for i := 0; i < b.N; i++ { names = append(names, fmt.Sprintf("test.%d.lastvalue", i)) } - cb := func(_ context.Context, result metric.Int64ObserverResult) {} b.ResetTimer() for i := 0; i < b.N; i++ { - fix.meterMust().NewInt64GaugeObserver(names[i], cb) + ctr, _ := fix.meter.AsyncInt64().Counter(names[i]) + _ = fix.meter.RegisterCallback([]instrument.Asynchronous{ctr}, func(context.Context) {}) } } @@ -277,11 +306,16 @@ func BenchmarkGaugeObserverObservationInt64(b *testing.B) { ctx := context.Background() fix := newFixture(b) labs := makeLabels(1) - _ = fix.meterMust().NewInt64GaugeObserver("test.lastvalue", func(_ context.Context, result metric.Int64ObserverResult) { + ctr, _ := fix.meter.AsyncInt64().Counter("test.lastvalue") + err := fix.meter.RegisterCallback([]instrument.Asynchronous{ctr}, func(ctx context.Context) { for i := 0; i < b.N; i++ { - result.Observe((int64)(i), labs...) + ctr.Observe(ctx, (int64)(i), labs...) } }) + if err != nil { + b.Errorf("could not register callback: %v", err) + b.FailNow() + } b.ResetTimer() @@ -292,11 +326,16 @@ func BenchmarkGaugeObserverObservationFloat64(b *testing.B) { ctx := context.Background() fix := newFixture(b) labs := makeLabels(1) - _ = fix.meterMust().NewFloat64GaugeObserver("test.lastvalue", func(_ context.Context, result metric.Float64ObserverResult) { + ctr, _ := fix.meter.AsyncFloat64().Counter("test.lastvalue") + err := fix.meter.RegisterCallback([]instrument.Asynchronous{ctr}, func(ctx context.Context) { for i := 0; i < b.N; i++ { - result.Observe((float64)(i), labs...) + ctr.Observe(ctx, (float64)(i), labs...) } }) + if err != nil { + b.Errorf("could not register callback: %v", err) + b.FailNow() + } b.ResetTimer() @@ -310,17 +349,18 @@ func benchmarkBatchRecord8Labels(b *testing.B, numInst int) { ctx := context.Background() fix := newFixture(b) labs := makeLabels(numLabels) - var meas []sdkapi.Measurement + var meas []syncint64.Counter for i := 0; i < numInst; i++ { - inst := fix.meterMust().NewInt64Counter(fmt.Sprintf("int64.%d.sum", i)) - meas = append(meas, inst.Measurement(1)) + meas = append(meas, fix.iCounter(fmt.Sprintf("int64.%d.sum", i))) } b.ResetTimer() for i := 0; i < b.N; i++ { - fix.accumulator.RecordBatch(ctx, labs, meas...) + for _, ctr := range meas { + ctr.Add(ctx, 1, labs...) + } } } @@ -346,7 +386,7 @@ func BenchmarkRepeatedDirectCalls(b *testing.B) { ctx := context.Background() fix := newFixture(b) - c := fix.meterMust().NewInt64Counter("int64.sum") + c := fix.iCounter("int64.sum") k := attribute.String("bench", "true") b.ResetTimer() diff --git a/sdk/metric/controller/basic/controller.go b/sdk/metric/controller/basic/controller.go index ee694056228..de0da5484c9 100644 --- a/sdk/metric/controller/basic/controller.go +++ b/sdk/metric/controller/basic/controller.go @@ -21,12 +21,13 @@ import ( "time" "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/internal/metric/registry" "go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/sdk/instrumentation" sdk "go.opentelemetry.io/otel/sdk/metric" controllerTime "go.opentelemetry.io/otel/sdk/metric/controller/time" "go.opentelemetry.io/otel/sdk/metric/export" + "go.opentelemetry.io/otel/sdk/metric/registry" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" "go.opentelemetry.io/otel/sdk/resource" ) @@ -99,7 +100,7 @@ func (c *Controller) Meter(instrumentationName string, opts ...metric.MeterOptio library: library, })) } - return metric.WrapMeterImpl(m.(*registry.UniqueInstrumentMeterImpl)) + return sdkapi.WrapMeterImpl(m.(*registry.UniqueInstrumentMeterImpl)) } type accumulatorCheckpointer struct { @@ -108,6 +109,8 @@ type accumulatorCheckpointer struct { library instrumentation.Library } +var _ sdkapi.MeterImpl = &accumulatorCheckpointer{} + // New constructs a Controller using the provided checkpointer factory // and options (including optional exporter) to configure a metric // export pipeline. diff --git a/sdk/metric/controller/basic/controller_test.go b/sdk/metric/controller/basic/controller_test.go index 503a278148c..26dcf4bb286 100644 --- a/sdk/metric/controller/basic/controller_test.go +++ b/sdk/metric/controller/basic/controller_test.go @@ -25,8 +25,7 @@ import ( "go.opentelemetry.io/otel/attribute" ottest "go.opentelemetry.io/otel/internal/internaltest" - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/sdkapi" + "go.opentelemetry.io/otel/metric/instrument" "go.opentelemetry.io/otel/sdk/instrumentation" controller "go.opentelemetry.io/otel/sdk/metric/controller/basic" "go.opentelemetry.io/otel/sdk/metric/controller/controllertest" @@ -34,6 +33,7 @@ import ( "go.opentelemetry.io/otel/sdk/metric/export/aggregation" processor "go.opentelemetry.io/otel/sdk/metric/processor/basic" "go.opentelemetry.io/otel/sdk/metric/processor/processortest" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" "go.opentelemetry.io/otel/sdk/resource" ) @@ -127,7 +127,7 @@ func TestControllerUsesResource(t *testing.T) { ctx := context.Background() require.NoError(t, cont.Start(ctx)) - ctr := metric.Must(cont.Meter("named")).NewFloat64Counter("calls.sum") + ctr, _ := cont.Meter("named").SyncFloat64().Counter("calls.sum") ctr.Add(context.Background(), 1.) // Collect once @@ -152,16 +152,19 @@ func TestStartNoExporter(t *testing.T) { ) mock := controllertest.NewMockClock() cont.SetClock(mock) + meter := cont.Meter("go.opentelemetry.io/otel/sdk/metric/controller/basic_test#StartNoExporter") calls := int64(0) - _ = metric.Must(cont.Meter("named")).NewInt64CounterObserver("calls.lastvalue", - func(ctx context.Context, result metric.Int64ObserverResult) { - calls++ - checkTestContext(t, ctx) - result.Observe(calls, attribute.String("A", "B")) - }, - ) + counterObserver, err := meter.AsyncInt64().Counter("calls.lastvalue") + require.NoError(t, err) + + err = meter.RegisterCallback([]instrument.Asynchronous{counterObserver}, func(ctx context.Context) { + calls++ + checkTestContext(t, ctx) + counterObserver.Observe(ctx, calls, attribute.String("A", "B")) + }) + require.NoError(t, err) // Collect() has not been called. The controller is unstarted. expect := map[string]float64{} @@ -220,18 +223,22 @@ func TestObserverCanceled(t *testing.T) { controller.WithCollectTimeout(time.Millisecond), controller.WithResource(resource.Empty()), ) + meter := cont.Meter("go.opentelemetry.io/otel/sdk/metric/controller/basic_test#ObserverCanceled") calls := int64(0) - _ = metric.Must(cont.Meter("named")).NewInt64CounterObserver("done.lastvalue", - func(ctx context.Context, result metric.Int64ObserverResult) { - <-ctx.Done() - calls++ - result.Observe(calls) - }, - ) + counterObserver, err := meter.AsyncInt64().Counter("done.lastvalue") + require.NoError(t, err) + + err = meter.RegisterCallback([]instrument.Asynchronous{counterObserver}, func(ctx context.Context) { + <-ctx.Done() + calls++ + counterObserver.Observe(ctx, calls) + }) + require.NoError(t, err) + // This relies on the context timing out - err := cont.Collect(context.Background()) + err = cont.Collect(context.Background()) require.Error(t, err) require.True(t, errors.Is(err, context.DeadlineExceeded)) @@ -251,14 +258,18 @@ func TestObserverContext(t *testing.T) { controller.WithCollectTimeout(0), controller.WithResource(resource.Empty()), ) + meter := cont.Meter("go.opentelemetry.io/otel/sdk/metric/controller/basic_test#ObserverContext") + + counterObserver, err := meter.AsyncInt64().Counter("done.lastvalue") + require.NoError(t, err) + + err = meter.RegisterCallback([]instrument.Asynchronous{counterObserver}, func(ctx context.Context) { + time.Sleep(10 * time.Millisecond) + checkTestContext(t, ctx) + counterObserver.Observe(ctx, 1) + }) + require.NoError(t, err) - _ = metric.Must(cont.Meter("named")).NewInt64CounterObserver("done.lastvalue", - func(ctx context.Context, result metric.Int64ObserverResult) { - time.Sleep(10 * time.Millisecond) - checkTestContext(t, ctx) - result.Observe(1) - }, - ) ctx := testContext() require.NoError(t, cont.Collect(ctx)) @@ -314,14 +325,17 @@ func TestExportTimeout(t *testing.T) { ) mock := controllertest.NewMockClock() cont.SetClock(mock) + meter := cont.Meter("go.opentelemetry.io/otel/sdk/metric/controller/basic_test#ExportTimeout") calls := int64(0) - _ = metric.Must(cont.Meter("named")).NewInt64CounterObserver("one.lastvalue", - func(ctx context.Context, result metric.Int64ObserverResult) { - calls++ - result.Observe(calls) - }, - ) + counterObserver, err := meter.AsyncInt64().Counter("one.lastvalue") + require.NoError(t, err) + + err = meter.RegisterCallback([]instrument.Asynchronous{counterObserver}, func(ctx context.Context) { + calls++ + counterObserver.Observe(ctx, calls) + }) + require.NoError(t, err) require.NoError(t, cont.Start(context.Background())) @@ -332,7 +346,7 @@ func TestExportTimeout(t *testing.T) { // Collect after 1s, timeout mock.Add(time.Second) - err := testHandler.Flush() + err = testHandler.Flush() require.Error(t, err) require.True(t, errors.Is(err, context.DeadlineExceeded)) @@ -369,13 +383,17 @@ func TestCollectAfterStopThenStartAgain(t *testing.T) { mock := controllertest.NewMockClock() cont.SetClock(mock) + meter := cont.Meter("go.opentelemetry.io/otel/sdk/metric/controller/basic_test#CollectAfterStopThenStartAgain") + calls := 0 - _ = metric.Must(cont.Meter("named")).NewInt64CounterObserver("one.lastvalue", - func(ctx context.Context, result metric.Int64ObserverResult) { - calls++ - result.Observe(int64(calls)) - }, - ) + counterObserver, err := meter.AsyncInt64().Counter("one.lastvalue") + require.NoError(t, err) + + err = meter.RegisterCallback([]instrument.Asynchronous{counterObserver}, func(ctx context.Context) { + calls++ + counterObserver.Observe(ctx, int64(calls)) + }) + require.NoError(t, err) // No collections happen (because mock clock does not advance): require.NoError(t, cont.Start(context.Background())) @@ -403,7 +421,7 @@ func TestCollectAfterStopThenStartAgain(t *testing.T) { // explicit collection should still fail. require.NoError(t, cont.Start(context.Background())) require.True(t, cont.IsRunning()) - err := cont.Collect(context.Background()) + err = cont.Collect(context.Background()) require.Error(t, err) require.Equal(t, controller.ErrControllerStarted, err) @@ -452,10 +470,10 @@ func TestRegistryFunction(t *testing.T) { require.NotNil(t, m1) require.Equal(t, m1, m2) - c1, err := m1.NewInt64Counter("counter.sum") + c1, err := m1.SyncInt64().Counter("counter.sum") require.NoError(t, err) - c2, err := m1.NewInt64Counter("counter.sum") + c2, err := m1.SyncInt64().Counter("counter.sum") require.NoError(t, err) require.Equal(t, c1, c2) diff --git a/sdk/metric/controller/basic/pull_test.go b/sdk/metric/controller/basic/pull_test.go index 96d1e1adad1..2284e68a71d 100644 --- a/sdk/metric/controller/basic/pull_test.go +++ b/sdk/metric/controller/basic/pull_test.go @@ -23,7 +23,6 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric" controller "go.opentelemetry.io/otel/sdk/metric/controller/basic" "go.opentelemetry.io/otel/sdk/metric/controller/controllertest" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" @@ -45,7 +44,8 @@ func TestPullNoCollect(t *testing.T) { ctx := context.Background() meter := puller.Meter("nocache") - counter := metric.Must(meter).NewInt64Counter("counter.sum") + counter, err := meter.SyncInt64().Counter("counter.sum") + require.NoError(t, err) counter.Add(ctx, 10, attribute.String("A", "B")) @@ -83,7 +83,8 @@ func TestPullWithCollect(t *testing.T) { ctx := context.Background() meter := puller.Meter("nocache") - counter := metric.Must(meter).NewInt64Counter("counter.sum") + counter, err := meter.SyncInt64().Counter("counter.sum") + require.NoError(t, err) counter.Add(ctx, 10, attribute.String("A", "B")) diff --git a/sdk/metric/controller/basic/push_test.go b/sdk/metric/controller/basic/push_test.go index 0a6679b29de..67bbddfdc84 100644 --- a/sdk/metric/controller/basic/push_test.go +++ b/sdk/metric/controller/basic/push_test.go @@ -27,7 +27,6 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric" controller "go.opentelemetry.io/otel/sdk/metric/controller/basic" "go.opentelemetry.io/otel/sdk/metric/controller/controllertest" "go.opentelemetry.io/otel/sdk/metric/export" @@ -117,7 +116,8 @@ func TestPushTicker(t *testing.T) { ctx := context.Background() - counter := metric.Must(meter).NewInt64Counter("counter.sum") + counter, err := meter.SyncInt64().Counter("counter.sum") + require.NoError(t, err) require.NoError(t, p.Start(ctx)) @@ -197,8 +197,10 @@ func TestPushExportError(t *testing.T) { ctx := context.Background() meter := p.Meter("name") - counter1 := metric.Must(meter).NewInt64Counter("counter1.sum") - counter2 := metric.Must(meter).NewInt64Counter("counter2.sum") + counter1, err := meter.SyncInt64().Counter("counter1.sum") + require.NoError(t, err) + counter2, err := meter.SyncInt64().Counter("counter2.sum") + require.NoError(t, err) require.NoError(t, p.Start(ctx)) runtime.Gosched() diff --git a/sdk/metric/correct_test.go b/sdk/metric/correct_test.go index 25e7fc60875..1b24a209c76 100644 --- a/sdk/metric/correct_test.go +++ b/sdk/metric/correct_test.go @@ -26,16 +26,17 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/sdkapi" + "go.opentelemetry.io/otel/metric/instrument" + "go.opentelemetry.io/otel/metric/instrument/asyncint64" + "go.opentelemetry.io/otel/metric/nonrecording" metricsdk "go.opentelemetry.io/otel/sdk/metric" "go.opentelemetry.io/otel/sdk/metric/aggregator" "go.opentelemetry.io/otel/sdk/metric/export" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" "go.opentelemetry.io/otel/sdk/metric/processor/processortest" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" ) -var Must = metric.Must - type handler struct { sync.Mutex err error @@ -88,7 +89,7 @@ func newSDK(t *testing.T) (metric.Meter, *metricsdk.Accumulator, *testSelector, accum := metricsdk.NewAccumulator( processor, ) - meter := metric.WrapMeterImpl(accum) + meter := sdkapi.WrapMeterImpl(accum) return meter, accum, testSelector, processor } @@ -96,7 +97,8 @@ func TestInputRangeCounter(t *testing.T) { ctx := context.Background() meter, sdk, _, processor := newSDK(t) - counter := Must(meter).NewInt64Counter("name.sum") + counter, err := meter.SyncInt64().Counter("name.sum") + require.NoError(t, err) counter.Add(ctx, -1) require.Equal(t, aggregation.ErrNegativeInput, testHandler.Flush()) @@ -118,7 +120,8 @@ func TestInputRangeUpDownCounter(t *testing.T) { ctx := context.Background() meter, sdk, _, processor := newSDK(t) - counter := Must(meter).NewInt64UpDownCounter("name.sum") + counter, err := meter.SyncInt64().UpDownCounter("name.sum") + require.NoError(t, err) counter.Add(ctx, -1) counter.Add(ctx, -1) @@ -137,7 +140,8 @@ func TestInputRangeHistogram(t *testing.T) { ctx := context.Background() meter, sdk, _, processor := newSDK(t) - histogram := Must(meter).NewFloat64Histogram("name.histogram") + histogram, err := meter.SyncFloat64().Histogram("name.histogram") + require.NoError(t, err) histogram.Record(ctx, math.NaN()) require.Equal(t, aggregation.ErrNaNInput, testHandler.Flush()) @@ -162,7 +166,8 @@ func TestDisabledInstrument(t *testing.T) { ctx := context.Background() meter, sdk, _, processor := newSDK(t) - histogram := Must(meter).NewFloat64Histogram("name.disabled") + histogram, err := meter.SyncFloat64().Histogram("name.disabled") + require.NoError(t, err) histogram.Record(ctx, -1) checkpointed := sdk.Collect(ctx) @@ -175,7 +180,8 @@ func TestRecordNaN(t *testing.T) { ctx := context.Background() meter, _, _, _ := newSDK(t) - c := Must(meter).NewFloat64Counter("name.sum") + c, err := meter.SyncFloat64().Counter("name.sum") + require.NoError(t, err) require.Nil(t, testHandler.Flush()) c.Add(ctx, math.NaN()) @@ -186,7 +192,8 @@ func TestSDKLabelsDeduplication(t *testing.T) { ctx := context.Background() meter, sdk, _, processor := newSDK(t) - counter := Must(meter).NewInt64Counter("name.sum") + counter, err := meter.SyncInt64().Counter("name.sum") + require.NoError(t, err) const ( maxKeys = 21 @@ -277,48 +284,86 @@ func TestObserverCollection(t *testing.T) { meter, sdk, _, processor := newSDK(t) mult := 1 - _ = Must(meter).NewFloat64GaugeObserver("float.gauge.lastvalue", func(_ context.Context, result metric.Float64ObserverResult) { - result.Observe(float64(mult), attribute.String("A", "B")) + gaugeF, err := meter.AsyncFloat64().Gauge("float.gauge.lastvalue") + require.NoError(t, err) + err = meter.RegisterCallback([]instrument.Asynchronous{ + gaugeF, + }, func(ctx context.Context) { + gaugeF.Observe(ctx, float64(mult), attribute.String("A", "B")) // last value wins - result.Observe(float64(-mult), attribute.String("A", "B")) - result.Observe(float64(-mult), attribute.String("C", "D")) + gaugeF.Observe(ctx, float64(-mult), attribute.String("A", "B")) + gaugeF.Observe(ctx, float64(-mult), attribute.String("C", "D")) }) - _ = Must(meter).NewInt64GaugeObserver("int.gauge.lastvalue", func(_ context.Context, result metric.Int64ObserverResult) { - result.Observe(int64(-mult), attribute.String("A", "B")) - result.Observe(int64(mult)) + require.NoError(t, err) + + gaugeI, err := meter.AsyncInt64().Gauge("int.gauge.lastvalue") + require.NoError(t, err) + err = meter.RegisterCallback([]instrument.Asynchronous{ + gaugeI, + }, func(ctx context.Context) { + gaugeI.Observe(ctx, int64(-mult), attribute.String("A", "B")) + gaugeI.Observe(ctx, int64(mult)) // last value wins - result.Observe(int64(mult), attribute.String("A", "B")) - result.Observe(int64(mult)) + gaugeI.Observe(ctx, int64(mult), attribute.String("A", "B")) + gaugeI.Observe(ctx, int64(mult)) }) - - _ = Must(meter).NewFloat64CounterObserver("float.counterobserver.sum", func(_ context.Context, result metric.Float64ObserverResult) { - result.Observe(float64(mult), attribute.String("A", "B")) - result.Observe(float64(2*mult), attribute.String("A", "B")) - result.Observe(float64(mult), attribute.String("C", "D")) + require.NoError(t, err) + + counterF, err := meter.AsyncFloat64().Counter("float.counterobserver.sum") + require.NoError(t, err) + err = meter.RegisterCallback([]instrument.Asynchronous{ + counterF, + }, func(ctx context.Context) { + counterF.Observe(ctx, float64(mult), attribute.String("A", "B")) + counterF.Observe(ctx, float64(2*mult), attribute.String("A", "B")) + counterF.Observe(ctx, float64(mult), attribute.String("C", "D")) }) - _ = Must(meter).NewInt64CounterObserver("int.counterobserver.sum", func(_ context.Context, result metric.Int64ObserverResult) { - result.Observe(int64(2*mult), attribute.String("A", "B")) - result.Observe(int64(mult)) + require.NoError(t, err) + + counterI, err := meter.AsyncInt64().Counter("int.counterobserver.sum") + require.NoError(t, err) + err = meter.RegisterCallback([]instrument.Asynchronous{ + counterI, + }, func(ctx context.Context) { + counterI.Observe(ctx, int64(2*mult), attribute.String("A", "B")) + counterI.Observe(ctx, int64(mult)) // last value wins - result.Observe(int64(mult), attribute.String("A", "B")) - result.Observe(int64(mult)) + counterI.Observe(ctx, int64(mult), attribute.String("A", "B")) + counterI.Observe(ctx, int64(mult)) }) - - _ = Must(meter).NewFloat64UpDownCounterObserver("float.updowncounterobserver.sum", func(_ context.Context, result metric.Float64ObserverResult) { - result.Observe(float64(mult), attribute.String("A", "B")) - result.Observe(float64(-2*mult), attribute.String("A", "B")) - result.Observe(float64(mult), attribute.String("C", "D")) + require.NoError(t, err) + + updowncounterF, err := meter.AsyncFloat64().UpDownCounter("float.updowncounterobserver.sum") + require.NoError(t, err) + err = meter.RegisterCallback([]instrument.Asynchronous{ + updowncounterF, + }, func(ctx context.Context) { + updowncounterF.Observe(ctx, float64(mult), attribute.String("A", "B")) + updowncounterF.Observe(ctx, float64(-2*mult), attribute.String("A", "B")) + updowncounterF.Observe(ctx, float64(mult), attribute.String("C", "D")) }) - _ = Must(meter).NewInt64UpDownCounterObserver("int.updowncounterobserver.sum", func(_ context.Context, result metric.Int64ObserverResult) { - result.Observe(int64(2*mult), attribute.String("A", "B")) - result.Observe(int64(mult)) + require.NoError(t, err) + + updowncounterI, err := meter.AsyncInt64().UpDownCounter("int.updowncounterobserver.sum") + require.NoError(t, err) + err = meter.RegisterCallback([]instrument.Asynchronous{ + updowncounterI, + }, func(ctx context.Context) { + updowncounterI.Observe(ctx, int64(2*mult), attribute.String("A", "B")) + updowncounterI.Observe(ctx, int64(mult)) // last value wins - result.Observe(int64(mult), attribute.String("A", "B")) - result.Observe(int64(-mult)) + updowncounterI.Observe(ctx, int64(mult), attribute.String("A", "B")) + updowncounterI.Observe(ctx, int64(-mult)) }) + require.NoError(t, err) - _ = Must(meter).NewInt64GaugeObserver("empty.gauge.sum", func(_ context.Context, result metric.Int64ObserverResult) { + unused, err := meter.AsyncInt64().Gauge("empty.gauge.sum") + require.NoError(t, err) + err = meter.RegisterCallback([]instrument.Asynchronous{ + unused, + }, func(ctx context.Context) { }) + require.NoError(t, err) for mult = 0; mult < 3; mult++ { processor.Reset() @@ -333,15 +378,15 @@ func TestObserverCollection(t *testing.T) { "int.gauge.lastvalue//": mult, "int.gauge.lastvalue/A=B/": mult, - "float.counterobserver.sum/A=B/": 2 * mult, + "float.counterobserver.sum/A=B/": 3 * mult, "float.counterobserver.sum/C=D/": mult, - "int.counterobserver.sum//": mult, - "int.counterobserver.sum/A=B/": mult, + "int.counterobserver.sum//": 2 * mult, + "int.counterobserver.sum/A=B/": 3 * mult, - "float.updowncounterobserver.sum/A=B/": -2 * mult, + "float.updowncounterobserver.sum/A=B/": -mult, "float.updowncounterobserver.sum/C=D/": mult, - "int.updowncounterobserver.sum//": -mult, - "int.updowncounterobserver.sum/A=B/": mult, + "int.updowncounterobserver.sum//": 0, + "int.updowncounterobserver.sum/A=B/": 3 * mult, }, processor.Values()) } } @@ -351,18 +396,26 @@ func TestCounterObserverInputRange(t *testing.T) { meter, sdk, _, processor := newSDK(t) // TODO: these tests are testing for negative values, not for _descending values_. Fix. - _ = Must(meter).NewFloat64CounterObserver("float.counterobserver.sum", func(_ context.Context, result metric.Float64ObserverResult) { - result.Observe(-2, attribute.String("A", "B")) + counterF, _ := meter.AsyncFloat64().Counter("float.counterobserver.sum") + err := meter.RegisterCallback([]instrument.Asynchronous{ + counterF, + }, func(ctx context.Context) { + counterF.Observe(ctx, -2, attribute.String("A", "B")) require.Equal(t, aggregation.ErrNegativeInput, testHandler.Flush()) - result.Observe(-1, attribute.String("C", "D")) + counterF.Observe(ctx, -1, attribute.String("C", "D")) require.Equal(t, aggregation.ErrNegativeInput, testHandler.Flush()) }) - _ = Must(meter).NewInt64CounterObserver("int.counterobserver.sum", func(_ context.Context, result metric.Int64ObserverResult) { - result.Observe(-1, attribute.String("A", "B")) + require.NoError(t, err) + counterI, _ := meter.AsyncInt64().Counter("int.counterobserver.sum") + err = meter.RegisterCallback([]instrument.Asynchronous{ + counterI, + }, func(ctx context.Context) { + counterI.Observe(ctx, -1, attribute.String("A", "B")) require.Equal(t, aggregation.ErrNegativeInput, testHandler.Flush()) - result.Observe(-1) + counterI.Observe(ctx, -1) require.Equal(t, aggregation.ErrNegativeInput, testHandler.Flush()) }) + require.NoError(t, err) collected := sdk.Collect(ctx) @@ -377,51 +430,43 @@ func TestObserverBatch(t *testing.T) { ctx := context.Background() meter, sdk, _, processor := newSDK(t) - var floatGaugeObs metric.Float64GaugeObserver - var intGaugeObs metric.Int64GaugeObserver - var floatCounterObs metric.Float64CounterObserver - var intCounterObs metric.Int64CounterObserver - var floatUpDownCounterObs metric.Float64UpDownCounterObserver - var intUpDownCounterObs metric.Int64UpDownCounterObserver - - var batch = Must(meter).NewBatchObserver( - func(_ context.Context, result metric.BatchObserverResult) { - result.Observe( - []attribute.KeyValue{ - attribute.String("A", "B"), - }, - floatGaugeObs.Observation(1), - floatGaugeObs.Observation(-1), - intGaugeObs.Observation(-1), - intGaugeObs.Observation(1), - floatCounterObs.Observation(1000), - intCounterObs.Observation(100), - floatUpDownCounterObs.Observation(-1000), - intUpDownCounterObs.Observation(-100), - ) - result.Observe( - []attribute.KeyValue{ - attribute.String("C", "D"), - }, - floatGaugeObs.Observation(-1), - floatCounterObs.Observation(-1), - floatUpDownCounterObs.Observation(-1), - ) - result.Observe( - nil, - intGaugeObs.Observation(1), - intGaugeObs.Observation(1), - intCounterObs.Observation(10), - floatCounterObs.Observation(1.1), - intUpDownCounterObs.Observation(10), - ) - }) - floatGaugeObs = batch.NewFloat64GaugeObserver("float.gauge.lastvalue") - intGaugeObs = batch.NewInt64GaugeObserver("int.gauge.lastvalue") - floatCounterObs = batch.NewFloat64CounterObserver("float.counterobserver.sum") - intCounterObs = batch.NewInt64CounterObserver("int.counterobserver.sum") - floatUpDownCounterObs = batch.NewFloat64UpDownCounterObserver("float.updowncounterobserver.sum") - intUpDownCounterObs = batch.NewInt64UpDownCounterObserver("int.updowncounterobserver.sum") + floatGaugeObs, _ := meter.AsyncFloat64().Gauge("float.gauge.lastvalue") + intGaugeObs, _ := meter.AsyncInt64().Gauge("int.gauge.lastvalue") + floatCounterObs, _ := meter.AsyncFloat64().Counter("float.counterobserver.sum") + intCounterObs, _ := meter.AsyncInt64().Counter("int.counterobserver.sum") + floatUpDownCounterObs, _ := meter.AsyncFloat64().UpDownCounter("float.updowncounterobserver.sum") + intUpDownCounterObs, _ := meter.AsyncInt64().UpDownCounter("int.updowncounterobserver.sum") + + err := meter.RegisterCallback([]instrument.Asynchronous{ + floatGaugeObs, + intGaugeObs, + floatCounterObs, + intCounterObs, + floatUpDownCounterObs, + intUpDownCounterObs, + }, func(ctx context.Context) { + ab := attribute.String("A", "B") + floatGaugeObs.Observe(ctx, 1, ab) + floatGaugeObs.Observe(ctx, -1, ab) + intGaugeObs.Observe(ctx, -1, ab) + intGaugeObs.Observe(ctx, 1, ab) + floatCounterObs.Observe(ctx, 1000, ab) + intCounterObs.Observe(ctx, 100, ab) + floatUpDownCounterObs.Observe(ctx, -1000, ab) + intUpDownCounterObs.Observe(ctx, -100, ab) + + cd := attribute.String("C", "D") + floatGaugeObs.Observe(ctx, -1, cd) + floatCounterObs.Observe(ctx, -1, cd) + floatUpDownCounterObs.Observe(ctx, -1, cd) + + intGaugeObs.Observe(ctx, 1) + intGaugeObs.Observe(ctx, 1) + intCounterObs.Observe(ctx, 10) + floatCounterObs.Observe(ctx, 1.1) + intUpDownCounterObs.Observe(ctx, 10) + }) + require.NoError(t, err) collected := sdk.Collect(ctx) @@ -445,37 +490,6 @@ func TestObserverBatch(t *testing.T) { }, processor.Values()) } -func TestRecordBatch(t *testing.T) { - ctx := context.Background() - meter, sdk, _, processor := newSDK(t) - - counter1 := Must(meter).NewInt64Counter("int64.sum") - counter2 := Must(meter).NewFloat64Counter("float64.sum") - histogram1 := Must(meter).NewInt64Histogram("int64.histogram") - histogram2 := Must(meter).NewFloat64Histogram("float64.histogram") - - sdk.RecordBatch( - ctx, - []attribute.KeyValue{ - attribute.String("A", "B"), - attribute.String("C", "D"), - }, - counter1.Measurement(1), - counter2.Measurement(2), - histogram1.Measurement(3), - histogram2.Measurement(4), - ) - - sdk.Collect(ctx) - - require.EqualValues(t, map[string]float64{ - "int64.sum/A=B,C=D/": 1, - "float64.sum/A=B,C=D/": 2, - "int64.histogram/A=B,C=D/": 3, - "float64.histogram/A=B,C=D/": 4, - }, processor.Values()) -} - // TestRecordPersistence ensures that a direct-called instrument that // is repeatedly used each interval results in a persistent record, so // that its encoded labels will be cached across collection intervals. @@ -483,7 +497,9 @@ func TestRecordPersistence(t *testing.T) { ctx := context.Background() meter, sdk, selector, _ := newSDK(t) - c := Must(meter).NewFloat64Counter("name.sum") + c, err := meter.SyncFloat64().Counter("name.sum") + require.NoError(t, err) + uk := attribute.String("bound", "false") for i := 0; i < 100; i++ { @@ -497,51 +513,58 @@ func TestRecordPersistence(t *testing.T) { func TestIncorrectInstruments(t *testing.T) { // The Batch observe/record APIs are susceptible to // uninitialized instruments. - var counter metric.Int64Counter - var observer metric.Int64GaugeObserver + var observer asyncint64.Gauge ctx := context.Background() meter, sdk, _, processor := newSDK(t) // Now try with uninitialized instruments. - meter.RecordBatch(ctx, nil, counter.Measurement(1)) - meter.NewBatchObserver(func(_ context.Context, result metric.BatchObserverResult) { - result.Observe(nil, observer.Observation(1)) + err := meter.RegisterCallback([]instrument.Asynchronous{ + observer, + }, func(ctx context.Context) { + observer.Observe(ctx, 1) }) + require.ErrorIs(t, err, metricsdk.ErrBadInstrument) collected := sdk.Collect(ctx) - require.Equal(t, metricsdk.ErrUninitializedInstrument, testHandler.Flush()) + err = testHandler.Flush() + require.NoError(t, err) require.Equal(t, 0, collected) // Now try with instruments from another SDK. - var noopMeter metric.Meter - counter = metric.Must(noopMeter).NewInt64Counter("name.sum") - observer = metric.Must(noopMeter).NewBatchObserver( - func(context.Context, metric.BatchObserverResult) {}, - ).NewInt64GaugeObserver("observer") - - meter.RecordBatch(ctx, nil, counter.Measurement(1)) - meter.NewBatchObserver(func(_ context.Context, result metric.BatchObserverResult) { - result.Observe(nil, observer.Observation(1)) - }) + noopMeter := nonrecording.NewNoopMeter() + observer, _ = noopMeter.AsyncInt64().Gauge("observer") + + err = meter.RegisterCallback( + []instrument.Asynchronous{observer}, + func(ctx context.Context) { + observer.Observe(ctx, 1) + }, + ) + require.ErrorIs(t, err, metricsdk.ErrBadInstrument) collected = sdk.Collect(ctx) require.Equal(t, 0, collected) require.EqualValues(t, map[string]float64{}, processor.Values()) - require.Equal(t, metricsdk.ErrUninitializedInstrument, testHandler.Flush()) + + err = testHandler.Flush() + require.NoError(t, err) } func TestSyncInAsync(t *testing.T) { ctx := context.Background() meter, sdk, _, processor := newSDK(t) - counter := Must(meter).NewFloat64Counter("counter.sum") - _ = Must(meter).NewInt64GaugeObserver("observer.lastvalue", - func(ctx context.Context, result metric.Int64ObserverResult) { - result.Observe(10) - counter.Add(ctx, 100) - }, - ) + counter, _ := meter.SyncFloat64().Counter("counter.sum") + gauge, _ := meter.AsyncInt64().Gauge("observer.lastvalue") + + err := meter.RegisterCallback([]instrument.Asynchronous{ + gauge, + }, func(ctx context.Context) { + gauge.Observe(ctx, 10) + counter.Add(ctx, 100) + }) + require.NoError(t, err) sdk.Collect(ctx) diff --git a/sdk/metric/export/aggregation/aggregation.go b/sdk/metric/export/aggregation/aggregation.go index 44c8c3320e2..ea09fa68344 100644 --- a/sdk/metric/export/aggregation/aggregation.go +++ b/sdk/metric/export/aggregation/aggregation.go @@ -18,7 +18,7 @@ import ( "fmt" "time" - "go.opentelemetry.io/otel/metric/number" + "go.opentelemetry.io/otel/sdk/metric/number" ) // These interfaces describe the various ways to access state from an diff --git a/sdk/metric/export/aggregation/temporality.go b/sdk/metric/export/aggregation/temporality.go index ca71b79d03f..0612fe06af0 100644 --- a/sdk/metric/export/aggregation/temporality.go +++ b/sdk/metric/export/aggregation/temporality.go @@ -17,7 +17,7 @@ package aggregation // import "go.opentelemetry.io/otel/sdk/metric/export/aggregation" import ( - "go.opentelemetry.io/otel/metric/sdkapi" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" ) // Temporality indicates the temporal aggregation exported by an exporter. diff --git a/sdk/metric/export/aggregation/temporality_test.go b/sdk/metric/export/aggregation/temporality_test.go index d5d73e9d049..69b976da773 100644 --- a/sdk/metric/export/aggregation/temporality_test.go +++ b/sdk/metric/export/aggregation/temporality_test.go @@ -19,9 +19,9 @@ import ( "github.com/stretchr/testify/require" - "go.opentelemetry.io/otel/metric/metrictest" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" + "go.opentelemetry.io/otel/sdk/metric/metrictest" + "go.opentelemetry.io/otel/sdk/metric/number" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" ) func TestTemporalityIncludes(t *testing.T) { diff --git a/sdk/metric/export/metric.go b/sdk/metric/export/metric.go index 5251a059e1a..7937995e5cc 100644 --- a/sdk/metric/export/metric.go +++ b/sdk/metric/export/metric.go @@ -20,10 +20,10 @@ import ( "time" "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/sdk/instrumentation" "go.opentelemetry.io/otel/sdk/metric/aggregator" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" "go.opentelemetry.io/otel/sdk/resource" ) diff --git a/sdk/metric/go.mod b/sdk/metric/go.mod index fc70fcf873e..33fda254764 100644 --- a/sdk/metric/go.mod +++ b/sdk/metric/go.mod @@ -42,7 +42,6 @@ require ( github.com/benbjohnson/clock v1.3.0 github.com/stretchr/testify v1.7.0 go.opentelemetry.io/otel v1.4.1 - go.opentelemetry.io/otel/internal/metric v0.27.0 go.opentelemetry.io/otel/metric v0.27.0 go.opentelemetry.io/otel/sdk v1.4.1 ) @@ -55,8 +54,6 @@ replace go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc => ../.. replace go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp => ../../exporters/otlp/otlptrace/otlptracehttp -replace go.opentelemetry.io/otel/internal/metric => ../../internal/metric - replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric => ../../exporters/otlp/otlpmetric replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc => ../../exporters/otlp/otlpmetric/otlpmetricgrpc diff --git a/sdk/metric/histogram_stress_test.go b/sdk/metric/histogram_stress_test.go index caca662aa0e..abc8b967c60 100644 --- a/sdk/metric/histogram_stress_test.go +++ b/sdk/metric/histogram_stress_test.go @@ -22,10 +22,10 @@ import ( "github.com/stretchr/testify/require" - "go.opentelemetry.io/otel/metric/metrictest" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/sdk/metric/aggregator/histogram" + "go.opentelemetry.io/otel/sdk/metric/metrictest" + "go.opentelemetry.io/otel/sdk/metric/number" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" ) func TestStressInt64Histogram(t *testing.T) { diff --git a/metric/metrictest/alignment_test.go b/sdk/metric/metrictest/alignment_test.go similarity index 100% rename from metric/metrictest/alignment_test.go rename to sdk/metric/metrictest/alignment_test.go diff --git a/sdk/metric/metrictest/meter.go b/sdk/metric/metrictest/meter.go new file mode 100644 index 00000000000..8222441e48f --- /dev/null +++ b/sdk/metric/metrictest/meter.go @@ -0,0 +1,56 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metrictest // import "go.opentelemetry.io/otel/sdk/metric/metrictest" + +import ( + "context" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric/instrument" + "go.opentelemetry.io/otel/sdk/metric/number" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" +) + +type ( + + // Library is the same as "sdk/instrumentation".Library but there is + // a package cycle to use it. + Library struct { + InstrumentationName string + InstrumentationVersion string + SchemaURL string + } + + Batch struct { + // Measurement needs to be aligned for 64-bit atomic operations. + Measurements []Measurement + Ctx context.Context + Labels []attribute.KeyValue + Library Library + } + + Measurement struct { + // Number needs to be aligned for 64-bit atomic operations. + Number number.Number + Instrument sdkapi.InstrumentImpl + } +) + +// NewDescriptor is a test helper for constructing test metric +// descriptors using standard options. +func NewDescriptor(name string, ikind sdkapi.InstrumentKind, nkind number.Kind, opts ...instrument.Option) sdkapi.Descriptor { + cfg := instrument.NewConfig(opts...) + return sdkapi.NewDescriptor(name, ikind, nkind, cfg.Description(), cfg.Unit()) +} diff --git a/metric/number/doc.go b/sdk/metric/number/doc.go similarity index 92% rename from metric/number/doc.go rename to sdk/metric/number/doc.go index 0649ff875e7..6f947400a4b 100644 --- a/metric/number/doc.go +++ b/sdk/metric/number/doc.go @@ -20,4 +20,4 @@ This package is currently in a pre-GA phase. Backwards incompatible changes may be introduced in subsequent minor version releases as we work to track the evolving OpenTelemetry specification and user feedback. */ -package number // import "go.opentelemetry.io/otel/metric/number" +package number // import "go.opentelemetry.io/otel/sdk/metric/number" diff --git a/metric/number/kind_string.go b/sdk/metric/number/kind_string.go similarity index 100% rename from metric/number/kind_string.go rename to sdk/metric/number/kind_string.go diff --git a/metric/number/number.go b/sdk/metric/number/number.go similarity index 99% rename from metric/number/number.go rename to sdk/metric/number/number.go index 3ec95e2014d..5fd2f38f663 100644 --- a/metric/number/number.go +++ b/sdk/metric/number/number.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package number // import "go.opentelemetry.io/otel/metric/number" +package number // import "go.opentelemetry.io/otel/sdk/metric/number" //go:generate stringer -type=Kind diff --git a/metric/number/number_test.go b/sdk/metric/number/number_test.go similarity index 100% rename from metric/number/number_test.go rename to sdk/metric/number/number_test.go diff --git a/sdk/metric/processor/basic/basic.go b/sdk/metric/processor/basic/basic.go index 71101bc4bce..096044c043c 100644 --- a/sdk/metric/processor/basic/basic.go +++ b/sdk/metric/processor/basic/basic.go @@ -21,10 +21,10 @@ import ( "time" "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/sdk/metric/aggregator" "go.opentelemetry.io/otel/sdk/metric/export" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" ) type ( diff --git a/sdk/metric/processor/basic/basic_test.go b/sdk/metric/processor/basic/basic_test.go index 1378bf60d6e..80d0e2a20d8 100644 --- a/sdk/metric/processor/basic/basic_test.go +++ b/sdk/metric/processor/basic/basic_test.go @@ -25,19 +25,19 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/metrictest" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" + "go.opentelemetry.io/otel/metric/instrument" "go.opentelemetry.io/otel/sdk/instrumentation" sdk "go.opentelemetry.io/otel/sdk/metric" "go.opentelemetry.io/otel/sdk/metric/aggregator" "go.opentelemetry.io/otel/sdk/metric/aggregator/aggregatortest" "go.opentelemetry.io/otel/sdk/metric/export" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/metrictest" + "go.opentelemetry.io/otel/sdk/metric/number" "go.opentelemetry.io/otel/sdk/metric/processor/basic" "go.opentelemetry.io/otel/sdk/metric/processor/processortest" processorTest "go.opentelemetry.io/otel/sdk/metric/processor/processortest" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" "go.opentelemetry.io/otel/sdk/resource" ) @@ -450,15 +450,16 @@ func TestCounterObserverEndToEnd(t *testing.T) { eselector, ) accum := sdk.NewAccumulator(proc) - meter := metric.WrapMeterImpl(accum) + meter := sdkapi.WrapMeterImpl(accum) var calls int64 - metric.Must(meter).NewInt64CounterObserver("observer.sum", - func(_ context.Context, result metric.Int64ObserverResult) { - calls++ - result.Observe(calls) - }, - ) + ctr, err := meter.AsyncInt64().Counter("observer.sum") + require.NoError(t, err) + err = meter.RegisterCallback([]instrument.Asynchronous{ctr}, func(ctx context.Context) { + calls++ + ctr.Observe(ctx, calls) + }) + require.NoError(t, err) reader := proc.Reader() var startTime [3]time.Time diff --git a/sdk/metric/processor/processortest/test.go b/sdk/metric/processor/processortest/test.go index 6dbad262489..8931fc833f8 100644 --- a/sdk/metric/processor/processortest/test.go +++ b/sdk/metric/processor/processortest/test.go @@ -22,7 +22,6 @@ import ( "time" "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/sdk/instrumentation" "go.opentelemetry.io/otel/sdk/metric/aggregator" "go.opentelemetry.io/otel/sdk/metric/aggregator/histogram" @@ -30,6 +29,7 @@ import ( "go.opentelemetry.io/otel/sdk/metric/aggregator/sum" "go.opentelemetry.io/otel/sdk/metric/export" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" "go.opentelemetry.io/otel/sdk/resource" ) diff --git a/sdk/metric/processor/processortest/test_test.go b/sdk/metric/processor/processortest/test_test.go index 4cc990c344a..c157ad47e3e 100644 --- a/sdk/metric/processor/processortest/test_test.go +++ b/sdk/metric/processor/processortest/test_test.go @@ -21,33 +21,37 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/metric/instrument" "go.opentelemetry.io/otel/sdk/instrumentation" metricsdk "go.opentelemetry.io/otel/sdk/metric" "go.opentelemetry.io/otel/sdk/metric/export" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" "go.opentelemetry.io/otel/sdk/metric/processor/processortest" processorTest "go.opentelemetry.io/otel/sdk/metric/processor/processortest" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" "go.opentelemetry.io/otel/sdk/resource" ) -func generateTestData(proc export.Processor) { +func generateTestData(t *testing.T, proc export.Processor) { ctx := context.Background() accum := metricsdk.NewAccumulator(proc) - meter := metric.WrapMeterImpl(accum) + meter := sdkapi.WrapMeterImpl(accum) - counter := metric.Must(meter).NewFloat64Counter("counter.sum") - - _ = metric.Must(meter).NewInt64CounterObserver("observer.sum", - func(_ context.Context, result metric.Int64ObserverResult) { - result.Observe(10, attribute.String("K1", "V1")) - result.Observe(11, attribute.String("K1", "V2")) - }, - ) + counter, err := meter.SyncFloat64().Counter("counter.sum") + require.NoError(t, err) counter.Add(ctx, 100, attribute.String("K1", "V1")) counter.Add(ctx, 101, attribute.String("K1", "V2")) + counterObserver, err := meter.AsyncInt64().Counter("observer.sum") + require.NoError(t, err) + + err = meter.RegisterCallback([]instrument.Asynchronous{counterObserver}, func(ctx context.Context) { + counterObserver.Observe(ctx, 10, attribute.String("K1", "V1")) + counterObserver.Observe(ctx, 11, attribute.String("K1", "V2")) + }) + require.NoError(t, err) + accum.Collect(ctx) } @@ -60,7 +64,7 @@ func TestProcessorTesting(t *testing.T) { attribute.DefaultEncoder(), ), ) - generateTestData(checkpointer) + generateTestData(t, checkpointer) res := resource.NewSchemaless(attribute.String("R", "V")) expect := map[string]float64{ diff --git a/sdk/metric/processor/reducer/reducer.go b/sdk/metric/processor/reducer/reducer.go index b7fb4894036..d26fd55345e 100644 --- a/sdk/metric/processor/reducer/reducer.go +++ b/sdk/metric/processor/reducer/reducer.go @@ -16,8 +16,8 @@ package reducer // import "go.opentelemetry.io/otel/sdk/metric/processor/reducer import ( "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/sdk/metric/export" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" ) type ( diff --git a/sdk/metric/processor/reducer/reducer_test.go b/sdk/metric/processor/reducer/reducer_test.go index 3da65d313ef..22fc774f17e 100644 --- a/sdk/metric/processor/reducer/reducer_test.go +++ b/sdk/metric/processor/reducer/reducer_test.go @@ -21,8 +21,7 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/sdkapi" + "go.opentelemetry.io/otel/metric/instrument" "go.opentelemetry.io/otel/sdk/instrumentation" metricsdk "go.opentelemetry.io/otel/sdk/metric" "go.opentelemetry.io/otel/sdk/metric/export/aggregation" @@ -30,6 +29,7 @@ import ( "go.opentelemetry.io/otel/sdk/metric/processor/processortest" processorTest "go.opentelemetry.io/otel/sdk/metric/processor/processortest" "go.opentelemetry.io/otel/sdk/metric/processor/reducer" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" "go.opentelemetry.io/otel/sdk/resource" ) @@ -54,21 +54,22 @@ func (testFilter) LabelFilterFor(_ *sdkapi.Descriptor) attribute.Filter { } } -func generateData(impl sdkapi.MeterImpl) { +func generateData(t *testing.T, impl sdkapi.MeterImpl) { ctx := context.Background() - meter := metric.WrapMeterImpl(impl) - - counter := metric.Must(meter).NewFloat64Counter("counter.sum") - - _ = metric.Must(meter).NewInt64CounterObserver("observer.sum", - func(_ context.Context, result metric.Int64ObserverResult) { - result.Observe(10, kvs1...) - result.Observe(10, kvs2...) - }, - ) + meter := sdkapi.WrapMeterImpl(impl) + counter, err := meter.SyncFloat64().Counter("counter.sum") + require.NoError(t, err) counter.Add(ctx, 100, kvs1...) counter.Add(ctx, 100, kvs2...) + + counterObserver, err := meter.AsyncInt64().Counter("observer.sum") + require.NoError(t, err) + err = meter.RegisterCallback([]instrument.Asynchronous{counterObserver}, func(ctx context.Context) { + counterObserver.Observe(ctx, 10, kvs1...) + counterObserver.Observe(ctx, 10, kvs2...) + }) + require.NoError(t, err) } func TestFilterProcessor(t *testing.T) { @@ -79,7 +80,7 @@ func TestFilterProcessor(t *testing.T) { accum := metricsdk.NewAccumulator( reducer.New(testFilter{}, processorTest.NewCheckpointer(testProc)), ) - generateData(accum) + generateData(t, accum) accum.Collect(context.Background()) @@ -97,7 +98,7 @@ func TestFilterBasicProcessor(t *testing.T) { ) exporter := processorTest.New(basicProc, attribute.DefaultEncoder()) - generateData(accum) + generateData(t, accum) basicProc.StartCollection() accum.Collect(context.Background()) diff --git a/internal/metric/registry/doc.go b/sdk/metric/registry/doc.go similarity index 92% rename from internal/metric/registry/doc.go rename to sdk/metric/registry/doc.go index 2f17562f0eb..b401408beef 100644 --- a/internal/metric/registry/doc.go +++ b/sdk/metric/registry/doc.go @@ -21,4 +21,4 @@ This package is currently in a pre-GA phase. Backwards incompatible changes may be introduced in subsequent minor version releases as we work to track the evolving OpenTelemetry specification and user feedback. */ -package registry // import "go.opentelemetry.io/otel/internal/metric/registry" +package registry // import "go.opentelemetry.io/otel/sdk/metric/registry" diff --git a/internal/metric/registry/registry.go b/sdk/metric/registry/registry.go similarity index 86% rename from internal/metric/registry/registry.go rename to sdk/metric/registry/registry.go index c929bf45c85..c2870e483d1 100644 --- a/internal/metric/registry/registry.go +++ b/sdk/metric/registry/registry.go @@ -12,15 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -package registry // import "go.opentelemetry.io/otel/internal/metric/registry" +package registry // import "go.opentelemetry.io/otel/sdk/metric/registry" import ( "context" "fmt" "sync" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric/sdkapi" + "go.opentelemetry.io/otel/metric/instrument" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" ) // UniqueInstrumentMeterImpl implements the metric.MeterImpl interface, adding @@ -53,11 +53,6 @@ func (u *UniqueInstrumentMeterImpl) MeterImpl() sdkapi.MeterImpl { return u.impl } -// RecordBatch implements sdkapi.MeterImpl. -func (u *UniqueInstrumentMeterImpl) RecordBatch(ctx context.Context, labels []attribute.KeyValue, ms ...sdkapi.Measurement) { - u.impl.RecordBatch(ctx, labels, ms...) -} - // NewMetricKindMismatchError formats an error that describes a // mismatched metric instrument definition. func NewMetricKindMismatchError(desc sdkapi.Descriptor) error { @@ -115,10 +110,7 @@ func (u *UniqueInstrumentMeterImpl) NewSyncInstrument(descriptor sdkapi.Descript } // NewAsyncInstrument implements sdkapi.MeterImpl. -func (u *UniqueInstrumentMeterImpl) NewAsyncInstrument( - descriptor sdkapi.Descriptor, - runner sdkapi.AsyncRunner, -) (sdkapi.AsyncImpl, error) { +func (u *UniqueInstrumentMeterImpl) NewAsyncInstrument(descriptor sdkapi.Descriptor) (sdkapi.AsyncImpl, error) { u.lock.Lock() defer u.lock.Unlock() @@ -130,10 +122,17 @@ func (u *UniqueInstrumentMeterImpl) NewAsyncInstrument( return impl.(sdkapi.AsyncImpl), nil } - asyncInst, err := u.impl.NewAsyncInstrument(descriptor, runner) + asyncInst, err := u.impl.NewAsyncInstrument(descriptor) if err != nil { return nil, err } u.state[descriptor.Name()] = asyncInst return asyncInst, nil } + +func (u *UniqueInstrumentMeterImpl) RegisterCallback(insts []instrument.Asynchronous, callback func(context.Context)) error { + u.lock.Lock() + defer u.lock.Unlock() + + return u.impl.RegisterCallback(insts, callback) +} diff --git a/internal/metric/registry/registry_test.go b/sdk/metric/registry/registry_test.go similarity index 71% rename from internal/metric/registry/registry_test.go rename to sdk/metric/registry/registry_test.go index 04884898822..5d2bc9b108f 100644 --- a/internal/metric/registry/registry_test.go +++ b/sdk/metric/registry/registry_test.go @@ -15,16 +15,15 @@ package registry_test import ( - "context" "errors" "testing" "github.com/stretchr/testify/require" - "go.opentelemetry.io/otel/internal/metric/registry" "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/metrictest" - "go.opentelemetry.io/otel/metric/sdkapi" + metricsdk "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/metric/registry" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" ) type ( @@ -34,22 +33,22 @@ type ( var ( allNew = map[string]newFunc{ "counter.int64": func(m metric.Meter, name string) (sdkapi.InstrumentImpl, error) { - return unwrap(m.NewInt64Counter(name)) + return unwrap(m.SyncInt64().Counter(name)) }, "counter.float64": func(m metric.Meter, name string) (sdkapi.InstrumentImpl, error) { - return unwrap(m.NewFloat64Counter(name)) + return unwrap(m.SyncFloat64().Counter(name)) }, "histogram.int64": func(m metric.Meter, name string) (sdkapi.InstrumentImpl, error) { - return unwrap(m.NewInt64Histogram(name)) + return unwrap(m.SyncInt64().Histogram(name)) }, "histogram.float64": func(m metric.Meter, name string) (sdkapi.InstrumentImpl, error) { - return unwrap(m.NewFloat64Histogram(name)) + return unwrap(m.SyncFloat64().Histogram(name)) }, "gaugeobserver.int64": func(m metric.Meter, name string) (sdkapi.InstrumentImpl, error) { - return unwrap(m.NewInt64GaugeObserver(name, func(context.Context, metric.Int64ObserverResult) {})) + return unwrap(m.AsyncInt64().Gauge(name)) }, "gaugeobserver.float64": func(m metric.Meter, name string) (sdkapi.InstrumentImpl, error) { - return unwrap(m.NewFloat64GaugeObserver(name, func(context.Context, metric.Float64ObserverResult) {})) + return unwrap(m.AsyncFloat64().Gauge(name)) }, } ) @@ -71,10 +70,11 @@ func unwrap(impl interface{}, err error) (sdkapi.InstrumentImpl, error) { return nil, err } +// TODO Replace with controller func testMeterWithRegistry(name string) metric.Meter { - return metric.WrapMeterImpl( + return sdkapi.WrapMeterImpl( registry.NewUniqueInstrumentMeterImpl( - metrictest.NewMeterProvider().Meter(name).MeterImpl(), + metricsdk.NewAccumulator(nil), ), ) } @@ -91,21 +91,6 @@ func TestRegistrySameInstruments(t *testing.T) { } } -func TestRegistryDifferentNamespace(t *testing.T) { - for _, nf := range allNew { - provider := metrictest.NewMeterProvider() - - meter1 := provider.Meter("meter1") - meter2 := provider.Meter("meter2") - inst1, err1 := nf(meter1, "this") - inst2, err2 := nf(meter2, "this") - - require.NoError(t, err1) - require.NoError(t, err2) - require.NotEqual(t, inst1, inst2) - } -} - func TestRegistryDiffInstruments(t *testing.T) { for origName, origf := range allNew { meter := testMeterWithRegistry("meter") @@ -120,7 +105,7 @@ func TestRegistryDiffInstruments(t *testing.T) { other, err := nf(meter, "this") require.Error(t, err) - require.NotNil(t, other) + require.Nil(t, other) require.True(t, errors.Is(err, registry.ErrMetricKindMismatch)) } } diff --git a/sdk/metric/sdk.go b/sdk/metric/sdk.go index a043342627b..db3ad330213 100644 --- a/sdk/metric/sdk.go +++ b/sdk/metric/sdk.go @@ -23,11 +23,11 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" - internal "go.opentelemetry.io/otel/internal/metric" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" + "go.opentelemetry.io/otel/metric/instrument" "go.opentelemetry.io/otel/sdk/metric/aggregator" "go.opentelemetry.io/otel/sdk/metric/export" + "go.opentelemetry.io/otel/sdk/metric/number" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" ) type ( @@ -44,10 +44,8 @@ type ( // current maps `mapkey` to *record. current sync.Map - // asyncInstruments is a set of - // `*asyncInstrument` instances - asyncLock sync.Mutex - asyncInstruments *internal.AsyncInstrumentState + callbackLock sync.Mutex + callbacks map[*callback]struct{} // currentEpoch is the current epoch number. It is // incremented in `Collect()`. @@ -58,15 +56,23 @@ type ( // collectLock prevents simultaneous calls to Collect(). collectLock sync.Mutex + } - // asyncSortSlice has a single purpose - as a temporary - // place for sorting during labels creation to avoid - // allocation. It is cleared after use. - asyncSortSlice attribute.Sortable + callback struct { + insts map[*asyncInstrument]struct{} + f func(context.Context) + } + + asyncContextKey struct{} + + asyncInstrument struct { + baseInstrument + instrument.Asynchronous } syncInstrument struct { - instrument + baseInstrument + instrument.Synchronous } // mapkey uniquely describes a metric instrument in terms of @@ -92,16 +98,10 @@ type ( // supports checking for no updates during a round. collectedCount int64 - // storage is the stored label set for this record, + // labels is the stored label set for this record, // except in cases where a label set is shared due to // batch recording. - storage attribute.Set - - // labels is the processed label set for this record. - // this may refer to the `storage` field in another - // record if this label set is shared resulting from - // `RecordBatch`. - labels *attribute.Set + labels attribute.Set // sortSlice has a single purpose - as a temporary // place for sorting during labels creation to avoid @@ -109,7 +109,7 @@ type ( sortSlice attribute.Sortable // inst is a pointer to the corresponding instrument. - inst *syncInstrument + inst *baseInstrument // current implements the actual RecordOne() API, // depending on the type of aggregation. If nil, the @@ -118,36 +118,23 @@ type ( checkpoint aggregator.Aggregator } - instrument struct { + baseInstrument struct { meter *Accumulator descriptor sdkapi.Descriptor } - - asyncInstrument struct { - instrument - // recorders maps ordered labels to the pair of - // labelset and recorder - recorders map[attribute.Distinct]*labeledRecorder - } - - labeledRecorder struct { - observedEpoch int64 - labels *attribute.Set - observed aggregator.Aggregator - } ) var ( _ sdkapi.MeterImpl = &Accumulator{} - _ sdkapi.AsyncImpl = &asyncInstrument{} - _ sdkapi.SyncImpl = &syncInstrument{} // ErrUninitializedInstrument is returned when an instrument is used when uninitialized. ErrUninitializedInstrument = fmt.Errorf("use of an uninitialized instrument") + + ErrBadInstrument = fmt.Errorf("use of a instrument from another SDK") ) -func (inst *instrument) Descriptor() sdkapi.Descriptor { - return inst.descriptor +func (b *baseInstrument) Descriptor() sdkapi.Descriptor { + return b.descriptor } func (a *asyncInstrument) Implementation() interface{} { @@ -158,77 +145,24 @@ func (s *syncInstrument) Implementation() interface{} { return s } -func (a *asyncInstrument) observe(num number.Number, labels *attribute.Set) { - if err := aggregator.RangeTest(num, &a.descriptor); err != nil { - otel.Handle(err) - return - } - recorder := a.getRecorder(labels) - if recorder == nil { - // The instrument is disabled according to the - // AggregatorSelector. - return - } - if err := recorder.Update(context.Background(), num, &a.descriptor); err != nil { - otel.Handle(err) - return - } -} - -func (a *asyncInstrument) getRecorder(labels *attribute.Set) aggregator.Aggregator { - lrec, ok := a.recorders[labels.Equivalent()] - if ok { - // Note: SynchronizedMove(nil) can't return an error - _ = lrec.observed.SynchronizedMove(nil, &a.descriptor) - lrec.observedEpoch = a.meter.currentEpoch - a.recorders[labels.Equivalent()] = lrec - return lrec.observed - } - var rec aggregator.Aggregator - a.meter.processor.AggregatorFor(&a.descriptor, &rec) - if a.recorders == nil { - a.recorders = make(map[attribute.Distinct]*labeledRecorder) - } - // This may store nil recorder in the map, thus disabling the - // asyncInstrument for the labelset for good. This is intentional, - // but will be revisited later. - a.recorders[labels.Equivalent()] = &labeledRecorder{ - observed: rec, - labels: labels, - observedEpoch: a.meter.currentEpoch, - } - return rec -} - // acquireHandle gets or creates a `*record` corresponding to `kvs`, -// the input labels. The second argument `labels` is passed in to -// support re-use of the orderedLabels computed by a previous -// measurement in the same batch. This performs two allocations -// in the common case. -func (s *syncInstrument) acquireHandle(kvs []attribute.KeyValue, labelPtr *attribute.Set) *record { - var rec *record - var equiv attribute.Distinct - - if labelPtr == nil { - // This memory allocation may not be used, but it's - // needed for the `sortSlice` field, to avoid an - // allocation while sorting. - rec = &record{} - rec.storage = attribute.NewSetWithSortable(kvs, &rec.sortSlice) - rec.labels = &rec.storage - equiv = rec.storage.Equivalent() - } else { - equiv = labelPtr.Equivalent() - } +// the input labels. +func (b *baseInstrument) acquireHandle(kvs []attribute.KeyValue) *record { + + // This memory allocation may not be used, but it's + // needed for the `sortSlice` field, to avoid an + // allocation while sorting. + rec := &record{} + rec.labels = attribute.NewSetWithSortable(kvs, &rec.sortSlice) // Create lookup key for sync.Map (one allocation, as this // passes through an interface{}) mk := mapkey{ - descriptor: &s.descriptor, - ordered: equiv, + descriptor: &b.descriptor, + ordered: rec.labels.Equivalent(), } - if actual, ok := s.meter.current.Load(mk); ok { + if actual, ok := b.meter.current.Load(mk); ok { // Existing record case. existingRec := actual.(*record) if existingRec.refMapped.ref() { @@ -239,19 +173,15 @@ func (s *syncInstrument) acquireHandle(kvs []attribute.KeyValue, labelPtr *attri // This entry is no longer mapped, try to add a new entry. } - if rec == nil { - rec = &record{} - rec.labels = labelPtr - } rec.refMapped = refcountMapped{value: 2} - rec.inst = s + rec.inst = b - s.meter.processor.AggregatorFor(&s.descriptor, &rec.current, &rec.checkpoint) + b.meter.processor.AggregatorFor(&b.descriptor, &rec.current, &rec.checkpoint) for { // Load/Store: there's a memory allocation to place `mk` into // an interface here. - if actual, loaded := s.meter.current.LoadOrStore(mk, rec); loaded { + if actual, loaded := b.meter.current.LoadOrStore(mk, rec); loaded { // Existing record case. Cannot change rec here because if fail // will try to add rec again to avoid new allocations. oldRec := actual.(*record) @@ -278,11 +208,22 @@ func (s *syncInstrument) acquireHandle(kvs []attribute.KeyValue, labelPtr *attri } } +// RecordOne captures a single synchronous metric event. +// // The order of the input array `kvs` may be sorted after the function is called. func (s *syncInstrument) RecordOne(ctx context.Context, num number.Number, kvs []attribute.KeyValue) { - h := s.acquireHandle(kvs, nil) + h := s.acquireHandle(kvs) defer h.unbind() - h.RecordOne(ctx, num) + h.captureOne(ctx, num) +} + +// ObserveOne captures a single asynchronous metric event. + +// The order of the input array `kvs` may be sorted after the function is called. +func (a *asyncInstrument) ObserveOne(ctx context.Context, num number.Number, attrs []attribute.KeyValue) { + h := a.acquireHandle(attrs) + defer h.unbind() + h.captureOne(ctx, num) } // NewAccumulator constructs a new Accumulator for the given @@ -296,15 +237,17 @@ func (s *syncInstrument) RecordOne(ctx context.Context, num number.Number, kvs [ // own periodic collection. func NewAccumulator(processor export.Processor) *Accumulator { return &Accumulator{ - processor: processor, - asyncInstruments: internal.NewAsyncInstrumentState(), + processor: processor, + callbacks: map[*callback]struct{}{}, } } +var _ sdkapi.MeterImpl = &Accumulator{} + // NewSyncInstrument implements sdkapi.MetricImpl. func (m *Accumulator) NewSyncInstrument(descriptor sdkapi.Descriptor) (sdkapi.SyncImpl, error) { return &syncInstrument{ - instrument: instrument{ + baseInstrument: baseInstrument{ descriptor: descriptor, meter: m, }, @@ -312,19 +255,40 @@ func (m *Accumulator) NewSyncInstrument(descriptor sdkapi.Descriptor) (sdkapi.Sy } // NewAsyncInstrument implements sdkapi.MetricImpl. -func (m *Accumulator) NewAsyncInstrument(descriptor sdkapi.Descriptor, runner sdkapi.AsyncRunner) (sdkapi.AsyncImpl, error) { +func (m *Accumulator) NewAsyncInstrument(descriptor sdkapi.Descriptor) (sdkapi.AsyncImpl, error) { a := &asyncInstrument{ - instrument: instrument{ + baseInstrument: baseInstrument{ descriptor: descriptor, meter: m, }, } - m.asyncLock.Lock() - defer m.asyncLock.Unlock() - m.asyncInstruments.Register(a, runner) return a, nil } +func (m *Accumulator) RegisterCallback(insts []instrument.Asynchronous, f func(context.Context)) error { + cb := &callback{ + insts: map[*asyncInstrument]struct{}{}, + f: f, + } + for _, inst := range insts { + impl, ok := inst.(sdkapi.AsyncImpl) + if !ok { + return ErrBadInstrument + } + + ai, err := m.fromAsync(impl) + if err != nil { + return err + } + cb.insts[ai] = struct{}{} + } + + m.callbackLock.Lock() + defer m.callbackLock.Unlock() + m.callbacks[cb] = struct{}{} + return nil +} + // Collect traverses the list of active records and observers and // exports data for each active instrument. Collect() may not be // called concurrently. @@ -337,14 +301,14 @@ func (m *Accumulator) Collect(ctx context.Context) int { m.collectLock.Lock() defer m.collectLock.Unlock() - checkpointed := m.observeAsyncInstruments(ctx) - checkpointed += m.collectSyncInstruments() + m.runAsyncCallbacks(ctx) + checkpointed := m.collectInstruments() m.currentEpoch++ return checkpointed } -func (m *Accumulator) collectSyncInstruments() int { +func (m *Accumulator) collectInstruments() int { checkpointed := 0 m.current.Range(func(key interface{}, value interface{}) bool { @@ -387,33 +351,15 @@ func (m *Accumulator) collectSyncInstruments() int { return checkpointed } -// CollectAsync implements internal.AsyncCollector. -// The order of the input array `kvs` may be sorted after the function is called. -func (m *Accumulator) CollectAsync(kv []attribute.KeyValue, obs ...sdkapi.Observation) { - labels := attribute.NewSetWithSortable(kv, &m.asyncSortSlice) - - for _, ob := range obs { - if a := m.fromAsync(ob.AsyncImpl()); a != nil { - a.observe(ob.Number(), &labels) - } - } -} - -func (m *Accumulator) observeAsyncInstruments(ctx context.Context) int { - m.asyncLock.Lock() - defer m.asyncLock.Unlock() - - asyncCollected := 0 +func (m *Accumulator) runAsyncCallbacks(ctx context.Context) { + m.callbackLock.Lock() + defer m.callbackLock.Unlock() - m.asyncInstruments.Run(ctx, m) + ctx = context.WithValue(ctx, asyncContextKey{}, m) - for _, inst := range m.asyncInstruments.Instruments() { - if a := m.fromAsync(inst); a != nil { - asyncCollected += m.checkpointAsync(a) - } + for cb := range m.callbacks { + cb.f(ctx) } - - return asyncCollected } func (m *Accumulator) checkpointRecord(r *record) int { @@ -426,7 +372,7 @@ func (m *Accumulator) checkpointRecord(r *record) int { return 0 } - a := export.NewAccumulation(&r.inst.descriptor, r.labels, r.checkpoint) + a := export.NewAccumulation(&r.inst.descriptor, &r.labels, r.checkpoint) err = m.processor.Process(a) if err != nil { otel.Handle(err) @@ -434,63 +380,7 @@ func (m *Accumulator) checkpointRecord(r *record) int { return 1 } -func (m *Accumulator) checkpointAsync(a *asyncInstrument) int { - if len(a.recorders) == 0 { - return 0 - } - checkpointed := 0 - for encodedLabels, lrec := range a.recorders { - lrec := lrec - epochDiff := m.currentEpoch - lrec.observedEpoch - if epochDiff == 0 { - if lrec.observed != nil { - a := export.NewAccumulation(&a.descriptor, lrec.labels, lrec.observed) - err := m.processor.Process(a) - if err != nil { - otel.Handle(err) - } - checkpointed++ - } - } else if epochDiff > 1 { - // This is second collection cycle with no - // observations for this labelset. Remove the - // recorder. - delete(a.recorders, encodedLabels) - } - } - if len(a.recorders) == 0 { - a.recorders = nil - } - return checkpointed -} - -// RecordBatch enters a batch of metric events. -// The order of the input array `kvs` may be sorted after the function is called. -func (m *Accumulator) RecordBatch(ctx context.Context, kvs []attribute.KeyValue, measurements ...sdkapi.Measurement) { - // Labels will be computed the first time acquireHandle is - // called. Subsequent calls to acquireHandle will re-use the - // previously computed value instead of recomputing the - // ordered labels. - var labelsPtr *attribute.Set - for i, meas := range measurements { - s := m.fromSync(meas.SyncImpl()) - if s == nil { - continue - } - h := s.acquireHandle(kvs, labelsPtr) - - // Re-use labels for the next measurement. - if i == 0 { - labelsPtr = h.labels - } - - defer h.unbind() - h.RecordOne(ctx, meas.Number()) - } -} - -// RecordOne implements sdkapi.SyncImpl. -func (r *record) RecordOne(ctx context.Context, num number.Number) { +func (r *record) captureOne(ctx context.Context, num number.Number) { if r.current == nil { // The instrument is disabled according to the AggregatorSelector. return @@ -519,26 +409,16 @@ func (r *record) mapkey() mapkey { } } -// fromSync gets a sync implementation object, checking for -// uninitialized instruments and instruments created by another SDK. -func (m *Accumulator) fromSync(sync sdkapi.SyncImpl) *syncInstrument { - if sync != nil { - if inst, ok := sync.Implementation().(*syncInstrument); ok { - return inst - } - } - otel.Handle(ErrUninitializedInstrument) - return nil -} - // fromSync gets an async implementation object, checking for // uninitialized instruments and instruments created by another SDK. -func (m *Accumulator) fromAsync(async sdkapi.AsyncImpl) *asyncInstrument { - if async != nil { - if inst, ok := async.Implementation().(*asyncInstrument); ok { - return inst - } +func (m *Accumulator) fromAsync(async sdkapi.AsyncImpl) (*asyncInstrument, error) { + if async == nil { + return nil, ErrUninitializedInstrument } - otel.Handle(ErrUninitializedInstrument) - return nil + inst, ok := async.Implementation().(*asyncInstrument) + if !ok { + return nil, ErrBadInstrument + } + return inst, nil + } diff --git a/metric/sdkapi/descriptor.go b/sdk/metric/sdkapi/descriptor.go similarity index 94% rename from metric/sdkapi/descriptor.go rename to sdk/metric/sdkapi/descriptor.go index 14eb0532e45..f86e4473459 100644 --- a/metric/sdkapi/descriptor.go +++ b/sdk/metric/sdkapi/descriptor.go @@ -12,11 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -package sdkapi // import "go.opentelemetry.io/otel/metric/sdkapi" +package sdkapi // import "go.opentelemetry.io/otel/sdk/metric/sdkapi" import ( - "go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/unit" + "go.opentelemetry.io/otel/sdk/metric/number" ) // Descriptor contains all the settings that describe an instrument, diff --git a/metric/sdkapi/descriptor_test.go b/sdk/metric/sdkapi/descriptor_test.go similarity index 96% rename from metric/sdkapi/descriptor_test.go rename to sdk/metric/sdkapi/descriptor_test.go index 6b6927075f9..1f084472535 100644 --- a/metric/sdkapi/descriptor_test.go +++ b/sdk/metric/sdkapi/descriptor_test.go @@ -19,8 +19,8 @@ import ( "github.com/stretchr/testify/require" - "go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/unit" + "go.opentelemetry.io/otel/sdk/metric/number" ) func TestDescriptorGetters(t *testing.T) { diff --git a/metric/sdkapi/instrumentkind.go b/sdk/metric/sdkapi/instrumentkind.go similarity index 97% rename from metric/sdkapi/instrumentkind.go rename to sdk/metric/sdkapi/instrumentkind.go index 64aa5ead123..c7406a3e49a 100644 --- a/metric/sdkapi/instrumentkind.go +++ b/sdk/metric/sdkapi/instrumentkind.go @@ -14,7 +14,7 @@ //go:generate stringer -type=InstrumentKind -package sdkapi // import "go.opentelemetry.io/otel/metric/sdkapi" +package sdkapi // import "go.opentelemetry.io/otel/sdk/metric/sdkapi" // InstrumentKind describes the kind of instrument. type InstrumentKind int8 diff --git a/metric/sdkapi/instrumentkind_string.go b/sdk/metric/sdkapi/instrumentkind_string.go similarity index 100% rename from metric/sdkapi/instrumentkind_string.go rename to sdk/metric/sdkapi/instrumentkind_string.go diff --git a/metric/sdkapi/instrumentkind_test.go b/sdk/metric/sdkapi/instrumentkind_test.go similarity index 96% rename from metric/sdkapi/instrumentkind_test.go rename to sdk/metric/sdkapi/instrumentkind_test.go index 0b2901383b2..cd1db02a898 100644 --- a/metric/sdkapi/instrumentkind_test.go +++ b/sdk/metric/sdkapi/instrumentkind_test.go @@ -19,7 +19,7 @@ import ( "github.com/stretchr/testify/require" - "go.opentelemetry.io/otel/metric/sdkapi" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" ) func TestInstrumentKinds(t *testing.T) { diff --git a/metric/sdkapi/noop.go b/sdk/metric/sdkapi/noop.go similarity index 71% rename from metric/sdkapi/noop.go rename to sdk/metric/sdkapi/noop.go index f22895dae6f..6b2374b68a3 100644 --- a/metric/sdkapi/noop.go +++ b/sdk/metric/sdkapi/noop.go @@ -12,20 +12,34 @@ // See the License for the specific language governing permissions and // limitations under the License. -package sdkapi // import "go.opentelemetry.io/otel/metric/sdkapi" +package sdkapi // import "go.opentelemetry.io/otel/sdk/metric/sdkapi" import ( "context" "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric/number" -) + "go.opentelemetry.io/otel/metric/instrument" + "go.opentelemetry.io/otel/sdk/metric/number" +) // import ( +// "context" + +// "go.opentelemetry.io/otel/attribute" +// "go.opentelemetry.io/otel/sdk/metric/number" +// ) type noopInstrument struct { descriptor Descriptor } -type noopSyncInstrument struct{ noopInstrument } -type noopAsyncInstrument struct{ noopInstrument } +type noopSyncInstrument struct { + noopInstrument + + instrument.Synchronous +} +type noopAsyncInstrument struct { + noopInstrument + + instrument.Asynchronous +} var _ SyncImpl = noopSyncInstrument{} var _ AsyncImpl = noopAsyncInstrument{} @@ -34,7 +48,7 @@ var _ AsyncImpl = noopAsyncInstrument{} // synchronous instrument interface. func NewNoopSyncInstrument() SyncImpl { return noopSyncInstrument{ - noopInstrument{ + noopInstrument: noopInstrument{ descriptor: Descriptor{ instrumentKind: CounterInstrumentKind, }, @@ -46,7 +60,7 @@ func NewNoopSyncInstrument() SyncImpl { // asynchronous instrument interface. func NewNoopAsyncInstrument() AsyncImpl { return noopAsyncInstrument{ - noopInstrument{ + noopInstrument: noopInstrument{ descriptor: Descriptor{ instrumentKind: CounterObserverInstrumentKind, }, @@ -64,3 +78,6 @@ func (n noopInstrument) Descriptor() Descriptor { func (noopSyncInstrument) RecordOne(context.Context, number.Number, []attribute.KeyValue) { } + +func (noopAsyncInstrument) ObserveOne(ctx context.Context, number number.Number, labels []attribute.KeyValue) { +} diff --git a/metric/sdkapi/sdkapi.go b/sdk/metric/sdkapi/sdkapi.go similarity index 90% rename from metric/sdkapi/sdkapi.go rename to sdk/metric/sdkapi/sdkapi.go index 36836364bdc..4345358ff3e 100644 --- a/metric/sdkapi/sdkapi.go +++ b/sdk/metric/sdkapi/sdkapi.go @@ -12,21 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -package sdkapi // import "go.opentelemetry.io/otel/metric/sdkapi" +package sdkapi // import "go.opentelemetry.io/otel/sdk/metric/sdkapi" import ( "context" "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric/number" + "go.opentelemetry.io/otel/metric/instrument" + "go.opentelemetry.io/otel/sdk/metric/number" ) // MeterImpl is the interface an SDK must implement to supply a Meter // implementation. type MeterImpl interface { - // RecordBatch atomically records a batch of measurements. - RecordBatch(ctx context.Context, labels []attribute.KeyValue, measurement ...Measurement) - // NewSyncInstrument returns a newly constructed // synchronous instrument implementation or an error, should // one occur. @@ -35,10 +33,10 @@ type MeterImpl interface { // NewAsyncInstrument returns a newly constructed // asynchronous instrument implementation or an error, should // one occur. - NewAsyncInstrument( - descriptor Descriptor, - runner AsyncRunner, - ) (AsyncImpl, error) + NewAsyncInstrument(descriptor Descriptor) (AsyncImpl, error) + + // Etc. + RegisterCallback(insts []instrument.Asynchronous, callback func(context.Context)) error } // InstrumentImpl is a common interface for synchronous and @@ -57,6 +55,7 @@ type InstrumentImpl interface { // synchronous instrument (e.g., Histogram and Counter instruments). type SyncImpl interface { InstrumentImpl + instrument.Synchronous // RecordOne captures a single synchronous metric event. RecordOne(ctx context.Context, number number.Number, labels []attribute.KeyValue) @@ -66,6 +65,10 @@ type SyncImpl interface { // asynchronous instrument (e.g., Observer instruments). type AsyncImpl interface { InstrumentImpl + instrument.Asynchronous + + // ObserveOne captures a single synchronous metric event. + ObserveOne(ctx context.Context, number number.Number, labels []attribute.KeyValue) } // AsyncRunner is expected to convert into an AsyncSingleRunner or an diff --git a/metric/sdkapi/sdkapi_test.go b/sdk/metric/sdkapi/sdkapi_test.go similarity index 96% rename from metric/sdkapi/sdkapi_test.go rename to sdk/metric/sdkapi/sdkapi_test.go index 9c80f89bddb..69fec0fe692 100644 --- a/metric/sdkapi/sdkapi_test.go +++ b/sdk/metric/sdkapi/sdkapi_test.go @@ -19,7 +19,7 @@ import ( "github.com/stretchr/testify/require" - "go.opentelemetry.io/otel/metric/number" + "go.opentelemetry.io/otel/sdk/metric/number" ) func TestMeasurementGetters(t *testing.T) { diff --git a/sdk/metric/sdkapi/wrap.go b/sdk/metric/sdkapi/wrap.go new file mode 100644 index 00000000000..9a4d5b0de14 --- /dev/null +++ b/sdk/metric/sdkapi/wrap.go @@ -0,0 +1,181 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package sdkapi // import "go.opentelemetry.io/otel/sdk/metric/sdkapi" + +import ( + "context" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/metric/instrument" + "go.opentelemetry.io/otel/metric/instrument/asyncfloat64" + "go.opentelemetry.io/otel/metric/instrument/asyncint64" + "go.opentelemetry.io/otel/metric/instrument/syncfloat64" + "go.opentelemetry.io/otel/metric/instrument/syncint64" + "go.opentelemetry.io/otel/sdk/metric/number" +) + +type ( + meter struct{ MeterImpl } + sfMeter struct{ meter } + siMeter struct{ meter } + afMeter struct{ meter } + aiMeter struct{ meter } + + iAdder struct{ SyncImpl } + fAdder struct{ SyncImpl } + iRecorder struct{ SyncImpl } + fRecorder struct{ SyncImpl } + iObserver struct{ AsyncImpl } + fObserver struct{ AsyncImpl } +) + +func WrapMeterImpl(impl MeterImpl) metric.Meter { + return meter{impl} +} + +func UnwrapMeterImpl(m metric.Meter) MeterImpl { + mm, ok := m.(meter) + if !ok { + return nil + } + return mm.MeterImpl +} + +func (m meter) AsyncFloat64() asyncfloat64.InstrumentProvider { + return afMeter{m} +} + +func (m meter) AsyncInt64() asyncint64.InstrumentProvider { + return aiMeter{m} +} + +func (m meter) SyncFloat64() syncfloat64.InstrumentProvider { + return sfMeter{m} +} + +func (m meter) SyncInt64() syncint64.InstrumentProvider { + return siMeter{m} +} + +func (m meter) RegisterCallback(insts []instrument.Asynchronous, cb func(ctx context.Context)) error { + return m.MeterImpl.RegisterCallback(insts, cb) +} + +func (m meter) newSync(name string, ikind InstrumentKind, nkind number.Kind, opts []instrument.Option) (SyncImpl, error) { + cfg := instrument.NewConfig(opts...) + return m.NewSyncInstrument(NewDescriptor(name, ikind, nkind, cfg.Description(), cfg.Unit())) +} + +func (m meter) newAsync(name string, ikind InstrumentKind, nkind number.Kind, opts []instrument.Option) (AsyncImpl, error) { + cfg := instrument.NewConfig(opts...) + return m.NewAsyncInstrument(NewDescriptor(name, ikind, nkind, cfg.Description(), cfg.Unit())) +} + +func (m afMeter) Counter(name string, opts ...instrument.Option) (asyncfloat64.Counter, error) { + inst, err := m.newAsync(name, CounterObserverInstrumentKind, number.Float64Kind, opts) + return fObserver{inst}, err +} + +func (m afMeter) UpDownCounter(name string, opts ...instrument.Option) (asyncfloat64.UpDownCounter, error) { + inst, err := m.newAsync(name, UpDownCounterObserverInstrumentKind, number.Float64Kind, opts) + return fObserver{inst}, err +} + +func (m afMeter) Gauge(name string, opts ...instrument.Option) (asyncfloat64.Gauge, error) { + inst, err := m.newAsync(name, GaugeObserverInstrumentKind, number.Float64Kind, opts) + return fObserver{inst}, err +} + +func (m aiMeter) Counter(name string, opts ...instrument.Option) (asyncint64.Counter, error) { + inst, err := m.newAsync(name, CounterObserverInstrumentKind, number.Int64Kind, opts) + return iObserver{inst}, err +} + +func (m aiMeter) UpDownCounter(name string, opts ...instrument.Option) (asyncint64.UpDownCounter, error) { + inst, err := m.newAsync(name, UpDownCounterObserverInstrumentKind, number.Int64Kind, opts) + return iObserver{inst}, err +} + +func (m aiMeter) Gauge(name string, opts ...instrument.Option) (asyncint64.Gauge, error) { + inst, err := m.newAsync(name, GaugeObserverInstrumentKind, number.Int64Kind, opts) + return iObserver{inst}, err +} + +func (m sfMeter) Counter(name string, opts ...instrument.Option) (syncfloat64.Counter, error) { + inst, err := m.newSync(name, CounterInstrumentKind, number.Float64Kind, opts) + return fAdder{inst}, err +} + +func (m sfMeter) UpDownCounter(name string, opts ...instrument.Option) (syncfloat64.UpDownCounter, error) { + inst, err := m.newSync(name, UpDownCounterInstrumentKind, number.Float64Kind, opts) + return fAdder{inst}, err +} + +func (m sfMeter) Histogram(name string, opts ...instrument.Option) (syncfloat64.Histogram, error) { + inst, err := m.newSync(name, HistogramInstrumentKind, number.Float64Kind, opts) + return fRecorder{inst}, err +} + +func (m siMeter) Counter(name string, opts ...instrument.Option) (syncint64.Counter, error) { + inst, err := m.newSync(name, CounterInstrumentKind, number.Int64Kind, opts) + return iAdder{inst}, err +} + +func (m siMeter) UpDownCounter(name string, opts ...instrument.Option) (syncint64.UpDownCounter, error) { + inst, err := m.newSync(name, UpDownCounterInstrumentKind, number.Int64Kind, opts) + return iAdder{inst}, err +} + +func (m siMeter) Histogram(name string, opts ...instrument.Option) (syncint64.Histogram, error) { + inst, err := m.newSync(name, HistogramInstrumentKind, number.Int64Kind, opts) + return iRecorder{inst}, err +} + +func (a fAdder) Add(ctx context.Context, value float64, attrs ...attribute.KeyValue) { + if a.SyncImpl != nil { + a.SyncImpl.RecordOne(ctx, number.NewFloat64Number(value), attrs) + } +} + +func (a iAdder) Add(ctx context.Context, value int64, attrs ...attribute.KeyValue) { + if a.SyncImpl != nil { + a.SyncImpl.RecordOne(ctx, number.NewInt64Number(value), attrs) + } +} + +func (a fRecorder) Record(ctx context.Context, value float64, attrs ...attribute.KeyValue) { + if a.SyncImpl != nil { + a.SyncImpl.RecordOne(ctx, number.NewFloat64Number(value), attrs) + } +} + +func (a iRecorder) Record(ctx context.Context, value int64, attrs ...attribute.KeyValue) { + if a.SyncImpl != nil { + a.SyncImpl.RecordOne(ctx, number.NewInt64Number(value), attrs) + } +} + +func (a fObserver) Observe(ctx context.Context, value float64, attrs ...attribute.KeyValue) { + if a.AsyncImpl != nil { + a.AsyncImpl.ObserveOne(ctx, number.NewFloat64Number(value), attrs) + } +} + +func (a iObserver) Observe(ctx context.Context, value int64, attrs ...attribute.KeyValue) { + if a.AsyncImpl != nil { + a.AsyncImpl.ObserveOne(ctx, number.NewInt64Number(value), attrs) + } +} diff --git a/sdk/metric/selector/simple/simple.go b/sdk/metric/selector/simple/simple.go index 5b3e1c5fd5e..5451072f607 100644 --- a/sdk/metric/selector/simple/simple.go +++ b/sdk/metric/selector/simple/simple.go @@ -15,12 +15,12 @@ package simple // import "go.opentelemetry.io/otel/sdk/metric/selector/simple" import ( - "go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/sdk/metric/aggregator" "go.opentelemetry.io/otel/sdk/metric/aggregator/histogram" "go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue" "go.opentelemetry.io/otel/sdk/metric/aggregator/sum" "go.opentelemetry.io/otel/sdk/metric/export" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" ) type ( diff --git a/sdk/metric/selector/simple/simple_test.go b/sdk/metric/selector/simple/simple_test.go index a25291b5112..9e946864e53 100644 --- a/sdk/metric/selector/simple/simple_test.go +++ b/sdk/metric/selector/simple/simple_test.go @@ -19,14 +19,14 @@ import ( "github.com/stretchr/testify/require" - "go.opentelemetry.io/otel/metric/metrictest" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/sdk/metric/aggregator" "go.opentelemetry.io/otel/sdk/metric/aggregator/histogram" "go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue" "go.opentelemetry.io/otel/sdk/metric/aggregator/sum" "go.opentelemetry.io/otel/sdk/metric/export" + "go.opentelemetry.io/otel/sdk/metric/metrictest" + "go.opentelemetry.io/otel/sdk/metric/number" + "go.opentelemetry.io/otel/sdk/metric/sdkapi" "go.opentelemetry.io/otel/sdk/metric/selector/simple" ) diff --git a/sdk/metric/stress_test.go b/sdk/metric/stress_test.go deleted file mode 100644 index f6b9eb4ba02..00000000000 --- a/sdk/metric/stress_test.go +++ /dev/null @@ -1,502 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// This test is too large for the race detector. This SDK uses no locks -// that the race detector would help with, anyway. -//go:build !race -// +build !race - -package metric - -import ( - "context" - "fmt" - "math" - "math/rand" - "runtime" - "sort" - "strings" - "sync" - "sync/atomic" - "testing" - "time" - - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/number" - "go.opentelemetry.io/otel/metric/sdkapi" - "go.opentelemetry.io/otel/sdk/metric/export" - "go.opentelemetry.io/otel/sdk/metric/export/aggregation" - "go.opentelemetry.io/otel/sdk/metric/processor/processortest" -) - -const ( - concurrencyPerCPU = 100 - reclaimPeriod = time.Millisecond * 100 - testRun = 5 * time.Second - epsilon = 1e-10 -) - -var Must = metric.Must - -type ( - testFixture struct { - // stop has to be aligned for 64-bit atomic operations. - stop int64 - expected sync.Map - received sync.Map // Note: doesn't require synchronization - wg sync.WaitGroup - impl testImpl - T *testing.T - - export.AggregatorSelector - - lock sync.Mutex - lused map[string]bool - - dupCheck map[testKey]int - totalDups int64 - } - - testKey struct { - labels string - descriptor *sdkapi.Descriptor - } - - testImpl struct { - newInstrument func(meter metric.Meter, name string) SyncImpler - getUpdateValue func() number.Number - operate func(interface{}, context.Context, number.Number, []attribute.KeyValue) - newStore func() interface{} - - // storeCollect and storeExpect are the same for - // counters, different for lastValues, to ensure we are - // testing the timestamps correctly. - storeCollect func(store interface{}, value number.Number, ts time.Time) - storeExpect func(store interface{}, value number.Number) - readStore func(store interface{}) number.Number - equalValues func(a, b number.Number) bool - } - - SyncImpler interface { - SyncImpl() sdkapi.SyncImpl - } - - // lastValueState supports merging lastValue values, for the case - // where a race condition causes duplicate records. We always - // take the later timestamp. - lastValueState struct { - // raw has to be aligned for 64-bit atomic operations. - raw number.Number - ts time.Time - } -) - -func concurrency() int { - return concurrencyPerCPU * runtime.NumCPU() -} - -func canonicalizeLabels(ls []attribute.KeyValue) string { - copy := append(ls[0:0:0], ls...) - sort.SliceStable(copy, func(i, j int) bool { - return copy[i].Key < copy[j].Key - }) - var b strings.Builder - for _, kv := range copy { - b.WriteString(string(kv.Key)) - b.WriteString("=") - b.WriteString(kv.Value.Emit()) - b.WriteString("$") - } - return b.String() -} - -func getPeriod() time.Duration { - dur := math.Max( - float64(reclaimPeriod)/10, - float64(reclaimPeriod)*(1+0.1*rand.NormFloat64()), - ) - return time.Duration(dur) -} - -func (f *testFixture) someLabels() []attribute.KeyValue { - n := 1 + rand.Intn(3) - l := make([]attribute.KeyValue, n) - - for { - oused := map[string]bool{} - for i := 0; i < n; i++ { - var k string - for { - k = fmt.Sprint("k", rand.Intn(1000000000)) - if !oused[k] { - oused[k] = true - break - } - } - l[i] = attribute.String(k, fmt.Sprint("v", rand.Intn(1000000000))) - } - lc := canonicalizeLabels(l) - f.lock.Lock() - avail := !f.lused[lc] - if avail { - f.lused[lc] = true - f.lock.Unlock() - return l - } - f.lock.Unlock() - } -} - -func (f *testFixture) startWorker(impl *Accumulator, meter metric.Meter, wg *sync.WaitGroup, i int) { - ctx := context.Background() - name := fmt.Sprint("test_", i) - instrument := f.impl.newInstrument(meter, name) - var descriptor *sdkapi.Descriptor - if ii, ok := instrument.SyncImpl().(*syncInstrument); ok { - descriptor = &ii.descriptor - } - kvs := f.someLabels() - clabs := canonicalizeLabels(kvs) - dur := getPeriod() - key := testKey{ - labels: clabs, - descriptor: descriptor, - } - for { - sleep := time.Duration(rand.ExpFloat64() * float64(dur)) - time.Sleep(sleep) - value := f.impl.getUpdateValue() - f.impl.operate(instrument, ctx, value, kvs) - - actual, _ := f.expected.LoadOrStore(key, f.impl.newStore()) - - f.impl.storeExpect(actual, value) - - if atomic.LoadInt64(&f.stop) != 0 { - wg.Done() - return - } - } -} - -func (f *testFixture) assertTest(numCollect int) { - var allErrs []func() - csize := 0 - f.received.Range(func(key, gstore interface{}) bool { - csize++ - gvalue := f.impl.readStore(gstore) - - estore, loaded := f.expected.Load(key) - if !loaded { - allErrs = append(allErrs, func() { - f.T.Error("Could not locate expected key: ", key) - }) - return true - } - evalue := f.impl.readStore(estore) - - if !f.impl.equalValues(evalue, gvalue) { - allErrs = append(allErrs, func() { - f.T.Error("Expected value mismatch: ", - evalue, "!=", gvalue, " for ", key) - }) - } - return true - }) - rsize := 0 - f.expected.Range(func(key, value interface{}) bool { - rsize++ - if _, loaded := f.received.Load(key); !loaded { - allErrs = append(allErrs, func() { - f.T.Error("Did not receive expected key: ", key) - }) - } - return true - }) - if rsize != csize { - f.T.Error("Did not receive the correct set of metrics: Received != Expected", rsize, csize) - } - - for _, anErr := range allErrs { - anErr() - } - - // Note: It's useful to know the test triggers this condition, - // but we can't assert it. Infrequently no duplicates are - // found, and we can't really force a race to happen. - // - // fmt.Printf("Test duplicate records seen: %.1f%%\n", - // float64(100*f.totalDups/int64(numCollect*concurrency()))) -} - -func (f *testFixture) preCollect() { - // Collect calls Process in a single-threaded context. No need - // to lock this struct. - f.dupCheck = map[testKey]int{} -} - -func (*testFixture) Reader() export.Reader { - return nil -} - -func (f *testFixture) Process(accumulation export.Accumulation) error { - labels := accumulation.Labels().ToSlice() - key := testKey{ - labels: canonicalizeLabels(labels), - descriptor: accumulation.Descriptor(), - } - if f.dupCheck[key] == 0 { - f.dupCheck[key]++ - } else { - f.totalDups++ - } - - actual, _ := f.received.LoadOrStore(key, f.impl.newStore()) - - agg := accumulation.Aggregator() - switch accumulation.Descriptor().InstrumentKind() { - case sdkapi.CounterInstrumentKind: - sum, err := agg.(aggregation.Sum).Sum() - if err != nil { - f.T.Fatal("Sum error: ", err) - } - f.impl.storeCollect(actual, sum, time.Time{}) - case sdkapi.HistogramInstrumentKind: - lv, ts, err := agg.(aggregation.LastValue).LastValue() - if err != nil && err != aggregation.ErrNoData { - f.T.Fatal("Last value error: ", err) - } - f.impl.storeCollect(actual, lv, ts) - default: - panic("Not used in this test") - } - return nil -} - -func stressTest(t *testing.T, impl testImpl) { - ctx := context.Background() - t.Parallel() - fixture := &testFixture{ - T: t, - impl: impl, - lused: map[string]bool{}, - AggregatorSelector: processortest.AggregatorSelector(), - } - cc := concurrency() - - sdk := NewAccumulator(fixture) - meter := metric.WrapMeterImpl(sdk) - fixture.wg.Add(cc + 1) - - for i := 0; i < cc; i++ { - go fixture.startWorker(sdk, meter, &fixture.wg, i) - } - - numCollect := 0 - - go func() { - for { - time.Sleep(reclaimPeriod) - fixture.preCollect() - sdk.Collect(ctx) - numCollect++ - if atomic.LoadInt64(&fixture.stop) != 0 { - fixture.wg.Done() - return - } - } - }() - - time.Sleep(testRun) - atomic.StoreInt64(&fixture.stop, 1) - fixture.wg.Wait() - fixture.preCollect() - sdk.Collect(ctx) - numCollect++ - - fixture.assertTest(numCollect) -} - -func int64sEqual(a, b number.Number) bool { - return a.AsInt64() == b.AsInt64() -} - -func float64sEqual(a, b number.Number) bool { - diff := math.Abs(a.AsFloat64() - b.AsFloat64()) - return diff < math.Abs(a.AsFloat64())*epsilon -} - -// Counters - -func intCounterTestImpl() testImpl { - return testImpl{ - newInstrument: func(meter metric.Meter, name string) SyncImpler { - return Must(meter).NewInt64Counter(name + ".sum") - }, - getUpdateValue: func() number.Number { - for { - x := int64(rand.Intn(100)) - if x != 0 { - return number.NewInt64Number(x) - } - } - }, - operate: func(inst interface{}, ctx context.Context, value number.Number, labels []attribute.KeyValue) { - counter := inst.(metric.Int64Counter) - counter.Add(ctx, value.AsInt64(), labels...) - }, - newStore: func() interface{} { - n := number.NewInt64Number(0) - return &n - }, - storeCollect: func(store interface{}, value number.Number, _ time.Time) { - store.(*number.Number).AddInt64Atomic(value.AsInt64()) - }, - storeExpect: func(store interface{}, value number.Number) { - store.(*number.Number).AddInt64Atomic(value.AsInt64()) - }, - readStore: func(store interface{}) number.Number { - return store.(*number.Number).AsNumberAtomic() - }, - equalValues: int64sEqual, - } -} - -func TestStressInt64Counter(t *testing.T) { - stressTest(t, intCounterTestImpl()) -} - -func floatCounterTestImpl() testImpl { - return testImpl{ - newInstrument: func(meter metric.Meter, name string) SyncImpler { - return Must(meter).NewFloat64Counter(name + ".sum") - }, - getUpdateValue: func() number.Number { - for { - x := rand.Float64() - if x != 0 { - return number.NewFloat64Number(x) - } - } - }, - operate: func(inst interface{}, ctx context.Context, value number.Number, labels []attribute.KeyValue) { - counter := inst.(metric.Float64Counter) - counter.Add(ctx, value.AsFloat64(), labels...) - }, - newStore: func() interface{} { - n := number.NewFloat64Number(0.0) - return &n - }, - storeCollect: func(store interface{}, value number.Number, _ time.Time) { - store.(*number.Number).AddFloat64Atomic(value.AsFloat64()) - }, - storeExpect: func(store interface{}, value number.Number) { - store.(*number.Number).AddFloat64Atomic(value.AsFloat64()) - }, - readStore: func(store interface{}) number.Number { - return store.(*number.Number).AsNumberAtomic() - }, - equalValues: float64sEqual, - } -} - -func TestStressFloat64Counter(t *testing.T) { - stressTest(t, floatCounterTestImpl()) -} - -// LastValue - -func intLastValueTestImpl() testImpl { - return testImpl{ - newInstrument: func(meter metric.Meter, name string) SyncImpler { - return Must(meter).NewInt64Histogram(name + ".lastvalue") - }, - getUpdateValue: func() number.Number { - r1 := rand.Int63() - return number.NewInt64Number(rand.Int63() - r1) - }, - operate: func(inst interface{}, ctx context.Context, value number.Number, labels []attribute.KeyValue) { - histogram := inst.(metric.Int64Histogram) - histogram.Record(ctx, value.AsInt64(), labels...) - }, - newStore: func() interface{} { - return &lastValueState{ - raw: number.NewInt64Number(0), - } - }, - storeCollect: func(store interface{}, value number.Number, ts time.Time) { - gs := store.(*lastValueState) - - if !ts.Before(gs.ts) { - gs.ts = ts - gs.raw.SetInt64Atomic(value.AsInt64()) - } - }, - storeExpect: func(store interface{}, value number.Number) { - gs := store.(*lastValueState) - gs.raw.SetInt64Atomic(value.AsInt64()) - }, - readStore: func(store interface{}) number.Number { - gs := store.(*lastValueState) - return gs.raw.AsNumberAtomic() - }, - equalValues: int64sEqual, - } -} - -func TestStressInt64LastValue(t *testing.T) { - stressTest(t, intLastValueTestImpl()) -} - -func floatLastValueTestImpl() testImpl { - return testImpl{ - newInstrument: func(meter metric.Meter, name string) SyncImpler { - return Must(meter).NewFloat64Histogram(name + ".lastvalue") - }, - getUpdateValue: func() number.Number { - return number.NewFloat64Number((-0.5 + rand.Float64()) * 100000) - }, - operate: func(inst interface{}, ctx context.Context, value number.Number, labels []attribute.KeyValue) { - histogram := inst.(metric.Float64Histogram) - histogram.Record(ctx, value.AsFloat64(), labels...) - }, - newStore: func() interface{} { - return &lastValueState{ - raw: number.NewFloat64Number(0), - } - }, - storeCollect: func(store interface{}, value number.Number, ts time.Time) { - gs := store.(*lastValueState) - - if !ts.Before(gs.ts) { - gs.ts = ts - gs.raw.SetFloat64Atomic(value.AsFloat64()) - } - }, - storeExpect: func(store interface{}, value number.Number) { - gs := store.(*lastValueState) - gs.raw.SetFloat64Atomic(value.AsFloat64()) - }, - readStore: func(store interface{}) number.Number { - gs := store.(*lastValueState) - return gs.raw.AsNumberAtomic() - }, - equalValues: float64sEqual, - } -} - -func TestStressFloat64LastValue(t *testing.T) { - stressTest(t, floatLastValueTestImpl()) -} From 24414b2455ec9331feaa49370c79b83d60dd21cc Mon Sep 17 00:00:00 2001 From: Damien Mathieu <42@dmathieu.com> Date: Thu, 3 Mar 2022 03:07:06 +0100 Subject: [PATCH 05/29] Refactor OTLP exporter env config to be shared across all exporters (#2608) * setup global envconfig package for otlp exporter * use envconfig in otlpmetrics package * fix lint * add changelog entry * Update exporters/otlp/internal/envconfig/envconfig.go Co-authored-by: Chester Cheung * fix lint Co-authored-by: Chester Cheung Co-authored-by: Anthony Mirabella --- CHANGELOG.md | 1 + .../otlp/internal/envconfig/envconfig.go | 148 ++++++++ .../otlp/internal/envconfig/envconfig_test.go | 345 ++++++++++++++++++ .../internal/otlpconfig/envconfig.go | 225 ++++-------- .../internal/otlpconfig/envconfig_test.go | 60 --- .../internal/otlpconfig/options_test.go | 8 +- .../internal/otlpconfig/envconfig.go | 218 +++-------- .../internal/otlpconfig/envconfig_test.go | 60 --- .../internal/otlpconfig/options_test.go | 8 +- 9 files changed, 627 insertions(+), 446 deletions(-) create mode 100644 exporters/otlp/internal/envconfig/envconfig.go create mode 100644 exporters/otlp/internal/envconfig/envconfig_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 30b4333441d..b90c3a4b167 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ This update is a breaking change of the unstable Metrics API. Code instrumented - The metrics API has been significantly changed. (#2587) - Unify path cleaning functionally in the `otlpmetric` and `otlptrace` config. (#2639) - Change the debug message from the `sdk/trace.BatchSpanProcessor` to reflect the count is cumulative. (#2640) +- Introduce new internal envconfig package for OTLP exporters (#2608) ### Fixed diff --git a/exporters/otlp/internal/envconfig/envconfig.go b/exporters/otlp/internal/envconfig/envconfig.go new file mode 100644 index 00000000000..b696338ec9a --- /dev/null +++ b/exporters/otlp/internal/envconfig/envconfig.go @@ -0,0 +1,148 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package envconfig // import "go.opentelemetry.io/otel/exporters/otlp/internal/envconfig" + +import ( + "crypto/tls" + "crypto/x509" + "errors" + "fmt" + "net/url" + "strconv" + "strings" + "time" +) + +// ConfigFn is the generic function used to set a config +type ConfigFn func(*EnvOptionsReader) + +// EnvOptionsReader reads the required environment variables +type EnvOptionsReader struct { + GetEnv func(string) string + ReadFile func(string) ([]byte, error) + Namespace string +} + +// Apply runs every ConfigFn +func (e *EnvOptionsReader) Apply(opts ...ConfigFn) { + for _, o := range opts { + o(e) + } +} + +// GetEnvValue gets an OTLP environment variable value of the specified key +// using the GetEnv function. +// This function prepends the OTLP specified namespace to all key lookups. +func (e *EnvOptionsReader) GetEnvValue(key string) (string, bool) { + v := strings.TrimSpace(e.GetEnv(keyWithNamespace(e.Namespace, key))) + return v, v != "" +} + +// WithString retrieves the specified config and passes it to ConfigFn as a string +func WithString(n string, fn func(string)) func(e *EnvOptionsReader) { + return func(e *EnvOptionsReader) { + if v, ok := e.GetEnvValue(n); ok { + fn(v) + } + } +} + +// WithDuration retrieves the specified config and passes it to ConfigFn as a duration +func WithDuration(n string, fn func(time.Duration)) func(e *EnvOptionsReader) { + return func(e *EnvOptionsReader) { + if v, ok := e.GetEnvValue(n); ok { + if d, err := strconv.Atoi(v); err == nil { + fn(time.Duration(d) * time.Millisecond) + } + } + } +} + +// WithHeaders retrieves the specified config and passes it to ConfigFn as a map of HTTP headers +func WithHeaders(n string, fn func(map[string]string)) func(e *EnvOptionsReader) { + return func(e *EnvOptionsReader) { + if v, ok := e.GetEnvValue(n); ok { + fn(stringToHeader(v)) + } + } +} + +// WithURL retrieves the specified config and passes it to ConfigFn as a net/url.URL +func WithURL(n string, fn func(*url.URL)) func(e *EnvOptionsReader) { + return func(e *EnvOptionsReader) { + if v, ok := e.GetEnvValue(n); ok { + if u, err := url.Parse(v); err == nil { + fn(u) + } + } + } +} + +// WithTLSConfig retrieves the specified config and passes it to ConfigFn as a crypto/tls.Config +func WithTLSConfig(n string, fn func(*tls.Config)) func(e *EnvOptionsReader) { + return func(e *EnvOptionsReader) { + if v, ok := e.GetEnvValue(n); ok { + if b, err := e.ReadFile(v); err == nil { + if c, err := createTLSConfig(b); err == nil { + fn(c) + } + } + } + } +} + +func keyWithNamespace(ns, key string) string { + if ns == "" { + return key + } + return fmt.Sprintf("%s_%s", ns, key) +} + +func stringToHeader(value string) map[string]string { + headersPairs := strings.Split(value, ",") + headers := make(map[string]string) + + for _, header := range headersPairs { + nameValue := strings.SplitN(header, "=", 2) + if len(nameValue) < 2 { + continue + } + name, err := url.QueryUnescape(nameValue[0]) + if err != nil { + continue + } + trimmedName := strings.TrimSpace(name) + value, err := url.QueryUnescape(nameValue[1]) + if err != nil { + continue + } + trimmedValue := strings.TrimSpace(value) + + headers[trimmedName] = trimmedValue + } + + return headers +} + +func createTLSConfig(certBytes []byte) (*tls.Config, error) { + cp := x509.NewCertPool() + if ok := cp.AppendCertsFromPEM(certBytes); !ok { + return nil, errors.New("failed to append certificate to the cert pool") + } + + return &tls.Config{ + RootCAs: cp, + }, nil +} diff --git a/exporters/otlp/internal/envconfig/envconfig_test.go b/exporters/otlp/internal/envconfig/envconfig_test.go new file mode 100644 index 00000000000..b141cd42b93 --- /dev/null +++ b/exporters/otlp/internal/envconfig/envconfig_test.go @@ -0,0 +1,345 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package envconfig // import "go.opentelemetry.io/otel/exporters/otlp/internal/envconfig" + +import ( + "crypto/tls" + "net/url" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +const WeakCertificate = ` +-----BEGIN CERTIFICATE----- +MIIBhzCCASygAwIBAgIRANHpHgAWeTnLZpTSxCKs0ggwCgYIKoZIzj0EAwIwEjEQ +MA4GA1UEChMHb3RlbC1nbzAeFw0yMTA0MDExMzU5MDNaFw0yMTA0MDExNDU5MDNa +MBIxEDAOBgNVBAoTB290ZWwtZ28wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS9 +nWSkmPCxShxnp43F+PrOtbGV7sNfkbQ/kxzi9Ego0ZJdiXxkmv/C05QFddCW7Y0Z +sJCLHGogQsYnWJBXUZOVo2MwYTAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYI +KwYBBQUHAwEwDAYDVR0TAQH/BAIwADAsBgNVHREEJTAjgglsb2NhbGhvc3SHEAAA +AAAAAAAAAAAAAAAAAAGHBH8AAAEwCgYIKoZIzj0EAwIDSQAwRgIhANwZVVKvfvQ/ +1HXsTvgH+xTQswOwSSKYJ1cVHQhqK7ZbAiEAus8NxpTRnp5DiTMuyVmhVNPB+bVH +Lhnm4N/QDk5rek0= +-----END CERTIFICATE----- +` + +type testOption struct { + TestString string + TestDuration time.Duration + TestHeaders map[string]string + TestURL *url.URL + TestTLS *tls.Config +} + +func TestEnvConfig(t *testing.T) { + parsedURL, err := url.Parse("https://example.com") + assert.NoError(t, err) + + options := []testOption{} + for _, testcase := range []struct { + name string + reader EnvOptionsReader + configs []ConfigFn + expectedOptions []testOption + }{ + { + name: "with no namespace and a matching key", + reader: EnvOptionsReader{ + GetEnv: func(n string) string { + if n == "HELLO" { + return "world" + } + return "" + }, + }, + configs: []ConfigFn{ + WithString("HELLO", func(v string) { + options = append(options, testOption{TestString: v}) + }), + }, + expectedOptions: []testOption{ + { + TestString: "world", + }, + }, + }, + { + name: "with no namespace and a non-matching key", + reader: EnvOptionsReader{ + GetEnv: func(n string) string { + if n == "HELLO" { + return "world" + } + return "" + }, + }, + configs: []ConfigFn{ + WithString("HOLA", func(v string) { + options = append(options, testOption{TestString: v}) + }), + }, + expectedOptions: []testOption{}, + }, + { + name: "with a namespace and a matching key", + reader: EnvOptionsReader{ + Namespace: "MY_NAMESPACE", + GetEnv: func(n string) string { + if n == "MY_NAMESPACE_HELLO" { + return "world" + } + return "" + }, + }, + configs: []ConfigFn{ + WithString("HELLO", func(v string) { + options = append(options, testOption{TestString: v}) + }), + }, + expectedOptions: []testOption{ + { + TestString: "world", + }, + }, + }, + { + name: "with no namespace and a non-matching key", + reader: EnvOptionsReader{ + Namespace: "MY_NAMESPACE", + GetEnv: func(n string) string { + if n == "HELLO" { + return "world" + } + return "" + }, + }, + configs: []ConfigFn{ + WithString("HELLO", func(v string) { + options = append(options, testOption{TestString: v}) + }), + }, + expectedOptions: []testOption{}, + }, + { + name: "with a duration config", + reader: EnvOptionsReader{ + GetEnv: func(n string) string { + if n == "HELLO" { + return "60" + } + return "" + }, + }, + configs: []ConfigFn{ + WithDuration("HELLO", func(v time.Duration) { + options = append(options, testOption{TestDuration: v}) + }), + }, + expectedOptions: []testOption{ + { + TestDuration: 60_000_000, // 60 milliseconds + }, + }, + }, + { + name: "with an invalid duration config", + reader: EnvOptionsReader{ + GetEnv: func(n string) string { + if n == "HELLO" { + return "world" + } + return "" + }, + }, + configs: []ConfigFn{ + WithDuration("HELLO", func(v time.Duration) { + options = append(options, testOption{TestDuration: v}) + }), + }, + expectedOptions: []testOption{}, + }, + { + name: "with headers", + reader: EnvOptionsReader{ + GetEnv: func(n string) string { + if n == "HELLO" { + return "userId=42,userName=alice" + } + return "" + }, + }, + configs: []ConfigFn{ + WithHeaders("HELLO", func(v map[string]string) { + options = append(options, testOption{TestHeaders: v}) + }), + }, + expectedOptions: []testOption{ + { + TestHeaders: map[string]string{ + "userId": "42", + "userName": "alice", + }, + }, + }, + }, + { + name: "with invalid headers", + reader: EnvOptionsReader{ + GetEnv: func(n string) string { + if n == "HELLO" { + return "world" + } + return "" + }, + }, + configs: []ConfigFn{ + WithHeaders("HELLO", func(v map[string]string) { + options = append(options, testOption{TestHeaders: v}) + }), + }, + expectedOptions: []testOption{ + { + TestHeaders: map[string]string{}, + }, + }, + }, + { + name: "with URL", + reader: EnvOptionsReader{ + GetEnv: func(n string) string { + if n == "HELLO" { + return "https://example.com" + } + return "" + }, + }, + configs: []ConfigFn{ + WithURL("HELLO", func(v *url.URL) { + options = append(options, testOption{TestURL: v}) + }), + }, + expectedOptions: []testOption{ + { + TestURL: parsedURL, + }, + }, + }, + { + name: "with invalid URL", + reader: EnvOptionsReader{ + GetEnv: func(n string) string { + if n == "HELLO" { + return "i nvalid://url" + } + return "" + }, + }, + configs: []ConfigFn{ + WithURL("HELLO", func(v *url.URL) { + options = append(options, testOption{TestURL: v}) + }), + }, + expectedOptions: []testOption{}, + }, + } { + t.Run(testcase.name, func(t *testing.T) { + testcase.reader.Apply(testcase.configs...) + assert.Equal(t, testcase.expectedOptions, options) + options = []testOption{} + }) + } +} + +func TestWithTLSConfig(t *testing.T) { + tlsCert, err := createTLSConfig([]byte(WeakCertificate)) + assert.NoError(t, err) + + reader := EnvOptionsReader{ + GetEnv: func(n string) string { + if n == "CERTIFICATE" { + return "/path/cert.pem" + } + return "" + }, + ReadFile: func(p string) ([]byte, error) { + if p == "/path/cert.pem" { + return []byte(WeakCertificate), nil + } + return []byte{}, nil + }, + } + + var option testOption + reader.Apply( + WithTLSConfig("CERTIFICATE", func(v *tls.Config) { + option = testOption{TestTLS: v} + })) + assert.Equal(t, tlsCert.RootCAs.Subjects(), option.TestTLS.RootCAs.Subjects()) +} + +func TestStringToHeader(t *testing.T) { + tests := []struct { + name string + value string + want map[string]string + }{ + { + name: "simple test", + value: "userId=alice", + want: map[string]string{"userId": "alice"}, + }, + { + name: "simple test with spaces", + value: " userId = alice ", + want: map[string]string{"userId": "alice"}, + }, + { + name: "multiples headers encoded", + value: "userId=alice,serverNode=DF%3A28,isProduction=false", + want: map[string]string{ + "userId": "alice", + "serverNode": "DF:28", + "isProduction": "false", + }, + }, + { + name: "invalid headers format", + value: "userId:alice", + want: map[string]string{}, + }, + { + name: "invalid key", + value: "%XX=missing,userId=alice", + want: map[string]string{ + "userId": "alice", + }, + }, + { + name: "invalid value", + value: "missing=%XX,userId=alice", + want: map[string]string{ + "userId": "alice", + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.want, stringToHeader(tt.value)) + }) + } +} diff --git a/exporters/otlp/otlpmetric/internal/otlpconfig/envconfig.go b/exporters/otlp/otlpmetric/internal/otlpconfig/envconfig.go index ecf2ecaf9c2..d59912ddb6e 100644 --- a/exporters/otlp/otlpmetric/internal/otlpconfig/envconfig.go +++ b/exporters/otlp/otlpmetric/internal/otlpconfig/envconfig.go @@ -16,66 +16,58 @@ package otlpconfig // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric import ( "crypto/tls" - "fmt" "io/ioutil" "net/url" "os" "path" - "strconv" "strings" "time" - "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/exporters/otlp/internal/envconfig" ) -var DefaultEnvOptionsReader = EnvOptionsReader{ - GetEnv: os.Getenv, - ReadFile: ioutil.ReadFile, +// DefaultEnvOptionsReader is the default environments reader +var DefaultEnvOptionsReader = envconfig.EnvOptionsReader{ + GetEnv: os.Getenv, + ReadFile: ioutil.ReadFile, + Namespace: "OTEL_EXPORTER_OTLP", } +// ApplyGRPCEnvConfigs applies the env configurations for gRPC func ApplyGRPCEnvConfigs(cfg Config) Config { - return DefaultEnvOptionsReader.ApplyGRPCEnvConfigs(cfg) -} - -func ApplyHTTPEnvConfigs(cfg Config) Config { - return DefaultEnvOptionsReader.ApplyHTTPEnvConfigs(cfg) -} - -type EnvOptionsReader struct { - GetEnv func(string) string - ReadFile func(filename string) ([]byte, error) -} - -func (e *EnvOptionsReader) ApplyHTTPEnvConfigs(cfg Config) Config { - opts := e.GetOptionsFromEnv() + opts := getOptionsFromEnv() for _, opt := range opts { - cfg = opt.ApplyHTTPOption(cfg) + cfg = opt.ApplyGRPCOption(cfg) } return cfg } -func (e *EnvOptionsReader) ApplyGRPCEnvConfigs(cfg Config) Config { - opts := e.GetOptionsFromEnv() +// ApplyHTTPEnvConfigs applies the env configurations for HTTP +func ApplyHTTPEnvConfigs(cfg Config) Config { + opts := getOptionsFromEnv() for _, opt := range opts { - cfg = opt.ApplyGRPCOption(cfg) + cfg = opt.ApplyHTTPOption(cfg) } return cfg } -func (e *EnvOptionsReader) GetOptionsFromEnv() []GenericOption { - var opts []GenericOption +func getOptionsFromEnv() []GenericOption { + opts := []GenericOption{} - // Endpoint - if v, ok := e.getEnvValue("METRICS_ENDPOINT"); ok { - u, err := url.Parse(v) - // Ignore invalid values. - if err == nil { - // This is used to set the scheme for OTLP/HTTP. - if insecureSchema(u.Scheme) { - opts = append(opts, WithInsecure()) - } else { - opts = append(opts, WithSecure()) - } + DefaultEnvOptionsReader.Apply( + envconfig.WithURL("ENDPOINT", func(u *url.URL) { + opts = append(opts, withEndpointScheme(u)) + opts = append(opts, newSplitOption(func(cfg Config) Config { + cfg.Metrics.Endpoint = u.Host + // For OTLP/HTTP endpoint URLs without a per-signal + // configuration, the passed endpoint is used as a base URL + // and the signals are sent to these paths relative to that. + cfg.Metrics.URLPath = path.Join(u.Path, DefaultMetricsPath) + return cfg + }, withEndpointForGRPC(u))) + }), + envconfig.WithURL("METRICS_ENDPOINT", func(u *url.URL) { + opts = append(opts, withEndpointScheme(u)) opts = append(opts, newSplitOption(func(cfg Config) Config { cfg.Metrics.Endpoint = u.Host // For endpoint URLs for OTLP/HTTP per-signal variables, the @@ -88,141 +80,50 @@ func (e *EnvOptionsReader) GetOptionsFromEnv() []GenericOption { } cfg.Metrics.URLPath = path return cfg - }, func(cfg Config) Config { - // For OTLP/gRPC endpoints, this is the target to which the - // exporter is going to send telemetry. - cfg.Metrics.Endpoint = path.Join(u.Host, u.Path) - return cfg - })) - } - } else if v, ok = e.getEnvValue("ENDPOINT"); ok { - u, err := url.Parse(v) - // Ignore invalid values. - if err == nil { - // This is used to set the scheme for OTLP/HTTP. - if insecureSchema(u.Scheme) { - opts = append(opts, WithInsecure()) - } else { - opts = append(opts, WithSecure()) - } - opts = append(opts, newSplitOption(func(cfg Config) Config { - cfg.Metrics.Endpoint = u.Host - // For OTLP/HTTP endpoint URLs without a per-signal - // configuration, the passed endpoint is used as a base URL - // and the signals are sent to these paths relative to that. - cfg.Metrics.URLPath = path.Join(u.Path, DefaultMetricsPath) - return cfg - }, func(cfg Config) Config { - // For OTLP/gRPC endpoints, this is the target to which the - // exporter is going to send telemetry. - cfg.Metrics.Endpoint = path.Join(u.Host, u.Path) - return cfg - })) - } - } - - // Certificate File - if path, ok := e.getEnvValue("CERTIFICATE"); ok { - if tls, err := e.readTLSConfig(path); err == nil { - opts = append(opts, WithTLSClientConfig(tls)) - } else { - otel.Handle(fmt.Errorf("failed to configure otlp exporter certificate '%s': %w", path, err)) - } - } - if path, ok := e.getEnvValue("METRICS_CERTIFICATE"); ok { - if tls, err := e.readTLSConfig(path); err == nil { - opts = append(opts, WithTLSClientConfig(tls)) - } else { - otel.Handle(fmt.Errorf("failed to configure otlp exporter certificate '%s': %w", path, err)) - } - } - - // Headers - if h, ok := e.getEnvValue("HEADERS"); ok { - opts = append(opts, WithHeaders(stringToHeader(h))) - } - if h, ok := e.getEnvValue("METRICS_HEADERS"); ok { - opts = append(opts, WithHeaders(stringToHeader(h))) - } - - // Compression - if c, ok := e.getEnvValue("COMPRESSION"); ok { - opts = append(opts, WithCompression(stringToCompression(c))) - } - if c, ok := e.getEnvValue("METRICS_COMPRESSION"); ok { - opts = append(opts, WithCompression(stringToCompression(c))) - } - - // Timeout - if t, ok := e.getEnvValue("TIMEOUT"); ok { - if d, err := strconv.Atoi(t); err == nil { - opts = append(opts, WithTimeout(time.Duration(d)*time.Millisecond)) - } - } - if t, ok := e.getEnvValue("METRICS_TIMEOUT"); ok { - if d, err := strconv.Atoi(t); err == nil { - opts = append(opts, WithTimeout(time.Duration(d)*time.Millisecond)) - } - } + }, withEndpointForGRPC(u))) + }), + envconfig.WithTLSConfig("CERTIFICATE", func(c *tls.Config) { opts = append(opts, WithTLSClientConfig(c)) }), + envconfig.WithTLSConfig("METRICS_CERTIFICATE", func(c *tls.Config) { opts = append(opts, WithTLSClientConfig(c)) }), + envconfig.WithHeaders("HEADERS", func(h map[string]string) { opts = append(opts, WithHeaders(h)) }), + envconfig.WithHeaders("METRICS_HEADERS", func(h map[string]string) { opts = append(opts, WithHeaders(h)) }), + WithEnvCompression("COMPRESSION", func(c Compression) { opts = append(opts, WithCompression(c)) }), + WithEnvCompression("METRICS_COMPRESSION", func(c Compression) { opts = append(opts, WithCompression(c)) }), + envconfig.WithDuration("TIMEOUT", func(d time.Duration) { opts = append(opts, WithTimeout(d)) }), + envconfig.WithDuration("METRICS_TIMEOUT", func(d time.Duration) { opts = append(opts, WithTimeout(d)) }), + ) return opts } -func insecureSchema(schema string) bool { - switch strings.ToLower(schema) { - case "http", "unix": - return true - default: - return false +func withEndpointForGRPC(u *url.URL) func(cfg Config) Config { + return func(cfg Config) Config { + // For OTLP/gRPC endpoints, this is the target to which the + // exporter is going to send telemetry. + cfg.Metrics.Endpoint = path.Join(u.Host, u.Path) + return cfg } } -// getEnvValue gets an OTLP environment variable value of the specified key using the GetEnv function. -// This function already prepends the OTLP prefix to all key lookup. -func (e *EnvOptionsReader) getEnvValue(key string) (string, bool) { - v := strings.TrimSpace(e.GetEnv(fmt.Sprintf("OTEL_EXPORTER_OTLP_%s", key))) - return v, v != "" -} - -func (e *EnvOptionsReader) readTLSConfig(path string) (*tls.Config, error) { - b, err := e.ReadFile(path) - if err != nil { - return nil, err - } - return CreateTLSConfig(b) -} +// WithEnvCompression retrieves the specified config and passes it to ConfigFn as a Compression +func WithEnvCompression(n string, fn func(Compression)) func(e *envconfig.EnvOptionsReader) { + return func(e *envconfig.EnvOptionsReader) { + if v, ok := e.GetEnvValue(n); ok { + cp := NoCompression + switch v { + case "gzip": + cp = GzipCompression + } -func stringToCompression(value string) Compression { - switch value { - case "gzip": - return GzipCompression + fn(cp) + } } - - return NoCompression } -func stringToHeader(value string) map[string]string { - headersPairs := strings.Split(value, ",") - headers := make(map[string]string) - - for _, header := range headersPairs { - nameValue := strings.SplitN(header, "=", 2) - if len(nameValue) < 2 { - continue - } - name, err := url.QueryUnescape(nameValue[0]) - if err != nil { - continue - } - trimmedName := strings.TrimSpace(name) - value, err := url.QueryUnescape(nameValue[1]) - if err != nil { - continue - } - trimmedValue := strings.TrimSpace(value) - - headers[trimmedName] = trimmedValue +func withEndpointScheme(u *url.URL) GenericOption { + switch strings.ToLower(u.Scheme) { + case "http", "unix": + return WithInsecure() + default: + return WithSecure() } - - return headers } diff --git a/exporters/otlp/otlpmetric/internal/otlpconfig/envconfig_test.go b/exporters/otlp/otlpmetric/internal/otlpconfig/envconfig_test.go index 7a6316a2d10..25021f7328c 100644 --- a/exporters/otlp/otlpmetric/internal/otlpconfig/envconfig_test.go +++ b/exporters/otlp/otlpmetric/internal/otlpconfig/envconfig_test.go @@ -13,63 +13,3 @@ // limitations under the License. package otlpconfig - -import ( - "reflect" - "testing" -) - -func TestStringToHeader(t *testing.T) { - tests := []struct { - name string - value string - want map[string]string - }{ - { - name: "simple test", - value: "userId=alice", - want: map[string]string{"userId": "alice"}, - }, - { - name: "simple test with spaces", - value: " userId = alice ", - want: map[string]string{"userId": "alice"}, - }, - { - name: "multiples headers encoded", - value: "userId=alice,serverNode=DF%3A28,isProduction=false", - want: map[string]string{ - "userId": "alice", - "serverNode": "DF:28", - "isProduction": "false", - }, - }, - { - name: "invalid headers format", - value: "userId:alice", - want: map[string]string{}, - }, - { - name: "invalid key", - value: "%XX=missing,userId=alice", - want: map[string]string{ - "userId": "alice", - }, - }, - { - name: "invalid value", - value: "missing=%XX,userId=alice", - want: map[string]string{ - "userId": "alice", - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := stringToHeader(tt.value); !reflect.DeepEqual(got, tt.want) { - t.Errorf("stringToHeader() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/exporters/otlp/otlpmetric/internal/otlpconfig/options_test.go b/exporters/otlp/otlpmetric/internal/otlpconfig/options_test.go index 44c9af4d94c..fad37d60be5 100644 --- a/exporters/otlp/otlpmetric/internal/otlpconfig/options_test.go +++ b/exporters/otlp/otlpmetric/internal/otlpconfig/options_test.go @@ -21,6 +21,7 @@ import ( "github.com/stretchr/testify/assert" + "go.opentelemetry.io/otel/exporters/otlp/internal/envconfig" "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal/otlpconfig" ) @@ -383,9 +384,10 @@ func TestConfigs(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { origEOR := otlpconfig.DefaultEnvOptionsReader - otlpconfig.DefaultEnvOptionsReader = otlpconfig.EnvOptionsReader{ - GetEnv: tt.env.getEnv, - ReadFile: tt.fileReader.readFile, + otlpconfig.DefaultEnvOptionsReader = envconfig.EnvOptionsReader{ + GetEnv: tt.env.getEnv, + ReadFile: tt.fileReader.readFile, + Namespace: "OTEL_EXPORTER_OTLP", } t.Cleanup(func() { otlpconfig.DefaultEnvOptionsReader = origEOR }) diff --git a/exporters/otlp/otlptrace/internal/otlpconfig/envconfig.go b/exporters/otlp/otlptrace/internal/otlpconfig/envconfig.go index 77f13a1937b..1ff8b1d5fc9 100644 --- a/exporters/otlp/otlptrace/internal/otlpconfig/envconfig.go +++ b/exporters/otlp/otlptrace/internal/otlpconfig/envconfig.go @@ -16,66 +16,58 @@ package otlpconfig // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/ import ( "crypto/tls" - "fmt" "io/ioutil" "net/url" "os" "path" - "strconv" "strings" "time" - "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/exporters/otlp/internal/envconfig" ) -var DefaultEnvOptionsReader = EnvOptionsReader{ - GetEnv: os.Getenv, - ReadFile: ioutil.ReadFile, +// DefaultEnvOptionsReader is the default environments reader +var DefaultEnvOptionsReader = envconfig.EnvOptionsReader{ + GetEnv: os.Getenv, + ReadFile: ioutil.ReadFile, + Namespace: "OTEL_EXPORTER_OTLP", } +// ApplyGRPCEnvConfigs applies the env configurations for gRPC func ApplyGRPCEnvConfigs(cfg Config) Config { - return DefaultEnvOptionsReader.ApplyGRPCEnvConfigs(cfg) -} - -func ApplyHTTPEnvConfigs(cfg Config) Config { - return DefaultEnvOptionsReader.ApplyHTTPEnvConfigs(cfg) -} - -type EnvOptionsReader struct { - GetEnv func(string) string - ReadFile func(filename string) ([]byte, error) -} - -func (e *EnvOptionsReader) ApplyHTTPEnvConfigs(cfg Config) Config { - opts := e.GetOptionsFromEnv() + opts := getOptionsFromEnv() for _, opt := range opts { - cfg = opt.ApplyHTTPOption(cfg) + cfg = opt.ApplyGRPCOption(cfg) } return cfg } -func (e *EnvOptionsReader) ApplyGRPCEnvConfigs(cfg Config) Config { - opts := e.GetOptionsFromEnv() +// ApplyHTTPEnvConfigs applies the env configurations for HTTP +func ApplyHTTPEnvConfigs(cfg Config) Config { + opts := getOptionsFromEnv() for _, opt := range opts { - cfg = opt.ApplyGRPCOption(cfg) + cfg = opt.ApplyHTTPOption(cfg) } return cfg } -func (e *EnvOptionsReader) GetOptionsFromEnv() []GenericOption { - var opts []GenericOption +func getOptionsFromEnv() []GenericOption { + opts := []GenericOption{} - // Endpoint - if v, ok := e.getEnvValue("TRACES_ENDPOINT"); ok { - u, err := url.Parse(v) - // Ignore invalid values. - if err == nil { - // This is used to set the scheme for OTLP/HTTP. - if insecureSchema(u.Scheme) { - opts = append(opts, WithInsecure()) - } else { - opts = append(opts, WithSecure()) - } + DefaultEnvOptionsReader.Apply( + envconfig.WithURL("ENDPOINT", func(u *url.URL) { + opts = append(opts, withEndpointScheme(u)) + opts = append(opts, newSplitOption(func(cfg Config) Config { + cfg.Traces.Endpoint = u.Host + // For OTLP/HTTP endpoint URLs without a per-signal + // configuration, the passed endpoint is used as a base URL + // and the signals are sent to these paths relative to that. + cfg.Traces.URLPath = path.Join(u.Path, DefaultTracesPath) + return cfg + }, withEndpointForGRPC(u))) + }), + envconfig.WithURL("TRACES_ENDPOINT", func(u *url.URL) { + opts = append(opts, withEndpointScheme(u)) opts = append(opts, newSplitOption(func(cfg Config) Config { cfg.Traces.Endpoint = u.Host // For endpoint URLs for OTLP/HTTP per-signal variables, the @@ -88,140 +80,50 @@ func (e *EnvOptionsReader) GetOptionsFromEnv() []GenericOption { } cfg.Traces.URLPath = path return cfg - }, func(cfg Config) Config { - // For OTLP/gRPC endpoints, this is the target to which the - // exporter is going to send telemetry. - cfg.Traces.Endpoint = path.Join(u.Host, u.Path) - return cfg - })) - } - } else if v, ok = e.getEnvValue("ENDPOINT"); ok { - u, err := url.Parse(v) - // Ignore invalid values. - if err == nil { - // This is used to set the scheme for OTLP/HTTP. - if insecureSchema(u.Scheme) { - opts = append(opts, WithInsecure()) - } else { - opts = append(opts, WithSecure()) - } - opts = append(opts, newSplitOption(func(cfg Config) Config { - cfg.Traces.Endpoint = u.Host - // For OTLP/HTTP endpoint URLs without a per-signal - // configuration, the passed endpoint is used as a base URL - // and the signals are sent to these paths relative to that. - cfg.Traces.URLPath = path.Join(u.Path, DefaultTracesPath) - return cfg - }, func(cfg Config) Config { - // For OTLP/gRPC endpoints, this is the target to which the - // exporter is going to send telemetry. - cfg.Traces.Endpoint = path.Join(u.Host, u.Path) - return cfg - })) - } - } - - // Certificate File - if path, ok := e.getEnvValue("CERTIFICATE"); ok { - if tls, err := e.readTLSConfig(path); err == nil { - opts = append(opts, WithTLSClientConfig(tls)) - } else { - otel.Handle(fmt.Errorf("failed to configure otlp exporter certificate '%s': %w", path, err)) - } - } - if path, ok := e.getEnvValue("TRACES_CERTIFICATE"); ok { - if tls, err := e.readTLSConfig(path); err == nil { - opts = append(opts, WithTLSClientConfig(tls)) - } else { - otel.Handle(fmt.Errorf("failed to configure otlp traces exporter certificate '%s': %w", path, err)) - } - } - - // Headers - if h, ok := e.getEnvValue("HEADERS"); ok { - opts = append(opts, WithHeaders(stringToHeader(h))) - } - if h, ok := e.getEnvValue("TRACES_HEADERS"); ok { - opts = append(opts, WithHeaders(stringToHeader(h))) - } - - // Compression - if c, ok := e.getEnvValue("COMPRESSION"); ok { - opts = append(opts, WithCompression(stringToCompression(c))) - } - if c, ok := e.getEnvValue("TRACES_COMPRESSION"); ok { - opts = append(opts, WithCompression(stringToCompression(c))) - } - // Timeout - if t, ok := e.getEnvValue("TIMEOUT"); ok { - if d, err := strconv.Atoi(t); err == nil { - opts = append(opts, WithTimeout(time.Duration(d)*time.Millisecond)) - } - } - if t, ok := e.getEnvValue("TRACES_TIMEOUT"); ok { - if d, err := strconv.Atoi(t); err == nil { - opts = append(opts, WithTimeout(time.Duration(d)*time.Millisecond)) - } - } + }, withEndpointForGRPC(u))) + }), + envconfig.WithTLSConfig("CERTIFICATE", func(c *tls.Config) { opts = append(opts, WithTLSClientConfig(c)) }), + envconfig.WithTLSConfig("TRACES_CERTIFICATE", func(c *tls.Config) { opts = append(opts, WithTLSClientConfig(c)) }), + envconfig.WithHeaders("HEADERS", func(h map[string]string) { opts = append(opts, WithHeaders(h)) }), + envconfig.WithHeaders("TRACES_HEADERS", func(h map[string]string) { opts = append(opts, WithHeaders(h)) }), + WithEnvCompression("COMPRESSION", func(c Compression) { opts = append(opts, WithCompression(c)) }), + WithEnvCompression("TRACES_COMPRESSION", func(c Compression) { opts = append(opts, WithCompression(c)) }), + envconfig.WithDuration("TIMEOUT", func(d time.Duration) { opts = append(opts, WithTimeout(d)) }), + envconfig.WithDuration("TRACES_TIMEOUT", func(d time.Duration) { opts = append(opts, WithTimeout(d)) }), + ) return opts } -func insecureSchema(schema string) bool { - switch strings.ToLower(schema) { +func withEndpointScheme(u *url.URL) GenericOption { + switch strings.ToLower(u.Scheme) { case "http", "unix": - return true + return WithInsecure() default: - return false - } -} - -// getEnvValue gets an OTLP environment variable value of the specified key using the GetEnv function. -// This function already prepends the OTLP prefix to all key lookup. -func (e *EnvOptionsReader) getEnvValue(key string) (string, bool) { - v := strings.TrimSpace(e.GetEnv(fmt.Sprintf("OTEL_EXPORTER_OTLP_%s", key))) - return v, v != "" -} - -func (e *EnvOptionsReader) readTLSConfig(path string) (*tls.Config, error) { - b, err := e.ReadFile(path) - if err != nil { - return nil, err + return WithSecure() } - return CreateTLSConfig(b) } -func stringToCompression(value string) Compression { - switch value { - case "gzip": - return GzipCompression +func withEndpointForGRPC(u *url.URL) func(cfg Config) Config { + return func(cfg Config) Config { + // For OTLP/gRPC endpoints, this is the target to which the + // exporter is going to send telemetry. + cfg.Traces.Endpoint = path.Join(u.Host, u.Path) + return cfg } - - return NoCompression } -func stringToHeader(value string) map[string]string { - headersPairs := strings.Split(value, ",") - headers := make(map[string]string) +// WithEnvCompression retrieves the specified config and passes it to ConfigFn as a Compression +func WithEnvCompression(n string, fn func(Compression)) func(e *envconfig.EnvOptionsReader) { + return func(e *envconfig.EnvOptionsReader) { + if v, ok := e.GetEnvValue(n); ok { + cp := NoCompression + switch v { + case "gzip": + cp = GzipCompression + } - for _, header := range headersPairs { - nameValue := strings.SplitN(header, "=", 2) - if len(nameValue) < 2 { - continue - } - name, err := url.QueryUnescape(nameValue[0]) - if err != nil { - continue + fn(cp) } - trimmedName := strings.TrimSpace(name) - value, err := url.QueryUnescape(nameValue[1]) - if err != nil { - continue - } - trimmedValue := strings.TrimSpace(value) - - headers[trimmedName] = trimmedValue } - - return headers } diff --git a/exporters/otlp/otlptrace/internal/otlpconfig/envconfig_test.go b/exporters/otlp/otlptrace/internal/otlpconfig/envconfig_test.go index 7a6316a2d10..25021f7328c 100644 --- a/exporters/otlp/otlptrace/internal/otlpconfig/envconfig_test.go +++ b/exporters/otlp/otlptrace/internal/otlpconfig/envconfig_test.go @@ -13,63 +13,3 @@ // limitations under the License. package otlpconfig - -import ( - "reflect" - "testing" -) - -func TestStringToHeader(t *testing.T) { - tests := []struct { - name string - value string - want map[string]string - }{ - { - name: "simple test", - value: "userId=alice", - want: map[string]string{"userId": "alice"}, - }, - { - name: "simple test with spaces", - value: " userId = alice ", - want: map[string]string{"userId": "alice"}, - }, - { - name: "multiples headers encoded", - value: "userId=alice,serverNode=DF%3A28,isProduction=false", - want: map[string]string{ - "userId": "alice", - "serverNode": "DF:28", - "isProduction": "false", - }, - }, - { - name: "invalid headers format", - value: "userId:alice", - want: map[string]string{}, - }, - { - name: "invalid key", - value: "%XX=missing,userId=alice", - want: map[string]string{ - "userId": "alice", - }, - }, - { - name: "invalid value", - value: "missing=%XX,userId=alice", - want: map[string]string{ - "userId": "alice", - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := stringToHeader(tt.value); !reflect.DeepEqual(got, tt.want) { - t.Errorf("stringToHeader() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/exporters/otlp/otlptrace/internal/otlpconfig/options_test.go b/exporters/otlp/otlptrace/internal/otlpconfig/options_test.go index 4efa2f7c630..30dc5ea8015 100644 --- a/exporters/otlp/otlptrace/internal/otlpconfig/options_test.go +++ b/exporters/otlp/otlptrace/internal/otlpconfig/options_test.go @@ -21,6 +21,7 @@ import ( "github.com/stretchr/testify/assert" + "go.opentelemetry.io/otel/exporters/otlp/internal/envconfig" "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig" ) @@ -381,9 +382,10 @@ func TestConfigs(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { origEOR := otlpconfig.DefaultEnvOptionsReader - otlpconfig.DefaultEnvOptionsReader = otlpconfig.EnvOptionsReader{ - GetEnv: tt.env.getEnv, - ReadFile: tt.fileReader.readFile, + otlpconfig.DefaultEnvOptionsReader = envconfig.EnvOptionsReader{ + GetEnv: tt.env.getEnv, + ReadFile: tt.fileReader.readFile, + Namespace: "OTEL_EXPORTER_OTLP", } t.Cleanup(func() { otlpconfig.DefaultEnvOptionsReader = origEOR }) From 0d0a7320e6eab18df12e2542b4ea000ced32d5bb Mon Sep 17 00:00:00 2001 From: Tyler Yahn Date: Thu, 3 Mar 2022 07:56:07 -0800 Subject: [PATCH 06/29] Update span limits to comply with specification (#2637) * PoC for span limit refactor * Rename config.go to span_limits.go * Add unit tests for truncateAttr * Add unit tests for non-string attrs * Add span limit benchmark tests * Fix lint * Isolate span limit tests * Clean span limits test * Test limits on exported spans * Remove duplicate test code * Fix lint * Add WithRawSpanLimits option * Add test for raw and orig span limits opts * Add changes to changelog * Add tests for span resource disabled * Test unlimited instead of default limit * Update docs * Add fix to changelog * Fix option docs * Do no mutate attribute * Fix truncateAttr comment * Remake NewSpanLimits to be newEnvSpanLimits Update and unify documentation accordingly. * Update truncateAttr string slice update comment * Update CHANGELOG.md Co-authored-by: Anthony Mirabella Co-authored-by: Anthony Mirabella --- CHANGELOG.md | 23 ++- sdk/internal/env/env.go | 61 +++++++- sdk/trace/benchmark_test.go | 102 +++++++++++- sdk/trace/config.go | 84 ---------- sdk/trace/evictedqueue.go | 7 +- sdk/trace/provider.go | 66 ++++++-- sdk/trace/provider_test.go | 61 -------- sdk/trace/span.go | 116 ++++++++++---- sdk/trace/span_limits.go | 126 +++++++++++++++ sdk/trace/span_limits_test.go | 283 ++++++++++++++++++++++++++++++++++ sdk/trace/span_test.go | 145 +++++++++++++++++ sdk/trace/trace_test.go | 23 ++- 12 files changed, 895 insertions(+), 202 deletions(-) delete mode 100644 sdk/trace/config.go create mode 100644 sdk/trace/span_limits.go create mode 100644 sdk/trace/span_limits_test.go create mode 100644 sdk/trace/span_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index b90c3a4b167..d7d51e21893 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,15 +14,26 @@ This update is a breaking change of the unstable Metrics API. Code instrumented ### Added +- Log the Exporters configuration in the TracerProviders message. (#2578) - Added support to configure the span limits with environment variables. - The following environment variables are used. (#2606) + The following environment variables are used. (#2606, #2637) + - `OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT` - `OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT` - `OTEL_SPAN_EVENT_COUNT_LIMIT` + - `OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT` - `OTEL_SPAN_LINK_COUNT_LIMIT` + - `OTEL_LINK_ATTRIBUTE_COUNT_LIMIT` If the provided environment variables are invalid (negative), the default values would be used. - Rename the `gc` runtime name to `go` (#2560) -- Log the Exporters configuration in the TracerProviders message. (#2578) +- Add span attribute value length limit. + The new `AttributeValueLengthLimit` field is added to the `"go.opentelemetry.io/otel/sdk/trace".SpanLimits` type to configure this limit for a `TracerProvider`. + The default limit for this resource is "unlimited". (#2637) +- Add the `WithRawSpanLimits` option to `go.opentelemetry.io/otel/sdk/trace`. + This option replaces the `WithSpanLimits` option. + Zero or negative values will not be changed to the default value like `WithSpanLimits` does. + Setting a limit to zero will effectively disable the related resource it limits and setting to a negative value will mean that resource is unlimited. + Consequentially, limits should be constructed using `NewSpanLimits` and updated accordingly. (#2637) ### Changed @@ -37,6 +48,14 @@ This update is a breaking change of the unstable Metrics API. Code instrumented - Remove the OTLP trace exporter limit of SpanEvents when exporting. (#2616) - Use port `4318` instead of `4317` for default for the `otlpmetrichttp` and `otlptracehttp` client. (#2614, #2625) +- Unlimited span limits are now supported (negative values). (#2636, #2637) + +### Deprecated + +- Deprecated `"go.opentelemetry.io/otel/sdk/trace".WithSpanLimits`. + Use `WithRawSpanLimits` instead. + That option allows setting unlimited and zero limits, this option does not. + This option will be kept until the next major version incremented release. (#2637) ## [1.4.1] - 2022-02-16 diff --git a/sdk/internal/env/env.go b/sdk/internal/env/env.go index df7a05626b3..dbc8f512492 100644 --- a/sdk/internal/env/env.go +++ b/sdk/internal/env/env.go @@ -41,20 +41,29 @@ const ( // i.e. 512 BatchSpanProcessorMaxExportBatchSizeKey = "OTEL_BSP_MAX_EXPORT_BATCH_SIZE" - // SpanAttributesCountKey + // SpanAttributeValueLengthKey + // Maximum allowed attribute value size. + SpanAttributeValueLengthKey = "OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT" + + // SpanAttributeCountKey // Maximum allowed span attribute count - // Default: 128 - SpanAttributesCountKey = "OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT" + SpanAttributeCountKey = "OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT" // SpanEventCountKey // Maximum allowed span event count - // Default: 128 SpanEventCountKey = "OTEL_SPAN_EVENT_COUNT_LIMIT" + // SpanEventAttributeCountKey + // Maximum allowed attribute per span event count. + SpanEventAttributeCountKey = "OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT" + // SpanLinkCountKey // Maximum allowed span link count - // Default: 128 SpanLinkCountKey = "OTEL_SPAN_LINK_COUNT_LIMIT" + + // SpanLinkAttributeCountKey + // Maximum allowed attribute per span link count + SpanLinkAttributeCountKey = "OTEL_LINK_ATTRIBUTE_COUNT_LIMIT" ) // IntEnvOr returns the int value of the environment variable with name key if @@ -101,3 +110,45 @@ func BatchSpanProcessorMaxQueueSize(defaultValue int) int { func BatchSpanProcessorMaxExportBatchSize(defaultValue int) int { return IntEnvOr(BatchSpanProcessorMaxExportBatchSizeKey, defaultValue) } + +// SpanAttributeValueLength returns the environment variable value for the +// OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT key if it exists, otherwise +// defaultValue is returned. +func SpanAttributeValueLength(defaultValue int) int { + return IntEnvOr(SpanAttributeValueLengthKey, defaultValue) +} + +// SpanAttributeCount returns the environment variable value for the +// OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT key if it exists, otherwise defaultValue is +// returned. +func SpanAttributeCount(defaultValue int) int { + return IntEnvOr(SpanAttributeCountKey, defaultValue) +} + +// SpanEventCount returns the environment variable value for the +// OTEL_SPAN_EVENT_COUNT_LIMIT key if it exists, otherwise defaultValue is +// returned. +func SpanEventCount(defaultValue int) int { + return IntEnvOr(SpanEventCountKey, defaultValue) +} + +// SpanEventAttributeCount returns the environment variable value for the +// OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT key if it exists, otherwise defaultValue +// is returned. +func SpanEventAttributeCount(defaultValue int) int { + return IntEnvOr(SpanEventAttributeCountKey, defaultValue) +} + +// SpanLinkCount returns the environment variable value for the +// OTEL_SPAN_LINK_COUNT_LIMIT key if it exists, otherwise defaultValue is +// returned. +func SpanLinkCount(defaultValue int) int { + return IntEnvOr(SpanLinkCountKey, defaultValue) +} + +// SpanLinkAttributeCount returns the environment variable value for the +// OTEL_LINK_ATTRIBUTE_COUNT_LIMIT key if it exists, otherwise defaultValue is +// returned. +func SpanLinkAttributeCount(defaultValue int) int { + return IntEnvOr(SpanLinkAttributeCountKey, defaultValue) +} diff --git a/sdk/trace/benchmark_test.go b/sdk/trace/benchmark_test.go index 81a06e2f8f9..b7dde8d96b0 100644 --- a/sdk/trace/benchmark_test.go +++ b/sdk/trace/benchmark_test.go @@ -25,10 +25,106 @@ import ( "go.opentelemetry.io/otel/trace" ) +func benchmarkSpanLimits(b *testing.B, limits sdktrace.SpanLimits) { + tp := sdktrace.NewTracerProvider(sdktrace.WithSpanLimits(limits)) + tracer := tp.Tracer(b.Name()) + ctx := context.Background() + + const count = 8 + + attrs := []attribute.KeyValue{ + attribute.Bool("bool", true), + attribute.BoolSlice("boolSlice", []bool{true, false}), + attribute.Int("int", 42), + attribute.IntSlice("intSlice", []int{42, -1}), + attribute.Int64("int64", 42), + attribute.Int64Slice("int64Slice", []int64{42, -1}), + attribute.Float64("float64", 42), + attribute.Float64Slice("float64Slice", []float64{42, -1}), + attribute.String("string", "value"), + attribute.StringSlice("stringSlice", []string{"value", "value-1"}), + } + + links := make([]trace.Link, count) + for i := range links { + links[i] = trace.Link{ + SpanContext: trace.NewSpanContext(trace.SpanContextConfig{ + TraceID: [16]byte{0x01}, + SpanID: [8]byte{0x01}, + }), + Attributes: attrs, + } + } + + events := make([]struct { + name string + attr []attribute.KeyValue + }, count) + for i := range events { + events[i] = struct { + name string + attr []attribute.KeyValue + }{ + name: fmt.Sprintf("event-%d", i), + attr: attrs, + } + } + + b.ReportAllocs() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + _, span := tracer.Start(ctx, "span-name", trace.WithLinks(links...)) + span.SetAttributes(attrs...) + for _, e := range events { + span.AddEvent(e.name, trace.WithAttributes(e.attr...)) + } + span.End() + } +} + +func BenchmarkSpanLimits(b *testing.B) { + b.Run("AttributeValueLengthLimit", func(b *testing.B) { + limits := sdktrace.NewSpanLimits() + limits.AttributeValueLengthLimit = 2 + benchmarkSpanLimits(b, limits) + }) + + b.Run("AttributeCountLimit", func(b *testing.B) { + limits := sdktrace.NewSpanLimits() + limits.AttributeCountLimit = 1 + benchmarkSpanLimits(b, limits) + }) + + b.Run("EventCountLimit", func(b *testing.B) { + limits := sdktrace.NewSpanLimits() + limits.EventCountLimit = 1 + benchmarkSpanLimits(b, limits) + }) + + b.Run("LinkCountLimit", func(b *testing.B) { + limits := sdktrace.NewSpanLimits() + limits.LinkCountLimit = 1 + benchmarkSpanLimits(b, limits) + }) + + b.Run("AttributePerEventCountLimit", func(b *testing.B) { + limits := sdktrace.NewSpanLimits() + limits.AttributePerEventCountLimit = 1 + benchmarkSpanLimits(b, limits) + }) + + b.Run("AttributePerLinkCountLimit", func(b *testing.B) { + limits := sdktrace.NewSpanLimits() + limits.AttributePerLinkCountLimit = 1 + benchmarkSpanLimits(b, limits) + }) +} + func BenchmarkSpanSetAttributesOverCapacity(b *testing.B) { - tp := sdktrace.NewTracerProvider( - sdktrace.WithSpanLimits(sdktrace.SpanLimits{AttributeCountLimit: 1}), - ) + limits := sdktrace.NewSpanLimits() + limits.AttributeCountLimit = 1 + tp := sdktrace.NewTracerProvider(sdktrace.WithSpanLimits(limits)) tracer := tp.Tracer("BenchmarkSpanSetAttributesOverCapacity") ctx := context.Background() attrs := make([]attribute.KeyValue, 128) diff --git a/sdk/trace/config.go b/sdk/trace/config.go deleted file mode 100644 index efea7b302f9..00000000000 --- a/sdk/trace/config.go +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package trace // import "go.opentelemetry.io/otel/sdk/trace" -import "go.opentelemetry.io/otel/sdk/internal/env" - -// SpanLimits represents the limits of a span. -type SpanLimits struct { - // AttributeCountLimit is the maximum allowed span attribute count. - AttributeCountLimit int - - // EventCountLimit is the maximum allowed span event count. - EventCountLimit int - - // LinkCountLimit is the maximum allowed span link count. - LinkCountLimit int - - // AttributePerEventCountLimit is the maximum allowed attribute per span event count. - AttributePerEventCountLimit int - - // AttributePerLinkCountLimit is the maximum allowed attribute per span link count. - AttributePerLinkCountLimit int -} - -func (sl *SpanLimits) ensureDefault() { - if sl.EventCountLimit <= 0 { - sl.EventCountLimit = DefaultEventCountLimit - } - if sl.AttributeCountLimit <= 0 { - sl.AttributeCountLimit = DefaultAttributeCountLimit - } - if sl.LinkCountLimit <= 0 { - sl.LinkCountLimit = DefaultLinkCountLimit - } - if sl.AttributePerEventCountLimit <= 0 { - sl.AttributePerEventCountLimit = DefaultAttributePerEventCountLimit - } - if sl.AttributePerLinkCountLimit <= 0 { - sl.AttributePerLinkCountLimit = DefaultAttributePerLinkCountLimit - } -} - -func (sl *SpanLimits) parsePotentialEnvConfigs() { - sl.AttributeCountLimit = env.IntEnvOr(env.SpanAttributesCountKey, sl.AttributeCountLimit) - sl.LinkCountLimit = env.IntEnvOr(env.SpanLinkCountKey, sl.LinkCountLimit) - sl.EventCountLimit = env.IntEnvOr(env.SpanEventCountKey, sl.EventCountLimit) -} - -const ( - // DefaultAttributeCountLimit is the default maximum allowed span attribute count. - // If not specified via WithSpanLimits, will try to retrieve the value from - // environment variable `OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT`. - // If Invalid value (negative or zero) is provided, the default value 128 will be used. - DefaultAttributeCountLimit = 128 - - // DefaultEventCountLimit is the default maximum allowed span event count. - // If not specified via WithSpanLimits, will try to retrieve the value from - // environment variable `OTEL_SPAN_EVENT_COUNT_LIMIT`. - // If Invalid value (negative or zero) is provided, the default value 128 will be used. - DefaultEventCountLimit = 128 - - // DefaultLinkCountLimit is the default maximum allowed span link count. - // If the value is not specified via WithSpanLimits, will try to retrieve the value from - // environment variable `OTEL_SPAN_LINK_COUNT_LIMIT`. - // If Invalid value (negative or zero) is provided, the default value 128 will be used. - DefaultLinkCountLimit = 128 - - // DefaultAttributePerEventCountLimit is the default maximum allowed attribute per span event count. - DefaultAttributePerEventCountLimit = 128 - - // DefaultAttributePerLinkCountLimit is the default maximum allowed attribute per span link count. - DefaultAttributePerLinkCountLimit = 128 -) diff --git a/sdk/trace/evictedqueue.go b/sdk/trace/evictedqueue.go index 8e89e19d4b9..d1c86e59b22 100644 --- a/sdk/trace/evictedqueue.go +++ b/sdk/trace/evictedqueue.go @@ -29,7 +29,12 @@ func newEvictedQueue(capacity int) evictedQueue { // add adds value to the evictedQueue eq. If eq is at capacity, the oldest // queued value will be discarded and the drop count incremented. func (eq *evictedQueue) add(value interface{}) { - if len(eq.queue) == eq.capacity { + if eq.capacity == 0 { + eq.droppedCount++ + return + } + + if eq.capacity > 0 && len(eq.queue) == eq.capacity { // Drop first-in while avoiding allocating more capacity to eq.queue. copy(eq.queue[:eq.capacity-1], eq.queue[1:]) eq.queue = eq.queue[:eq.capacity-1] diff --git a/sdk/trace/provider.go b/sdk/trace/provider.go index 2de79f03397..0643d1a1611 100644 --- a/sdk/trace/provider.go +++ b/sdk/trace/provider.go @@ -96,9 +96,10 @@ var _ trace.TracerProvider = &TracerProvider{} // The passed opts are used to override these default values and configure the // returned TracerProvider appropriately. func NewTracerProvider(opts ...TracerProviderOption) *TracerProvider { - o := tracerProviderConfig{} + o := tracerProviderConfig{ + spanLimits: NewSpanLimits(), + } - o.spanLimits.parsePotentialEnvConfigs() for _, opt := range opts { o = opt.apply(o) } @@ -345,20 +346,68 @@ func WithSampler(s Sampler) TracerProviderOption { }) } -// WithSpanLimits returns a TracerProviderOption that will configure the -// SpanLimits sl as a TracerProvider's SpanLimits. The configured SpanLimits -// are used used by the Tracers the TracerProvider and the Spans they create -// to limit tracing resources used. +// WithSpanLimits returns a TracerProviderOption that configures a +// TracerProvider to use the SpanLimits sl. These SpanLimits bound any Span +// created by a Tracer from the TracerProvider. +// +// If any field of sl is zero or negative it will be replaced with the default +// value for that field. // -// If this option is not used, the TracerProvider will use the default -// SpanLimits. +// If this or WithRawSpanLimits are not provided, the TracerProvider will use +// the limits defined by environment variables, or the defaults if unset. +// Refer to the NewSpanLimits documentation for information about this +// relationship. +// +// Deprecated: Use WithRawSpanLimits instead which allows setting unlimited +// and zero limits. This option will be kept until the next major version +// incremented release. func WithSpanLimits(sl SpanLimits) TracerProviderOption { + if sl.AttributeValueLengthLimit <= 0 { + sl.AttributeValueLengthLimit = DefaultAttributeValueLengthLimit + } + if sl.AttributeCountLimit <= 0 { + sl.AttributeCountLimit = DefaultAttributeCountLimit + } + if sl.EventCountLimit <= 0 { + sl.EventCountLimit = DefaultEventCountLimit + } + if sl.AttributePerEventCountLimit <= 0 { + sl.AttributePerEventCountLimit = DefaultAttributePerEventCountLimit + } + if sl.LinkCountLimit <= 0 { + sl.LinkCountLimit = DefaultLinkCountLimit + } + if sl.AttributePerLinkCountLimit <= 0 { + sl.AttributePerLinkCountLimit = DefaultAttributePerLinkCountLimit + } return traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig { cfg.spanLimits = sl return cfg }) } +// WithRawSpanLimits returns a TracerProviderOption that configures a +// TracerProvider to use these limits. These limits bound any Span created by +// a Tracer from the TracerProvider. +// +// The limits will be used as-is. Zero or negative values will not be changed +// to the default value like WithSpanLimits does. Setting a limit to zero will +// effectively disable the related resource it limits and setting to a +// negative value will mean that resource is unlimited. Consequentially, this +// means that the zero-value SpanLimits will disable all span resources. +// Because of this, limits should be constructed using NewSpanLimits and +// updated accordingly. +// +// If this or WithSpanLimits are not provided, the TracerProvider will use the +// limits defined by environment variables, or the defaults if unset. Refer to +// the NewSpanLimits documentation for information about this relationship. +func WithRawSpanLimits(limits SpanLimits) TracerProviderOption { + return traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig { + cfg.spanLimits = limits + return cfg + }) +} + // ensureValidTracerProviderConfig ensures that given TracerProviderConfig is valid. func ensureValidTracerProviderConfig(cfg tracerProviderConfig) tracerProviderConfig { if cfg.sampler == nil { @@ -367,7 +416,6 @@ func ensureValidTracerProviderConfig(cfg tracerProviderConfig) tracerProviderCon if cfg.idGenerator == nil { cfg.idGenerator = defaultIDGenerator() } - cfg.spanLimits.ensureDefault() if cfg.resource == nil { cfg.resource = resource.Default() } diff --git a/sdk/trace/provider_test.go b/sdk/trace/provider_test.go index 0633889bdc2..e2fce31d7f7 100644 --- a/sdk/trace/provider_test.go +++ b/sdk/trace/provider_test.go @@ -17,14 +17,8 @@ package trace import ( "context" "errors" - "os" "testing" - "github.com/stretchr/testify/require" - - ottest "go.opentelemetry.io/otel/internal/internaltest" - "go.opentelemetry.io/otel/sdk/internal/env" - "github.com/stretchr/testify/assert" "go.opentelemetry.io/otel/trace" @@ -100,58 +94,3 @@ func TestSchemaURL(t *testing.T) { tracerStruct := tracerIface.(*tracer) assert.EqualValues(t, schemaURL, tracerStruct.instrumentationLibrary.SchemaURL) } - -func TestNewTraceProviderWithoutSpanLimitConfiguration(t *testing.T) { - envStore := ottest.NewEnvStore() - defer func() { - require.NoError(t, envStore.Restore()) - }() - envStore.Record(env.SpanAttributesCountKey) - envStore.Record(env.SpanEventCountKey) - envStore.Record(env.SpanLinkCountKey) - require.NoError(t, os.Setenv(env.SpanEventCountKey, "111")) - require.NoError(t, os.Setenv(env.SpanAttributesCountKey, "222")) - require.NoError(t, os.Setenv(env.SpanLinkCountKey, "333")) - tp := NewTracerProvider() - assert.Equal(t, 111, tp.spanLimits.EventCountLimit) - assert.Equal(t, 222, tp.spanLimits.AttributeCountLimit) - assert.Equal(t, 333, tp.spanLimits.LinkCountLimit) -} - -func TestNewTraceProviderWithSpanLimitConfigurationFromOptsAndEnvironmentVariable(t *testing.T) { - envStore := ottest.NewEnvStore() - defer func() { - require.NoError(t, envStore.Restore()) - }() - envStore.Record(env.SpanAttributesCountKey) - envStore.Record(env.SpanEventCountKey) - envStore.Record(env.SpanLinkCountKey) - require.NoError(t, os.Setenv(env.SpanEventCountKey, "111")) - require.NoError(t, os.Setenv(env.SpanAttributesCountKey, "222")) - require.NoError(t, os.Setenv(env.SpanLinkCountKey, "333")) - tp := NewTracerProvider(WithSpanLimits(SpanLimits{ - EventCountLimit: 1, - AttributeCountLimit: 2, - LinkCountLimit: 3, - })) - assert.Equal(t, 1, tp.spanLimits.EventCountLimit) - assert.Equal(t, 2, tp.spanLimits.AttributeCountLimit) - assert.Equal(t, 3, tp.spanLimits.LinkCountLimit) -} - -func TestNewTraceProviderWithInvalidSpanLimitConfigurationFromEnvironmentVariable(t *testing.T) { - envStore := ottest.NewEnvStore() - defer func() { - require.NoError(t, envStore.Restore()) - }() - envStore.Record(env.SpanAttributesCountKey) - envStore.Record(env.SpanEventCountKey) - envStore.Record(env.SpanLinkCountKey) - require.NoError(t, os.Setenv(env.SpanEventCountKey, "-111")) - require.NoError(t, os.Setenv(env.SpanAttributesCountKey, "-222")) - require.NoError(t, os.Setenv(env.SpanLinkCountKey, "-333")) - tp := NewTracerProvider() - assert.Equal(t, 128, tp.spanLimits.EventCountLimit) - assert.Equal(t, 128, tp.spanLimits.AttributeCountLimit) - assert.Equal(t, 128, tp.spanLimits.LinkCountLimit) -} diff --git a/sdk/trace/span.go b/sdk/trace/span.go index 779cde691dd..f2dda294580 100644 --- a/sdk/trace/span.go +++ b/sdk/trace/span.go @@ -212,10 +212,17 @@ func (s *recordingSpan) SetAttributes(attributes ...attribute.KeyValue) { s.mu.Lock() defer s.mu.Unlock() + limit := s.tracer.provider.spanLimits.AttributeCountLimit + if limit == 0 { + // No attributes allowed. + s.droppedAttributes += len(attributes) + return + } + // If adding these attributes could exceed the capacity of s perform a // de-duplication and truncation while adding to avoid over allocation. - if len(s.attributes)+len(attributes) > s.tracer.provider.spanLimits.AttributeCountLimit { - s.addOverCapAttrs(attributes) + if limit > 0 && len(s.attributes)+len(attributes) > limit { + s.addOverCapAttrs(limit, attributes) return } @@ -227,21 +234,25 @@ func (s *recordingSpan) SetAttributes(attributes ...attribute.KeyValue) { s.droppedAttributes++ continue } + a = truncateAttr(s.tracer.provider.spanLimits.AttributeValueLengthLimit, a) s.attributes = append(s.attributes, a) } } // addOverCapAttrs adds the attributes attrs to the span s while // de-duplicating the attributes of s and attrs and dropping attributes that -// exceed the capacity of s. +// exceed the limit. // // This method assumes s.mu.Lock is held by the caller. // // This method should only be called when there is a possibility that adding -// attrs to s will exceed the capacity of s. Otherwise, attrs should be added -// to s without checking for duplicates and all retrieval methods of the -// attributes for s will de-duplicate as needed. -func (s *recordingSpan) addOverCapAttrs(attrs []attribute.KeyValue) { +// attrs to s will exceed the limit. Otherwise, attrs should be added to s +// without checking for duplicates and all retrieval methods of the attributes +// for s will de-duplicate as needed. +// +// This method assumes limit is a value > 0. The argument should be validated +// by the caller. +func (s *recordingSpan) addOverCapAttrs(limit int, attrs []attribute.KeyValue) { // In order to not allocate more capacity to s.attributes than needed, // prune and truncate this addition of attributes while adding. @@ -265,17 +276,58 @@ func (s *recordingSpan) addOverCapAttrs(attrs []attribute.KeyValue) { continue } - if len(s.attributes) >= s.tracer.provider.spanLimits.AttributeCountLimit { + if len(s.attributes) >= limit { // Do not just drop all of the remaining attributes, make sure // updates are checked and performed. s.droppedAttributes++ } else { + a = truncateAttr(s.tracer.provider.spanLimits.AttributeValueLengthLimit, a) s.attributes = append(s.attributes, a) exists[a.Key] = len(s.attributes) - 1 } } } +// truncateAttr returns a truncated version of attr. Only string and string +// slice attribute values are truncated. String values are truncated to at +// most a length of limit. Each string slice value is truncated in this fasion +// (the slice length itself is unaffected). +// +// No truncation is perfromed for a negative limit. +func truncateAttr(limit int, attr attribute.KeyValue) attribute.KeyValue { + if limit < 0 { + return attr + } + switch attr.Value.Type() { + case attribute.STRING: + if v := attr.Value.AsString(); len(v) > limit { + return attr.Key.String(v[:limit]) + } + case attribute.STRINGSLICE: + // Do no mutate the original, make a copy. + trucated := attr.Key.StringSlice(attr.Value.AsStringSlice()) + // Do not do this. + // + // v := trucated.Value.AsStringSlice() + // cp := make([]string, len(v)) + // /* Copy and truncate values to cp ... */ + // trucated.Value = attribute.StringSliceValue(cp) + // + // Copying the []string and then assigning it back as a new value with + // attribute.StringSliceValue will copy the data twice. Instead, we + // already made a copy above that only this function owns, update the + // underlying slice data of our copy. + v := trucated.Value.AsStringSlice() + for i := range v { + if len(v[i]) > limit { + v[i] = v[i][:limit] + } + } + return trucated + } + return attr +} + // End ends the span. This method does nothing if the span is already ended or // is not being recorded. // @@ -396,22 +448,23 @@ func (s *recordingSpan) AddEvent(name string, o ...trace.EventOption) { func (s *recordingSpan) addEvent(name string, o ...trace.EventOption) { c := trace.NewEventConfig(o...) + e := Event{Name: name, Attributes: c.Attributes(), Time: c.Timestamp()} - // Discard over limited attributes - attributes := c.Attributes() - var discarded int - if len(attributes) > s.tracer.provider.spanLimits.AttributePerEventCountLimit { - discarded = len(attributes) - s.tracer.provider.spanLimits.AttributePerEventCountLimit - attributes = attributes[:s.tracer.provider.spanLimits.AttributePerEventCountLimit] + // Discard attributes over limit. + limit := s.tracer.provider.spanLimits.AttributePerEventCountLimit + if limit == 0 { + // Drop all attributes. + e.DroppedAttributeCount = len(e.Attributes) + e.Attributes = nil + } else if limit > 0 && len(e.Attributes) > limit { + // Drop over capacity. + e.DroppedAttributeCount = len(e.Attributes) - limit + e.Attributes = e.Attributes[:limit] } + s.mu.Lock() - defer s.mu.Unlock() - s.events.add(Event{ - Name: name, - Attributes: attributes, - DroppedAttributeCount: discarded, - Time: c.Timestamp(), - }) + s.events.add(e) + s.mu.Unlock() } // SetName sets the name of this span. If this span is not being recorded than @@ -551,18 +604,23 @@ func (s *recordingSpan) addLink(link trace.Link) { if !s.IsRecording() || !link.SpanContext.IsValid() { return } - s.mu.Lock() - defer s.mu.Unlock() - var droppedAttributeCount int + l := Link{SpanContext: link.SpanContext, Attributes: link.Attributes} - // Discard over limited attributes - if len(link.Attributes) > s.tracer.provider.spanLimits.AttributePerLinkCountLimit { - droppedAttributeCount = len(link.Attributes) - s.tracer.provider.spanLimits.AttributePerLinkCountLimit - link.Attributes = link.Attributes[:s.tracer.provider.spanLimits.AttributePerLinkCountLimit] + // Discard attributes over limit. + limit := s.tracer.provider.spanLimits.AttributePerLinkCountLimit + if limit == 0 { + // Drop all attributes. + l.DroppedAttributeCount = len(l.Attributes) + l.Attributes = nil + } else if limit > 0 && len(l.Attributes) > limit { + l.DroppedAttributeCount = len(l.Attributes) - limit + l.Attributes = l.Attributes[:limit] } - s.links.add(Link{link.SpanContext, link.Attributes, droppedAttributeCount}) + s.mu.Lock() + s.links.add(l) + s.mu.Unlock() } // DroppedAttributes returns the number of attributes dropped by the span diff --git a/sdk/trace/span_limits.go b/sdk/trace/span_limits.go new file mode 100644 index 00000000000..b2c47584ae5 --- /dev/null +++ b/sdk/trace/span_limits.go @@ -0,0 +1,126 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trace // import "go.opentelemetry.io/otel/sdk/trace" + +import "go.opentelemetry.io/otel/sdk/internal/env" + +const ( + // DefaultAttributeValueLengthLimit is the default maximum allowed + // attribute value length, unlimited. + DefaultAttributeValueLengthLimit = -1 + + // DefaultAttributeCountLimit is the default maximum number of attributes + // a span can have. + DefaultAttributeCountLimit = 128 + + // DefaultEventCountLimit is the default maximum number of events a span + // can have. + DefaultEventCountLimit = 128 + + // DefaultLinkCountLimit is the default maximum number of links a span can + // have. + DefaultLinkCountLimit = 128 + + // DefaultAttributePerEventCountLimit is the default maximum number of + // attributes a span event can have. + DefaultAttributePerEventCountLimit = 128 + + // DefaultAttributePerLinkCountLimit is the default maximum number of + // attributes a span link can have. + DefaultAttributePerLinkCountLimit = 128 +) + +// SpanLimits represents the limits of a span. +type SpanLimits struct { + // AttributeValueLengthLimit is the maximum allowed attribute value length. + // + // This limit only applies to string and string slice attribute values. + // Any string longer than this value will be truncated to this length. + // + // Setting this to a negative value means no limit is applied. + AttributeValueLengthLimit int + + // AttributeCountLimit is the maximum allowed span attribute count. Any + // attribute added to a span once this limit is reached will be dropped. + // + // Setting this to zero means no attributes will be recorded. + // + // Setting this to a negative value means no limit is applied. + AttributeCountLimit int + + // EventCountLimit is the maximum allowed span event count. Any event + // added to a span once this limit is reached means it will be added but + // the oldest event will be dropped. + // + // Setting this to zero means no events we be recorded. + // + // Setting this to a negative value means no limit is applied. + EventCountLimit int + + // LinkCountLimit is the maximum allowed span link count. Any link added + // to a span once this limit is reached means it will be added but the + // oldest link will be dropped. + // + // Setting this to zero means no links we be recorded. + // + // Setting this to a negative value means no limit is applied. + LinkCountLimit int + + // AttributePerEventCountLimit is the maximum number of attributes allowed + // per span event. Any attribute added after this limit reached will be + // dropped. + // + // Setting this to zero means no attributes will be recorded for events. + // + // Setting this to a negative value means no limit is applied. + AttributePerEventCountLimit int + + // AttributePerLinkCountLimit is the maximum number of attributes allowed + // per span link. Any attribute added after this limit reached will be + // dropped. + // + // Setting this to zero means no attributes will be recorded for links. + // + // Setting this to a negative value means no limit is applied. + AttributePerLinkCountLimit int +} + +// NewSpanLimits returns a SpanLimits with all limits set to the value their +// corresponding environment variable holds, or the default if unset. +// +// • AttributeValueLengthLimit: OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT +// (default: unlimited) +// +// • AttributeCountLimit: OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT (default: 128) +// +// • EventCountLimit: OTEL_SPAN_EVENT_COUNT_LIMIT (default: 128) +// +// • AttributePerEventCountLimit: OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT (default: +// 128) +// +// • LinkCountLimit: OTEL_SPAN_LINK_COUNT_LIMIT (default: 128) +// +// • AttributePerLinkCountLimit: OTEL_LINK_ATTRIBUTE_COUNT_LIMIT (default: +// 128) +func NewSpanLimits() SpanLimits { + return SpanLimits{ + AttributeValueLengthLimit: env.SpanAttributeValueLength(DefaultAttributeValueLengthLimit), + AttributeCountLimit: env.SpanAttributeCount(DefaultAttributeCountLimit), + EventCountLimit: env.SpanEventCount(DefaultEventCountLimit), + LinkCountLimit: env.SpanLinkCount(DefaultLinkCountLimit), + AttributePerEventCountLimit: env.SpanEventAttributeCount(DefaultAttributePerEventCountLimit), + AttributePerLinkCountLimit: env.SpanLinkAttributeCount(DefaultAttributePerLinkCountLimit), + } +} diff --git a/sdk/trace/span_limits_test.go b/sdk/trace/span_limits_test.go new file mode 100644 index 00000000000..91199516c56 --- /dev/null +++ b/sdk/trace/span_limits_test.go @@ -0,0 +1,283 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trace + +import ( + "context" + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "go.opentelemetry.io/otel/attribute" + ottest "go.opentelemetry.io/otel/internal/internaltest" + "go.opentelemetry.io/otel/sdk/internal/env" + "go.opentelemetry.io/otel/trace" +) + +func TestSettingSpanLimits(t *testing.T) { + envLimits := func(val string) map[string]string { + return map[string]string{ + env.SpanAttributeValueLengthKey: val, + env.SpanEventCountKey: val, + env.SpanAttributeCountKey: val, + env.SpanLinkCountKey: val, + env.SpanEventAttributeCountKey: val, + env.SpanLinkAttributeCountKey: val, + } + } + + limits := func(n int) *SpanLimits { + lims := NewSpanLimits() + lims.AttributeValueLengthLimit = n + lims.AttributeCountLimit = n + lims.EventCountLimit = n + lims.LinkCountLimit = n + lims.AttributePerEventCountLimit = n + lims.AttributePerLinkCountLimit = n + return &lims + } + + tests := []struct { + name string + env map[string]string + opt *SpanLimits + rawOpt *SpanLimits + want SpanLimits + }{ + { + name: "defaults", + want: NewSpanLimits(), + }, + { + name: "env", + env: envLimits("42"), + want: *(limits(42)), + }, + { + name: "opt", + opt: limits(42), + want: *(limits(42)), + }, + { + name: "raw-opt", + rawOpt: limits(42), + want: *(limits(42)), + }, + { + name: "opt-override", + env: envLimits("-2"), + // Option take priority. + opt: limits(43), + want: *(limits(43)), + }, + { + name: "raw-opt-override", + env: envLimits("-2"), + // Option take priority. + rawOpt: limits(43), + want: *(limits(43)), + }, + { + name: "last-opt-wins", + opt: limits(-2), + rawOpt: limits(-3), + want: *(limits(-3)), + }, + { + name: "env(unlimited)", + // OTel spec says negative SpanLinkAttributeCountKey is invalid, + // but since we will revert to the default (unlimited) which uses + // negative values to signal this than this value is expected to + // pass through. + env: envLimits("-1"), + want: *(limits(-1)), + }, + { + name: "opt(unlimited)", + // Corrects to defaults. + opt: limits(-1), + want: NewSpanLimits(), + }, + { + name: "raw-opt(unlimited)", + rawOpt: limits(-1), + want: *(limits(-1)), + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if test.env != nil { + es := ottest.NewEnvStore() + t.Cleanup(func() { require.NoError(t, es.Restore()) }) + for k, v := range test.env { + es.Record(k) + require.NoError(t, os.Setenv(k, v)) + } + } + + var opts []TracerProviderOption + if test.opt != nil { + opts = append(opts, WithSpanLimits(*test.opt)) + } + if test.rawOpt != nil { + opts = append(opts, WithRawSpanLimits(*test.rawOpt)) + } + + assert.Equal(t, test.want, NewTracerProvider(opts...).spanLimits) + }) + } +} + +type recorder []ReadOnlySpan + +func (r *recorder) OnStart(context.Context, ReadWriteSpan) {} +func (r *recorder) OnEnd(s ReadOnlySpan) { *r = append(*r, s) } +func (r *recorder) ForceFlush(context.Context) error { return nil } +func (r *recorder) Shutdown(context.Context) error { return nil } + +func testSpanLimits(t *testing.T, limits SpanLimits) ReadOnlySpan { + rec := new(recorder) + tp := NewTracerProvider(WithRawSpanLimits(limits), WithSpanProcessor(rec)) + tracer := tp.Tracer("testSpanLimits") + + ctx := context.Background() + a := []attribute.KeyValue{attribute.Bool("one", true), attribute.Bool("two", true)} + l := trace.Link{ + SpanContext: trace.NewSpanContext(trace.SpanContextConfig{ + TraceID: [16]byte{0x01}, + SpanID: [8]byte{0x01}, + }), + Attributes: a, + } + _, span := tracer.Start(ctx, "span-name", trace.WithLinks(l, l)) + span.SetAttributes( + attribute.String("string", "abc"), + attribute.StringSlice("stringSlice", []string{"abc", "def"}), + ) + span.AddEvent("event 1", trace.WithAttributes(a...)) + span.AddEvent("event 2", trace.WithAttributes(a...)) + span.End() + require.NoError(t, tp.Shutdown(ctx)) + + require.Len(t, *rec, 1, "exported spans") + return (*rec)[0] +} + +func TestSpanLimits(t *testing.T) { + t.Run("AttributeValueLengthLimit", func(t *testing.T) { + limits := NewSpanLimits() + // Unlimited. + limits.AttributeValueLengthLimit = -1 + attrs := testSpanLimits(t, limits).Attributes() + assert.Contains(t, attrs, attribute.String("string", "abc")) + assert.Contains(t, attrs, attribute.StringSlice("stringSlice", []string{"abc", "def"})) + + limits.AttributeValueLengthLimit = 2 + attrs = testSpanLimits(t, limits).Attributes() + // Ensure string and string slice attributes are truncated. + assert.Contains(t, attrs, attribute.String("string", "ab")) + assert.Contains(t, attrs, attribute.StringSlice("stringSlice", []string{"ab", "de"})) + + limits.AttributeValueLengthLimit = 0 + attrs = testSpanLimits(t, limits).Attributes() + assert.Contains(t, attrs, attribute.String("string", "")) + assert.Contains(t, attrs, attribute.StringSlice("stringSlice", []string{"", ""})) + }) + + t.Run("AttributeCountLimit", func(t *testing.T) { + limits := NewSpanLimits() + // Unlimited. + limits.AttributeCountLimit = -1 + assert.Len(t, testSpanLimits(t, limits).Attributes(), 2) + + limits.AttributeCountLimit = 1 + assert.Len(t, testSpanLimits(t, limits).Attributes(), 1) + + // Ensure this can be disabled. + limits.AttributeCountLimit = 0 + assert.Len(t, testSpanLimits(t, limits).Attributes(), 0) + }) + + t.Run("EventCountLimit", func(t *testing.T) { + limits := NewSpanLimits() + // Unlimited. + limits.EventCountLimit = -1 + assert.Len(t, testSpanLimits(t, limits).Events(), 2) + + limits.EventCountLimit = 1 + assert.Len(t, testSpanLimits(t, limits).Events(), 1) + + // Ensure this can be disabled. + limits.EventCountLimit = 0 + assert.Len(t, testSpanLimits(t, limits).Events(), 0) + }) + + t.Run("AttributePerEventCountLimit", func(t *testing.T) { + limits := NewSpanLimits() + // Unlimited. + limits.AttributePerEventCountLimit = -1 + for _, e := range testSpanLimits(t, limits).Events() { + assert.Len(t, e.Attributes, 2) + } + + limits.AttributePerEventCountLimit = 1 + for _, e := range testSpanLimits(t, limits).Events() { + assert.Len(t, e.Attributes, 1) + } + + // Ensure this can be disabled. + limits.AttributePerEventCountLimit = 0 + for _, e := range testSpanLimits(t, limits).Events() { + assert.Len(t, e.Attributes, 0) + } + }) + + t.Run("LinkCountLimit", func(t *testing.T) { + limits := NewSpanLimits() + // Unlimited. + limits.LinkCountLimit = -1 + assert.Len(t, testSpanLimits(t, limits).Links(), 2) + + limits.LinkCountLimit = 1 + assert.Len(t, testSpanLimits(t, limits).Links(), 1) + + // Ensure this can be disabled. + limits.LinkCountLimit = 0 + assert.Len(t, testSpanLimits(t, limits).Links(), 0) + }) + + t.Run("AttributePerLinkCountLimit", func(t *testing.T) { + limits := NewSpanLimits() + // Unlimited. + limits.AttributePerLinkCountLimit = -1 + for _, l := range testSpanLimits(t, limits).Links() { + assert.Len(t, l.Attributes, 2) + } + + limits.AttributePerLinkCountLimit = 1 + for _, l := range testSpanLimits(t, limits).Links() { + assert.Len(t, l.Attributes, 1) + } + + // Ensure this can be disabled. + limits.AttributePerLinkCountLimit = 0 + for _, l := range testSpanLimits(t, limits).Links() { + assert.Len(t, l.Attributes, 0) + } + }) +} diff --git a/sdk/trace/span_test.go b/sdk/trace/span_test.go new file mode 100644 index 00000000000..2c7992e457e --- /dev/null +++ b/sdk/trace/span_test.go @@ -0,0 +1,145 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trace + +import ( + "bytes" + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + + "go.opentelemetry.io/otel/attribute" +) + +func TestTruncateAttr(t *testing.T) { + const key = "key" + + strAttr := attribute.String(key, "value") + strSliceAttr := attribute.StringSlice(key, []string{"value-0", "value-1"}) + + tests := []struct { + limit int + attr, want attribute.KeyValue + }{ + { + limit: -1, + attr: strAttr, + want: strAttr, + }, + { + limit: -1, + attr: strSliceAttr, + want: strSliceAttr, + }, + { + limit: 0, + attr: attribute.Bool(key, true), + want: attribute.Bool(key, true), + }, + { + limit: 0, + attr: attribute.BoolSlice(key, []bool{true, false}), + want: attribute.BoolSlice(key, []bool{true, false}), + }, + { + limit: 0, + attr: attribute.Int(key, 42), + want: attribute.Int(key, 42), + }, + { + limit: 0, + attr: attribute.IntSlice(key, []int{42, -1}), + want: attribute.IntSlice(key, []int{42, -1}), + }, + { + limit: 0, + attr: attribute.Int64(key, 42), + want: attribute.Int64(key, 42), + }, + { + limit: 0, + attr: attribute.Int64Slice(key, []int64{42, -1}), + want: attribute.Int64Slice(key, []int64{42, -1}), + }, + { + limit: 0, + attr: attribute.Float64(key, 42), + want: attribute.Float64(key, 42), + }, + { + limit: 0, + attr: attribute.Float64Slice(key, []float64{42, -1}), + want: attribute.Float64Slice(key, []float64{42, -1}), + }, + { + limit: 0, + attr: strAttr, + want: attribute.String(key, ""), + }, + { + limit: 0, + attr: strSliceAttr, + want: attribute.StringSlice(key, []string{"", ""}), + }, + { + limit: 0, + attr: attribute.Stringer(key, bytes.NewBufferString("value")), + want: attribute.String(key, ""), + }, + { + limit: 1, + attr: strAttr, + want: attribute.String(key, "v"), + }, + { + limit: 1, + attr: strSliceAttr, + want: attribute.StringSlice(key, []string{"v", "v"}), + }, + { + limit: 5, + attr: strAttr, + want: strAttr, + }, + { + limit: 7, + attr: strSliceAttr, + want: strSliceAttr, + }, + { + limit: 6, + attr: attribute.StringSlice(key, []string{"value", "value-1"}), + want: attribute.StringSlice(key, []string{"value", "value-"}), + }, + { + limit: 128, + attr: strAttr, + want: strAttr, + }, + { + limit: 128, + attr: strSliceAttr, + want: strSliceAttr, + }, + } + + for _, test := range tests { + name := fmt.Sprintf("%s->%s(limit:%d)", test.attr.Key, test.attr.Value.Emit(), test.limit) + t.Run(name, func(t *testing.T) { + assert.Equal(t, test.want, truncateAttr(test.limit, test.attr)) + }) + } +} diff --git a/sdk/trace/trace_test.go b/sdk/trace/trace_test.go index 5ba0015584a..fe401d06535 100644 --- a/sdk/trace/trace_test.go +++ b/sdk/trace/trace_test.go @@ -604,10 +604,9 @@ func TestSpanSetAttributes(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { te := NewTestExporter() - tp := NewTracerProvider( - WithSyncer(te), - WithSpanLimits(SpanLimits{AttributeCountLimit: capacity}), - ) + sl := NewSpanLimits() + sl.AttributeCountLimit = capacity + tp := NewTracerProvider(WithSyncer(te), WithSpanLimits(sl)) _, span := tp.Tracer(instName).Start(context.Background(), spanName) for _, a := range test.input { span.SetAttributes(a...) @@ -677,7 +676,9 @@ func TestEvents(t *testing.T) { func TestEventsOverLimit(t *testing.T) { te := NewTestExporter() - tp := NewTracerProvider(WithSpanLimits(SpanLimits{EventCountLimit: 2}), WithSyncer(te), WithResource(resource.Empty())) + sl := NewSpanLimits() + sl.EventCountLimit = 2 + tp := NewTracerProvider(WithSpanLimits(sl), WithSyncer(te), WithResource(resource.Empty())) span := startSpan(tp, "EventsOverLimit") k1v1 := attribute.String("key1", "value1") @@ -779,7 +780,9 @@ func TestLinksOverLimit(t *testing.T) { sc2 := trace.NewSpanContext(trace.SpanContextConfig{TraceID: trace.TraceID([16]byte{1, 1}), SpanID: trace.SpanID{3}}) sc3 := trace.NewSpanContext(trace.SpanContextConfig{TraceID: trace.TraceID([16]byte{1, 1}), SpanID: trace.SpanID{3}}) - tp := NewTracerProvider(WithSpanLimits(SpanLimits{LinkCountLimit: 2}), WithSyncer(te), WithResource(resource.Empty())) + sl := NewSpanLimits() + sl.LinkCountLimit = 2 + tp := NewTracerProvider(WithSpanLimits(sl), WithSyncer(te), WithResource(resource.Empty())) span := startSpan(tp, "LinksOverLimit", trace.WithLinks( @@ -1637,8 +1640,10 @@ func TestReadWriteSpan(t *testing.T) { func TestAddEventsWithMoreAttributesThanLimit(t *testing.T) { te := NewTestExporter() + sl := NewSpanLimits() + sl.AttributePerEventCountLimit = 2 tp := NewTracerProvider( - WithSpanLimits(SpanLimits{AttributePerEventCountLimit: 2}), + WithSpanLimits(sl), WithSyncer(te), WithResource(resource.Empty()), ) @@ -1701,8 +1706,10 @@ func TestAddEventsWithMoreAttributesThanLimit(t *testing.T) { func TestAddLinksWithMoreAttributesThanLimit(t *testing.T) { te := NewTestExporter() + sl := NewSpanLimits() + sl.AttributePerLinkCountLimit = 1 tp := NewTracerProvider( - WithSpanLimits(SpanLimits{AttributePerLinkCountLimit: 1}), + WithSpanLimits(sl), WithSyncer(te), WithResource(resource.Empty()), ) From f4ec95d027ddc97d4808b7e808c4720aec1fb858 Mon Sep 17 00:00:00 2001 From: Sam Xie Date: Fri, 4 Mar 2022 01:13:31 +0800 Subject: [PATCH 07/29] Add container id support to Resource (#2418) * Add container id support to Resource * Fix wrong test case name * Add WithContainer option * Update CHANGELOG * Fix comments * Update CHANGELOG * Use regex to find container id * Add tests for reading cgroup file * Update sdk/resource/container.go Co-authored-by: Chester Cheung * Update format Co-authored-by: Chester Cheung Co-authored-by: Anthony Mirabella --- CHANGELOG.md | 1 + sdk/resource/config.go | 13 +++ sdk/resource/container.go | 100 +++++++++++++++++++ sdk/resource/container_test.go | 169 +++++++++++++++++++++++++++++++++ sdk/resource/export_test.go | 2 + sdk/resource/process_test.go | 5 +- sdk/resource/resource_test.go | 71 ++++++++++++++ 7 files changed, 359 insertions(+), 2 deletions(-) create mode 100644 sdk/resource/container.go create mode 100644 sdk/resource/container_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index d7d51e21893..52cc0c413e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ This update is a breaking change of the unstable Metrics API. Code instrumented If the provided environment variables are invalid (negative), the default values would be used. - Rename the `gc` runtime name to `go` (#2560) +- Add container id support to Resource. (#2418) - Add span attribute value length limit. The new `AttributeValueLengthLimit` field is added to the `"go.opentelemetry.io/otel/sdk/trace".SpanLimits` type to configure this limit for a `TracerProvider`. The default limit for this resource is "unlimited". (#2637) diff --git a/sdk/resource/config.go b/sdk/resource/config.go index d80b5ae6214..09f30d57127 100644 --- a/sdk/resource/config.go +++ b/sdk/resource/config.go @@ -171,3 +171,16 @@ func WithProcessRuntimeVersion() Option { func WithProcessRuntimeDescription() Option { return WithDetectors(processRuntimeDescriptionDetector{}) } + +// WithContainer adds all the Container attributes to the configured Resource. +// See individual WithContainer* functions to configure specific attributes. +func WithContainer() Option { + return WithDetectors( + cgroupContainerIDDetector{}, + ) +} + +// WithContainerID adds an attribute with the id of the container to the configured Resource. +func WithContainerID() Option { + return WithDetectors(cgroupContainerIDDetector{}) +} diff --git a/sdk/resource/container.go b/sdk/resource/container.go new file mode 100644 index 00000000000..e56978adad5 --- /dev/null +++ b/sdk/resource/container.go @@ -0,0 +1,100 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package resource // import "go.opentelemetry.io/otel/sdk/resource" + +import ( + "bufio" + "context" + "errors" + "io" + "os" + "regexp" + + semconv "go.opentelemetry.io/otel/semconv/v1.7.0" +) + +type containerIDProvider func() (string, error) + +var ( + containerID containerIDProvider = getContainerIDFromCGroup + cgroupContainerIDRe = regexp.MustCompile(`^.*/(?:.*-)?([0-9a-f]+)(?:\.|\s*$)`) +) + +type cgroupContainerIDDetector struct{} + +const cgroupPath = "/proc/self/cgroup" + +// Detect returns a *Resource that describes the id of the container. +// If no container id found, an empty resource will be returned. +func (cgroupContainerIDDetector) Detect(ctx context.Context) (*Resource, error) { + containerID, err := containerID() + if err != nil { + return nil, err + } + + if containerID == "" { + return Empty(), nil + } + return NewWithAttributes(semconv.SchemaURL, semconv.ContainerIDKey.String(containerID)), nil +} + +var ( + defaultOSStat = os.Stat + osStat = defaultOSStat + + defaultOSOpen = func(name string) (io.ReadCloser, error) { + return os.Open(name) + } + osOpen = defaultOSOpen +) + +// getContainerIDFromCGroup returns the id of the container from the cgroup file. +// If no container id found, an empty string will be returned. +func getContainerIDFromCGroup() (string, error) { + if _, err := osStat(cgroupPath); errors.Is(err, os.ErrNotExist) { + // File does not exist, skip + return "", nil + } + + file, err := osOpen(cgroupPath) + if err != nil { + return "", err + } + defer file.Close() + + return getContainerIDFromReader(file), nil +} + +// getContainerIDFromReader returns the id of the container from reader. +func getContainerIDFromReader(reader io.Reader) string { + scanner := bufio.NewScanner(reader) + for scanner.Scan() { + line := scanner.Text() + + if id := getContainerIDFromLine(line); id != "" { + return id + } + } + return "" +} + +// getContainerIDFromLine returns the id of the container from one string line. +func getContainerIDFromLine(line string) string { + matches := cgroupContainerIDRe.FindStringSubmatch(line) + if len(matches) <= 1 { + return "" + } + return matches[1] +} diff --git a/sdk/resource/container_test.go b/sdk/resource/container_test.go new file mode 100644 index 00000000000..b09160da872 --- /dev/null +++ b/sdk/resource/container_test.go @@ -0,0 +1,169 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package resource + +import ( + "errors" + "io" + "os" + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +func setDefaultContainerProviders() { + setContainerProviders( + getContainerIDFromCGroup, + ) +} + +func setContainerProviders( + idProvider containerIDProvider, +) { + containerID = idProvider +} + +func TestGetContainerIDFromLine(t *testing.T) { + testCases := []struct { + name string + line string + expectedContainerID string + }{ + { + name: "with suffix", + line: "13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d23.aaaa", + expectedContainerID: "ac679f8a8319c8cf7d38e1adf263bc08d23", + }, + { + name: "with prefix and suffix", + line: "13:name=systemd:/podruntime/docker/kubepods/crio-dc679f8a8319c8cf7d38e1adf263bc08d23.stuff", + expectedContainerID: "dc679f8a8319c8cf7d38e1adf263bc08d23", + }, + { + name: "no prefix and suffix", + line: "13:name=systemd:/pod/d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356", + expectedContainerID: "d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356", + }, + { + name: "with space", + line: " 13:name=systemd:/pod/d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356 ", + expectedContainerID: "d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356", + }, + { + name: "invalid hex string", + line: "13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d23zzzz", + }, + { + name: "no container id - 1", + line: "pids: /", + }, + { + name: "no container id - 2", + line: "pids: ", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + containerID := getContainerIDFromLine(tc.line) + assert.Equal(t, tc.expectedContainerID, containerID) + }) + } +} + +func TestGetContainerIDFromReader(t *testing.T) { + testCases := []struct { + name string + reader io.Reader + expectedContainerID string + }{ + { + name: "multiple lines", + reader: strings.NewReader(`// +1:name=systemd:/podruntime/docker/kubepods/docker-dc579f8a8319c8cf7d38e1adf263bc08d23 +1:name=systemd:/podruntime/docker/kubepods/docker-dc579f8a8319c8cf7d38e1adf263bc08d24 +`), + expectedContainerID: "dc579f8a8319c8cf7d38e1adf263bc08d23", + }, + { + name: "no container id", + reader: strings.NewReader(`// +1:name=systemd:/podruntime/docker +`), + expectedContainerID: "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + containerID := getContainerIDFromReader(tc.reader) + assert.Equal(t, tc.expectedContainerID, containerID) + }) + } +} + +func TestGetContainerIDFromCGroup(t *testing.T) { + t.Cleanup(func() { + osStat = defaultOSStat + osOpen = defaultOSOpen + }) + + testCases := []struct { + name string + cgroupFileNotExist bool + openFileError error + content string + expectedContainerID string + expectedError bool + }{ + { + name: "the cgroup file does not exist", + cgroupFileNotExist: true, + }, + { + name: "error when opening cgroup file", + openFileError: errors.New("test"), + expectedError: true, + }, + { + name: "cgroup file", + content: "1:name=systemd:/podruntime/docker/kubepods/docker-dc579f8a8319c8cf7d38e1adf263bc08d23", + expectedContainerID: "dc579f8a8319c8cf7d38e1adf263bc08d23", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + osStat = func(name string) (os.FileInfo, error) { + if tc.cgroupFileNotExist { + return nil, os.ErrNotExist + } + return nil, nil + } + + osOpen = func(name string) (io.ReadCloser, error) { + if tc.openFileError != nil { + return nil, tc.openFileError + } + return io.NopCloser(strings.NewReader(tc.content)), nil + } + + containerID, err := getContainerIDFromCGroup() + assert.Equal(t, tc.expectedError, err != nil) + assert.Equal(t, tc.expectedContainerID, containerID) + }) + } +} diff --git a/sdk/resource/export_test.go b/sdk/resource/export_test.go index 4cad64f0b65..6c767e595c5 100644 --- a/sdk/resource/export_test.go +++ b/sdk/resource/export_test.go @@ -23,6 +23,8 @@ var ( SetUserProviders = setUserProviders SetDefaultOSDescriptionProvider = setDefaultOSDescriptionProvider SetOSDescriptionProvider = setOSDescriptionProvider + SetDefaultContainerProviders = setDefaultContainerProviders + SetContainerProviders = setContainerProviders ) var ( diff --git a/sdk/resource/process_test.go b/sdk/resource/process_test.go index 0f9c628cc8d..408d0a5a300 100644 --- a/sdk/resource/process_test.go +++ b/sdk/resource/process_test.go @@ -102,13 +102,14 @@ func restoreAttributesProviders() { resource.SetDefaultRuntimeProviders() resource.SetDefaultUserProviders() resource.SetDefaultOSDescriptionProvider() + resource.SetDefaultContainerProviders() } func TestWithProcessFuncsErrors(t *testing.T) { mockProcessAttributesProvidersWithErrors() - t.Run("WithPID", testWithProcessExecutablePathError) - t.Run("WithExecutableName", testWithProcessOwnerError) + t.Run("WithExecutablePath", testWithProcessExecutablePathError) + t.Run("WithOwner", testWithProcessOwnerError) restoreAttributesProviders() } diff --git a/sdk/resource/resource_test.go b/sdk/resource/resource_test.go index 526ad13008f..fa9b9e4ea05 100644 --- a/sdk/resource/resource_test.go +++ b/sdk/resource/resource_test.go @@ -649,3 +649,74 @@ func hostname() string { } return hn } + +func TestWithContainerID(t *testing.T) { + t.Cleanup(restoreAttributesProviders) + + fakeContainerID := "fake-container-id" + + testCases := []struct { + name string + containerIDProvider func() (string, error) + expectedResource map[string]string + expectedErr bool + }{ + { + name: "get container id", + containerIDProvider: func() (string, error) { + return fakeContainerID, nil + }, + expectedResource: map[string]string{ + string(semconv.ContainerIDKey): fakeContainerID, + }, + }, + { + name: "no container id found", + containerIDProvider: func() (string, error) { + return "", nil + }, + expectedResource: map[string]string{}, + }, + { + name: "error", + containerIDProvider: func() (string, error) { + return "", fmt.Errorf("unable to get container id") + }, + expectedResource: map[string]string{}, + expectedErr: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + resource.SetContainerProviders(tc.containerIDProvider) + + res, err := resource.New(context.Background(), + resource.WithContainerID(), + ) + + if tc.expectedErr { + assert.Error(t, err) + } + assert.Equal(t, tc.expectedResource, toMap(res)) + }) + } +} + +func TestWithContainer(t *testing.T) { + t.Cleanup(restoreAttributesProviders) + + fakeContainerID := "fake-container-id" + resource.SetContainerProviders(func() (string, error) { + return fakeContainerID, nil + }) + + res, err := resource.New(context.Background(), + resource.WithContainer(), + ) + + assert.NoError(t, err) + assert.Equal(t, map[string]string{ + string(semconv.ContainerIDKey): fakeContainerID, + }, toMap(res)) +} From 4eb3cc4f1cc99ec12812e33de27d8ad6a33a5c46 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Mar 2022 08:54:12 -0800 Subject: [PATCH 08/29] Bump github.com/itchyny/gojq from 0.12.6 to 0.12.7 in /internal/tools (#2647) * Bump github.com/itchyny/gojq from 0.12.6 to 0.12.7 in /internal/tools Bumps [github.com/itchyny/gojq](https://github.com/itchyny/gojq) from 0.12.6 to 0.12.7. - [Release notes](https://github.com/itchyny/gojq/releases) - [Changelog](https://github.com/itchyny/gojq/blob/main/CHANGELOG.md) - [Commits](https://github.com/itchyny/gojq/compare/v0.12.6...v0.12.7) --- updated-dependencies: - dependency-name: github.com/itchyny/gojq dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Auto-fix go.sum changes in dependent modules Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: MrAlias --- internal/tools/go.mod | 2 +- internal/tools/go.sum | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/internal/tools/go.mod b/internal/tools/go.mod index 583d72b1a50..9aefef1006d 100644 --- a/internal/tools/go.mod +++ b/internal/tools/go.mod @@ -6,7 +6,7 @@ require ( github.com/client9/misspell v0.3.4 github.com/gogo/protobuf v1.3.2 github.com/golangci/golangci-lint v1.44.2 - github.com/itchyny/gojq v0.12.6 + github.com/itchyny/gojq v0.12.7 github.com/jcchavezs/porto v0.4.0 github.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad go.opentelemetry.io/build-tools/multimod v0.0.0-20210920164323-2ceabab23375 diff --git a/internal/tools/go.sum b/internal/tools/go.sum index 1604fe5e896..58392f05da5 100644 --- a/internal/tools/go.sum +++ b/internal/tools/go.sum @@ -472,8 +472,8 @@ github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/itchyny/gojq v0.12.6 h1:VjaFn59Em2wTxDNGcrRkDK9ZHMNa8IksOgL13sLL4d0= -github.com/itchyny/gojq v0.12.6/go.mod h1:ZHrkfu7A+RbZLy5J1/JKpS4poEqrzItSTGDItqsfP0A= +github.com/itchyny/gojq v0.12.7 h1:hYPTpeWfrJ1OT+2j6cvBScbhl0TkdwGM4bc66onUSOQ= +github.com/itchyny/gojq v0.12.7/go.mod h1:ZdvNHVlzPgUf8pgjnuDTmGfHA/21KoutQUJ3An/xNuw= github.com/itchyny/timefmt-go v0.1.3 h1:7M3LGVDsqcd0VZH2U+x393obrzZisp7C0uEe921iRkU= github.com/itchyny/timefmt-go v0.1.3/go.mod h1:0osSSCQSASBJMsIZnhAaF1C2fCBTJZXrnj37mG8/c+A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= @@ -1146,8 +1146,9 @@ golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211213223007-03aa0b5f6827/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220111092808-5a964db01320 h1:0jf+tOCoZ3LyutmCOWpVni1chK4VfFLhRsDK7MhqGRY= golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 h1:nhht2DYV/Sn3qOayu8lM+cU1ii9sTLUeBQwQQfUHtrs= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= From a27afaae364c65306730cb289f4c7acad13acbca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Mar 2022 09:30:19 -0800 Subject: [PATCH 09/29] Bump actions/setup-go from 2.2.0 to 3 (#2646) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 2.2.0 to 3. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/v2.2.0...v3) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/benchmark.yml | 2 +- .github/workflows/ci.yml | 8 ++++---- .github/workflows/dependabot.yml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index c14b91aa4f1..d523602e125 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2.4.0 - - uses: actions/setup-go@v2.2.0 + - uses: actions/setup-go@v3 with: go-version: ${{ env.DEFAULT_GO_VERSION }} - name: Run benchmarks diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3cb2893edcf..247a64dedf5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Install Go - uses: actions/setup-go@v2.2.0 + uses: actions/setup-go@v3 with: go-version: ${{ env.DEFAULT_GO_VERSION }} - name: Checkout Repo @@ -48,7 +48,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Install Go - uses: actions/setup-go@v2.2.0 + uses: actions/setup-go@v3 with: go-version: ${{ env.DEFAULT_GO_VERSION }} - name: Checkout Repo @@ -71,7 +71,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Install Go - uses: actions/setup-go@v2.2.0 + uses: actions/setup-go@v3 with: go-version: ${{ env.DEFAULT_GO_VERSION }} - name: Checkout Repo @@ -123,7 +123,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Install Go - uses: actions/setup-go@v2.2.0 + uses: actions/setup-go@v3 with: go-version: ${{ matrix.go-version }} - name: Checkout code diff --git a/.github/workflows/dependabot.yml b/.github/workflows/dependabot.yml index b679cbaf7f9..067b033ff3c 100644 --- a/.github/workflows/dependabot.yml +++ b/.github/workflows/dependabot.yml @@ -11,7 +11,7 @@ jobs: - uses: actions/checkout@v2 with: ref: ${{ github.head_ref }} - - uses: actions/setup-go@v2.2.0 + - uses: actions/setup-go@v3 with: go-version: '^1.16.0' - uses: evantorrie/mott-the-tidier@v1-beta From d6f9d0d38723e540ba8b66215d405dec90ab6b0a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Mar 2022 10:15:56 -0800 Subject: [PATCH 10/29] Bump actions/checkout from 2.4.0 to 3 (#2645) Bumps [actions/checkout](https://github.com/actions/checkout) from 2.4.0 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2.4.0...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/benchmark.yml | 2 +- .github/workflows/changelog.yml | 2 +- .github/workflows/ci.yml | 8 ++++---- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/dependabot.yml | 2 +- .github/workflows/gosec.yml | 2 +- .github/workflows/markdown.yml | 6 +++--- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index d523602e125..c08b4f69b90 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -10,7 +10,7 @@ jobs: name: Benchmarks runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2.4.0 + - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: go-version: ${{ env.DEFAULT_GO_VERSION }} diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index f11751142b4..10ea8d4bbeb 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -15,7 +15,7 @@ jobs: if: "!contains(github.event.pull_request.labels.*.name, 'Skip Changelog')" steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Check for CHANGELOG changes run: | diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 247a64dedf5..353df7ce38d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: with: go-version: ${{ env.DEFAULT_GO_VERSION }} - name: Checkout Repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup Environment run: | echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV @@ -52,7 +52,7 @@ jobs: with: go-version: ${{ env.DEFAULT_GO_VERSION }} - name: Checkout Repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup Environment run: | echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV @@ -75,7 +75,7 @@ jobs: with: go-version: ${{ env.DEFAULT_GO_VERSION }} - name: Checkout Repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup Environment run: | echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV @@ -127,7 +127,7 @@ jobs: with: go-version: ${{ matrix.go-version }} - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup Environment run: | echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 780ad807831..521063ac4b5 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -20,7 +20,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/dependabot.yml b/.github/workflows/dependabot.yml index 067b033ff3c..c101ef4bb32 100644 --- a/.github/workflows/dependabot.yml +++ b/.github/workflows/dependabot.yml @@ -8,7 +8,7 @@ jobs: if: ${{ contains(github.event.pull_request.labels.*.name, 'dependencies') }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: ref: ${{ github.head_ref }} - uses: actions/setup-go@v3 diff --git a/.github/workflows/gosec.yml b/.github/workflows/gosec.yml index 7050dbe2d53..c0c1c621b16 100644 --- a/.github/workflows/gosec.yml +++ b/.github/workflows/gosec.yml @@ -19,7 +19,7 @@ jobs: GO111MODULE: on steps: - name: Checkout Source - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Run Gosec Security Scanner uses: securego/gosec@master with: diff --git a/.github/workflows/markdown.yml b/.github/workflows/markdown.yml index 31271c2e968..ff8ddc1d9e0 100644 --- a/.github/workflows/markdown.yml +++ b/.github/workflows/markdown.yml @@ -12,7 +12,7 @@ jobs: md: ${{ steps.changes.outputs.md }} steps: - name: Checkout Repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 - name: Get changed files @@ -27,7 +27,7 @@ jobs: if: ${{needs.changedfiles.outputs.md}} steps: - name: Checkout Repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Run linter uses: docker://avtodev/markdown-lint:v1 with: @@ -37,7 +37,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 - uses: gaurav-nelson/github-action-markdown-link-check@v1 From 16e52ed9cc8e80a4adcc531246b3384fd1b37da5 Mon Sep 17 00:00:00 2001 From: Nathan Landis Date: Fri, 4 Mar 2022 12:49:36 -0600 Subject: [PATCH 11/29] Fix typo in go libraries (#2652) --- website_docs/libraries.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website_docs/libraries.md b/website_docs/libraries.md index 8cd772da06d..c4bdc16c356 100644 --- a/website_docs/libraries.md +++ b/website_docs/libraries.md @@ -60,7 +60,7 @@ func sleepy(ctx context.Context) { // httpHandler is an HTTP handler function that is going to be instrumented. func httpHandler(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, "Hello, World! I am instrumented autoamtically!") + fmt.Fprintf(w, "Hello, World! I am instrumented automatically!") ctx := r.Context() sleepy(ctx) } From 0e4c1563e9931ebb178576bb28360293d90b443c Mon Sep 17 00:00:00 2001 From: Damien Mathieu <42@dmathieu.com> Date: Fri, 4 Mar 2022 20:32:49 +0100 Subject: [PATCH 12/29] double benchmark alert threshold (#2649) Co-authored-by: Chester Cheung Co-authored-by: Tyler Yahn --- .github/workflows/benchmark.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index c08b4f69b90..8366db387dd 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -30,3 +30,4 @@ jobs: external-data-json-path: ./benchmarks/data.json auto-push: false fail-on-alert: true + alert-threshold: "400%" From 68e24958ff7a8885b9f8b3ea269190ac3b5629a7 Mon Sep 17 00:00:00 2001 From: Nelz <88060063+nelzkiddom@users.noreply.github.com> Date: Wed, 9 Mar 2022 08:00:10 -0800 Subject: [PATCH 13/29] fallback to URL.Host if Request.Host is empty (#2661) * fallback to URL.Host if Request.Host is empty * changelog * previous versions --- CHANGELOG.md | 1 + semconv/v1.4.0/http.go | 2 ++ semconv/v1.4.0/http_test.go | 47 +++++++++++++++++++++++++++++++++++++ semconv/v1.5.0/http.go | 2 ++ semconv/v1.5.0/http_test.go | 47 +++++++++++++++++++++++++++++++++++++ semconv/v1.6.1/http.go | 2 ++ semconv/v1.6.1/http_test.go | 47 +++++++++++++++++++++++++++++++++++++ semconv/v1.7.0/http.go | 2 ++ semconv/v1.7.0/http_test.go | 47 +++++++++++++++++++++++++++++++++++++ 9 files changed, 197 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52cc0c413e7..b83debc78bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ This update is a breaking change of the unstable Metrics API. Code instrumented - Unify path cleaning functionally in the `otlpmetric` and `otlptrace` config. (#2639) - Change the debug message from the `sdk/trace.BatchSpanProcessor` to reflect the count is cumulative. (#2640) - Introduce new internal envconfig package for OTLP exporters (#2608) +- If `http.Request.Host` is empty, fall back to use `URL.Host` when populating `http.host` in the `semconv` packages. (#2661) ### Fixed diff --git a/semconv/v1.4.0/http.go b/semconv/v1.4.0/http.go index d9537ff3903..a9032ccc3c2 100644 --- a/semconv/v1.4.0/http.go +++ b/semconv/v1.4.0/http.go @@ -166,6 +166,8 @@ func httpBasicAttributesFromHTTPRequest(request *http.Request) []attribute.KeyVa if request.Host != "" { attrs = append(attrs, HTTPHostKey.String(request.Host)) + } else if request.URL != nil && request.URL.Host != "" { + attrs = append(attrs, HTTPHostKey.String(request.URL.Host)) } flavor := "" diff --git a/semconv/v1.4.0/http_test.go b/semconv/v1.4.0/http_test.go index 5d707be5d61..2a76bd68714 100644 --- a/semconv/v1.4.0/http_test.go +++ b/semconv/v1.4.0/http_test.go @@ -705,6 +705,31 @@ func TestHTTPServerAttributesFromHTTPRequest(t *testing.T) { attribute.String("http.host", "example.com"), }, }, + { + name: "with host fallback", + serverName: "my-server-name", + route: "/user/:id", + method: "GET", + requestURI: "/user/123", + proto: "HTTP/1.0", + remoteAddr: "", + host: "", + url: &url.URL{ + Host: "example.com", + Path: "/user/123", + }, + header: nil, + tls: withTLS, + expected: []attribute.KeyValue{ + attribute.String("http.method", "GET"), + attribute.String("http.target", "/user/123"), + attribute.String("http.scheme", "https"), + attribute.String("http.flavor", "1.0"), + attribute.String("http.server_name", "my-server-name"), + attribute.String("http.route", "/user/:id"), + attribute.String("http.host", "example.com"), + }, + }, { name: "with user agent", serverName: "my-server-name", @@ -1042,6 +1067,28 @@ func TestHTTPClientAttributesFromHTTPRequest(t *testing.T) { attribute.String("http.host", "example.com"), }, }, + { + name: "with host fallback", + method: "GET", + requestURI: "/user/123", + proto: "HTTP/1.0", + remoteAddr: "", + host: "", + url: &url.URL{ + Scheme: "https", + Host: "example.com", + Path: "/user/123", + }, + header: nil, + tls: withTLS, + expected: []attribute.KeyValue{ + attribute.String("http.method", "GET"), + attribute.String("http.url", "https://example.com/user/123"), + attribute.String("http.scheme", "https"), + attribute.String("http.flavor", "1.0"), + attribute.String("http.host", "example.com"), + }, + }, { name: "with user agent", method: "GET", diff --git a/semconv/v1.5.0/http.go b/semconv/v1.5.0/http.go index 1ab89a93aa8..114e24b0512 100644 --- a/semconv/v1.5.0/http.go +++ b/semconv/v1.5.0/http.go @@ -166,6 +166,8 @@ func httpBasicAttributesFromHTTPRequest(request *http.Request) []attribute.KeyVa if request.Host != "" { attrs = append(attrs, HTTPHostKey.String(request.Host)) + } else if request.URL != nil && request.URL.Host != "" { + attrs = append(attrs, HTTPHostKey.String(request.URL.Host)) } flavor := "" diff --git a/semconv/v1.5.0/http_test.go b/semconv/v1.5.0/http_test.go index af8567e1d18..c2043860bf7 100644 --- a/semconv/v1.5.0/http_test.go +++ b/semconv/v1.5.0/http_test.go @@ -705,6 +705,31 @@ func TestHTTPServerAttributesFromHTTPRequest(t *testing.T) { attribute.String("http.host", "example.com"), }, }, + { + name: "with host fallback", + serverName: "my-server-name", + route: "/user/:id", + method: "GET", + requestURI: "/user/123", + proto: "HTTP/1.0", + remoteAddr: "", + host: "", + url: &url.URL{ + Host: "example.com", + Path: "/user/123", + }, + header: nil, + tls: withTLS, + expected: []attribute.KeyValue{ + attribute.String("http.method", "GET"), + attribute.String("http.target", "/user/123"), + attribute.String("http.scheme", "https"), + attribute.String("http.flavor", "1.0"), + attribute.String("http.server_name", "my-server-name"), + attribute.String("http.route", "/user/:id"), + attribute.String("http.host", "example.com"), + }, + }, { name: "with user agent", serverName: "my-server-name", @@ -1042,6 +1067,28 @@ func TestHTTPClientAttributesFromHTTPRequest(t *testing.T) { attribute.String("http.host", "example.com"), }, }, + { + name: "with host fallback", + method: "GET", + requestURI: "/user/123", + proto: "HTTP/1.0", + remoteAddr: "", + host: "", + url: &url.URL{ + Scheme: "https", + Host: "example.com", + Path: "/user/123", + }, + header: nil, + tls: withTLS, + expected: []attribute.KeyValue{ + attribute.String("http.method", "GET"), + attribute.String("http.url", "https://example.com/user/123"), + attribute.String("http.scheme", "https"), + attribute.String("http.flavor", "1.0"), + attribute.String("http.host", "example.com"), + }, + }, { name: "with user agent", method: "GET", diff --git a/semconv/v1.6.1/http.go b/semconv/v1.6.1/http.go index 838e5135b00..d2194b3e47b 100644 --- a/semconv/v1.6.1/http.go +++ b/semconv/v1.6.1/http.go @@ -166,6 +166,8 @@ func httpBasicAttributesFromHTTPRequest(request *http.Request) []attribute.KeyVa if request.Host != "" { attrs = append(attrs, HTTPHostKey.String(request.Host)) + } else if request.URL != nil && request.URL.Host != "" { + attrs = append(attrs, HTTPHostKey.String(request.URL.Host)) } flavor := "" diff --git a/semconv/v1.6.1/http_test.go b/semconv/v1.6.1/http_test.go index 017bd13502d..4b4a652c74d 100644 --- a/semconv/v1.6.1/http_test.go +++ b/semconv/v1.6.1/http_test.go @@ -704,6 +704,31 @@ func TestHTTPServerAttributesFromHTTPRequest(t *testing.T) { attribute.String("http.host", "example.com"), }, }, + { + name: "with host fallback", + serverName: "my-server-name", + route: "/user/:id", + method: "GET", + requestURI: "/user/123", + proto: "HTTP/1.0", + remoteAddr: "", + host: "", + url: &url.URL{ + Host: "example.com", + Path: "/user/123", + }, + header: nil, + tls: withTLS, + expected: []attribute.KeyValue{ + attribute.String("http.method", "GET"), + attribute.String("http.target", "/user/123"), + attribute.String("http.scheme", "https"), + attribute.String("http.flavor", "1.0"), + attribute.String("http.server_name", "my-server-name"), + attribute.String("http.route", "/user/:id"), + attribute.String("http.host", "example.com"), + }, + }, { name: "with user agent", serverName: "my-server-name", @@ -1041,6 +1066,28 @@ func TestHTTPClientAttributesFromHTTPRequest(t *testing.T) { attribute.String("http.host", "example.com"), }, }, + { + name: "with host fallback", + method: "GET", + requestURI: "/user/123", + proto: "HTTP/1.0", + remoteAddr: "", + host: "", + url: &url.URL{ + Scheme: "https", + Host: "example.com", + Path: "/user/123", + }, + header: nil, + tls: withTLS, + expected: []attribute.KeyValue{ + attribute.String("http.method", "GET"), + attribute.String("http.url", "https://example.com/user/123"), + attribute.String("http.scheme", "https"), + attribute.String("http.flavor", "1.0"), + attribute.String("http.host", "example.com"), + }, + }, { name: "with user agent", method: "GET", diff --git a/semconv/v1.7.0/http.go b/semconv/v1.7.0/http.go index 9b430fac0c6..fafee88a953 100644 --- a/semconv/v1.7.0/http.go +++ b/semconv/v1.7.0/http.go @@ -167,6 +167,8 @@ func httpBasicAttributesFromHTTPRequest(request *http.Request) []attribute.KeyVa if request.Host != "" { attrs = append(attrs, HTTPHostKey.String(request.Host)) + } else if request.URL != nil && request.URL.Host != "" { + attrs = append(attrs, HTTPHostKey.String(request.URL.Host)) } flavor := "" diff --git a/semconv/v1.7.0/http_test.go b/semconv/v1.7.0/http_test.go index 5d707be5d61..2a76bd68714 100644 --- a/semconv/v1.7.0/http_test.go +++ b/semconv/v1.7.0/http_test.go @@ -705,6 +705,31 @@ func TestHTTPServerAttributesFromHTTPRequest(t *testing.T) { attribute.String("http.host", "example.com"), }, }, + { + name: "with host fallback", + serverName: "my-server-name", + route: "/user/:id", + method: "GET", + requestURI: "/user/123", + proto: "HTTP/1.0", + remoteAddr: "", + host: "", + url: &url.URL{ + Host: "example.com", + Path: "/user/123", + }, + header: nil, + tls: withTLS, + expected: []attribute.KeyValue{ + attribute.String("http.method", "GET"), + attribute.String("http.target", "/user/123"), + attribute.String("http.scheme", "https"), + attribute.String("http.flavor", "1.0"), + attribute.String("http.server_name", "my-server-name"), + attribute.String("http.route", "/user/:id"), + attribute.String("http.host", "example.com"), + }, + }, { name: "with user agent", serverName: "my-server-name", @@ -1042,6 +1067,28 @@ func TestHTTPClientAttributesFromHTTPRequest(t *testing.T) { attribute.String("http.host", "example.com"), }, }, + { + name: "with host fallback", + method: "GET", + requestURI: "/user/123", + proto: "HTTP/1.0", + remoteAddr: "", + host: "", + url: &url.URL{ + Scheme: "https", + Host: "example.com", + Path: "/user/123", + }, + header: nil, + tls: withTLS, + expected: []attribute.KeyValue{ + attribute.String("http.method", "GET"), + attribute.String("http.url", "https://example.com/user/123"), + attribute.String("http.scheme", "https"), + attribute.String("http.flavor", "1.0"), + attribute.String("http.host", "example.com"), + }, + }, { name: "with user agent", method: "GET", From d3ab885e2993f0e343d03989b7f177e668777ebd Mon Sep 17 00:00:00 2001 From: Mike Dame Date: Thu, 10 Mar 2022 13:54:24 -0500 Subject: [PATCH 14/29] Update otel-collector example readme (#2662) Co-authored-by: Tyler Yahn --- example/otel-collector/README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/example/otel-collector/README.md b/example/otel-collector/README.md index 5a1e937dd5b..6e13a59144a 100644 --- a/example/otel-collector/README.md +++ b/example/otel-collector/README.md @@ -30,6 +30,9 @@ Ideally you'd want to either have your application running as part of the kubernetes cluster, or use a secured connection (NodePort/LoadBalancer with TLS or an ingress extension). +If not using microk8s, ensure that cert-manager is installed by following [the +instructions here](https://cert-manager.io/docs/installation/). + # Deploying to Kubernetes All the necessary Kubernetes deployment files are available in this demo, in the @@ -51,10 +54,10 @@ microk8s enable prometheus and you're good to go. Move on to [Using the makefile](#using-the-makefile). Otherwise, obtain a copy of the Prometheus Operator stack from -[coreos](https://github.com/coreos/kube-prometheus): +[prometheus-operator](https://github.com/prometheus-operator/kube-prometheus): ```bash -git clone https://github.com/coreos/kube-prometheus.git +git clone https://github.com/prometheus-operator/kube-prometheus.git cd kube-prometheus kubectl create -f manifests/setup From 005eefef95fbd7dc111e7ba5bde9aa97bcb6acc9 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Thu, 10 Mar 2022 16:01:29 -0500 Subject: [PATCH 15/29] [website_docs] Fix link intra-site link refs (#2666) * [website_docs] Fix link intra-site link refs * Markdown-link config: add replace pattern for /docs/ Co-authored-by: Tyler Yahn --- .markdown-link.json | 4 ++++ website_docs/libraries.md | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.markdown-link.json b/.markdown-link.json index f222ad89c31..bd786f03c15 100644 --- a/.markdown-link.json +++ b/.markdown-link.json @@ -8,6 +8,10 @@ { "pattern": "^/registry", "replacement": "https://opentelemetry.io/registry" + }, + { + "pattern": "^/docs/", + "replacement": "https://opentelemetry.io/docs/" } ], "retryOn429": true, diff --git a/website_docs/libraries.md b/website_docs/libraries.md index c4bdc16c356..5e069a26de3 100644 --- a/website_docs/libraries.md +++ b/website_docs/libraries.md @@ -5,7 +5,7 @@ linkTitle: Libraries aliases: [/docs/instrumentation/go/using_instrumentation_libraries, /docs/instrumentation/go/automatic_instrumentation] --- -Go does not support truly automatic instrumentation like other languages today. Instead, you'll need to depend on [instrumentation libraries](https://opentelemetry.io/docs/reference/specification/glossary/#instrumentation-library) that generate telemetry data for a particular instrumented library. For example, the instrumentation library for `net/http` will automatically create spans that track inbound and outbound requests once you configure it in your code. +Go does not support truly automatic instrumentation like other languages today. Instead, you'll need to depend on [instrumentation libraries](/docs/reference/specification/glossary/#instrumentation-library) that generate telemetry data for a particular instrumented library. For example, the instrumentation library for `net/http` will automatically create spans that track inbound and outbound requests once you configure it in your code. ## Setup @@ -86,7 +86,7 @@ Connecting manual instrumentation you write in your app with instrumentation gen ## Available packages -A full list of instrumentation libraries available can be found in the [OpenTelemetry registry](https://opentelemetry.io/registry/?language=go&component=instrumentation). +A full list of instrumentation libraries available can be found in the [OpenTelemetry registry](/registry/?language=go&component=instrumentation). ## Next steps From 27633f0a3265abc8353b4c5cad48622f7d4a951d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Mar 2022 09:09:46 -0700 Subject: [PATCH 16/29] Bump google.golang.org/grpc from 1.44.0 to 1.45.0 in /example/otel-collector (#2669) * Bump google.golang.org/grpc in /example/otel-collector Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.44.0 to 1.45.0. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.44.0...v1.45.0) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Auto-fix go.sum changes in dependent modules Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: MrAlias --- example/otel-collector/go.mod | 2 +- example/otel-collector/go.sum | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/example/otel-collector/go.mod b/example/otel-collector/go.mod index bc705fd9bac..080fa32ce79 100644 --- a/example/otel-collector/go.mod +++ b/example/otel-collector/go.mod @@ -12,7 +12,7 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.4.1 go.opentelemetry.io/otel/sdk v1.4.1 go.opentelemetry.io/otel/trace v1.4.1 - google.golang.org/grpc v1.44.0 + google.golang.org/grpc v1.45.0 ) replace go.opentelemetry.io/otel/bridge/opencensus => ../../bridge/opencensus diff --git a/example/otel-collector/go.sum b/example/otel-collector/go.sum index ca5dbebdb8b..8612268ef70 100644 --- a/example/otel-collector/go.sum +++ b/example/otel-collector/go.sum @@ -135,8 +135,9 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.44.0 h1:weqSxi/TMs1SqFRMHCtBgXRs8k3X39QIDEZ0pRcttUg= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= From b1d29783a7a793ef711b3628f8b4f7009ff23cc3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Mar 2022 09:27:38 -0700 Subject: [PATCH 17/29] Bump google.golang.org/grpc from 1.44.0 to 1.45.0 in /exporters/otlp/otlpmetric (#2672) * Bump google.golang.org/grpc in /exporters/otlp/otlpmetric Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.44.0 to 1.45.0. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.44.0...v1.45.0) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Auto-fix go.sum changes in dependent modules Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: MrAlias --- exporters/otlp/otlpmetric/go.mod | 2 +- exporters/otlp/otlpmetric/go.sum | 4 ++-- exporters/otlp/otlpmetric/otlpmetricgrpc/go.mod | 2 +- exporters/otlp/otlpmetric/otlpmetricgrpc/go.sum | 4 ++-- exporters/otlp/otlpmetric/otlpmetrichttp/go.sum | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/exporters/otlp/otlpmetric/go.mod b/exporters/otlp/otlpmetric/go.mod index 3a1567c0ec2..9676fc3b2d2 100644 --- a/exporters/otlp/otlpmetric/go.mod +++ b/exporters/otlp/otlpmetric/go.mod @@ -11,7 +11,7 @@ require ( go.opentelemetry.io/otel/sdk v1.4.1 go.opentelemetry.io/otel/sdk/metric v0.27.0 go.opentelemetry.io/proto/otlp v0.12.0 - google.golang.org/grpc v1.44.0 + google.golang.org/grpc v1.45.0 google.golang.org/protobuf v1.27.1 ) diff --git a/exporters/otlp/otlpmetric/go.sum b/exporters/otlp/otlpmetric/go.sum index c965d892816..fa7935b2ab3 100644 --- a/exporters/otlp/otlpmetric/go.sum +++ b/exporters/otlp/otlpmetric/go.sum @@ -115,8 +115,8 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.44.0 h1:weqSxi/TMs1SqFRMHCtBgXRs8k3X39QIDEZ0pRcttUg= -google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/exporters/otlp/otlpmetric/otlpmetricgrpc/go.mod b/exporters/otlp/otlpmetric/otlpmetricgrpc/go.mod index cba505c7944..b8c7ce3d048 100644 --- a/exporters/otlp/otlpmetric/otlpmetricgrpc/go.mod +++ b/exporters/otlp/otlpmetric/otlpmetricgrpc/go.mod @@ -12,7 +12,7 @@ require ( go.opentelemetry.io/otel/sdk/metric v0.27.0 go.opentelemetry.io/proto/otlp v0.12.0 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 - google.golang.org/grpc v1.44.0 + google.golang.org/grpc v1.45.0 google.golang.org/protobuf v1.27.1 ) diff --git a/exporters/otlp/otlpmetric/otlpmetricgrpc/go.sum b/exporters/otlp/otlpmetric/otlpmetricgrpc/go.sum index c965d892816..fa7935b2ab3 100644 --- a/exporters/otlp/otlpmetric/otlpmetricgrpc/go.sum +++ b/exporters/otlp/otlpmetric/otlpmetricgrpc/go.sum @@ -115,8 +115,8 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.44.0 h1:weqSxi/TMs1SqFRMHCtBgXRs8k3X39QIDEZ0pRcttUg= -google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/exporters/otlp/otlpmetric/otlpmetrichttp/go.sum b/exporters/otlp/otlpmetric/otlpmetrichttp/go.sum index c965d892816..fa7935b2ab3 100644 --- a/exporters/otlp/otlpmetric/otlpmetrichttp/go.sum +++ b/exporters/otlp/otlpmetric/otlpmetrichttp/go.sum @@ -115,8 +115,8 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.44.0 h1:weqSxi/TMs1SqFRMHCtBgXRs8k3X39QIDEZ0pRcttUg= -google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= From b22999748b5997c19b25556f3e98c3273cd49e9a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Mar 2022 09:47:52 -0700 Subject: [PATCH 18/29] Bump google.golang.org/grpc from 1.44.0 to 1.45.0 in /exporters/otlp/otlptrace (#2671) * Bump google.golang.org/grpc in /exporters/otlp/otlptrace Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.44.0 to 1.45.0. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.44.0...v1.45.0) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Auto-fix go.sum changes in dependent modules * Auto-fix go.sum changes in dependent modules Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: MrAlias --- example/otel-collector/go.sum | 1 - exporters/otlp/otlptrace/go.mod | 2 +- exporters/otlp/otlptrace/go.sum | 4 ++-- exporters/otlp/otlptrace/otlptracegrpc/go.mod | 2 +- exporters/otlp/otlptrace/otlptracegrpc/go.sum | 4 ++-- exporters/otlp/otlptrace/otlptracehttp/go.sum | 4 ++-- 6 files changed, 8 insertions(+), 9 deletions(-) diff --git a/example/otel-collector/go.sum b/example/otel-collector/go.sum index 8612268ef70..f0cc9cfefcb 100644 --- a/example/otel-collector/go.sum +++ b/example/otel-collector/go.sum @@ -135,7 +135,6 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= diff --git a/exporters/otlp/otlptrace/go.mod b/exporters/otlp/otlptrace/go.mod index dd9eb1815aa..8ccda24f2bd 100644 --- a/exporters/otlp/otlptrace/go.mod +++ b/exporters/otlp/otlptrace/go.mod @@ -10,7 +10,7 @@ require ( go.opentelemetry.io/otel/sdk v1.4.1 go.opentelemetry.io/otel/trace v1.4.1 go.opentelemetry.io/proto/otlp v0.12.0 - google.golang.org/grpc v1.44.0 + google.golang.org/grpc v1.45.0 google.golang.org/protobuf v1.27.1 ) diff --git a/exporters/otlp/otlptrace/go.sum b/exporters/otlp/otlptrace/go.sum index b41a0280fd8..090d0fa09c9 100644 --- a/exporters/otlp/otlptrace/go.sum +++ b/exporters/otlp/otlptrace/go.sum @@ -113,8 +113,8 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.44.0 h1:weqSxi/TMs1SqFRMHCtBgXRs8k3X39QIDEZ0pRcttUg= -google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/exporters/otlp/otlptrace/otlptracegrpc/go.mod b/exporters/otlp/otlptrace/otlptracegrpc/go.mod index 024bd30407c..17bfa61093f 100644 --- a/exporters/otlp/otlptrace/otlptracegrpc/go.mod +++ b/exporters/otlp/otlptrace/otlptracegrpc/go.mod @@ -11,7 +11,7 @@ require ( go.opentelemetry.io/proto/otlp v0.12.0 go.uber.org/goleak v1.1.12 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 - google.golang.org/grpc v1.44.0 + google.golang.org/grpc v1.45.0 google.golang.org/protobuf v1.27.1 ) diff --git a/exporters/otlp/otlptrace/otlptracegrpc/go.sum b/exporters/otlp/otlptrace/otlptracegrpc/go.sum index d2dc43a4872..6b09989fa98 100644 --- a/exporters/otlp/otlptrace/otlptracegrpc/go.sum +++ b/exporters/otlp/otlptrace/otlptracegrpc/go.sum @@ -139,8 +139,8 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.44.0 h1:weqSxi/TMs1SqFRMHCtBgXRs8k3X39QIDEZ0pRcttUg= -google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/exporters/otlp/otlptrace/otlptracehttp/go.sum b/exporters/otlp/otlptrace/otlptracehttp/go.sum index b41a0280fd8..090d0fa09c9 100644 --- a/exporters/otlp/otlptrace/otlptracehttp/go.sum +++ b/exporters/otlp/otlptrace/otlptracehttp/go.sum @@ -113,8 +113,8 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.44.0 h1:weqSxi/TMs1SqFRMHCtBgXRs8k3X39QIDEZ0pRcttUg= -google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= From 2cfc5210f254e9fa3537582830446a64ab3016ab Mon Sep 17 00:00:00 2001 From: Tyler Yahn Date: Wed, 16 Mar 2022 09:13:17 -0700 Subject: [PATCH 19/29] Release v1.5.0 (#2676) * Bump stable-v1 from v1.4.1 to v1.5.0 * Remove internal/metric module from versions file This module was removed from the project. * Prepare stable-v1 for version v1.5.0 * Update changelog * Update CHANGELOG.md --- CHANGELOG.md | 25 ++++++++++++------- bridge/opencensus/go.mod | 6 ++--- bridge/opencensus/test/go.mod | 6 ++--- bridge/opentracing/go.mod | 4 +-- example/fib/go.mod | 8 +++--- example/jaeger/go.mod | 6 ++--- example/namedtracer/go.mod | 8 +++--- example/opencensus/go.mod | 6 ++--- example/otel-collector/go.mod | 8 +++--- example/passthrough/go.mod | 8 +++--- example/prometheus/go.mod | 2 +- example/zipkin/go.mod | 8 +++--- exporters/jaeger/go.mod | 6 ++--- exporters/otlp/otlpmetric/go.mod | 6 ++--- .../otlp/otlpmetric/otlpmetricgrpc/go.mod | 6 ++--- .../otlp/otlpmetric/otlpmetrichttp/go.mod | 4 +-- exporters/otlp/otlptrace/go.mod | 8 +++--- exporters/otlp/otlptrace/otlptracegrpc/go.mod | 8 +++--- exporters/otlp/otlptrace/otlptracehttp/go.mod | 10 ++++---- exporters/prometheus/go.mod | 4 +-- exporters/stdout/stdoutmetric/go.mod | 4 +-- exporters/stdout/stdouttrace/go.mod | 6 ++--- exporters/zipkin/go.mod | 6 ++--- go.mod | 2 +- metric/go.mod | 2 +- sdk/export/metric/go.mod | 2 +- sdk/go.mod | 4 +-- sdk/metric/go.mod | 4 +-- trace/go.mod | 2 +- version.go | 2 +- versions.yaml | 3 +-- 31 files changed, 95 insertions(+), 89 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b83debc78bc..da2760a0e2f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,13 +10,20 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ### ⚠️ Notice ⚠️ -This update is a breaking change of the unstable Metrics API. Code instrumented with the `go.opentelemetry.io/otel/metric` <= v0.27.0 will need to be modified. +This update is a breaking change of the unstable Metrics API. +Code instrumented with the `go.opentelemetry.io/otel/metric` will need to be modified. + +### Changed + +- The metrics API has been significantly changed. (#2587) + +## [1.5.0] - 2022-03-16 ### Added - Log the Exporters configuration in the TracerProviders message. (#2578) - Added support to configure the span limits with environment variables. - The following environment variables are used. (#2606, #2637) + The following environment variables are supported. (#2606, #2637) - `OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT` - `OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT` - `OTEL_SPAN_EVENT_COUNT_LIMIT` @@ -26,7 +33,7 @@ This update is a breaking change of the unstable Metrics API. Code instrumented If the provided environment variables are invalid (negative), the default values would be used. - Rename the `gc` runtime name to `go` (#2560) -- Add container id support to Resource. (#2418) +- Add resource container ID detection. (#2418) - Add span attribute value length limit. The new `AttributeValueLengthLimit` field is added to the `"go.opentelemetry.io/otel/sdk/trace".SpanLimits` type to configure this limit for a `TracerProvider`. The default limit for this resource is "unlimited". (#2637) @@ -38,18 +45,17 @@ This update is a breaking change of the unstable Metrics API. Code instrumented ### Changed -- For tracestate's members, prepend the new element and remove the oldest one, which is over capacity (#2592) +- Drop oldest tracestate `Member` when capacity is reached. (#2592) - Add event and link drop counts to the exported data from the `oltptrace` exporter. (#2601) -- The metrics API has been significantly changed. (#2587) -- Unify path cleaning functionally in the `otlpmetric` and `otlptrace` config. (#2639) +- Unify path cleaning functionally in the `otlpmetric` and `otlptrace` configuration. (#2639) - Change the debug message from the `sdk/trace.BatchSpanProcessor` to reflect the count is cumulative. (#2640) -- Introduce new internal envconfig package for OTLP exporters (#2608) +- Introduce new internal `envconfig` package for OTLP exporters. (#2608) - If `http.Request.Host` is empty, fall back to use `URL.Host` when populating `http.host` in the `semconv` packages. (#2661) ### Fixed - Remove the OTLP trace exporter limit of SpanEvents when exporting. (#2616) -- Use port `4318` instead of `4317` for default for the `otlpmetrichttp` and `otlptracehttp` client. (#2614, #2625) +- Default to port `4318` instead of `4317` for the `otlpmetrichttp` and `otlptracehttp` client. (#2614, #2625) - Unlimited span limits are now supported (negative values). (#2636, #2637) ### Deprecated @@ -1740,7 +1746,8 @@ It contains api and sdk for trace and meter. - CircleCI build CI manifest files. - CODEOWNERS file to track owners of this project. -[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.4.1...HEAD +[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.5.0...HEAD +[1.5.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.5.0 [1.4.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.4.1 [1.4.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.4.0 [1.3.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.3.0 diff --git a/bridge/opencensus/go.mod b/bridge/opencensus/go.mod index db2733fc484..dce769c4a7c 100644 --- a/bridge/opencensus/go.mod +++ b/bridge/opencensus/go.mod @@ -4,11 +4,11 @@ go 1.16 require ( go.opencensus.io v0.22.6-0.20201102222123-380f4078db9f - go.opentelemetry.io/otel v1.4.1 + go.opentelemetry.io/otel v1.5.0 go.opentelemetry.io/otel/metric v0.27.0 - go.opentelemetry.io/otel/sdk v1.4.1 + go.opentelemetry.io/otel/sdk v1.5.0 go.opentelemetry.io/otel/sdk/metric v0.27.0 - go.opentelemetry.io/otel/trace v1.4.1 + go.opentelemetry.io/otel/trace v1.5.0 ) replace go.opentelemetry.io/otel => ../.. diff --git a/bridge/opencensus/test/go.mod b/bridge/opencensus/test/go.mod index b262f82d5e8..bbd8c7df52c 100644 --- a/bridge/opencensus/test/go.mod +++ b/bridge/opencensus/test/go.mod @@ -4,10 +4,10 @@ go 1.16 require ( go.opencensus.io v0.23.0 - go.opentelemetry.io/otel v1.4.1 + go.opentelemetry.io/otel v1.5.0 go.opentelemetry.io/otel/bridge/opencensus v0.27.1 - go.opentelemetry.io/otel/sdk v1.4.1 - go.opentelemetry.io/otel/trace v1.4.1 + go.opentelemetry.io/otel/sdk v1.5.0 + go.opentelemetry.io/otel/trace v1.5.0 ) replace go.opentelemetry.io/otel => ../../.. diff --git a/bridge/opentracing/go.mod b/bridge/opentracing/go.mod index 6a36fde8822..446fd94bbd1 100644 --- a/bridge/opentracing/go.mod +++ b/bridge/opentracing/go.mod @@ -6,8 +6,8 @@ replace go.opentelemetry.io/otel => ../.. require ( github.com/opentracing/opentracing-go v1.2.0 - go.opentelemetry.io/otel v1.4.1 - go.opentelemetry.io/otel/trace v1.4.1 + go.opentelemetry.io/otel v1.5.0 + go.opentelemetry.io/otel/trace v1.5.0 ) replace go.opentelemetry.io/otel/bridge/opencensus => ../opencensus diff --git a/example/fib/go.mod b/example/fib/go.mod index f32a17d8ed9..a76f072c296 100644 --- a/example/fib/go.mod +++ b/example/fib/go.mod @@ -3,10 +3,10 @@ module go.opentelemetry.io/otel/example/fib go 1.16 require ( - go.opentelemetry.io/otel v1.4.1 - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.4.1 - go.opentelemetry.io/otel/sdk v1.4.1 - go.opentelemetry.io/otel/trace v1.4.1 + go.opentelemetry.io/otel v1.5.0 + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.5.0 + go.opentelemetry.io/otel/sdk v1.5.0 + go.opentelemetry.io/otel/trace v1.5.0 ) replace go.opentelemetry.io/otel => ../.. diff --git a/example/jaeger/go.mod b/example/jaeger/go.mod index c67a139299d..06e6cdef268 100644 --- a/example/jaeger/go.mod +++ b/example/jaeger/go.mod @@ -9,9 +9,9 @@ replace ( ) require ( - go.opentelemetry.io/otel v1.4.1 - go.opentelemetry.io/otel/exporters/jaeger v1.4.1 - go.opentelemetry.io/otel/sdk v1.4.1 + go.opentelemetry.io/otel v1.5.0 + go.opentelemetry.io/otel/exporters/jaeger v1.5.0 + go.opentelemetry.io/otel/sdk v1.5.0 ) replace go.opentelemetry.io/otel/bridge/opencensus => ../../bridge/opencensus diff --git a/example/namedtracer/go.mod b/example/namedtracer/go.mod index 3873edf2951..0efbd773dbc 100644 --- a/example/namedtracer/go.mod +++ b/example/namedtracer/go.mod @@ -9,10 +9,10 @@ replace ( require ( github.com/go-logr/stdr v1.2.2 - go.opentelemetry.io/otel v1.4.1 - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.4.1 - go.opentelemetry.io/otel/sdk v1.4.1 - go.opentelemetry.io/otel/trace v1.4.1 + go.opentelemetry.io/otel v1.5.0 + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.5.0 + go.opentelemetry.io/otel/sdk v1.5.0 + go.opentelemetry.io/otel/trace v1.5.0 ) replace go.opentelemetry.io/otel/bridge/opencensus => ../../bridge/opencensus diff --git a/example/opencensus/go.mod b/example/opencensus/go.mod index ba0fa9db3de..d4073d2aabe 100644 --- a/example/opencensus/go.mod +++ b/example/opencensus/go.mod @@ -10,11 +10,11 @@ replace ( require ( go.opencensus.io v0.22.6-0.20201102222123-380f4078db9f - go.opentelemetry.io/otel v1.4.1 + go.opentelemetry.io/otel v1.5.0 go.opentelemetry.io/otel/bridge/opencensus v0.27.1 go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.27.0 - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.4.1 - go.opentelemetry.io/otel/sdk v1.4.1 + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.5.0 + go.opentelemetry.io/otel/sdk v1.5.0 go.opentelemetry.io/otel/sdk/metric v0.27.0 ) diff --git a/example/otel-collector/go.mod b/example/otel-collector/go.mod index 080fa32ce79..ca6a4b4aefe 100644 --- a/example/otel-collector/go.mod +++ b/example/otel-collector/go.mod @@ -8,10 +8,10 @@ replace ( ) require ( - go.opentelemetry.io/otel v1.4.1 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.4.1 - go.opentelemetry.io/otel/sdk v1.4.1 - go.opentelemetry.io/otel/trace v1.4.1 + go.opentelemetry.io/otel v1.5.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.5.0 + go.opentelemetry.io/otel/sdk v1.5.0 + go.opentelemetry.io/otel/trace v1.5.0 google.golang.org/grpc v1.45.0 ) diff --git a/example/passthrough/go.mod b/example/passthrough/go.mod index b738a24061b..50b16bda87f 100644 --- a/example/passthrough/go.mod +++ b/example/passthrough/go.mod @@ -3,10 +3,10 @@ module go.opentelemetry.io/otel/example/passthrough go 1.16 require ( - go.opentelemetry.io/otel v1.4.1 - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.4.1 - go.opentelemetry.io/otel/sdk v1.4.1 - go.opentelemetry.io/otel/trace v1.4.1 + go.opentelemetry.io/otel v1.5.0 + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.5.0 + go.opentelemetry.io/otel/sdk v1.5.0 + go.opentelemetry.io/otel/trace v1.5.0 ) replace ( diff --git a/example/prometheus/go.mod b/example/prometheus/go.mod index b30c60e547f..21d620dbce1 100644 --- a/example/prometheus/go.mod +++ b/example/prometheus/go.mod @@ -9,7 +9,7 @@ replace ( ) require ( - go.opentelemetry.io/otel v1.4.1 + go.opentelemetry.io/otel v1.5.0 go.opentelemetry.io/otel/exporters/prometheus v0.27.0 go.opentelemetry.io/otel/metric v0.27.0 go.opentelemetry.io/otel/sdk/metric v0.27.0 diff --git a/example/zipkin/go.mod b/example/zipkin/go.mod index c47de71dfda..fc2a8a0bdf9 100644 --- a/example/zipkin/go.mod +++ b/example/zipkin/go.mod @@ -9,10 +9,10 @@ replace ( ) require ( - go.opentelemetry.io/otel v1.4.1 - go.opentelemetry.io/otel/exporters/zipkin v1.4.1 - go.opentelemetry.io/otel/sdk v1.4.1 - go.opentelemetry.io/otel/trace v1.4.1 + go.opentelemetry.io/otel v1.5.0 + go.opentelemetry.io/otel/exporters/zipkin v1.5.0 + go.opentelemetry.io/otel/sdk v1.5.0 + go.opentelemetry.io/otel/trace v1.5.0 ) replace go.opentelemetry.io/otel/bridge/opencensus => ../../bridge/opencensus diff --git a/exporters/jaeger/go.mod b/exporters/jaeger/go.mod index 265bbc92eb3..9254779fa2c 100644 --- a/exporters/jaeger/go.mod +++ b/exporters/jaeger/go.mod @@ -5,9 +5,9 @@ go 1.16 require ( github.com/google/go-cmp v0.5.7 github.com/stretchr/testify v1.7.0 - go.opentelemetry.io/otel v1.4.1 - go.opentelemetry.io/otel/sdk v1.4.1 - go.opentelemetry.io/otel/trace v1.4.1 + go.opentelemetry.io/otel v1.5.0 + go.opentelemetry.io/otel/sdk v1.5.0 + go.opentelemetry.io/otel/trace v1.5.0 ) replace go.opentelemetry.io/otel/bridge/opencensus => ../../bridge/opencensus diff --git a/exporters/otlp/otlpmetric/go.mod b/exporters/otlp/otlpmetric/go.mod index 9676fc3b2d2..6dc1807cddb 100644 --- a/exporters/otlp/otlpmetric/go.mod +++ b/exporters/otlp/otlpmetric/go.mod @@ -5,10 +5,10 @@ go 1.16 require ( github.com/google/go-cmp v0.5.7 github.com/stretchr/testify v1.7.0 - go.opentelemetry.io/otel v1.4.1 - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.4.1 + go.opentelemetry.io/otel v1.5.0 + go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.5.0 go.opentelemetry.io/otel/metric v0.27.0 - go.opentelemetry.io/otel/sdk v1.4.1 + go.opentelemetry.io/otel/sdk v1.5.0 go.opentelemetry.io/otel/sdk/metric v0.27.0 go.opentelemetry.io/proto/otlp v0.12.0 google.golang.org/grpc v1.45.0 diff --git a/exporters/otlp/otlpmetric/otlpmetricgrpc/go.mod b/exporters/otlp/otlpmetric/otlpmetricgrpc/go.mod index b8c7ce3d048..c4d6a575adc 100644 --- a/exporters/otlp/otlpmetric/otlpmetricgrpc/go.mod +++ b/exporters/otlp/otlpmetric/otlpmetricgrpc/go.mod @@ -4,11 +4,11 @@ go 1.16 require ( github.com/stretchr/testify v1.7.0 - go.opentelemetry.io/otel v1.4.1 - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.4.1 + go.opentelemetry.io/otel v1.5.0 + go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.5.0 go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.27.0 go.opentelemetry.io/otel/metric v0.27.0 - go.opentelemetry.io/otel/sdk v1.4.1 + go.opentelemetry.io/otel/sdk v1.5.0 go.opentelemetry.io/otel/sdk/metric v0.27.0 go.opentelemetry.io/proto/otlp v0.12.0 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 diff --git a/exporters/otlp/otlpmetric/otlpmetrichttp/go.mod b/exporters/otlp/otlpmetric/otlpmetrichttp/go.mod index a91939eff01..b70ba6e66e5 100644 --- a/exporters/otlp/otlpmetric/otlpmetrichttp/go.mod +++ b/exporters/otlp/otlpmetric/otlpmetrichttp/go.mod @@ -4,9 +4,9 @@ go 1.16 require ( github.com/stretchr/testify v1.7.0 - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.4.1 + go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.5.0 go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.27.0 - go.opentelemetry.io/otel/sdk v1.4.1 + go.opentelemetry.io/otel/sdk v1.5.0 go.opentelemetry.io/proto/otlp v0.12.0 google.golang.org/protobuf v1.27.1 ) diff --git a/exporters/otlp/otlptrace/go.mod b/exporters/otlp/otlptrace/go.mod index 8ccda24f2bd..48d7c36ee82 100644 --- a/exporters/otlp/otlptrace/go.mod +++ b/exporters/otlp/otlptrace/go.mod @@ -5,10 +5,10 @@ go 1.16 require ( github.com/google/go-cmp v0.5.7 github.com/stretchr/testify v1.7.0 - go.opentelemetry.io/otel v1.4.1 - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.4.1 - go.opentelemetry.io/otel/sdk v1.4.1 - go.opentelemetry.io/otel/trace v1.4.1 + go.opentelemetry.io/otel v1.5.0 + go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.5.0 + go.opentelemetry.io/otel/sdk v1.5.0 + go.opentelemetry.io/otel/trace v1.5.0 go.opentelemetry.io/proto/otlp v0.12.0 google.golang.org/grpc v1.45.0 google.golang.org/protobuf v1.27.1 diff --git a/exporters/otlp/otlptrace/otlptracegrpc/go.mod b/exporters/otlp/otlptrace/otlptracegrpc/go.mod index 17bfa61093f..58acd836e9e 100644 --- a/exporters/otlp/otlptrace/otlptracegrpc/go.mod +++ b/exporters/otlp/otlptrace/otlptracegrpc/go.mod @@ -4,10 +4,10 @@ go 1.16 require ( github.com/stretchr/testify v1.7.0 - go.opentelemetry.io/otel v1.4.1 - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.4.1 - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.4.1 - go.opentelemetry.io/otel/sdk v1.4.1 + go.opentelemetry.io/otel v1.5.0 + go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.5.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.5.0 + go.opentelemetry.io/otel/sdk v1.5.0 go.opentelemetry.io/proto/otlp v0.12.0 go.uber.org/goleak v1.1.12 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 diff --git a/exporters/otlp/otlptrace/otlptracehttp/go.mod b/exporters/otlp/otlptrace/otlptracehttp/go.mod index fb3ca1c3429..774b04e51ae 100644 --- a/exporters/otlp/otlptrace/otlptracehttp/go.mod +++ b/exporters/otlp/otlptrace/otlptracehttp/go.mod @@ -4,11 +4,11 @@ go 1.16 require ( github.com/stretchr/testify v1.7.0 - go.opentelemetry.io/otel v1.4.1 - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.4.1 - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.4.1 - go.opentelemetry.io/otel/sdk v1.4.1 - go.opentelemetry.io/otel/trace v1.4.1 + go.opentelemetry.io/otel v1.5.0 + go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.5.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.5.0 + go.opentelemetry.io/otel/sdk v1.5.0 + go.opentelemetry.io/otel/trace v1.5.0 go.opentelemetry.io/proto/otlp v0.12.0 google.golang.org/protobuf v1.27.1 ) diff --git a/exporters/prometheus/go.mod b/exporters/prometheus/go.mod index 3d02af45d5f..a9c686515ae 100644 --- a/exporters/prometheus/go.mod +++ b/exporters/prometheus/go.mod @@ -5,9 +5,9 @@ go 1.16 require ( github.com/prometheus/client_golang v1.12.1 github.com/stretchr/testify v1.7.0 - go.opentelemetry.io/otel v1.4.1 + go.opentelemetry.io/otel v1.5.0 go.opentelemetry.io/otel/metric v0.27.0 - go.opentelemetry.io/otel/sdk v1.4.1 + go.opentelemetry.io/otel/sdk v1.5.0 go.opentelemetry.io/otel/sdk/metric v0.27.0 ) diff --git a/exporters/stdout/stdoutmetric/go.mod b/exporters/stdout/stdoutmetric/go.mod index 07989e72e67..d44e40119db 100644 --- a/exporters/stdout/stdoutmetric/go.mod +++ b/exporters/stdout/stdoutmetric/go.mod @@ -9,9 +9,9 @@ replace ( require ( github.com/stretchr/testify v1.7.0 - go.opentelemetry.io/otel v1.4.1 + go.opentelemetry.io/otel v1.5.0 go.opentelemetry.io/otel/metric v0.27.0 - go.opentelemetry.io/otel/sdk v1.4.1 + go.opentelemetry.io/otel/sdk v1.5.0 go.opentelemetry.io/otel/sdk/metric v0.27.0 ) diff --git a/exporters/stdout/stdouttrace/go.mod b/exporters/stdout/stdouttrace/go.mod index 88d59d2d605..81ffc9ad995 100644 --- a/exporters/stdout/stdouttrace/go.mod +++ b/exporters/stdout/stdouttrace/go.mod @@ -9,9 +9,9 @@ replace ( require ( github.com/stretchr/testify v1.7.0 - go.opentelemetry.io/otel v1.4.1 - go.opentelemetry.io/otel/sdk v1.4.1 - go.opentelemetry.io/otel/trace v1.4.1 + go.opentelemetry.io/otel v1.5.0 + go.opentelemetry.io/otel/sdk v1.5.0 + go.opentelemetry.io/otel/trace v1.5.0 ) replace go.opentelemetry.io/otel/bridge/opencensus => ../../../bridge/opencensus diff --git a/exporters/zipkin/go.mod b/exporters/zipkin/go.mod index c9d56ed8d03..ea061de6174 100644 --- a/exporters/zipkin/go.mod +++ b/exporters/zipkin/go.mod @@ -6,9 +6,9 @@ require ( github.com/google/go-cmp v0.5.7 github.com/openzipkin/zipkin-go v0.4.0 github.com/stretchr/testify v1.7.0 - go.opentelemetry.io/otel v1.4.1 - go.opentelemetry.io/otel/sdk v1.4.1 - go.opentelemetry.io/otel/trace v1.4.1 + go.opentelemetry.io/otel v1.5.0 + go.opentelemetry.io/otel/sdk v1.5.0 + go.opentelemetry.io/otel/trace v1.5.0 ) replace go.opentelemetry.io/otel/bridge/opencensus => ../../bridge/opencensus diff --git a/go.mod b/go.mod index f37c9bf371a..90517f78fb0 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/go-logr/stdr v1.2.2 github.com/google/go-cmp v0.5.7 github.com/stretchr/testify v1.7.0 - go.opentelemetry.io/otel/trace v1.4.1 + go.opentelemetry.io/otel/trace v1.5.0 ) replace go.opentelemetry.io/otel => ./ diff --git a/metric/go.mod b/metric/go.mod index 7d510be1f32..188c44326eb 100644 --- a/metric/go.mod +++ b/metric/go.mod @@ -2,7 +2,7 @@ module go.opentelemetry.io/otel/metric go 1.16 -require go.opentelemetry.io/otel v1.4.1 +require go.opentelemetry.io/otel v1.5.0 replace go.opentelemetry.io/otel => ../ diff --git a/sdk/export/metric/go.mod b/sdk/export/metric/go.mod index 415e71a87f9..9752e1e771a 100644 --- a/sdk/export/metric/go.mod +++ b/sdk/export/metric/go.mod @@ -40,7 +40,7 @@ replace go.opentelemetry.io/otel/sdk/metric => ../../metric replace go.opentelemetry.io/otel/trace => ../../../trace require ( - go.opentelemetry.io/otel v1.4.1 + go.opentelemetry.io/otel v1.5.0 go.opentelemetry.io/otel/sdk/metric v0.27.0 ) diff --git a/sdk/go.mod b/sdk/go.mod index bad9bd0c41c..37b14cf6120 100644 --- a/sdk/go.mod +++ b/sdk/go.mod @@ -8,8 +8,8 @@ require ( github.com/go-logr/logr v1.2.2 github.com/google/go-cmp v0.5.7 github.com/stretchr/testify v1.7.0 - go.opentelemetry.io/otel v1.4.1 - go.opentelemetry.io/otel/trace v1.4.1 + go.opentelemetry.io/otel v1.5.0 + go.opentelemetry.io/otel/trace v1.5.0 golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 ) diff --git a/sdk/metric/go.mod b/sdk/metric/go.mod index 33fda254764..5f4c7f54118 100644 --- a/sdk/metric/go.mod +++ b/sdk/metric/go.mod @@ -41,9 +41,9 @@ replace go.opentelemetry.io/otel/trace => ../../trace require ( github.com/benbjohnson/clock v1.3.0 github.com/stretchr/testify v1.7.0 - go.opentelemetry.io/otel v1.4.1 + go.opentelemetry.io/otel v1.5.0 go.opentelemetry.io/otel/metric v0.27.0 - go.opentelemetry.io/otel/sdk v1.4.1 + go.opentelemetry.io/otel/sdk v1.5.0 ) replace go.opentelemetry.io/otel/example/passthrough => ../../example/passthrough diff --git a/trace/go.mod b/trace/go.mod index e7a32932464..112d54673bb 100644 --- a/trace/go.mod +++ b/trace/go.mod @@ -41,7 +41,7 @@ replace go.opentelemetry.io/otel/trace => ./ require ( github.com/google/go-cmp v0.5.7 github.com/stretchr/testify v1.7.0 - go.opentelemetry.io/otel v1.4.1 + go.opentelemetry.io/otel v1.5.0 ) replace go.opentelemetry.io/otel/example/passthrough => ../example/passthrough diff --git a/version.go b/version.go index a09bcbb5e8f..92d9fda8ff4 100644 --- a/version.go +++ b/version.go @@ -16,5 +16,5 @@ package otel // import "go.opentelemetry.io/otel" // Version is the current release version of OpenTelemetry in use. func Version() string { - return "1.4.1" + return "1.5.0" } diff --git a/versions.yaml b/versions.yaml index 3f06f299346..15b35e14fe1 100644 --- a/versions.yaml +++ b/versions.yaml @@ -14,7 +14,7 @@ module-sets: stable-v1: - version: v1.4.1 + version: v1.5.0 modules: - go.opentelemetry.io/otel - go.opentelemetry.io/otel/bridge/opentracing @@ -42,7 +42,6 @@ module-sets: - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp - go.opentelemetry.io/otel/exporters/prometheus - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric - - go.opentelemetry.io/otel/internal/metric - go.opentelemetry.io/otel/metric - go.opentelemetry.io/otel/sdk/export/metric - go.opentelemetry.io/otel/sdk/metric From 0fe5eee21f6bc40ab7eb9dfaef36f2b451d511e7 Mon Sep 17 00:00:00 2001 From: Sourik Ghosh <61813998+sourikghosh@users.noreply.github.com> Date: Wed, 16 Mar 2022 22:33:35 +0530 Subject: [PATCH 20/29] silence tlsCert.RootCAs.Subjects is deprecated lint err (#2674) * silence tlsCert.RootCAs.Subjects is deprecated lint err Signed-off-by: Sourik Ghosh * silence rest of the occurrence Signed-off-by: Sourik Ghosh Co-authored-by: Aaron Clawson <3766680+MadVikingGod@users.noreply.github.com> Co-authored-by: Tyler Yahn --- exporters/otlp/internal/envconfig/envconfig_test.go | 2 ++ exporters/otlp/otlpmetric/internal/otlpconfig/options_test.go | 3 +++ exporters/otlp/otlptrace/internal/otlpconfig/options_test.go | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/exporters/otlp/internal/envconfig/envconfig_test.go b/exporters/otlp/internal/envconfig/envconfig_test.go index b141cd42b93..eaf85b1ec7a 100644 --- a/exporters/otlp/internal/envconfig/envconfig_test.go +++ b/exporters/otlp/internal/envconfig/envconfig_test.go @@ -288,6 +288,8 @@ func TestWithTLSConfig(t *testing.T) { WithTLSConfig("CERTIFICATE", func(v *tls.Config) { option = testOption{TestTLS: v} })) + + // nolint:staticcheck // ignoring tlsCert.RootCAs.Subjects is deprecated ERR because cert does not come from SystemCertPool. assert.Equal(t, tlsCert.RootCAs.Subjects(), option.TestTLS.RootCAs.Subjects()) } diff --git a/exporters/otlp/otlpmetric/internal/otlpconfig/options_test.go b/exporters/otlp/otlpmetric/internal/otlpconfig/options_test.go index fad37d60be5..3496b17cccd 100644 --- a/exporters/otlp/otlpmetric/internal/otlpconfig/options_test.go +++ b/exporters/otlp/otlpmetric/internal/otlpconfig/options_test.go @@ -202,6 +202,7 @@ func TestConfigs(t *testing.T) { //TODO: make sure gRPC's credentials actually works assert.NotNil(t, c.Metrics.GRPCCredentials) } else { + // nolint:staticcheck // ignoring tlsCert.RootCAs.Subjects is deprecated ERR because cert does not come from SystemCertPool. assert.Equal(t, tlsCert.RootCAs.Subjects(), c.Metrics.TLSCfg.RootCAs.Subjects()) } }, @@ -218,6 +219,7 @@ func TestConfigs(t *testing.T) { if grpcOption { assert.NotNil(t, c.Metrics.GRPCCredentials) } else { + // nolint:staticcheck // ignoring tlsCert.RootCAs.Subjects is deprecated ERR because cert does not come from SystemCertPool. assert.Equal(t, tlsCert.RootCAs.Subjects(), c.Metrics.TLSCfg.RootCAs.Subjects()) } }, @@ -236,6 +238,7 @@ func TestConfigs(t *testing.T) { if grpcOption { assert.NotNil(t, c.Metrics.GRPCCredentials) } else { + // nolint:staticcheck // ignoring tlsCert.RootCAs.Subjects is deprecated ERR because cert does not come from SystemCertPool. assert.Equal(t, tlsCert.RootCAs.Subjects(), c.Metrics.TLSCfg.RootCAs.Subjects()) } }, diff --git a/exporters/otlp/otlptrace/internal/otlpconfig/options_test.go b/exporters/otlp/otlptrace/internal/otlpconfig/options_test.go index 30dc5ea8015..3d50e057bef 100644 --- a/exporters/otlp/otlptrace/internal/otlpconfig/options_test.go +++ b/exporters/otlp/otlptrace/internal/otlpconfig/options_test.go @@ -202,6 +202,7 @@ func TestConfigs(t *testing.T) { //TODO: make sure gRPC's credentials actually works assert.NotNil(t, c.Traces.GRPCCredentials) } else { + // nolint:staticcheck // ignoring tlsCert.RootCAs.Subjects is deprecated ERR because cert does not come from SystemCertPool. assert.Equal(t, tlsCert.RootCAs.Subjects(), c.Traces.TLSCfg.RootCAs.Subjects()) } }, @@ -218,6 +219,7 @@ func TestConfigs(t *testing.T) { if grpcOption { assert.NotNil(t, c.Traces.GRPCCredentials) } else { + // nolint:staticcheck // ignoring tlsCert.RootCAs.Subjects is deprecated ERR because cert does not come from SystemCertPool. assert.Equal(t, tlsCert.RootCAs.Subjects(), c.Traces.TLSCfg.RootCAs.Subjects()) } }, @@ -236,6 +238,7 @@ func TestConfigs(t *testing.T) { if grpcOption { assert.NotNil(t, c.Traces.GRPCCredentials) } else { + // nolint:staticcheck // ignoring tlsCert.RootCAs.Subjects is deprecated ERR because cert does not come from SystemCertPool. assert.Equal(t, tlsCert.RootCAs.Subjects(), c.Traces.TLSCfg.RootCAs.Subjects()) } }, @@ -253,6 +256,7 @@ func TestConfigs(t *testing.T) { if grpcOption { assert.NotNil(t, c.Traces.GRPCCredentials) } else { + // nolint:staticcheck // ignoring tlsCert.RootCAs.Subjects is deprecated ERR because cert does not come from SystemCertPool. assert.Equal(t, tlsCert.RootCAs.Subjects(), c.Traces.TLSCfg.RootCAs.Subjects()) } }, From b1c1e781e6df6ac8a280da21766a00d16a45a9ed Mon Sep 17 00:00:00 2001 From: Tyler Yahn Date: Wed, 16 Mar 2022 14:33:59 -0700 Subject: [PATCH 21/29] Support general attribute limits for spans (#2677) * Support general attribute limits for spans When model specific limits are not set fallback to the general ones defined by environment variables before defaults for attribute length and count limits. This is in compliance with the specification. * Update env pkg unit tests Test all environment variable helper functions. * Add changes to changelog * Update firstInt doc --- CHANGELOG.md | 1 + sdk/internal/env/env.go | 54 ++++++++++++++---- sdk/internal/env/env_test.go | 103 ++++++++++++++++++++++++++++------- 3 files changed, 126 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index da2760a0e2f..53543ace68a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,6 +57,7 @@ Code instrumented with the `go.opentelemetry.io/otel/metric` will need to be mod - Remove the OTLP trace exporter limit of SpanEvents when exporting. (#2616) - Default to port `4318` instead of `4317` for the `otlpmetrichttp` and `otlptracehttp` client. (#2614, #2625) - Unlimited span limits are now supported (negative values). (#2636, #2637) +- Fallback to general attribute limits when span specific ones are not set in the environment. (#2675, #2677) ### Deprecated diff --git a/sdk/internal/env/env.go b/sdk/internal/env/env.go index dbc8f512492..1a03bf7af49 100644 --- a/sdk/internal/env/env.go +++ b/sdk/internal/env/env.go @@ -41,16 +41,24 @@ const ( // i.e. 512 BatchSpanProcessorMaxExportBatchSizeKey = "OTEL_BSP_MAX_EXPORT_BATCH_SIZE" - // SpanAttributeValueLengthKey + // AttributeValueLengthKey // Maximum allowed attribute value size. + AttributeValueLengthKey = "OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT" + + // AttributeCountKey + // Maximum allowed span attribute count + AttributeCountKey = "OTEL_ATTRIBUTE_COUNT_LIMIT" + + // SpanAttributeValueLengthKey + // Maximum allowed attribute value size for a span. SpanAttributeValueLengthKey = "OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT" // SpanAttributeCountKey - // Maximum allowed span attribute count + // Maximum allowed span attribute count for a span. SpanAttributeCountKey = "OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT" // SpanEventCountKey - // Maximum allowed span event count + // Maximum allowed span event count. SpanEventCountKey = "OTEL_SPAN_EVENT_COUNT_LIMIT" // SpanEventAttributeCountKey @@ -58,14 +66,36 @@ const ( SpanEventAttributeCountKey = "OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT" // SpanLinkCountKey - // Maximum allowed span link count + // Maximum allowed span link count. SpanLinkCountKey = "OTEL_SPAN_LINK_COUNT_LIMIT" // SpanLinkAttributeCountKey - // Maximum allowed attribute per span link count + // Maximum allowed attribute per span link count. SpanLinkAttributeCountKey = "OTEL_LINK_ATTRIBUTE_COUNT_LIMIT" ) +// firstInt returns the value of the first matching environment variable from +// keys. If the value is not an integer or no match is found, defaultValue is +// returned. +func firstInt(defaultValue int, keys ...string) int { + for _, key := range keys { + value, ok := os.LookupEnv(key) + if !ok { + continue + } + + intValue, err := strconv.Atoi(value) + if err != nil { + global.Info("Got invalid value, number value expected.", key, value) + return defaultValue + } + + return intValue + } + + return defaultValue +} + // IntEnvOr returns the int value of the environment variable with name key if // it exists and the value is an int. Otherwise, defaultValue is returned. func IntEnvOr(key string, defaultValue int) int { @@ -112,17 +142,19 @@ func BatchSpanProcessorMaxExportBatchSize(defaultValue int) int { } // SpanAttributeValueLength returns the environment variable value for the -// OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT key if it exists, otherwise -// defaultValue is returned. +// OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT key if it exists. Otherwise, the +// environment variable value for OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT is +// returned or defaultValue if that is not set. func SpanAttributeValueLength(defaultValue int) int { - return IntEnvOr(SpanAttributeValueLengthKey, defaultValue) + return firstInt(defaultValue, SpanAttributeValueLengthKey, AttributeValueLengthKey) } // SpanAttributeCount returns the environment variable value for the -// OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT key if it exists, otherwise defaultValue is -// returned. +// OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT key if it exists. Otherwise, the +// environment variable value for OTEL_ATTRIBUTE_COUNT_LIMIT is returned or +// defaultValue if that is not set. func SpanAttributeCount(defaultValue int) int { - return IntEnvOr(SpanAttributeCountKey, defaultValue) + return firstInt(defaultValue, SpanAttributeCountKey, AttributeCountKey) } // SpanEventCount returns the environment variable value for the diff --git a/sdk/internal/env/env_test.go b/sdk/internal/env/env_test.go index 8c293f65453..e150f108c5d 100644 --- a/sdk/internal/env/env_test.go +++ b/sdk/internal/env/env_test.go @@ -24,37 +24,98 @@ import ( ottest "go.opentelemetry.io/otel/internal/internaltest" ) -func TestIntEnvOr(t *testing.T) { +func TestEnvParse(t *testing.T) { testCases := []struct { - name string - envValue string - defaultValue int - expectedValue int + name string + keys []string + f func(int) int }{ { - name: "IntEnvOrTest - Basic", - envValue: "2500", - defaultValue: 500, - expectedValue: 2500, + name: "BatchSpanProcessorScheduleDelay", + keys: []string{BatchSpanProcessorScheduleDelayKey}, + f: BatchSpanProcessorScheduleDelay, }, + + { + name: "BatchSpanProcessorExportTimeout", + keys: []string{BatchSpanProcessorExportTimeoutKey}, + f: BatchSpanProcessorExportTimeout, + }, + + { + name: "BatchSpanProcessorMaxQueueSize", + keys: []string{BatchSpanProcessorMaxQueueSizeKey}, + f: BatchSpanProcessorMaxQueueSize, + }, + + { + name: "BatchSpanProcessorMaxExportBatchSize", + keys: []string{BatchSpanProcessorMaxExportBatchSizeKey}, + f: BatchSpanProcessorMaxExportBatchSize, + }, + + { + name: "SpanAttributeValueLength", + keys: []string{SpanAttributeValueLengthKey, AttributeValueLengthKey}, + f: SpanAttributeValueLength, + }, + + { + name: "SpanAttributeCount", + keys: []string{SpanAttributeCountKey, AttributeCountKey}, + f: SpanAttributeCount, + }, + + { + name: "SpanEventCount", + keys: []string{SpanEventCountKey}, + f: SpanEventCount, + }, + { - name: "IntEnvOrTest - Invalid Number", - envValue: "localhost", - defaultValue: 500, - expectedValue: 500, + name: "SpanEventAttributeCount", + keys: []string{SpanEventAttributeCountKey}, + f: SpanEventAttributeCount, + }, + + { + name: "SpanLinkCount", + keys: []string{SpanLinkCountKey}, + f: SpanLinkCount, + }, + + { + name: "SpanLinkAttributeCount", + keys: []string{SpanLinkAttributeCountKey}, + f: SpanLinkAttributeCount, }, } - envStore := ottest.NewEnvStore() - envStore.Record(BatchSpanProcessorMaxQueueSizeKey) - defer func() { - require.NoError(t, envStore.Restore()) - }() + const ( + defVal = 500 + envVal = 2500 + envValStr = "2500" + invalid = "localhost" + ) + for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - require.NoError(t, os.Setenv(BatchSpanProcessorMaxQueueSizeKey, tc.envValue)) - actualValue := BatchSpanProcessorMaxQueueSize(tc.defaultValue) - assert.Equal(t, tc.expectedValue, actualValue) + for _, key := range tc.keys { + t.Run(key, func(t *testing.T) { + envStore := ottest.NewEnvStore() + t.Cleanup(func() { require.NoError(t, envStore.Restore()) }) + envStore.Record(key) + + assert.Equal(t, defVal, tc.f(defVal), "environment variable unset") + + require.NoError(t, os.Setenv(key, envValStr)) + assert.Equal(t, envVal, tc.f(defVal), "environment variable set/valid") + + require.NoError(t, os.Setenv(key, invalid)) + assert.Equal(t, defVal, tc.f(defVal), "invalid value") + }) + + } }) } } From a4ea45c38cbcf76c43ab0555b2d4bcacbbfdce9a Mon Sep 17 00:00:00 2001 From: Tyler Yahn Date: Thu, 17 Mar 2022 08:49:33 -0700 Subject: [PATCH 22/29] Fix changelog entry section to be unreleased (#2680) --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53543ace68a..b103051c6ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,10 @@ Code instrumented with the `go.opentelemetry.io/otel/metric` will need to be mod - The metrics API has been significantly changed. (#2587) +### Fixed + +- Fallback to general attribute limits when span specific ones are not set in the environment. (#2675, #2677) + ## [1.5.0] - 2022-03-16 ### Added @@ -57,7 +61,6 @@ Code instrumented with the `go.opentelemetry.io/otel/metric` will need to be mod - Remove the OTLP trace exporter limit of SpanEvents when exporting. (#2616) - Default to port `4318` instead of `4317` for the `otlpmetrichttp` and `otlptracehttp` client. (#2614, #2625) - Unlimited span limits are now supported (negative values). (#2636, #2637) -- Fallback to general attribute limits when span specific ones are not set in the environment. (#2675, #2677) ### Deprecated From 5bf1f48e80f1fba149b447c25e7e42294d868d7c Mon Sep 17 00:00:00 2001 From: Sam <370182+plantfansam@users.noreply.github.com> Date: Fri, 18 Mar 2022 10:01:52 -0600 Subject: [PATCH 23/29] Remove link to exporters in opentelemetry-go-contrib (#2683) --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 21c2a71612e..4e8639ec8cd 100644 --- a/README.md +++ b/README.md @@ -95,8 +95,6 @@ All officially supported exporters for the OpenTelemetry project are contained i | [stdout](./exporters/stdout/) | ✓ | ✓ | | [Zipkin](./exporters/zipkin/) | | ✓ | -Additionally, OpenTelemetry community supported exporters can be found in the [contrib repository](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/main/exporters). - ## Contributing See the [contributing documentation](CONTRIBUTING.md). From 421d6867eea4656a207c6fd2595a7cb919d85677 Mon Sep 17 00:00:00 2001 From: Aaron Clawson <3766680+MadVikingGod@users.noreply.github.com> Date: Fri, 18 Mar 2022 11:36:16 -0500 Subject: [PATCH 24/29] Add Go 1.18 to our supported versions. (#2679) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Adds go1.18 to tests, moves default version to 1.17 * Added note to readme. * Update CHANGELOG.md Co-authored-by: Tyler Yahn * Update README.md Co-authored-by: Robert Pająk * Move default go version back to 1.16 * Move changelog entry to unreleased section Co-authored-by: Chester Cheung Co-authored-by: Tyler Yahn Co-authored-by: Robert Pająk Co-authored-by: Tyler Yahn --- .github/workflows/ci.yml | 2 +- CHANGELOG.md | 4 ++++ README.md | 8 ++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 353df7ce38d..1c16023015b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -109,7 +109,7 @@ jobs: compatibility-test: strategy: matrix: - go-version: [1.17, 1.16] + go-version: [1.18, 1.17, 1.16] os: [ubuntu-latest, macos-latest, windows-latest] # GitHub Actions does not support arm* architectures on default # runners. It is possible to acomplish this with a self-hosted runner diff --git a/CHANGELOG.md b/CHANGELOG.md index b103051c6ba..b4c0d047217 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm This update is a breaking change of the unstable Metrics API. Code instrumented with the `go.opentelemetry.io/otel/metric` will need to be modified. +### Added + +- Add go 1.18 to our compatibility tests. (#2679) + ### Changed - The metrics API has been significantly changed. (#2587) diff --git a/README.md b/README.md index 4e8639ec8cd..3eee84a671f 100644 --- a/README.md +++ b/README.md @@ -41,20 +41,28 @@ This project is tested on the following systems. | OS | Go Version | Architecture | | ------- | ---------- | ------------ | +| Ubuntu | 1.18 | amd64 | | Ubuntu | 1.17 | amd64 | | Ubuntu | 1.16 | amd64 | +| Ubuntu | 1.18 | 386 | | Ubuntu | 1.17 | 386 | | Ubuntu | 1.16 | 386 | +| MacOS | 1.18 | amd64 | | MacOS | 1.17 | amd64 | | MacOS | 1.16 | amd64 | +| Windows | 1.18 | amd64 | | Windows | 1.17 | amd64 | | Windows | 1.16 | amd64 | +| Windows | 1.18 | 386 | | Windows | 1.17 | 386 | | Windows | 1.16 | 386 | While this project should work for other systems, no compatibility guarantees are made for those systems currently. +Go 1.18 was added in March of 2022. +Go 1.16 will be removed around June 2022. + ## Getting Started You can find a getting started guide on [opentelemetry.io](https://opentelemetry.io/docs/go/getting-started/). From 2f8698c3b1539fbdd31cc8df8d44652062800c83 Mon Sep 17 00:00:00 2001 From: Aaron Clawson <3766680+MadVikingGod@users.noreply.github.com> Date: Mon, 21 Mar 2022 10:05:16 -0500 Subject: [PATCH 25/29] Update versions of dependences (#2710) github.com/stretchr/testify v1.7.1 github.com/go-logr/logr v1.2.3 github.com/golangci/golangci-lint v1.45.0 golang.org/x/tools v0.1.10 --- bridge/opencensus/go.sum | 7 ++- bridge/opencensus/test/go.sum | 7 ++- bridge/opentracing/go.sum | 7 ++- example/fib/go.sum | 7 ++- example/jaeger/go.sum | 7 ++- example/namedtracer/go.sum | 7 ++- example/opencensus/go.sum | 7 ++- example/otel-collector/go.sum | 6 +- example/passthrough/go.sum | 7 ++- example/prometheus/go.sum | 7 ++- example/zipkin/go.sum | 6 +- exporters/jaeger/go.mod | 2 +- exporters/jaeger/go.sum | 7 ++- exporters/otlp/internal/retry/go.mod | 2 +- exporters/otlp/internal/retry/go.sum | 4 +- exporters/otlp/otlpmetric/go.mod | 2 +- exporters/otlp/otlpmetric/go.sum | 6 +- .../otlp/otlpmetric/otlpmetricgrpc/go.mod | 2 +- .../otlp/otlpmetric/otlpmetricgrpc/go.sum | 6 +- .../otlp/otlpmetric/otlpmetrichttp/go.mod | 2 +- .../otlp/otlpmetric/otlpmetrichttp/go.sum | 6 +- exporters/otlp/otlptrace/go.mod | 2 +- exporters/otlp/otlptrace/go.sum | 6 +- exporters/otlp/otlptrace/otlptracegrpc/go.mod | 2 +- exporters/otlp/otlptrace/otlptracegrpc/go.sum | 6 +- exporters/otlp/otlptrace/otlptracehttp/go.mod | 2 +- exporters/otlp/otlptrace/otlptracehttp/go.sum | 6 +- exporters/prometheus/go.mod | 2 +- exporters/prometheus/go.sum | 7 ++- exporters/stdout/stdoutmetric/go.mod | 2 +- exporters/stdout/stdoutmetric/go.sum | 7 ++- exporters/stdout/stdouttrace/go.mod | 2 +- exporters/stdout/stdouttrace/go.sum | 7 ++- exporters/zipkin/go.mod | 2 +- exporters/zipkin/go.sum | 6 +- go.mod | 4 +- go.sum | 7 ++- internal/tools/go.mod | 6 +- internal/tools/go.sum | 62 ++++++++++--------- metric/go.sum | 5 +- schema/go.mod | 2 +- schema/go.sum | 4 +- sdk/export/metric/go.sum | 7 ++- sdk/go.mod | 4 +- sdk/go.sum | 7 ++- sdk/metric/go.mod | 2 +- sdk/metric/go.sum | 7 ++- trace/go.mod | 2 +- trace/go.sum | 5 +- 49 files changed, 169 insertions(+), 128 deletions(-) diff --git a/bridge/opencensus/go.sum b/bridge/opencensus/go.sum index 9d4421e648c..a123b0ac005 100644 --- a/bridge/opencensus/go.sum +++ b/bridge/opencensus/go.sum @@ -5,8 +5,9 @@ github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZx github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -22,8 +23,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= go.opencensus.io v0.22.6-0.20201102222123-380f4078db9f h1:IUmbcoP9XyEXW+R9AbrZgDvaYVfTbISN92Y5RIV+Mx4= go.opencensus.io v0.22.6-0.20201102222123-380f4078db9f/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= diff --git a/bridge/opencensus/test/go.sum b/bridge/opencensus/test/go.sum index b0e85632d32..fcb0c9af429 100644 --- a/bridge/opencensus/test/go.sum +++ b/bridge/opencensus/test/go.sum @@ -11,8 +11,9 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -45,8 +46,8 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= go.opencensus.io v0.22.6-0.20201102222123-380f4078db9f/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= diff --git a/bridge/opentracing/go.sum b/bridge/opentracing/go.sum index 767a256a278..42b3e118d70 100644 --- a/bridge/opentracing/go.sum +++ b/bridge/opentracing/go.sum @@ -1,7 +1,8 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= @@ -12,8 +13,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= diff --git a/example/fib/go.sum b/example/fib/go.sum index 388165251c8..3a091225429 100644 --- a/example/fib/go.sum +++ b/example/fib/go.sum @@ -1,7 +1,8 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= @@ -9,8 +10,8 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/example/jaeger/go.sum b/example/jaeger/go.sum index e1b25057edf..3ecfae9ef6d 100644 --- a/example/jaeger/go.sum +++ b/example/jaeger/go.sum @@ -1,7 +1,8 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= @@ -10,8 +11,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/example/namedtracer/go.sum b/example/namedtracer/go.sum index 388165251c8..3a091225429 100644 --- a/example/namedtracer/go.sum +++ b/example/namedtracer/go.sum @@ -1,7 +1,8 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= @@ -9,8 +10,8 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/example/opencensus/go.sum b/example/opencensus/go.sum index 61a2e293569..435e0b939e7 100644 --- a/example/opencensus/go.sum +++ b/example/opencensus/go.sum @@ -5,8 +5,9 @@ github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZx github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -22,8 +23,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= go.opencensus.io v0.22.6-0.20201102222123-380f4078db9f h1:IUmbcoP9XyEXW+R9AbrZgDvaYVfTbISN92Y5RIV+Mx4= go.opencensus.io v0.22.6-0.20201102222123-380f4078db9f/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= diff --git a/example/otel-collector/go.sum b/example/otel-collector/go.sum index f0cc9cfefcb..7a3e7b70a74 100644 --- a/example/otel-collector/go.sum +++ b/example/otel-collector/go.sum @@ -22,8 +22,9 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -62,8 +63,9 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.12.0 h1:CMJ/3Wp7iOWES+CYLfnBv+DVmPbB+kmy9PJ92XvlR6c= diff --git a/example/passthrough/go.sum b/example/passthrough/go.sum index 388165251c8..3a091225429 100644 --- a/example/passthrough/go.sum +++ b/example/passthrough/go.sum @@ -1,7 +1,8 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= @@ -9,8 +10,8 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/example/prometheus/go.sum b/example/prometheus/go.sum index 673fc937581..039a63a4b81 100644 --- a/example/prometheus/go.sum +++ b/example/prometheus/go.sum @@ -69,8 +69,9 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -193,8 +194,8 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= diff --git a/example/zipkin/go.sum b/example/zipkin/go.sum index 4592dbd0760..fc8c693a77b 100644 --- a/example/zipkin/go.sum +++ b/example/zipkin/go.sum @@ -29,8 +29,9 @@ github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= @@ -103,8 +104,9 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= diff --git a/exporters/jaeger/go.mod b/exporters/jaeger/go.mod index 9254779fa2c..ac956110f1e 100644 --- a/exporters/jaeger/go.mod +++ b/exporters/jaeger/go.mod @@ -4,7 +4,7 @@ go 1.16 require ( github.com/google/go-cmp v0.5.7 - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.7.1 go.opentelemetry.io/otel v1.5.0 go.opentelemetry.io/otel/sdk v1.5.0 go.opentelemetry.io/otel/trace v1.5.0 diff --git a/exporters/jaeger/go.sum b/exporters/jaeger/go.sum index 3d22834d0f4..58eb3804ae5 100644 --- a/exporters/jaeger/go.sum +++ b/exporters/jaeger/go.sum @@ -1,7 +1,8 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= @@ -10,8 +11,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= diff --git a/exporters/otlp/internal/retry/go.mod b/exporters/otlp/internal/retry/go.mod index 8e064415d31..8884eee4d99 100644 --- a/exporters/otlp/internal/retry/go.mod +++ b/exporters/otlp/internal/retry/go.mod @@ -4,7 +4,7 @@ go 1.16 require ( github.com/cenkalti/backoff/v4 v4.1.2 - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.7.1 ) replace go.opentelemetry.io/otel => ../../../.. diff --git a/exporters/otlp/internal/retry/go.sum b/exporters/otlp/internal/retry/go.sum index de50e341131..0d874b89e7d 100644 --- a/exporters/otlp/internal/retry/go.sum +++ b/exporters/otlp/internal/retry/go.sum @@ -5,8 +5,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= diff --git a/exporters/otlp/otlpmetric/go.mod b/exporters/otlp/otlpmetric/go.mod index 6dc1807cddb..fb9e63ab831 100644 --- a/exporters/otlp/otlpmetric/go.mod +++ b/exporters/otlp/otlpmetric/go.mod @@ -4,7 +4,7 @@ go 1.16 require ( github.com/google/go-cmp v0.5.7 - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.7.1 go.opentelemetry.io/otel v1.5.0 go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.5.0 go.opentelemetry.io/otel/metric v0.27.0 diff --git a/exporters/otlp/otlpmetric/go.sum b/exporters/otlp/otlpmetric/go.sum index fa7935b2ab3..8115e273a2b 100644 --- a/exporters/otlp/otlpmetric/go.sum +++ b/exporters/otlp/otlpmetric/go.sum @@ -24,8 +24,9 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -61,8 +62,9 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.12.0 h1:CMJ/3Wp7iOWES+CYLfnBv+DVmPbB+kmy9PJ92XvlR6c= go.opentelemetry.io/proto/otlp v0.12.0/go.mod h1:TsIjwGWIx5VFYv9KGVlOpxoBl5Dy+63SUguV7GGvlSQ= diff --git a/exporters/otlp/otlpmetric/otlpmetricgrpc/go.mod b/exporters/otlp/otlpmetric/otlpmetricgrpc/go.mod index c4d6a575adc..8449a1cb4a9 100644 --- a/exporters/otlp/otlpmetric/otlpmetricgrpc/go.mod +++ b/exporters/otlp/otlpmetric/otlpmetricgrpc/go.mod @@ -3,7 +3,7 @@ module go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc go 1.16 require ( - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.7.1 go.opentelemetry.io/otel v1.5.0 go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.5.0 go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.27.0 diff --git a/exporters/otlp/otlpmetric/otlpmetricgrpc/go.sum b/exporters/otlp/otlpmetric/otlpmetricgrpc/go.sum index fa7935b2ab3..8115e273a2b 100644 --- a/exporters/otlp/otlpmetric/otlpmetricgrpc/go.sum +++ b/exporters/otlp/otlpmetric/otlpmetricgrpc/go.sum @@ -24,8 +24,9 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -61,8 +62,9 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.12.0 h1:CMJ/3Wp7iOWES+CYLfnBv+DVmPbB+kmy9PJ92XvlR6c= go.opentelemetry.io/proto/otlp v0.12.0/go.mod h1:TsIjwGWIx5VFYv9KGVlOpxoBl5Dy+63SUguV7GGvlSQ= diff --git a/exporters/otlp/otlpmetric/otlpmetrichttp/go.mod b/exporters/otlp/otlpmetric/otlpmetrichttp/go.mod index b70ba6e66e5..65359ee8bf1 100644 --- a/exporters/otlp/otlpmetric/otlpmetrichttp/go.mod +++ b/exporters/otlp/otlpmetric/otlpmetrichttp/go.mod @@ -3,7 +3,7 @@ module go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp go 1.16 require ( - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.7.1 go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.5.0 go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.27.0 go.opentelemetry.io/otel/sdk v1.5.0 diff --git a/exporters/otlp/otlpmetric/otlpmetrichttp/go.sum b/exporters/otlp/otlpmetric/otlpmetrichttp/go.sum index fa7935b2ab3..8115e273a2b 100644 --- a/exporters/otlp/otlpmetric/otlpmetrichttp/go.sum +++ b/exporters/otlp/otlpmetric/otlpmetrichttp/go.sum @@ -24,8 +24,9 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -61,8 +62,9 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.12.0 h1:CMJ/3Wp7iOWES+CYLfnBv+DVmPbB+kmy9PJ92XvlR6c= go.opentelemetry.io/proto/otlp v0.12.0/go.mod h1:TsIjwGWIx5VFYv9KGVlOpxoBl5Dy+63SUguV7GGvlSQ= diff --git a/exporters/otlp/otlptrace/go.mod b/exporters/otlp/otlptrace/go.mod index 48d7c36ee82..4754211d0ef 100644 --- a/exporters/otlp/otlptrace/go.mod +++ b/exporters/otlp/otlptrace/go.mod @@ -4,7 +4,7 @@ go 1.16 require ( github.com/google/go-cmp v0.5.7 - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.7.1 go.opentelemetry.io/otel v1.5.0 go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.5.0 go.opentelemetry.io/otel/sdk v1.5.0 diff --git a/exporters/otlp/otlptrace/go.sum b/exporters/otlp/otlptrace/go.sum index 090d0fa09c9..52075ac7cec 100644 --- a/exporters/otlp/otlptrace/go.sum +++ b/exporters/otlp/otlptrace/go.sum @@ -22,8 +22,9 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -59,8 +60,9 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.12.0 h1:CMJ/3Wp7iOWES+CYLfnBv+DVmPbB+kmy9PJ92XvlR6c= go.opentelemetry.io/proto/otlp v0.12.0/go.mod h1:TsIjwGWIx5VFYv9KGVlOpxoBl5Dy+63SUguV7GGvlSQ= diff --git a/exporters/otlp/otlptrace/otlptracegrpc/go.mod b/exporters/otlp/otlptrace/otlptracegrpc/go.mod index 58acd836e9e..bcb789a4da7 100644 --- a/exporters/otlp/otlptrace/otlptracegrpc/go.mod +++ b/exporters/otlp/otlptrace/otlptracegrpc/go.mod @@ -3,7 +3,7 @@ module go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc go 1.16 require ( - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.7.1 go.opentelemetry.io/otel v1.5.0 go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.5.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.5.0 diff --git a/exporters/otlp/otlptrace/otlptracegrpc/go.sum b/exporters/otlp/otlptrace/otlptracegrpc/go.sum index 6b09989fa98..1d81ffaf09a 100644 --- a/exporters/otlp/otlptrace/otlptracegrpc/go.sum +++ b/exporters/otlp/otlptrace/otlptracegrpc/go.sum @@ -22,8 +22,9 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -64,8 +65,9 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.12.0 h1:CMJ/3Wp7iOWES+CYLfnBv+DVmPbB+kmy9PJ92XvlR6c= diff --git a/exporters/otlp/otlptrace/otlptracehttp/go.mod b/exporters/otlp/otlptrace/otlptracehttp/go.mod index 774b04e51ae..92f98e0e789 100644 --- a/exporters/otlp/otlptrace/otlptracehttp/go.mod +++ b/exporters/otlp/otlptrace/otlptracehttp/go.mod @@ -3,7 +3,7 @@ module go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp go 1.16 require ( - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.7.1 go.opentelemetry.io/otel v1.5.0 go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.5.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.5.0 diff --git a/exporters/otlp/otlptrace/otlptracehttp/go.sum b/exporters/otlp/otlptrace/otlptracehttp/go.sum index 090d0fa09c9..52075ac7cec 100644 --- a/exporters/otlp/otlptrace/otlptracehttp/go.sum +++ b/exporters/otlp/otlptrace/otlptracehttp/go.sum @@ -22,8 +22,9 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -59,8 +60,9 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.12.0 h1:CMJ/3Wp7iOWES+CYLfnBv+DVmPbB+kmy9PJ92XvlR6c= go.opentelemetry.io/proto/otlp v0.12.0/go.mod h1:TsIjwGWIx5VFYv9KGVlOpxoBl5Dy+63SUguV7GGvlSQ= diff --git a/exporters/prometheus/go.mod b/exporters/prometheus/go.mod index a9c686515ae..7d08f50325d 100644 --- a/exporters/prometheus/go.mod +++ b/exporters/prometheus/go.mod @@ -4,7 +4,7 @@ go 1.16 require ( github.com/prometheus/client_golang v1.12.1 - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.7.1 go.opentelemetry.io/otel v1.5.0 go.opentelemetry.io/otel/metric v0.27.0 go.opentelemetry.io/otel/sdk v1.5.0 diff --git a/exporters/prometheus/go.sum b/exporters/prometheus/go.sum index 3a133e8de69..43be0c26beb 100644 --- a/exporters/prometheus/go.sum +++ b/exporters/prometheus/go.sum @@ -69,8 +69,9 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -195,8 +196,8 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= diff --git a/exporters/stdout/stdoutmetric/go.mod b/exporters/stdout/stdoutmetric/go.mod index d44e40119db..babf8838612 100644 --- a/exporters/stdout/stdoutmetric/go.mod +++ b/exporters/stdout/stdoutmetric/go.mod @@ -8,7 +8,7 @@ replace ( ) require ( - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.7.1 go.opentelemetry.io/otel v1.5.0 go.opentelemetry.io/otel/metric v0.27.0 go.opentelemetry.io/otel/sdk v1.5.0 diff --git a/exporters/stdout/stdoutmetric/go.sum b/exporters/stdout/stdoutmetric/go.sum index e7e3c1a2040..9ab648da527 100644 --- a/exporters/stdout/stdoutmetric/go.sum +++ b/exporters/stdout/stdoutmetric/go.sum @@ -2,8 +2,9 @@ github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= @@ -11,8 +12,8 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/exporters/stdout/stdouttrace/go.mod b/exporters/stdout/stdouttrace/go.mod index 81ffc9ad995..31d458c9630 100644 --- a/exporters/stdout/stdouttrace/go.mod +++ b/exporters/stdout/stdouttrace/go.mod @@ -8,7 +8,7 @@ replace ( ) require ( - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.7.1 go.opentelemetry.io/otel v1.5.0 go.opentelemetry.io/otel/sdk v1.5.0 go.opentelemetry.io/otel/trace v1.5.0 diff --git a/exporters/stdout/stdouttrace/go.sum b/exporters/stdout/stdouttrace/go.sum index fbd4605e0ee..f9af6c5ae9d 100644 --- a/exporters/stdout/stdouttrace/go.sum +++ b/exporters/stdout/stdouttrace/go.sum @@ -1,7 +1,8 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= @@ -9,8 +10,8 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/exporters/zipkin/go.mod b/exporters/zipkin/go.mod index ea061de6174..917d0eab385 100644 --- a/exporters/zipkin/go.mod +++ b/exporters/zipkin/go.mod @@ -5,7 +5,7 @@ go 1.16 require ( github.com/google/go-cmp v0.5.7 github.com/openzipkin/zipkin-go v0.4.0 - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.7.1 go.opentelemetry.io/otel v1.5.0 go.opentelemetry.io/otel/sdk v1.5.0 go.opentelemetry.io/otel/trace v1.5.0 diff --git a/exporters/zipkin/go.sum b/exporters/zipkin/go.sum index c0f74fbc982..f578de1840a 100644 --- a/exporters/zipkin/go.sum +++ b/exporters/zipkin/go.sum @@ -29,8 +29,9 @@ github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= @@ -105,8 +106,9 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= diff --git a/go.mod b/go.mod index 90517f78fb0..c7de5095b18 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,10 @@ module go.opentelemetry.io/otel go 1.16 require ( - github.com/go-logr/logr v1.2.2 + github.com/go-logr/logr v1.2.3 github.com/go-logr/stdr v1.2.2 github.com/google/go-cmp v0.5.7 - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.7.1 go.opentelemetry.io/otel/trace v1.5.0 ) diff --git a/go.sum b/go.sum index 531cae722ed..301997e9530 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,8 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= @@ -9,8 +10,8 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= diff --git a/internal/tools/go.mod b/internal/tools/go.mod index 9aefef1006d..9ce202b9249 100644 --- a/internal/tools/go.mod +++ b/internal/tools/go.mod @@ -5,14 +5,14 @@ go 1.16 require ( github.com/client9/misspell v0.3.4 github.com/gogo/protobuf v1.3.2 - github.com/golangci/golangci-lint v1.44.2 + github.com/golangci/golangci-lint v1.45.0 github.com/itchyny/gojq v0.12.7 github.com/jcchavezs/porto v0.4.0 github.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad go.opentelemetry.io/build-tools/multimod v0.0.0-20210920164323-2ceabab23375 go.opentelemetry.io/build-tools/semconvgen v0.0.0-20210920164323-2ceabab23375 - golang.org/x/mod v0.5.1 - golang.org/x/tools v0.1.9 + golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 + golang.org/x/tools v0.1.10 ) replace go.opentelemetry.io/otel => ../.. diff --git a/internal/tools/go.sum b/internal/tools/go.sum index 58392f05da5..a579c8d18e7 100644 --- a/internal/tools/go.sum +++ b/internal/tools/go.sum @@ -105,8 +105,8 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/ashanbrown/forbidigo v1.3.0 h1:VkYIwb/xxdireGAdJNZoo24O4lmnEWkactplBlWTShc= github.com/ashanbrown/forbidigo v1.3.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBFg8t0sG2FIxmI= -github.com/ashanbrown/makezero v1.1.0 h1:b2FVq4dTlBpy9f6qxhbyWH+6zy56IETE9cFbBGtDqs8= -github.com/ashanbrown/makezero v1.1.0/go.mod h1:oG9Dnez7/ESBqc4EdrdNlryeo7d0KcW1ftXHm7nU/UU= +github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5FcB28s= +github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI= github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.36.30/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= @@ -172,14 +172,14 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/daixiang0/gci v0.3.1-0.20220208004058-76d765e3ab48 h1:9rJGqaC5do9zkvKrtRdx0HJoxj7Jd6vDa0O2eBU0AbU= -github.com/daixiang0/gci v0.3.1-0.20220208004058-76d765e3ab48/go.mod h1:jaASoJmv/ykO9dAAPy31iJnreV19248qKDdVWf3QgC4= +github.com/daixiang0/gci v0.3.3 h1:55xJKH7Gl9Vk6oQ1cMkwrDWjAkT1D+D1G9kNmRcAIY4= +github.com/daixiang0/gci v0.3.3/go.mod h1:1Xr2bxnQbDxCqqulUOv8qpGqkgRw9RSCGGjEC2LjF8o= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/denis-tingajkin/go-header v0.4.2 h1:jEeSF4sdv8/3cT/WY8AgDHUoItNSoEZ7qg9dX7pc218= -github.com/denis-tingajkin/go-header v0.4.2/go.mod h1:eLRHAVXzE5atsKAnNRDB90WHCFFnBUn4RN0nRcs1LJA= +github.com/denis-tingaikin/go-header v0.4.3 h1:tEaZKAlqql6SKCY++utLmkPLd6K8IBM20Ha7UVm+mtU= +github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -209,8 +209,8 @@ github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYF github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/frankban/quicktest v1.14.0 h1:+cqqvzZV87b4adx/5ayVOaYZ2CrvM4ejQvUdBzPPUss= -github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= +github.com/frankban/quicktest v1.14.2 h1:SPb1KFFmM+ybpEjPUhCCkZOM5xlovT5UbrMvWnXyBns= +github.com/frankban/quicktest v1.14.2/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= @@ -318,8 +318,8 @@ github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613 h1:9kfjN3AdxcbsZB github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8= github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks= github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= -github.com/golangci/golangci-lint v1.44.2 h1:MzvkDt1j1OHkv42/feNJVNNXRFACPp7aAWBWDo5aYQw= -github.com/golangci/golangci-lint v1.44.2/go.mod h1:KjBgkLvsTWDkhfu12iCrv0gwL1kON5KNhbyjQ6qN7Jo= +github.com/golangci/golangci-lint v1.45.0 h1:T2oCVkYoeckBxcNS6DTYiSXN2QcTNuAWaHyLGfqzMlU= +github.com/golangci/golangci-lint v1.45.0/go.mod h1:Y6grRO3drH/7kGP88i9jSl9fGWwCrbA5u7i++jOXll4= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= @@ -522,7 +522,6 @@ github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8 github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -590,7 +589,6 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0j github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo= github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= -github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517 h1:zpIH83+oKzcpryru8ceC6BxnoG8TBrhgAvRg8obzup0= github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg= github.com/mgechev/revive v1.1.4 h1:sZOjY6GU35Kr9jKa/wsKSHgrFz8eASIB5i3tqWZMp0A= github.com/mgechev/revive v1.1.4/go.mod h1:ZZq2bmyssGh8MSPz3VVziqRNIMYTJXzP8MUKG90vZ9A= @@ -653,12 +651,14 @@ github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ= github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0 h1:9Luw4uT5HTjHTN8+aNcSThgH1vdXnmdJ8xIfZ4wyTRE= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/otiai10/copy v1.2.0 h1:HvG945u96iNadPoG2/Ja2+AUJeW5YuFQMixq9yirC+k= github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= @@ -745,25 +745,24 @@ github.com/sagikazarmark/crypt v0.4.0/go.mod h1:ALv2SRj7GxYV4HO9elxH9nS6M9gW+xDN github.com/sanposhiho/wastedassign/v2 v2.0.6 h1:+6/hQIHKNJAUixEj6EmOngGIisyeI+T3335lYTyxRoA= github.com/sanposhiho/wastedassign/v2 v2.0.6/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/securego/gosec/v2 v2.9.6 h1:ysfvgQBp2zmTgXQl65UkqEkYlQGbnVSRUGpCrJiiR4c= -github.com/securego/gosec/v2 v2.9.6/go.mod h1:EESY9Ywxo/Zc5NyF/qIj6Cop+4PSWM0F0OfGD7FdIXc= +github.com/securego/gosec/v2 v2.10.0 h1:l6BET4EzWtyUXCpY2v7N92v0DDCas0L7ngg3bpqbr8g= +github.com/securego/gosec/v2 v2.10.0/go.mod h1:PVq8Ewh/nCN8l/kKC6zrGXSr7m2NmEK6ITIAWMtIaA0= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= -github.com/shirou/gopsutil/v3 v3.22.1/go.mod h1:WapW1AOOPlHyXr+yOyw3uYx36enocrtSoSBy0L5vUHY= +github.com/shirou/gopsutil/v3 v3.22.2/go.mod h1:WapW1AOOPlHyXr+yOyw3uYx36enocrtSoSBy0L5vUHY= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sivchari/containedctx v1.0.1 h1:fJq44cX+tD+uT5xGrsg25GwiaY61NGybQk9WWKij3Uo= -github.com/sivchari/containedctx v1.0.1/go.mod h1:PwZOeqm4/DLoJOqMSIJs3aKqXRX4YO+uXww087KZ7Bw= +github.com/sivchari/containedctx v1.0.2 h1:0hLQKpgC53OVF1VT7CeoFHk9YKstur1XOgfYIc1yrHI= +github.com/sivchari/containedctx v1.0.2/go.mod h1:PwZOeqm4/DLoJOqMSIJs3aKqXRX4YO+uXww087KZ7Bw= github.com/sivchari/tenv v1.4.7 h1:FdTpgRlTue5eb5nXIYgS/lyVXSjugU8UUVDwhP1NLU8= github.com/sivchari/tenv v1.4.7/go.mod h1:5nF+bITvkebQVanjU6IuMbvIot/7ReNsUV7I5NbprB0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= @@ -785,8 +784,9 @@ github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= -github.com/spf13/cobra v1.3.0 h1:R7cSvGu+Vv+qX0gW5R/85dx2kmmJT5z5NM8ifdYjdn0= github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4= +github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= +github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= @@ -833,8 +833,8 @@ github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcy github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tomarrell/wrapcheck/v2 v2.4.0 h1:mU4H9KsqqPZUALOUbVOpjy8qNQbWLoLI9fV68/1tq30= -github.com/tomarrell/wrapcheck/v2 v2.4.0/go.mod h1:68bQ/eJg55BROaRTbMjC7vuhL2OgfoG8bLp9ZyoBfyY= +github.com/tomarrell/wrapcheck/v2 v2.5.0 h1:g27SGGHNoQdvHz4KZA9o4v09RcWzylR+b1yueE5ECiw= +github.com/tomarrell/wrapcheck/v2 v2.5.0/go.mod h1:68bQ/eJg55BROaRTbMjC7vuhL2OgfoG8bLp9ZyoBfyY= github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4= github.com/tommy-muehle/go-mnd/v2 v2.5.0 h1:iAj0a8e6+dXSL7Liq0aXPox36FiN1dBbjA6lt9fl65s= github.com/tommy-muehle/go-mnd/v2 v2.5.0/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= @@ -930,8 +930,9 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce h1:Roh6XWxHFKrPgC/EQhVubSAGQ6Ozk6IdxHSzt1mR0EI= -golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292 h1:f+lwQ+GtmgoY+A2YaQxlSOnDjXcQ7ZRLWOHbC6HtRqE= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -969,8 +970,9 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1147,6 +1149,7 @@ golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211213223007-03aa0b5f6827/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 h1:nhht2DYV/Sn3qOayu8lM+cU1ii9sTLUeBQwQQfUHtrs= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -1265,8 +1268,9 @@ golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.9-0.20211228192929-ee1ca4ffc4da/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -golang.org/x/tools v0.1.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8= golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1474,8 +1478,8 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.2.2 h1:MNh1AVMyVX23VUHE2O27jm6lNj3vjO5DexS4A1xvnzk= honnef.co/go/tools v0.2.2/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= -mvdan.cc/gofumpt v0.2.1 h1:7jakRGkQcLAJdT+C8Bwc9d0BANkVPSkHZkzNv07pJAs= -mvdan.cc/gofumpt v0.2.1/go.mod h1:a/rvZPhsNaedOJBzqRD9omnwVwHZsBdJirXHa9Gh9Ig= +mvdan.cc/gofumpt v0.3.0 h1:kTojdZo9AcEYbQYhGuLf/zszYthRdhDNDUi2JKTxas4= +mvdan.cc/gofumpt v0.3.0/go.mod h1:0+VyGZWleeIj5oostkOex+nDBA0eyavuDnDusAJ8ylo= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= diff --git a/metric/go.sum b/metric/go.sum index 5457c7626c5..2bcb4b5e74c 100644 --- a/metric/go.sum +++ b/metric/go.sum @@ -1,14 +1,15 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= diff --git a/schema/go.mod b/schema/go.mod index f98187eeaee..bd5888f698d 100644 --- a/schema/go.mod +++ b/schema/go.mod @@ -4,7 +4,7 @@ go 1.16 require ( github.com/Masterminds/semver/v3 v3.1.1 - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.7.1 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/schema/go.sum b/schema/go.sum index e524be97373..05b233a6568 100644 --- a/schema/go.sum +++ b/schema/go.sum @@ -5,8 +5,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= diff --git a/sdk/export/metric/go.sum b/sdk/export/metric/go.sum index 038e4dbddc8..5f902e9646f 100644 --- a/sdk/export/metric/go.sum +++ b/sdk/export/metric/go.sum @@ -1,8 +1,9 @@ github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= @@ -10,8 +11,8 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/sdk/go.mod b/sdk/go.mod index 37b14cf6120..019a61e12ba 100644 --- a/sdk/go.mod +++ b/sdk/go.mod @@ -5,9 +5,9 @@ go 1.16 replace go.opentelemetry.io/otel => ../ require ( - github.com/go-logr/logr v1.2.2 + github.com/go-logr/logr v1.2.3 github.com/google/go-cmp v0.5.7 - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.7.1 go.opentelemetry.io/otel v1.5.0 go.opentelemetry.io/otel/trace v1.5.0 golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 diff --git a/sdk/go.sum b/sdk/go.sum index 5ba370adf67..46b2d5b84b6 100644 --- a/sdk/go.sum +++ b/sdk/go.sum @@ -1,7 +1,8 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= @@ -9,8 +10,8 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= diff --git a/sdk/metric/go.mod b/sdk/metric/go.mod index 5f4c7f54118..ef2922af43c 100644 --- a/sdk/metric/go.mod +++ b/sdk/metric/go.mod @@ -40,7 +40,7 @@ replace go.opentelemetry.io/otel/trace => ../../trace require ( github.com/benbjohnson/clock v1.3.0 - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.7.1 go.opentelemetry.io/otel v1.5.0 go.opentelemetry.io/otel/metric v0.27.0 go.opentelemetry.io/otel/sdk v1.5.0 diff --git a/sdk/metric/go.sum b/sdk/metric/go.sum index e7e3c1a2040..9ab648da527 100644 --- a/sdk/metric/go.sum +++ b/sdk/metric/go.sum @@ -2,8 +2,9 @@ github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= @@ -11,8 +12,8 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/trace/go.mod b/trace/go.mod index 112d54673bb..050a05e3d83 100644 --- a/trace/go.mod +++ b/trace/go.mod @@ -40,7 +40,7 @@ replace go.opentelemetry.io/otel/trace => ./ require ( github.com/google/go-cmp v0.5.7 - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.7.1 go.opentelemetry.io/otel v1.5.0 ) diff --git a/trace/go.sum b/trace/go.sum index 83b153d9d1c..9b66702ac6a 100644 --- a/trace/go.sum +++ b/trace/go.sum @@ -1,14 +1,15 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= From fdbcf71c8f11616210dea17e20a98b138566c6fb Mon Sep 17 00:00:00 2001 From: Vibhav Pant Date: Mon, 21 Mar 2022 22:09:30 +0530 Subject: [PATCH 26/29] Allow setting the Sampler via environment variables (#2517) * Allow setting the Sampler via environment variables (#2305) * Add changelog entry. * Replace t.Setenv with internaltest/SetEnvVariables for Go <= 1.6. * Handle the lack of a sampler argument without logging errors. * Add additional test cases and error checks. * Refactor documentation. Co-authored-by: Joshua MacDonald * emitBatchOverhead should only be used for splitting spans into batches (#2512) * emitBatchOverhead should only be used for splitting spans into batches (#2503) * limit max packet size parameter * Add additional errors types, simplify abstractions and error handling * Make error comparisons less fragile. * Fix typo in jaeger example (#2524) * Fix some typos in docs for Go libraries (#2520) Co-authored-by: Tyler Yahn * Fix getting-started.md Run function (#2527) * Fix getting-started.md Run function, it assigns this new context to a variable shared between connections in to accept loop. Thus creating a growing chain of contexts. so every calculate fibonacci request, all spans in a trace. * add a comment explaining the reason for that new variable * update example fib * Bump github.com/google/go-cmp from 0.5.6 to 0.5.7 across the project (#2545) * update go-cmp to 0.5.7 * fixes go.sums Co-authored-by: Aaron Clawson * Un-escape url coding when parsing baggage. (#2529) * un-escape url coding when parsing baggage. * Added changelog Co-authored-by: Aaron Clawson Co-authored-by: Tyler Yahn * Bump go.opentelemetry.io/proto/otlp from 0.11.0 to 0.12.0 (#2546) * Update go.opentelemetry.io/proto/otlp to v0.12.0 * Changelog * Update CHANGELOG.md Fix's md linting Co-authored-by: Tyler Yahn Co-authored-by: Aaron Clawson Co-authored-by: Tyler Yahn * Remove unused sdk/internal/santize (#2549) * Add links to code examples and docs (#2551) * Bump github.com/prometheus/client_golang from 1.11.0 to 1.12.0 in /exporters/prometheus (#2541) * Bump github.com/prometheus/client_golang in /exporters/prometheus Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.11.0 to 1.12.0. - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.11.0...v1.12.0) --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * go mod tidy Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Tyler Yahn Co-authored-by: Tyler Yahn * Optimize evictedQueue implementation and use (#2556) * Optimize evictedQueue impl and use Avoid unnecessary allocations in the recordingSpan by using an evictedQueue type instead of a pointer to one. Lazy allocate the evictedQueue queue to prevent unnecessary operations for spans without any use of the queue. Document the evictedQueue * Fix grammar * Add env support for batch span processor (#2515) * Add env support for batch span processor * Update changelog * lint * Bump golang.org/x/tools from 0.1.8 to 0.1.9 in /internal/tools (#2566) * Bump golang.org/x/tools from 0.1.8 to 0.1.9 in /internal/tools Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.1.8 to 0.1.9. - [Release notes](https://github.com/golang/tools/releases) - [Commits](https://github.com/golang/tools/compare/v0.1.8...v0.1.9) --- updated-dependencies: - dependency-name: golang.org/x/tools dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Auto-fix go.sum changes in dependent modules Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: MrAlias * Bump github.com/golangci/golangci-lint from 1.43.0 to 1.44.0 in /internal/tools (#2567) * Bump github.com/golangci/golangci-lint in /internal/tools Bumps [github.com/golangci/golangci-lint](https://github.com/golangci/golangci-lint) from 1.43.0 to 1.44.0. - [Release notes](https://github.com/golangci/golangci-lint/releases) - [Changelog](https://github.com/golangci/golangci-lint/blob/master/CHANGELOG.md) - [Commits](https://github.com/golangci/golangci-lint/compare/v1.43.0...v1.44.0) --- updated-dependencies: - dependency-name: github.com/golangci/golangci-lint dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Auto-fix go.sum changes in dependent modules Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: MrAlias * Bump github.com/prometheus/client_golang from 1.12.0 to 1.12.1 in /exporters/prometheus (#2570) * Bump github.com/prometheus/client_golang in /exporters/prometheus Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.12.0 to 1.12.1. - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.12.0...v1.12.1) --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Auto-fix go.sum changes in dependent modules Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: MrAlias * Fix TestBackoffRetry in otlp/internal/retry package (#2562) * Fix TestBackoffRetry in otlp retry pkg The delay of the retry is within two times a randomization factor (the back-off time is delay * random number within [1 - factor, 1 + factor]. This means the waitFunc in TestBackoffRetry needs to check the delay is within an appropriate delta, not equal to configure initial delay. * Fix delta value * Fix delta Co-authored-by: Aaron Clawson * Bump google.golang.org/grpc from 1.43.0 to 1.44.0 in /exporters/otlp/otlptrace (#2568) * Bump google.golang.org/grpc in /exporters/otlp/otlptrace Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.43.0 to 1.44.0. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.43.0...v1.44.0) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Auto-fix go.sum changes in dependent modules Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: MrAlias * Bump google.golang.org/grpc from 1.43.0 to 1.44.0 in /example/otel-collector (#2565) * Bump google.golang.org/grpc in /example/otel-collector Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.43.0 to 1.44.0. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.43.0...v1.44.0) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Auto-fix go.sum changes in dependent modules Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: MrAlias * Bump google.golang.org/grpc from 1.43.0 to 1.44.0 in /exporters/otlp/otlpmetric (#2572) * Bump google.golang.org/grpc in /exporters/otlp/otlpmetric Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.43.0 to 1.44.0. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.43.0...v1.44.0) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Auto-fix go.sum changes in dependent modules Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: MrAlias * Change Options to accept type not pointer (#2558) * Change trace options to accept type not pointer Add benchmark to show allocation improvement. * Update CONTRIBUTING.md guidelines * Update all Option iface * Fix grammar in CONTRIBUTING * Do not store TracerProvider or Tracer fields in SDK recordingSpan (#2575) * Do not store TracerProvider fields in span Instead of keeping a reference to the span's Tracer, and therefore also it's TracerProvider, and the associated resource and spanLimits just keep the reference to the Tracer. Refer to the TracerProvider fields when needed instead. * Make span refer to the inst lib via the Tracer Instead of holding a field in the span, refer to the field in the parent Tracer. * [website_docs] fix page meta-links (#2580) Contributes to https://github.com/open-telemetry/opentelemetry.io/issues/1096 /cc @cartermp @austinlparker * Validate members once, in `NewMember` (#2522) * use NewMember, or specify if the member is not validated when creating new ones * expect members to already be validated when creating a new package * add changelog entry * add an isEmpty field to member and property for quick validation * rename isEmpty to hasData So by default, an empty struct really is marked as having no data * Update baggage/baggage_test.go Co-authored-by: Aaron Clawson * don't validate the member in parseMember, we alredy ran that validation We also don't want to use NewMember, as that runs the property validation again, making the benchmark quite slower * move changelog entry to the fixed section * provide the member/property data when returning an invalid error Co-authored-by: Aaron Clawson * Fix link to Zipkin exporter (#2581) Currently it is linked to the old package that was moved. * Unexport EnvBatchSpanProcessor* constants (#2583) * Move BSP env support to internal * Use pkg name * Update env test * Use internal/env in sdk/trace * Avoid an extra allocation in applyTracerProviderEnvConfigs. * Add additional errors for ratio > 1.0. * Add test cases for ratio > 1.0. * Update CHANGELOG.md Co-authored-by: Joshua MacDonald Co-authored-by: jaychung Co-authored-by: Ben Wells Co-authored-by: Jeremy Kaplan Co-authored-by: Tyler Yahn Co-authored-by: thinkgo <49174849+thinkgos@users.noreply.github.com> Co-authored-by: Aaron Clawson Co-authored-by: Aaron Clawson Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Tyler Yahn Co-authored-by: Chao Weng <19381524+sincejune@users.noreply.github.com> Co-authored-by: Patrice Chalin Co-authored-by: Damien Mathieu <42@dmathieu.com> --- CHANGELOG.md | 1 + sdk/trace/provider.go | 29 ++++++- sdk/trace/provider_test.go | 165 +++++++++++++++++++++++++++++++++++++ sdk/trace/sampler_env.go | 107 ++++++++++++++++++++++++ 4 files changed, 301 insertions(+), 1 deletion(-) create mode 100644 sdk/trace/sampler_env.go diff --git a/CHANGELOG.md b/CHANGELOG.md index b4c0d047217..137bf9ff910 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ Code instrumented with the `go.opentelemetry.io/otel/metric` will need to be mod ### Added - Add go 1.18 to our compatibility tests. (#2679) +- Allow configuring the Sampler with the `OTEL_TRACES_SAMPLER` and `OTEL_TRACES_SAMPLER_ARG` environment variables. (#2305, #2517) ### Changed diff --git a/sdk/trace/provider.go b/sdk/trace/provider.go index 0643d1a1611..77b86a84feb 100644 --- a/sdk/trace/provider.go +++ b/sdk/trace/provider.go @@ -99,6 +99,7 @@ func NewTracerProvider(opts ...TracerProviderOption) *TracerProvider { o := tracerProviderConfig{ spanLimits: NewSpanLimits(), } + o = applyTracerProviderEnvConfigs(o) for _, opt := range opts { o = opt.apply(o) @@ -335,7 +336,10 @@ func WithIDGenerator(g IDGenerator) TracerProviderOption { // Tracers the TracerProvider creates to make their sampling decisions for the // Spans they create. // -// If this option is not used, the TracerProvider will use a +// This option overrides the Sampler configured through the OTEL_TRACES_SAMPLER +// and OTEL_TRACES_SAMPLER_ARG environment variables. If this option is not used +// and the sampler is not configured through environment variables or the environment +// contains invalid/unsupported configuration, the TracerProvider will use a // ParentBased(AlwaysSample) Sampler by default. func WithSampler(s Sampler) TracerProviderOption { return traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig { @@ -408,6 +412,29 @@ func WithRawSpanLimits(limits SpanLimits) TracerProviderOption { }) } +func applyTracerProviderEnvConfigs(cfg tracerProviderConfig) tracerProviderConfig { + for _, opt := range tracerProviderOptionsFromEnv() { + cfg = opt.apply(cfg) + } + + return cfg +} + +func tracerProviderOptionsFromEnv() []TracerProviderOption { + var opts []TracerProviderOption + + sampler, err := samplerFromEnv() + if err != nil { + otel.Handle(err) + } + + if sampler != nil { + opts = append(opts, WithSampler(sampler)) + } + + return opts +} + // ensureValidTracerProviderConfig ensures that given TracerProviderConfig is valid. func ensureValidTracerProviderConfig(cfg tracerProviderConfig) tracerProviderConfig { if cfg.sampler == nil { diff --git a/sdk/trace/provider_test.go b/sdk/trace/provider_test.go index e2fce31d7f7..0cfe584c926 100644 --- a/sdk/trace/provider_test.go +++ b/sdk/trace/provider_test.go @@ -17,10 +17,14 @@ package trace import ( "context" "errors" + "fmt" + "math/rand" "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + ottest "go.opentelemetry.io/otel/internal/internaltest" "go.opentelemetry.io/otel/trace" ) @@ -94,3 +98,164 @@ func TestSchemaURL(t *testing.T) { tracerStruct := tracerIface.(*tracer) assert.EqualValues(t, schemaURL, tracerStruct.instrumentationLibrary.SchemaURL) } + +func TestTracerProviderSamplerConfigFromEnv(t *testing.T) { + type testCase struct { + sampler string + samplerArg string + argOptional bool + description string + errorType error + invalidArgErrorType interface{} + } + + randFloat := rand.Float64() + + tests := []testCase{ + { + sampler: "invalid-sampler", + argOptional: true, + description: ParentBased(AlwaysSample()).Description(), + errorType: errUnsupportedSampler("invalid-sampler"), + invalidArgErrorType: func() *errUnsupportedSampler { e := errUnsupportedSampler("invalid-sampler"); return &e }(), + }, + { + sampler: "always_on", + argOptional: true, + description: AlwaysSample().Description(), + }, + { + sampler: "always_off", + argOptional: true, + description: NeverSample().Description(), + }, + { + sampler: "traceidratio", + samplerArg: fmt.Sprintf("%g", randFloat), + description: TraceIDRatioBased(randFloat).Description(), + }, + { + sampler: "traceidratio", + samplerArg: fmt.Sprintf("%g", -randFloat), + description: TraceIDRatioBased(1.0).Description(), + errorType: errNegativeTraceIDRatio, + }, + { + sampler: "traceidratio", + samplerArg: fmt.Sprintf("%g", 1+randFloat), + description: TraceIDRatioBased(1.0).Description(), + errorType: errGreaterThanOneTraceIDRatio, + }, + { + sampler: "traceidratio", + argOptional: true, + description: TraceIDRatioBased(1.0).Description(), + invalidArgErrorType: new(samplerArgParseError), + }, + { + sampler: "parentbased_always_on", + argOptional: true, + description: ParentBased(AlwaysSample()).Description(), + }, + { + sampler: "parentbased_always_off", + argOptional: true, + description: ParentBased(NeverSample()).Description(), + }, + { + sampler: "parentbased_traceidratio", + samplerArg: fmt.Sprintf("%g", randFloat), + description: ParentBased(TraceIDRatioBased(randFloat)).Description(), + }, + { + sampler: "parentbased_traceidratio", + samplerArg: fmt.Sprintf("%g", -randFloat), + description: ParentBased(TraceIDRatioBased(1.0)).Description(), + errorType: errNegativeTraceIDRatio, + }, + { + sampler: "parentbased_traceidratio", + samplerArg: fmt.Sprintf("%g", 1+randFloat), + description: ParentBased(TraceIDRatioBased(1.0)).Description(), + errorType: errGreaterThanOneTraceIDRatio, + }, + { + sampler: "parentbased_traceidratio", + argOptional: true, + description: ParentBased(TraceIDRatioBased(1.0)).Description(), + invalidArgErrorType: new(samplerArgParseError), + }, + } + + handler.Reset() + + for _, test := range tests { + t.Run(test.sampler, func(t *testing.T) { + envVars := map[string]string{ + "OTEL_TRACES_SAMPLER": test.sampler, + } + + if test.samplerArg != "" { + envVars["OTEL_TRACES_SAMPLER_ARG"] = test.samplerArg + } + envStore, err := ottest.SetEnvVariables(envVars) + require.NoError(t, err) + t.Cleanup(func() { + handler.Reset() + require.NoError(t, envStore.Restore()) + }) + + stp := NewTracerProvider(WithSyncer(NewTestExporter())) + assert.Equal(t, test.description, stp.sampler.Description()) + if test.errorType != nil { + testStoredError(t, test.errorType) + } else { + assert.Empty(t, handler.errs) + } + + if test.argOptional { + t.Run("invalid sampler arg", func(t *testing.T) { + envStore, err := ottest.SetEnvVariables(map[string]string{ + "OTEL_TRACES_SAMPLER": test.sampler, + "OTEL_TRACES_SAMPLER_ARG": "invalid-ignored-string", + }) + require.NoError(t, err) + t.Cleanup(func() { + handler.Reset() + require.NoError(t, envStore.Restore()) + }) + + stp := NewTracerProvider(WithSyncer(NewTestExporter())) + t.Cleanup(func() { + require.NoError(t, stp.Shutdown(context.Background())) + }) + assert.Equal(t, test.description, stp.sampler.Description()) + + if test.invalidArgErrorType != nil { + testStoredError(t, test.invalidArgErrorType) + } else { + assert.Empty(t, handler.errs) + } + }) + } + }) + } +} + +func testStoredError(t *testing.T, target interface{}) { + t.Helper() + + if assert.Len(t, handler.errs, 1) && assert.Error(t, handler.errs[0]) { + err := handler.errs[0] + + require.Implements(t, (*error)(nil), target) + require.NotNil(t, target.(error)) + + defer handler.Reset() + if errors.Is(err, target.(error)) { + return + } + + assert.ErrorAs(t, err, target) + } +} diff --git a/sdk/trace/sampler_env.go b/sdk/trace/sampler_env.go new file mode 100644 index 00000000000..97f80576e68 --- /dev/null +++ b/sdk/trace/sampler_env.go @@ -0,0 +1,107 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trace // import "go.opentelemetry.io/otel/sdk/trace" + +import ( + "errors" + "fmt" + "os" + "strconv" + "strings" +) + +const ( + tracesSamplerKey = "OTEL_TRACES_SAMPLER" + tracesSamplerArgKey = "OTEL_TRACES_SAMPLER_ARG" + + samplerAlwaysOn = "always_on" + samplerAlwaysOff = "always_off" + samplerTraceIDRatio = "traceidratio" + samplerParentBasedAlwaysOn = "parentbased_always_on" + samplerParsedBasedAlwaysOff = "parentbased_always_off" + samplerParentBasedTraceIDRatio = "parentbased_traceidratio" +) + +type errUnsupportedSampler string + +func (e errUnsupportedSampler) Error() string { + return fmt.Sprintf("unsupported sampler: %s", string(e)) +} + +var ( + errNegativeTraceIDRatio = errors.New("invalid trace ID ratio: less than 0.0") + errGreaterThanOneTraceIDRatio = errors.New("invalid trace ID ratio: greater than 1.0") +) + +type samplerArgParseError struct { + parseErr error +} + +func (e samplerArgParseError) Error() string { + return fmt.Sprintf("parsing sampler argument: %s", e.parseErr.Error()) +} + +func (e samplerArgParseError) Unwrap() error { + return e.parseErr +} + +func samplerFromEnv() (Sampler, error) { + sampler, ok := os.LookupEnv(tracesSamplerKey) + if !ok { + return nil, nil + } + + sampler = strings.ToLower(strings.TrimSpace(sampler)) + samplerArg, hasSamplerArg := os.LookupEnv(tracesSamplerArgKey) + samplerArg = strings.TrimSpace(samplerArg) + + switch sampler { + case samplerAlwaysOn: + return AlwaysSample(), nil + case samplerAlwaysOff: + return NeverSample(), nil + case samplerTraceIDRatio: + ratio, err := parseTraceIDRatio(samplerArg, hasSamplerArg) + return ratio, err + case samplerParentBasedAlwaysOn: + return ParentBased(AlwaysSample()), nil + case samplerParsedBasedAlwaysOff: + return ParentBased(NeverSample()), nil + case samplerParentBasedTraceIDRatio: + ratio, err := parseTraceIDRatio(samplerArg, hasSamplerArg) + return ParentBased(ratio), err + default: + return nil, errUnsupportedSampler(sampler) + } + +} + +func parseTraceIDRatio(arg string, hasSamplerArg bool) (Sampler, error) { + if !hasSamplerArg { + return TraceIDRatioBased(1.0), nil + } + v, err := strconv.ParseFloat(arg, 64) + if err != nil { + return TraceIDRatioBased(1.0), samplerArgParseError{err} + } + if v < 0.0 { + return TraceIDRatioBased(1.0), errNegativeTraceIDRatio + } + if v > 1.0 { + return TraceIDRatioBased(1.0), errGreaterThanOneTraceIDRatio + } + + return TraceIDRatioBased(v), nil +} From 6132008a78658465be62f3ff851a7768e186a475 Mon Sep 17 00:00:00 2001 From: Tyler Yahn Date: Mon, 21 Mar 2022 12:38:13 -0700 Subject: [PATCH 27/29] Use upstream dbotconf (#2713) * Add upstream dbotconf dep * Remove local dbotconf * Update Makefile * Run dependabot generation --- .github/dependabot.yml | 131 ++++++++++++++-------------- Makefile | 24 ++--- internal/tools/dbotconf/dbotconf.go | 112 ------------------------ internal/tools/go.mod | 1 + internal/tools/go.sum | 8 +- internal/tools/tools.go | 1 + 6 files changed, 79 insertions(+), 198 deletions(-) delete mode 100644 internal/tools/dbotconf/dbotconf.go diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 5e4fc315deb..dd586259af2 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,5 +1,4 @@ -# File generated by "make dependabot-generate"; DO NOT EDIT. - +# File generated by dbotconf; DO NOT EDIT. version: 2 updates: - package-ecosystem: github-actions @@ -7,286 +6,286 @@ updates: labels: - dependencies - actions - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: / labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /bridge/opencensus labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /bridge/opencensus/test labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /bridge/opentracing labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /example/fib labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /example/jaeger labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /example/namedtracer labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /example/opencensus labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /example/otel-collector labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /example/passthrough labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /example/prometheus labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /example/zipkin labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /exporters/jaeger labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /exporters/otlp/internal/retry labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /exporters/otlp/otlpmetric labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /exporters/otlp/otlpmetric/otlpmetricgrpc labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /exporters/otlp/otlpmetric/otlpmetrichttp labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /exporters/otlp/otlptrace labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /exporters/otlp/otlptrace/otlptracegrpc labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /exporters/otlp/otlptrace/otlptracehttp labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /exporters/prometheus labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /exporters/stdout/stdoutmetric labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /exporters/stdout/stdouttrace labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /exporters/zipkin labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /internal/tools labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /metric labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /schema labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /sdk labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /sdk/export/metric labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /sdk/metric labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday - package-ecosystem: gomod directory: /trace labels: - dependencies - go - - "Skip Changelog" + - Skip Changelog schedule: - day: sunday interval: weekly + day: sunday diff --git a/Makefile b/Makefile index bcb3a6d8629..1b80eb72adf 100644 --- a/Makefile +++ b/Makefile @@ -48,7 +48,7 @@ CROSSLINK = $(TOOLS)/crosslink $(TOOLS)/crosslink: PACKAGE=go.opentelemetry.io/otel/$(TOOLS_MOD_DIR)/crosslink DBOTCONF = $(TOOLS)/dbotconf -$(TOOLS)/dbotconf: PACKAGE=go.opentelemetry.io/otel/$(TOOLS_MOD_DIR)/dbotconf +$(TOOLS)/dbotconf: PACKAGE=go.opentelemetry.io/build-tools/dbotconf GOLANGCI_LINT = $(TOOLS)/golangci-lint $(TOOLS)/golangci-lint: PACKAGE=github.com/golangci/golangci-lint/cmd/golangci-lint @@ -178,26 +178,14 @@ license-check: exit 1; \ fi -DEPENDABOT_PATH=./.github/dependabot.yml +DEPENDABOT_CONFIG = .github/dependabot.yml .PHONY: dependabot-check -dependabot-check: - @result=$$( \ - for f in $$( find . -type f -name go.mod -exec dirname {} \; | sed 's/^.//' ); \ - do grep -q "directory: \+$$f" $(DEPENDABOT_PATH) \ - || echo "$$f"; \ - done; \ - ); \ - if [ -n "$$result" ]; then \ - echo "missing dependabot entry:"; echo "$$result"; \ - echo "new modules need to be added to the $(DEPENDABOT_PATH) file"; \ - echo "(run: make dependabot-generate)"; \ - exit 1; \ - fi +dependabot-check: | $(DBOTCONF) + @$(DBOTCONF) verify $(DEPENDABOT_CONFIG) || echo "(run: make dependabot-generate)" .PHONY: dependabot-generate -dependabot-generate: $(DBOTCONF) - @echo "gerating dependabot configuration"; \ - $(DBOTCONF) +dependabot-generate: | $(DBOTCONF) + @$(DBOTCONF) generate > $(DEPENDABOT_CONFIG) .PHONY: check-clean-work-tree check-clean-work-tree: diff --git a/internal/tools/dbotconf/dbotconf.go b/internal/tools/dbotconf/dbotconf.go deleted file mode 100644 index a81a3a83fb9..00000000000 --- a/internal/tools/dbotconf/dbotconf.go +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package main provides a utility to generate a complete dependabot -// configuration for a repository with multiple Go modules. -package main - -import ( - "flag" - "fmt" - "log" - "os" - "path/filepath" - "sort" - "strings" - "text/template" - - "go.opentelemetry.io/otel/internal/tools" - "golang.org/x/mod/modfile" -) - -var configPtr = flag.String("config", "./.github/dependabot.yml", "dependabot configuration path") - -const configTemplate = `# File generated by "make dependabot-generate"; DO NOT EDIT. - -version: 2 -updates: - - package-ecosystem: github-actions - directory: / - labels: - - dependencies - - actions - - "Skip Changelog" - schedule: - day: sunday - interval: weekly -{{- range .}} - - package-ecosystem: gomod - directory: {{.}} - labels: - - dependencies - - go - - "Skip Changelog" - schedule: - day: sunday - interval: weekly -{{- end}} -` - -func gomodDirectories(basePath string, mods []*modfile.File) []string { - var dirs []string - for _, m := range mods { - targetPath := filepath.Dir(m.Syntax.Name) - relPath := strings.TrimPrefix(targetPath, basePath) - if relPath == "" { - relPath = "/" - } - dirs = append(dirs, relPath) - } - sort.Strings(dirs) - return dirs -} - -func generate(path string) error { - tpl, err := template.New("dependabot.yml").Parse(configTemplate) - if err != nil { - return fmt.Errorf("parse template: %w", err) - } - - root, err := tools.FindRepoRoot() - if err != nil { - return fmt.Errorf("find repo root: %w", err) - } - - mods, err := root.FindModules() - if err != nil { - return fmt.Errorf("list modules: %w", err) - } - data := gomodDirectories(string(root), mods) - - f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755) - if err != nil { - return err - } - if err = tpl.Execute(f, data); err != nil { - // Best effort. - _ = f.Close() - return fmt.Errorf("rendering template: %w", err) - } - if err = f.Close(); err != nil { - return fmt.Errorf("closing %s: %w", path, err) - } - return nil -} - -func main() { - flag.Parse() - if err := generate(*configPtr); err != nil { - log.Fatalf("failed to generate dependabot configuration: %v", err) - } -} diff --git a/internal/tools/go.mod b/internal/tools/go.mod index 9ce202b9249..78aee63e85e 100644 --- a/internal/tools/go.mod +++ b/internal/tools/go.mod @@ -9,6 +9,7 @@ require ( github.com/itchyny/gojq v0.12.7 github.com/jcchavezs/porto v0.4.0 github.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad + go.opentelemetry.io/build-tools/dbotconf v0.0.0-20220321164008-b8e03aff061a go.opentelemetry.io/build-tools/multimod v0.0.0-20210920164323-2ceabab23375 go.opentelemetry.io/build-tools/semconvgen v0.0.0-20210920164323-2ceabab23375 golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 diff --git a/internal/tools/go.sum b/internal/tools/go.sum index a579c8d18e7..5f1e09c9329 100644 --- a/internal/tools/go.sum +++ b/internal/tools/go.sum @@ -812,8 +812,9 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/sylvia7788/contextcheck v1.0.4 h1:MsiVqROAdr0efZc/fOCt0c235qm9XJqHtWwM+2h2B04= @@ -894,8 +895,11 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opentelemetry.io/build-tools v0.0.0-20210719163622-92017e64f35b h1:tFMjUqEDGM2F82663yYidqTluwEJmmihk/AXr19J7rI= go.opentelemetry.io/build-tools v0.0.0-20210719163622-92017e64f35b/go.mod h1:zZRrJN8qdwDdPNkCEyww4SW54mM1Da0v9H3TyQet9T4= +go.opentelemetry.io/build-tools v0.0.0-20220304161722-feb5ff5848f1 h1:R/LC1WK1TDCbS2ANSeI2XcKrO5Ym6tx1YCUo+AaiFoE= +go.opentelemetry.io/build-tools v0.0.0-20220304161722-feb5ff5848f1/go.mod h1:qO4vrNgLf0V5FHckLNwEw2CfBTaL8w6pKDm3bF6nhMk= +go.opentelemetry.io/build-tools/dbotconf v0.0.0-20220321164008-b8e03aff061a h1:VCNW72z+YKDAH8O5y+WmMuj2Jlgd+ZG5Abk9xTGw6dQ= +go.opentelemetry.io/build-tools/dbotconf v0.0.0-20220321164008-b8e03aff061a/go.mod h1:/X2uGFIoHCUyQiBqL6pY6AEU2j8q1e+EMWhZlCsY5dk= go.opentelemetry.io/build-tools/multimod v0.0.0-20210920164323-2ceabab23375 h1:5zVDNFcOwiMee9Qm8sH08iw+9cJZk+l/Y3mVa2D/zmM= go.opentelemetry.io/build-tools/multimod v0.0.0-20210920164323-2ceabab23375/go.mod h1:mPh1L/tfTGyVNnSQOTlTSi2CBpci13Ft8jE4Glik2es= go.opentelemetry.io/build-tools/semconvgen v0.0.0-20210920164323-2ceabab23375 h1:EaeArFokiObXc/jkX0Ck3u2d6lWDmeWdEPy2IdlF6iw= diff --git a/internal/tools/tools.go b/internal/tools/tools.go index 2966e7bfd26..53b4a545b23 100644 --- a/internal/tools/tools.go +++ b/internal/tools/tools.go @@ -24,6 +24,7 @@ import ( _ "github.com/itchyny/gojq" _ "github.com/jcchavezs/porto/cmd/porto" _ "github.com/wadey/gocovmerge" + _ "go.opentelemetry.io/build-tools/dbotconf" _ "go.opentelemetry.io/build-tools/multimod" _ "go.opentelemetry.io/build-tools/semconvgen" _ "golang.org/x/tools/cmd/stringer" From 9a51174e633d309ed922b9e69f3bff644a096008 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 16:18:20 -0400 Subject: [PATCH 28/29] Bump actions/cache from 2.1.7 to 3 (#2714) Bumps [actions/cache](https://github.com/actions/cache) from 2.1.7 to 3. - [Release notes](https://github.com/actions/cache/releases) - [Commits](https://github.com/actions/cache/compare/v2.1.7...v3) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/benchmark.yml | 2 +- .github/workflows/ci.yml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 8366db387dd..5328bd89576 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -17,7 +17,7 @@ jobs: - name: Run benchmarks run: make test-bench | tee output.txt - name: Download previous benchmark data - uses: actions/cache@v2.1.7 + uses: actions/cache@v3 with: path: ./benchmarks key: ${{ runner.os }}-benchmark diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1c16023015b..a5126759634 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,14 +24,14 @@ jobs: echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV echo "$(go env GOPATH)/bin" >> $GITHUB_PATH - name: Module cache - uses: actions/cache@v2.1.7 + uses: actions/cache@v3 env: cache-name: go-mod-cache with: path: ~/go/pkg/mod key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/go.sum') }} - name: Tools cache - uses: actions/cache@v2.1.7 + uses: actions/cache@v3 env: cache-name: go-tools-cache with: @@ -58,7 +58,7 @@ jobs: echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV echo "$(go env GOPATH)/bin" >> $GITHUB_PATH - name: Module cache - uses: actions/cache@v2.1.7 + uses: actions/cache@v3 env: cache-name: go-mod-cache with: @@ -81,7 +81,7 @@ jobs: echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV echo "$(go env GOPATH)/bin" >> $GITHUB_PATH - name: Module cache - uses: actions/cache@v2.1.7 + uses: actions/cache@v3 env: cache-name: go-mod-cache with: @@ -134,7 +134,7 @@ jobs: echo "$(go env GOPATH)/bin" >> $GITHUB_PATH shell: bash - name: Module cache - uses: actions/cache@v2.1.7 + uses: actions/cache@v3 env: cache-name: go-mod-cache with: From 8a7dcd9650c9f44cc514575a5d011bbb5f91a7c3 Mon Sep 17 00:00:00 2001 From: Aaron Clawson <3766680+MadVikingGod@users.noreply.github.com> Date: Tue, 22 Mar 2022 10:33:13 -0500 Subject: [PATCH 29/29] Adds metrics Global (#2660) * WIP: add global API * WIP * Add a global meter. * moved global access out of metric because of loop imports * fix linting issues * remove changes from other lint failures. * Add changelog * Fixes for comments. Changed name of global API. Added stop to all race tests go routine. Added race tests for other instruments. * Apply suggestions from code review Co-authored-by: Tyler Yahn * Consolidated instrument tests * fixed lint, and removed unneeded type checking * change require's to asserts. * Update misspelling Co-authored-by: Tyler Yahn * Fix meter race test. * Copy SetTracerProvider logic. * Fix global test for panic. * Fix linting error * bump testify version * moved changelog into unreleased Co-authored-by: Aaron Clawson Co-authored-by: Tyler Yahn --- CHANGELOG.md | 1 + metric/global/global.go | 31 ++ metric/go.mod | 5 +- metric/go.sum | 3 + metric/internal/global/instruments.go | 341 +++++++++++++++++++++ metric/internal/global/instruments_test.go | 171 +++++++++++ metric/internal/global/meter.go | 327 ++++++++++++++++++++ metric/internal/global/meter_test.go | 265 ++++++++++++++++ metric/internal/global/meter_types_test.go | 158 ++++++++++ metric/internal/global/state.go | 59 ++++ metric/internal/global/state_test.go | 68 ++++ 11 files changed, 1428 insertions(+), 1 deletion(-) create mode 100644 metric/global/global.go create mode 100644 metric/internal/global/instruments.go create mode 100644 metric/internal/global/instruments_test.go create mode 100644 metric/internal/global/meter.go create mode 100644 metric/internal/global/meter_test.go create mode 100644 metric/internal/global/meter_types_test.go create mode 100644 metric/internal/global/state.go create mode 100644 metric/internal/global/state_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 137bf9ff910..c6465e99e34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ Code instrumented with the `go.opentelemetry.io/otel/metric` will need to be mod - Add go 1.18 to our compatibility tests. (#2679) - Allow configuring the Sampler with the `OTEL_TRACES_SAMPLER` and `OTEL_TRACES_SAMPLER_ARG` environment variables. (#2305, #2517) +- Add the `metric/global` for obtaining and setting the global `MeterProvider` (#2660) ### Changed diff --git a/metric/global/global.go b/metric/global/global.go new file mode 100644 index 00000000000..8578c99ae5a --- /dev/null +++ b/metric/global/global.go @@ -0,0 +1,31 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package global // import "go.opentelemetry.io/otel/metric/global" + +import ( + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/metric/internal/global" +) + +// MeterProvider returns the registered global trace provider. +// If none is registered then a No-op MeterProvider is returned. +func MeterProvider() metric.MeterProvider { + return global.MeterProvider() +} + +// SetMeterProvider registers `mp` as the global meter provider. +func SetMeterProvider(mp metric.MeterProvider) { + global.SetMeterProvider(mp) +} diff --git a/metric/go.mod b/metric/go.mod index 188c44326eb..9714c1150a6 100644 --- a/metric/go.mod +++ b/metric/go.mod @@ -2,7 +2,10 @@ module go.opentelemetry.io/otel/metric go 1.16 -require go.opentelemetry.io/otel v1.5.0 +require ( + github.com/stretchr/testify v1.7.1 + go.opentelemetry.io/otel v1.5.0 +) replace go.opentelemetry.io/otel => ../ diff --git a/metric/go.sum b/metric/go.sum index 2bcb4b5e74c..f2ec9b9fab0 100644 --- a/metric/go.sum +++ b/metric/go.sum @@ -1,7 +1,9 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= @@ -11,6 +13,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/metric/internal/global/instruments.go b/metric/internal/global/instruments.go new file mode 100644 index 00000000000..6b2004af65f --- /dev/null +++ b/metric/internal/global/instruments.go @@ -0,0 +1,341 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package global // import "go.opentelemetry.io/otel/metric/internal/global" + +import ( + "context" + "sync/atomic" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/metric/instrument" + "go.opentelemetry.io/otel/metric/instrument/asyncfloat64" + "go.opentelemetry.io/otel/metric/instrument/asyncint64" + "go.opentelemetry.io/otel/metric/instrument/syncfloat64" + "go.opentelemetry.io/otel/metric/instrument/syncint64" +) + +type afCounter struct { + name string + opts []instrument.Option + + delegate atomic.Value //asyncfloat64.Counter + + instrument.Asynchronous +} + +func (i *afCounter) setDelegate(m metric.Meter) { + + ctr, err := m.AsyncFloat64().Counter(i.name, i.opts...) + if err != nil { + otel.Handle(err) + return + } + i.delegate.Store(ctr) + +} + +func (i *afCounter) Observe(ctx context.Context, x float64, attrs ...attribute.KeyValue) { + if ctr := i.delegate.Load(); ctr != nil { + ctr.(asyncfloat64.Counter).Observe(ctx, x, attrs...) + } +} + +type afUpDownCounter struct { + name string + opts []instrument.Option + + delegate atomic.Value //asyncfloat64.UpDownCounter + + instrument.Asynchronous +} + +func (i *afUpDownCounter) setDelegate(m metric.Meter) { + + ctr, err := m.AsyncFloat64().UpDownCounter(i.name, i.opts...) + if err != nil { + otel.Handle(err) + return + } + i.delegate.Store(ctr) + +} + +func (i *afUpDownCounter) Observe(ctx context.Context, x float64, attrs ...attribute.KeyValue) { + if ctr := i.delegate.Load(); ctr != nil { + ctr.(asyncfloat64.UpDownCounter).Observe(ctx, x, attrs...) + } +} + +type afGauge struct { + name string + opts []instrument.Option + + delegate atomic.Value //asyncfloat64.Gauge + + instrument.Asynchronous +} + +func (i *afGauge) setDelegate(m metric.Meter) { + + ctr, err := m.AsyncFloat64().Gauge(i.name, i.opts...) + if err != nil { + otel.Handle(err) + return + } + i.delegate.Store(ctr) + +} + +func (i *afGauge) Observe(ctx context.Context, x float64, attrs ...attribute.KeyValue) { + if ctr := i.delegate.Load(); ctr != nil { + ctr.(asyncfloat64.Gauge).Observe(ctx, x, attrs...) + } +} + +type aiCounter struct { + name string + opts []instrument.Option + + delegate atomic.Value //asyncint64.Counter + + instrument.Asynchronous +} + +func (i *aiCounter) setDelegate(m metric.Meter) { + + ctr, err := m.AsyncInt64().Counter(i.name, i.opts...) + if err != nil { + otel.Handle(err) + return + } + i.delegate.Store(ctr) + +} + +func (i *aiCounter) Observe(ctx context.Context, x int64, attrs ...attribute.KeyValue) { + if ctr := i.delegate.Load(); ctr != nil { + ctr.(asyncint64.Counter).Observe(ctx, x, attrs...) + } +} + +type aiUpDownCounter struct { + name string + opts []instrument.Option + + delegate atomic.Value //asyncint64.UpDownCounter + + instrument.Asynchronous +} + +func (i *aiUpDownCounter) setDelegate(m metric.Meter) { + + ctr, err := m.AsyncInt64().UpDownCounter(i.name, i.opts...) + if err != nil { + otel.Handle(err) + return + } + i.delegate.Store(ctr) + +} + +func (i *aiUpDownCounter) Observe(ctx context.Context, x int64, attrs ...attribute.KeyValue) { + if ctr := i.delegate.Load(); ctr != nil { + ctr.(asyncint64.UpDownCounter).Observe(ctx, x, attrs...) + } +} + +type aiGauge struct { + name string + opts []instrument.Option + + delegate atomic.Value //asyncint64.Gauge + + instrument.Asynchronous +} + +func (i *aiGauge) setDelegate(m metric.Meter) { + + ctr, err := m.AsyncInt64().Gauge(i.name, i.opts...) + if err != nil { + otel.Handle(err) + return + } + i.delegate.Store(ctr) + +} + +func (i *aiGauge) Observe(ctx context.Context, x int64, attrs ...attribute.KeyValue) { + if ctr := i.delegate.Load(); ctr != nil { + ctr.(asyncint64.Gauge).Observe(ctx, x, attrs...) + } +} + +//Sync Instruments +type sfCounter struct { + name string + opts []instrument.Option + + delegate atomic.Value //syncfloat64.Counter + + instrument.Synchronous +} + +func (i *sfCounter) setDelegate(m metric.Meter) { + + ctr, err := m.SyncFloat64().Counter(i.name, i.opts...) + if err != nil { + otel.Handle(err) + return + } + i.delegate.Store(ctr) + +} + +func (i *sfCounter) Add(ctx context.Context, incr float64, attrs ...attribute.KeyValue) { + if ctr := i.delegate.Load(); ctr != nil { + ctr.(syncfloat64.Counter).Add(ctx, incr, attrs...) + } +} + +type sfUpDownCounter struct { + name string + opts []instrument.Option + + delegate atomic.Value //syncfloat64.UpDownCounter + + instrument.Synchronous +} + +func (i *sfUpDownCounter) setDelegate(m metric.Meter) { + + ctr, err := m.SyncFloat64().UpDownCounter(i.name, i.opts...) + if err != nil { + otel.Handle(err) + return + } + i.delegate.Store(ctr) + +} + +func (i *sfUpDownCounter) Add(ctx context.Context, incr float64, attrs ...attribute.KeyValue) { + if ctr := i.delegate.Load(); ctr != nil { + ctr.(syncfloat64.UpDownCounter).Add(ctx, incr, attrs...) + } +} + +type sfHistogram struct { + name string + opts []instrument.Option + + delegate atomic.Value //syncfloat64.Histogram + + instrument.Synchronous +} + +func (i *sfHistogram) setDelegate(m metric.Meter) { + ctr, err := m.SyncFloat64().Histogram(i.name, i.opts...) + if err != nil { + otel.Handle(err) + return + } + i.delegate.Store(ctr) + +} + +func (i *sfHistogram) Record(ctx context.Context, x float64, attrs ...attribute.KeyValue) { + if ctr := i.delegate.Load(); ctr != nil { + ctr.(syncfloat64.Histogram).Record(ctx, x, attrs...) + } +} + +type siCounter struct { + name string + opts []instrument.Option + + delegate atomic.Value //syncint64.Counter + + instrument.Synchronous +} + +func (i *siCounter) setDelegate(m metric.Meter) { + + ctr, err := m.SyncInt64().Counter(i.name, i.opts...) + if err != nil { + otel.Handle(err) + return + } + i.delegate.Store(ctr) + +} + +func (i *siCounter) Add(ctx context.Context, x int64, attrs ...attribute.KeyValue) { + if ctr := i.delegate.Load(); ctr != nil { + ctr.(syncint64.Counter).Add(ctx, x, attrs...) + } +} + +type siUpDownCounter struct { + name string + opts []instrument.Option + + delegate atomic.Value //syncint64.UpDownCounter + + instrument.Synchronous +} + +func (i *siUpDownCounter) setDelegate(m metric.Meter) { + + ctr, err := m.SyncInt64().UpDownCounter(i.name, i.opts...) + if err != nil { + otel.Handle(err) + return + } + i.delegate.Store(ctr) + +} + +func (i *siUpDownCounter) Add(ctx context.Context, x int64, attrs ...attribute.KeyValue) { + if ctr := i.delegate.Load(); ctr != nil { + ctr.(syncint64.UpDownCounter).Add(ctx, x, attrs...) + } +} + +type siHistogram struct { + name string + opts []instrument.Option + + delegate atomic.Value //syncint64.Histogram + + instrument.Synchronous +} + +func (i *siHistogram) setDelegate(m metric.Meter) { + + ctr, err := m.SyncInt64().Histogram(i.name, i.opts...) + if err != nil { + otel.Handle(err) + return + } + i.delegate.Store(ctr) + +} + +func (i *siHistogram) Record(ctx context.Context, x int64, attrs ...attribute.KeyValue) { + if ctr := i.delegate.Load(); ctr != nil { + ctr.(syncint64.Histogram).Record(ctx, x, attrs...) + } +} diff --git a/metric/internal/global/instruments_test.go b/metric/internal/global/instruments_test.go new file mode 100644 index 00000000000..33c88f6b6f1 --- /dev/null +++ b/metric/internal/global/instruments_test.go @@ -0,0 +1,171 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package global + +import ( + "context" + "testing" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/metric/instrument" + "go.opentelemetry.io/otel/metric/nonrecording" +) + +func testFloat64Race(interact func(context.Context, float64, ...attribute.KeyValue), setDelegate func(metric.Meter)) { + finish := make(chan struct{}) + go func() { + for { + interact(context.Background(), 1) + select { + case <-finish: + return + default: + } + } + }() + + setDelegate(nonrecording.NewNoopMeter()) + close(finish) +} + +func testInt64Race(interact func(context.Context, int64, ...attribute.KeyValue), setDelegate func(metric.Meter)) { + finish := make(chan struct{}) + go func() { + for { + interact(context.Background(), 1) + select { + case <-finish: + return + default: + } + } + }() + + setDelegate(nonrecording.NewNoopMeter()) + close(finish) +} + +func TestAsyncInstrumentSetDelegateRace(t *testing.T) { + // Float64 Instruments + t.Run("Float64", func(t *testing.T) { + t.Run("Counter", func(t *testing.T) { + delegate := &afCounter{} + testFloat64Race(delegate.Observe, delegate.setDelegate) + }) + + t.Run("UpDownCounter", func(t *testing.T) { + delegate := &afUpDownCounter{} + testFloat64Race(delegate.Observe, delegate.setDelegate) + }) + + t.Run("Gauge", func(t *testing.T) { + delegate := &afGauge{} + testFloat64Race(delegate.Observe, delegate.setDelegate) + }) + }) + + // Int64 Instruments + + t.Run("Int64", func(t *testing.T) { + t.Run("Counter", func(t *testing.T) { + delegate := &aiCounter{} + testInt64Race(delegate.Observe, delegate.setDelegate) + }) + + t.Run("UpDownCounter", func(t *testing.T) { + delegate := &aiUpDownCounter{} + testInt64Race(delegate.Observe, delegate.setDelegate) + }) + + t.Run("Gauge", func(t *testing.T) { + delegate := &aiGauge{} + testInt64Race(delegate.Observe, delegate.setDelegate) + }) + }) +} + +func TestSyncInstrumentSetDelegateRace(t *testing.T) { + // Float64 Instruments + t.Run("Float64", func(t *testing.T) { + t.Run("Counter", func(t *testing.T) { + delegate := &sfCounter{} + testFloat64Race(delegate.Add, delegate.setDelegate) + }) + + t.Run("UpDownCounter", func(t *testing.T) { + delegate := &sfUpDownCounter{} + testFloat64Race(delegate.Add, delegate.setDelegate) + }) + + t.Run("Histogram", func(t *testing.T) { + delegate := &sfHistogram{} + testFloat64Race(delegate.Record, delegate.setDelegate) + }) + }) + + // Int64 Instruments + + t.Run("Int64", func(t *testing.T) { + t.Run("Counter", func(t *testing.T) { + delegate := &siCounter{} + testInt64Race(delegate.Add, delegate.setDelegate) + }) + + t.Run("UpDownCounter", func(t *testing.T) { + delegate := &siUpDownCounter{} + testInt64Race(delegate.Add, delegate.setDelegate) + }) + + t.Run("Histogram", func(t *testing.T) { + delegate := &siHistogram{} + testInt64Race(delegate.Record, delegate.setDelegate) + }) + }) +} + +type testCountingFloatInstrument struct { + count int + + instrument.Asynchronous + instrument.Synchronous +} + +func (i *testCountingFloatInstrument) Observe(context.Context, float64, ...attribute.KeyValue) { + i.count++ +} +func (i *testCountingFloatInstrument) Add(context.Context, float64, ...attribute.KeyValue) { + i.count++ +} +func (i *testCountingFloatInstrument) Record(context.Context, float64, ...attribute.KeyValue) { + i.count++ +} + +type testCountingIntInstrument struct { + count int + + instrument.Asynchronous + instrument.Synchronous +} + +func (i *testCountingIntInstrument) Observe(context.Context, int64, ...attribute.KeyValue) { + i.count++ +} +func (i *testCountingIntInstrument) Add(context.Context, int64, ...attribute.KeyValue) { + i.count++ +} +func (i *testCountingIntInstrument) Record(context.Context, int64, ...attribute.KeyValue) { + i.count++ +} diff --git a/metric/internal/global/meter.go b/metric/internal/global/meter.go new file mode 100644 index 00000000000..9001ae9427b --- /dev/null +++ b/metric/internal/global/meter.go @@ -0,0 +1,327 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package global // import "go.opentelemetry.io/otel/metric/internal/global" + +import ( + "context" + "sync" + "sync/atomic" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/metric/instrument" + "go.opentelemetry.io/otel/metric/instrument/asyncfloat64" + "go.opentelemetry.io/otel/metric/instrument/asyncint64" + "go.opentelemetry.io/otel/metric/instrument/syncfloat64" + "go.opentelemetry.io/otel/metric/instrument/syncint64" +) + +// meterProvider is a placeholder for a configured SDK MeterProvider. +// +// All MeterProvider functionality is forwarded to a delegate once +// configured. +type meterProvider struct { + mtx sync.Mutex + meters map[il]*meter + + delegate metric.MeterProvider +} + +type il struct { + name string + version string +} + +// setDelegate configures p to delegate all MeterProvider functionality to +// provider. +// +// All Meters provided prior to this function call are switched out to be +// Meters provided by provider. All instruments and callbacks are recreated and +// delegated. +// +// It is guaranteed by the caller that this happens only once. +func (p *meterProvider) setDelegate(provider metric.MeterProvider) { + p.mtx.Lock() + defer p.mtx.Unlock() + + p.delegate = provider + + if len(p.meters) == 0 { + return + } + + for _, meter := range p.meters { + meter.setDelegate(provider) + } + + p.meters = nil +} + +// Meter implements MeterProvider. +func (p *meterProvider) Meter(name string, opts ...metric.MeterOption) metric.Meter { + p.mtx.Lock() + defer p.mtx.Unlock() + + if p.delegate != nil { + return p.delegate.Meter(name, opts...) + } + + // At this moment it is guaranteed that no sdk is installed, save the meter in the meters map. + + c := metric.NewMeterConfig(opts...) + key := il{ + name: name, + version: c.InstrumentationVersion(), + } + + if p.meters == nil { + p.meters = make(map[il]*meter) + } + + if val, ok := p.meters[key]; ok { + return val + } + + t := &meter{name: name, opts: opts} + p.meters[key] = t + return t +} + +// meter is a placeholder for a metric.Meter. +// +// All Meter functionality is forwarded to a delegate once configured. +// Otherwise, all functionality is forwarded to a NoopMeter. +type meter struct { + name string + opts []metric.MeterOption + + mtx sync.Mutex + instruments []delegatedInstrument + callbacks []delegatedCallback + + delegate atomic.Value // metric.Meter +} + +type delegatedInstrument interface { + setDelegate(metric.Meter) +} + +// setDelegate configures m to delegate all Meter functionality to Meters +// created by provider. +// +// All subsequent calls to the Meter methods will be passed to the delegate. +// +// It is guaranteed by the caller that this happens only once. +func (m *meter) setDelegate(provider metric.MeterProvider) { + meter := provider.Meter(m.name, m.opts...) + m.delegate.Store(meter) + + m.mtx.Lock() + defer m.mtx.Unlock() + + for _, inst := range m.instruments { + inst.setDelegate(meter) + } + + for _, callback := range m.callbacks { + callback.setDelegate(meter) + } + + m.instruments = nil + m.callbacks = nil +} + +// AsyncInt64 is the namespace for the Asynchronous Integer instruments. +// +// To Observe data with instruments it must be registered in a callback. +func (m *meter) AsyncInt64() asyncint64.InstrumentProvider { + if del, ok := m.delegate.Load().(metric.Meter); ok { + return del.AsyncInt64() + } + return (*aiInstProvider)(m) +} + +// AsyncFloat64 is the namespace for the Asynchronous Float instruments. +// +// To Observe data with instruments it must be registered in a callback. +func (m *meter) AsyncFloat64() asyncfloat64.InstrumentProvider { + if del, ok := m.delegate.Load().(metric.Meter); ok { + return del.AsyncFloat64() + } + return (*afInstProvider)(m) +} + +// RegisterCallback captures the function that will be called during Collect. +// +// It is only valid to call Observe within the scope of the passed function, +// and only on the instruments that were registered with this call. +func (m *meter) RegisterCallback(insts []instrument.Asynchronous, function func(context.Context)) error { + if del, ok := m.delegate.Load().(metric.Meter); ok { + return del.RegisterCallback(insts, function) + } + + m.mtx.Lock() + defer m.mtx.Unlock() + m.callbacks = append(m.callbacks, delegatedCallback{ + instruments: insts, + function: function, + }) + + return nil +} + +// SyncInt64 is the namespace for the Synchronous Integer instruments +func (m *meter) SyncInt64() syncint64.InstrumentProvider { + if del, ok := m.delegate.Load().(metric.Meter); ok { + return del.SyncInt64() + } + return (*siInstProvider)(m) +} + +// SyncFloat64 is the namespace for the Synchronous Float instruments +func (m *meter) SyncFloat64() syncfloat64.InstrumentProvider { + if del, ok := m.delegate.Load().(metric.Meter); ok { + return del.SyncFloat64() + } + return (*sfInstProvider)(m) +} + +type delegatedCallback struct { + instruments []instrument.Asynchronous + function func(context.Context) +} + +func (c *delegatedCallback) setDelegate(m metric.Meter) { + err := m.RegisterCallback(c.instruments, c.function) + if err != nil { + otel.Handle(err) + } +} + +type afInstProvider meter + +// Counter creates an instrument for recording increasing values. +func (ip *afInstProvider) Counter(name string, opts ...instrument.Option) (asyncfloat64.Counter, error) { + ip.mtx.Lock() + defer ip.mtx.Unlock() + ctr := &afCounter{name: name, opts: opts} + ip.instruments = append(ip.instruments, ctr) + return ctr, nil +} + +// UpDownCounter creates an instrument for recording changes of a value. +func (ip *afInstProvider) UpDownCounter(name string, opts ...instrument.Option) (asyncfloat64.UpDownCounter, error) { + ip.mtx.Lock() + defer ip.mtx.Unlock() + ctr := &afUpDownCounter{name: name, opts: opts} + ip.instruments = append(ip.instruments, ctr) + return ctr, nil +} + +// Gauge creates an instrument for recording the current value. +func (ip *afInstProvider) Gauge(name string, opts ...instrument.Option) (asyncfloat64.Gauge, error) { + ip.mtx.Lock() + defer ip.mtx.Unlock() + ctr := &afGauge{name: name, opts: opts} + ip.instruments = append(ip.instruments, ctr) + return ctr, nil +} + +type aiInstProvider meter + +// Counter creates an instrument for recording increasing values. +func (ip *aiInstProvider) Counter(name string, opts ...instrument.Option) (asyncint64.Counter, error) { + ip.mtx.Lock() + defer ip.mtx.Unlock() + ctr := &aiCounter{name: name, opts: opts} + ip.instruments = append(ip.instruments, ctr) + return ctr, nil +} + +// UpDownCounter creates an instrument for recording changes of a value. +func (ip *aiInstProvider) UpDownCounter(name string, opts ...instrument.Option) (asyncint64.UpDownCounter, error) { + ip.mtx.Lock() + defer ip.mtx.Unlock() + ctr := &aiUpDownCounter{name: name, opts: opts} + ip.instruments = append(ip.instruments, ctr) + return ctr, nil +} + +// Gauge creates an instrument for recording the current value. +func (ip *aiInstProvider) Gauge(name string, opts ...instrument.Option) (asyncint64.Gauge, error) { + ip.mtx.Lock() + defer ip.mtx.Unlock() + ctr := &aiGauge{name: name, opts: opts} + ip.instruments = append(ip.instruments, ctr) + return ctr, nil +} + +type sfInstProvider meter + +// Counter creates an instrument for recording increasing values. +func (ip *sfInstProvider) Counter(name string, opts ...instrument.Option) (syncfloat64.Counter, error) { + ip.mtx.Lock() + defer ip.mtx.Unlock() + ctr := &sfCounter{name: name, opts: opts} + ip.instruments = append(ip.instruments, ctr) + return ctr, nil +} + +// UpDownCounter creates an instrument for recording changes of a value. +func (ip *sfInstProvider) UpDownCounter(name string, opts ...instrument.Option) (syncfloat64.UpDownCounter, error) { + ip.mtx.Lock() + defer ip.mtx.Unlock() + ctr := &sfUpDownCounter{name: name, opts: opts} + ip.instruments = append(ip.instruments, ctr) + return ctr, nil +} + +// Histogram creates an instrument for recording a distribution of values. +func (ip *sfInstProvider) Histogram(name string, opts ...instrument.Option) (syncfloat64.Histogram, error) { + ip.mtx.Lock() + defer ip.mtx.Unlock() + ctr := &sfHistogram{name: name, opts: opts} + ip.instruments = append(ip.instruments, ctr) + return ctr, nil +} + +type siInstProvider meter + +// Counter creates an instrument for recording increasing values. +func (ip *siInstProvider) Counter(name string, opts ...instrument.Option) (syncint64.Counter, error) { + ip.mtx.Lock() + defer ip.mtx.Unlock() + ctr := &siCounter{name: name, opts: opts} + ip.instruments = append(ip.instruments, ctr) + return ctr, nil +} + +// UpDownCounter creates an instrument for recording changes of a value. +func (ip *siInstProvider) UpDownCounter(name string, opts ...instrument.Option) (syncint64.UpDownCounter, error) { + ip.mtx.Lock() + defer ip.mtx.Unlock() + ctr := &siUpDownCounter{name: name, opts: opts} + ip.instruments = append(ip.instruments, ctr) + return ctr, nil +} + +// Histogram creates an instrument for recording a distribution of values. +func (ip *siInstProvider) Histogram(name string, opts ...instrument.Option) (syncint64.Histogram, error) { + ip.mtx.Lock() + defer ip.mtx.Unlock() + ctr := &siHistogram{name: name, opts: opts} + ip.instruments = append(ip.instruments, ctr) + return ctr, nil +} diff --git a/metric/internal/global/meter_test.go b/metric/internal/global/meter_test.go new file mode 100644 index 00000000000..481c55e2273 --- /dev/null +++ b/metric/internal/global/meter_test.go @@ -0,0 +1,265 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package global // import "go.opentelemetry.io/otel/metric/internal/global" + +import ( + "context" + "fmt" + "sync" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/metric/instrument" + "go.opentelemetry.io/otel/metric/instrument/asyncfloat64" + "go.opentelemetry.io/otel/metric/instrument/syncfloat64" + "go.opentelemetry.io/otel/metric/nonrecording" +) + +func TestMeterProviderRace(t *testing.T) { + mp := &meterProvider{} + finish := make(chan struct{}) + go func() { + for i := 0; ; i++ { + mp.Meter(fmt.Sprintf("a%d", i)) + select { + case <-finish: + return + default: + } + } + }() + + mp.setDelegate(nonrecording.NewNoopMeterProvider()) + close(finish) + +} + +func TestMeterRace(t *testing.T) { + mtr := &meter{} + + wg := &sync.WaitGroup{} + wg.Add(1) + finish := make(chan struct{}) + go func() { + for i, once := 0, false; ; i++ { + name := fmt.Sprintf("a%d", i) + _, _ = mtr.AsyncFloat64().Counter(name) + _, _ = mtr.AsyncFloat64().UpDownCounter(name) + _, _ = mtr.AsyncFloat64().Gauge(name) + _, _ = mtr.AsyncInt64().Counter(name) + _, _ = mtr.AsyncInt64().UpDownCounter(name) + _, _ = mtr.AsyncInt64().Gauge(name) + _, _ = mtr.SyncFloat64().Counter(name) + _, _ = mtr.SyncFloat64().UpDownCounter(name) + _, _ = mtr.SyncFloat64().Histogram(name) + _, _ = mtr.SyncInt64().Counter(name) + _, _ = mtr.SyncInt64().UpDownCounter(name) + _, _ = mtr.SyncInt64().Histogram(name) + _ = mtr.RegisterCallback(nil, func(ctx context.Context) {}) + if !once { + wg.Done() + once = true + } + select { + case <-finish: + return + default: + } + } + }() + + wg.Wait() + mtr.setDelegate(nonrecording.NewNoopMeterProvider()) + close(finish) +} + +func testSetupAllInstrumentTypes(t *testing.T, m metric.Meter) (syncfloat64.Counter, asyncfloat64.Counter) { + + afcounter, err := m.AsyncFloat64().Counter("test_Async_Counter") + require.NoError(t, err) + _, err = m.AsyncFloat64().UpDownCounter("test_Async_UpDownCounter") + assert.NoError(t, err) + _, err = m.AsyncFloat64().Gauge("test_Async_Gauge") + assert.NoError(t, err) + + _, err = m.AsyncInt64().Counter("test_Async_Counter") + assert.NoError(t, err) + _, err = m.AsyncInt64().UpDownCounter("test_Async_UpDownCounter") + assert.NoError(t, err) + _, err = m.AsyncInt64().Gauge("test_Async_Gauge") + assert.NoError(t, err) + + require.NoError(t, m.RegisterCallback([]instrument.Asynchronous{afcounter}, func(ctx context.Context) { + afcounter.Observe(ctx, 3) + })) + + sfcounter, err := m.SyncFloat64().Counter("test_Async_Counter") + require.NoError(t, err) + _, err = m.SyncFloat64().UpDownCounter("test_Async_UpDownCounter") + assert.NoError(t, err) + _, err = m.SyncFloat64().Histogram("test_Async_Histogram") + assert.NoError(t, err) + + _, err = m.SyncInt64().Counter("test_Async_Counter") + assert.NoError(t, err) + _, err = m.SyncInt64().UpDownCounter("test_Async_UpDownCounter") + assert.NoError(t, err) + _, err = m.SyncInt64().Histogram("test_Async_Histogram") + assert.NoError(t, err) + + return sfcounter, afcounter +} + +// This is to emulate a read from an exporter. +func testCollect(t *testing.T, m metric.Meter) { + if tMeter, ok := m.(*meter); ok { + m, ok = tMeter.delegate.Load().(metric.Meter) + if !ok { + t.Error("meter was not delegated") + return + } + } + tMeter, ok := m.(*testMeter) + if !ok { + t.Error("collect called on non-test Meter") + return + } + tMeter.collect() +} + +func TestMeterProviderDelegatesCalls(t *testing.T) { + + // The global MeterProvider should directly call the underlying MeterProvider + // if it is set prior to Meter() being called. + + // globalMeterProvider := otel.GetMeterProvider + globalMeterProvider := &meterProvider{} + + mp := &testMeterProvider{} + + // otel.SetMeterProvider(mp) + globalMeterProvider.setDelegate(mp) + + assert.Equal(t, 0, mp.count) + + meter := globalMeterProvider.Meter("go.opentelemetry.io/otel/metric/internal/global/meter_test") + + ctr, actr := testSetupAllInstrumentTypes(t, meter) + + ctr.Add(context.Background(), 5) + + testCollect(t, meter) // This is a hacky way to emulate a read from an exporter + + // Calls to Meter() after setDelegate() should be executed by the delegate + require.IsType(t, &testMeter{}, meter) + tMeter := meter.(*testMeter) + assert.Equal(t, 3, tMeter.afCount) + assert.Equal(t, 3, tMeter.aiCount) + assert.Equal(t, 3, tMeter.sfCount) + assert.Equal(t, 3, tMeter.siCount) + assert.Equal(t, 1, len(tMeter.callbacks)) + + // Because the Meter was provided by testmeterProvider it should also return our test instrument + require.IsType(t, &testCountingFloatInstrument{}, ctr, "the meter did not delegate calls to the meter") + assert.Equal(t, 1, ctr.(*testCountingFloatInstrument).count) + + require.IsType(t, &testCountingFloatInstrument{}, actr, "the meter did not delegate calls to the meter") + assert.Equal(t, 1, actr.(*testCountingFloatInstrument).count) + + assert.Equal(t, 1, mp.count) +} + +func TestMeterDelegatesCalls(t *testing.T) { + + // The global MeterProvider should directly provide a Meter instance that + // can be updated. If the SetMeterProvider is called after a Meter was + // obtained, but before instruments only the instrument should be generated + // by the delegated type. + + globalMeterProvider := &meterProvider{} + + mp := &testMeterProvider{} + + assert.Equal(t, 0, mp.count) + + m := globalMeterProvider.Meter("go.opentelemetry.io/otel/metric/internal/global/meter_test") + + globalMeterProvider.setDelegate(mp) + + ctr, actr := testSetupAllInstrumentTypes(t, m) + + ctr.Add(context.Background(), 5) + + testCollect(t, m) // This is a hacky way to emulate a read from an exporter + + // Calls to Meter methods after setDelegate() should be executed by the delegate + require.IsType(t, &meter{}, m) + tMeter := m.(*meter).delegate.Load().(*testMeter) + require.NotNil(t, tMeter) + assert.Equal(t, 3, tMeter.afCount) + assert.Equal(t, 3, tMeter.aiCount) + assert.Equal(t, 3, tMeter.sfCount) + assert.Equal(t, 3, tMeter.siCount) + + // Because the Meter was provided by testmeterProvider it should also return our test instrument + require.IsType(t, &testCountingFloatInstrument{}, ctr, "the meter did not delegate calls to the meter") + assert.Equal(t, 1, ctr.(*testCountingFloatInstrument).count) + + // Because the Meter was provided by testmeterProvider it should also return our test instrument + require.IsType(t, &testCountingFloatInstrument{}, actr, "the meter did not delegate calls to the meter") + assert.Equal(t, 1, actr.(*testCountingFloatInstrument).count) + + assert.Equal(t, 1, mp.count) +} + +func TestMeterDefersDelegations(t *testing.T) { + + // If SetMeterProvider is called after instruments are registered, the + // instruments should be recreated with the new meter. + + // globalMeterProvider := otel.GetMeterProvider + globalMeterProvider := &meterProvider{} + + m := globalMeterProvider.Meter("go.opentelemetry.io/otel/metric/internal/global/meter_test") + + ctr, actr := testSetupAllInstrumentTypes(t, m) + + ctr.Add(context.Background(), 5) + + mp := &testMeterProvider{} + + // otel.SetMeterProvider(mp) + globalMeterProvider.setDelegate(mp) + + testCollect(t, m) // This is a hacky way to emulate a read from an exporter + + // Calls to Meter() before setDelegate() should be the delegated type + require.IsType(t, &meter{}, m) + tMeter := m.(*meter).delegate.Load().(*testMeter) + require.NotNil(t, tMeter) + assert.Equal(t, 3, tMeter.afCount) + assert.Equal(t, 3, tMeter.aiCount) + assert.Equal(t, 3, tMeter.sfCount) + assert.Equal(t, 3, tMeter.siCount) + + // Because the Meter was a delegate it should return a delegated instrument + + assert.IsType(t, &sfCounter{}, ctr) + assert.IsType(t, &afCounter{}, actr) + assert.Equal(t, 1, mp.count) +} diff --git a/metric/internal/global/meter_types_test.go b/metric/internal/global/meter_types_test.go new file mode 100644 index 00000000000..acd07de1847 --- /dev/null +++ b/metric/internal/global/meter_types_test.go @@ -0,0 +1,158 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package global // import "go.opentelemetry.io/otel/metric/internal/global" + +import ( + "context" + + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/metric/instrument" + "go.opentelemetry.io/otel/metric/instrument/asyncfloat64" + "go.opentelemetry.io/otel/metric/instrument/asyncint64" + "go.opentelemetry.io/otel/metric/instrument/syncfloat64" + "go.opentelemetry.io/otel/metric/instrument/syncint64" +) + +type testMeterProvider struct { + count int +} + +func (p *testMeterProvider) Meter(name string, opts ...metric.MeterOption) metric.Meter { + p.count++ + + return &testMeter{} +} + +type testMeter struct { + afCount int + aiCount int + sfCount int + siCount int + + callbacks []func(context.Context) +} + +// AsyncInt64 is the namespace for the Asynchronous Integer instruments. +// +// To Observe data with instruments it must be registered in a callback. +func (m *testMeter) AsyncInt64() asyncint64.InstrumentProvider { + m.aiCount++ + return &testAIInstrumentProvider{} +} + +// AsyncFloat64 is the namespace for the Asynchronous Float instruments +// +// To Observe data with instruments it must be registered in a callback. +func (m *testMeter) AsyncFloat64() asyncfloat64.InstrumentProvider { + m.afCount++ + return &testAFInstrumentProvider{} +} + +// RegisterCallback captures the function that will be called during Collect. +// +// It is only valid to call Observe within the scope of the passed function, +// and only on the instruments that were registered with this call. +func (m *testMeter) RegisterCallback(insts []instrument.Asynchronous, function func(context.Context)) error { + m.callbacks = append(m.callbacks, function) + return nil +} + +// SyncInt64 is the namespace for the Synchronous Integer instruments +func (m *testMeter) SyncInt64() syncint64.InstrumentProvider { + m.siCount++ + return &testSIInstrumentProvider{} +} + +// SyncFloat64 is the namespace for the Synchronous Float instruments +func (m *testMeter) SyncFloat64() syncfloat64.InstrumentProvider { + m.sfCount++ + return &testSFInstrumentProvider{} +} + +// This enables async collection +func (m *testMeter) collect() { + ctx := context.Background() + for _, f := range m.callbacks { + f(ctx) + } +} + +type testAFInstrumentProvider struct{} + +// Counter creates an instrument for recording increasing values. +func (ip testAFInstrumentProvider) Counter(name string, opts ...instrument.Option) (asyncfloat64.Counter, error) { + return &testCountingFloatInstrument{}, nil +} + +// UpDownCounter creates an instrument for recording changes of a value. +func (ip testAFInstrumentProvider) UpDownCounter(name string, opts ...instrument.Option) (asyncfloat64.UpDownCounter, error) { + return &testCountingFloatInstrument{}, nil +} + +// Gauge creates an instrument for recording the current value. +func (ip testAFInstrumentProvider) Gauge(name string, opts ...instrument.Option) (asyncfloat64.Gauge, error) { + return &testCountingFloatInstrument{}, nil +} + +type testAIInstrumentProvider struct{} + +// Counter creates an instrument for recording increasing values. +func (ip testAIInstrumentProvider) Counter(name string, opts ...instrument.Option) (asyncint64.Counter, error) { + return &testCountingIntInstrument{}, nil +} + +// UpDownCounter creates an instrument for recording changes of a value. +func (ip testAIInstrumentProvider) UpDownCounter(name string, opts ...instrument.Option) (asyncint64.UpDownCounter, error) { + return &testCountingIntInstrument{}, nil +} + +// Gauge creates an instrument for recording the current value. +func (ip testAIInstrumentProvider) Gauge(name string, opts ...instrument.Option) (asyncint64.Gauge, error) { + return &testCountingIntInstrument{}, nil +} + +type testSFInstrumentProvider struct{} + +// Counter creates an instrument for recording increasing values. +func (ip testSFInstrumentProvider) Counter(name string, opts ...instrument.Option) (syncfloat64.Counter, error) { + return &testCountingFloatInstrument{}, nil +} + +// UpDownCounter creates an instrument for recording changes of a value. +func (ip testSFInstrumentProvider) UpDownCounter(name string, opts ...instrument.Option) (syncfloat64.UpDownCounter, error) { + return &testCountingFloatInstrument{}, nil +} + +// Histogram creates an instrument for recording a distribution of values. +func (ip testSFInstrumentProvider) Histogram(name string, opts ...instrument.Option) (syncfloat64.Histogram, error) { + return &testCountingFloatInstrument{}, nil +} + +type testSIInstrumentProvider struct{} + +// Counter creates an instrument for recording increasing values. +func (ip testSIInstrumentProvider) Counter(name string, opts ...instrument.Option) (syncint64.Counter, error) { + return &testCountingIntInstrument{}, nil +} + +// UpDownCounter creates an instrument for recording changes of a value. +func (ip testSIInstrumentProvider) UpDownCounter(name string, opts ...instrument.Option) (syncint64.UpDownCounter, error) { + return &testCountingIntInstrument{}, nil +} + +// Histogram creates an instrument for recording a distribution of values. +func (ip testSIInstrumentProvider) Histogram(name string, opts ...instrument.Option) (syncint64.Histogram, error) { + return &testCountingIntInstrument{}, nil +} diff --git a/metric/internal/global/state.go b/metric/internal/global/state.go new file mode 100644 index 00000000000..29a67c5dbe4 --- /dev/null +++ b/metric/internal/global/state.go @@ -0,0 +1,59 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// htmp://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package global // import "go.opentelemetry.io/otel/metric/internal/global" + +import ( + "sync" + "sync/atomic" + + "go.opentelemetry.io/otel/metric" +) + +var ( + globalMeterProvider = defaultMeterProvider() + + delegateMeterOnce sync.Once +) + +type meterProviderHolder struct { + mp metric.MeterProvider +} + +// MeterProvider is the internal implementation for global.MeterProvider. +func MeterProvider() metric.MeterProvider { + return globalMeterProvider.Load().(meterProviderHolder).mp +} + +// SetMeterProvider is the internal implementation for global.SetMeterProvider. +func SetMeterProvider(mp metric.MeterProvider) { + delegateMeterOnce.Do(func() { + current := MeterProvider() + if current == mp { + // Setting the provider to the prior default is nonsense, panic. + // Panic is acceptable because we are likely still early in the + // process lifetime. + panic("invalid MeterProvider, the global instance cannot be reinstalled") + } else if def, ok := current.(*meterProvider); ok { + def.setDelegate(mp) + } + }) + globalMeterProvider.Store(meterProviderHolder{mp: mp}) +} + +func defaultMeterProvider() *atomic.Value { + v := &atomic.Value{} + v.Store(meterProviderHolder{mp: &meterProvider{}}) + return v +} diff --git a/metric/internal/global/state_test.go b/metric/internal/global/state_test.go new file mode 100644 index 00000000000..69cb9b917d6 --- /dev/null +++ b/metric/internal/global/state_test.go @@ -0,0 +1,68 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// htmp://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package global // import "go.opentelemetry.io/otel/metric/internal/global" + +import ( + "sync" + "testing" + + "github.com/stretchr/testify/assert" + + "go.opentelemetry.io/otel/metric/nonrecording" +) + +func resetGlobalMeterProvider() { + globalMeterProvider = defaultMeterProvider() + delegateMeterOnce = sync.Once{} +} + +func TestSetMeterProvider(t *testing.T) { + t.Cleanup(resetGlobalMeterProvider) + + t.Run("Set With default panics", func(t *testing.T) { + resetGlobalMeterProvider() + + assert.Panics(t, func() { + SetMeterProvider(MeterProvider()) + }) + + }) + + t.Run("First Set() should replace the delegate", func(t *testing.T) { + resetGlobalMeterProvider() + + SetMeterProvider(nonrecording.NewNoopMeterProvider()) + + _, ok := MeterProvider().(*meterProvider) + if ok { + t.Error("Global Meter Provider was not changed") + return + } + }) + + t.Run("Set() should delegate existing Meter Providers", func(t *testing.T) { + resetGlobalMeterProvider() + + mp := MeterProvider() + + SetMeterProvider(nonrecording.NewNoopMeterProvider()) + + dmp := mp.(*meterProvider) + + if dmp.delegate == nil { + t.Error("The delegated meter providers should have a delegate") + } + }) +}