From f1f9b7a9e9e54ae8eff5ef9324bcaf2a438c6649 Mon Sep 17 00:00:00 2001 From: Wise-Wizard Date: Wed, 19 Jun 2024 22:44:04 +0530 Subject: [PATCH 01/16] Instantiated OTEL Metrics Signed-off-by: Wise-Wizard --- pkg/metrics/factory.go | 45 ++++++++++++++++++++++++++++++++++++++ pkg/metrics/otelCounter.go | 28 ++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 pkg/metrics/otelCounter.go diff --git a/pkg/metrics/factory.go b/pkg/metrics/factory.go index b1b9000a285..1eadfc19a95 100644 --- a/pkg/metrics/factory.go +++ b/pkg/metrics/factory.go @@ -16,7 +16,11 @@ package metrics import ( + "context" "time" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/metric" ) // NSOptions defines the name and tags map associated with a factory namespace @@ -48,6 +52,47 @@ type HistogramOptions struct { Buckets []float64 } +type otelFactory struct { + meter metric.Meter +} + +func NewOTelFactory() Factory { + return &otelFactory{ + meter: otel.Meter("jaeger-V2"), + } +} + +func (f *otelFactory) Counter(options Options) Counter { + counter, _ := f.meter.Int64Counter(options.Name) + attrs := getAttributes(options.Tags) + return &otelCounter{ + counter: counter, + ctx: context.Background(), + attrs: attrs, + } +} + +func (f *otelFactory) Timer(options TimerOptions) Timer { + // Implement the OTEL Timer + return NullTimer +} + +func (f *otelFactory) Gauge(options Options) Gauge { + // Implement the OTEL Gauge + return NullGauge +} + +func (f *otelFactory) Histogram(options HistogramOptions) Histogram { + // Implement the OTEL Histogram + return NullHistogram +} + +func (f *otelFactory) Namespace(scope NSOptions) Factory { + return &otelFactory{ + meter: otel.Meter(scope.Name), + } +} + // Factory creates new metrics type Factory interface { Counter(metric Options) Counter diff --git a/pkg/metrics/otelCounter.go b/pkg/metrics/otelCounter.go new file mode 100644 index 00000000000..6f426111696 --- /dev/null +++ b/pkg/metrics/otelCounter.go @@ -0,0 +1,28 @@ +package metrics + +import ( + "context" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" +) + +// otelCounter is a wrapper around otel.Counter + +type otelCounter struct { + counter metric.Int64Counter + ctx context.Context + attrs []metric.AddOption +} + +func (c *otelCounter) Inc(value int64) { + c.counter.Add(c.ctx, value, c.attrs...) +} + +func getAttributes(tags map[string]string) []metric.AddOption { + var options []metric.AddOption + for k, v := range tags { + options = append(options, metric.WithAttributes(attribute.String(k, v))) + } + return options +} From 12403b18b335440adbeb32237e4df02223418b87 Mon Sep 17 00:00:00 2001 From: Wise-Wizard Date: Wed, 19 Jun 2024 22:57:26 +0530 Subject: [PATCH 02/16] Ran make fmt Signed-off-by: Wise-Wizard --- pkg/metrics/otelCounter.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pkg/metrics/otelCounter.go b/pkg/metrics/otelCounter.go index 6f426111696..4caac6b9224 100644 --- a/pkg/metrics/otelCounter.go +++ b/pkg/metrics/otelCounter.go @@ -1,3 +1,6 @@ +// Copyright (c) 2024 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + package metrics import ( @@ -10,9 +13,9 @@ import ( // otelCounter is a wrapper around otel.Counter type otelCounter struct { - counter metric.Int64Counter - ctx context.Context - attrs []metric.AddOption + counter metric.Int64Counter + ctx context.Context + attrs []metric.AddOption } func (c *otelCounter) Inc(value int64) { From 0a073b65aff149d46e86f003ca1a4992bf05e0fb Mon Sep 17 00:00:00 2001 From: Wise-Wizard Date: Fri, 21 Jun 2024 14:25:15 +0530 Subject: [PATCH 03/16] Create otelmetrics package Signed-off-by: Wise-Wizard --- pkg/metrics/factory.go | 45 -------------------------- pkg/metrics/otelCounter.go | 31 ------------------ pkg/metrics/otelmetrics/factory.go | 32 ++++++++++++++++++ pkg/metrics/otelmetrics/otelCounter.go | 37 +++++++++++++++++++++ 4 files changed, 69 insertions(+), 76 deletions(-) delete mode 100644 pkg/metrics/otelCounter.go create mode 100644 pkg/metrics/otelmetrics/factory.go create mode 100644 pkg/metrics/otelmetrics/otelCounter.go diff --git a/pkg/metrics/factory.go b/pkg/metrics/factory.go index 1eadfc19a95..b1b9000a285 100644 --- a/pkg/metrics/factory.go +++ b/pkg/metrics/factory.go @@ -16,11 +16,7 @@ package metrics import ( - "context" "time" - - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/metric" ) // NSOptions defines the name and tags map associated with a factory namespace @@ -52,47 +48,6 @@ type HistogramOptions struct { Buckets []float64 } -type otelFactory struct { - meter metric.Meter -} - -func NewOTelFactory() Factory { - return &otelFactory{ - meter: otel.Meter("jaeger-V2"), - } -} - -func (f *otelFactory) Counter(options Options) Counter { - counter, _ := f.meter.Int64Counter(options.Name) - attrs := getAttributes(options.Tags) - return &otelCounter{ - counter: counter, - ctx: context.Background(), - attrs: attrs, - } -} - -func (f *otelFactory) Timer(options TimerOptions) Timer { - // Implement the OTEL Timer - return NullTimer -} - -func (f *otelFactory) Gauge(options Options) Gauge { - // Implement the OTEL Gauge - return NullGauge -} - -func (f *otelFactory) Histogram(options HistogramOptions) Histogram { - // Implement the OTEL Histogram - return NullHistogram -} - -func (f *otelFactory) Namespace(scope NSOptions) Factory { - return &otelFactory{ - meter: otel.Meter(scope.Name), - } -} - // Factory creates new metrics type Factory interface { Counter(metric Options) Counter diff --git a/pkg/metrics/otelCounter.go b/pkg/metrics/otelCounter.go deleted file mode 100644 index 4caac6b9224..00000000000 --- a/pkg/metrics/otelCounter.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2024 The Jaeger Authors. -// SPDX-License-Identifier: Apache-2.0 - -package metrics - -import ( - "context" - - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric" -) - -// otelCounter is a wrapper around otel.Counter - -type otelCounter struct { - counter metric.Int64Counter - ctx context.Context - attrs []metric.AddOption -} - -func (c *otelCounter) Inc(value int64) { - c.counter.Add(c.ctx, value, c.attrs...) -} - -func getAttributes(tags map[string]string) []metric.AddOption { - var options []metric.AddOption - for k, v := range tags { - options = append(options, metric.WithAttributes(attribute.String(k, v))) - } - return options -} diff --git a/pkg/metrics/otelmetrics/factory.go b/pkg/metrics/otelmetrics/factory.go new file mode 100644 index 00000000000..e57de719a29 --- /dev/null +++ b/pkg/metrics/otelmetrics/factory.go @@ -0,0 +1,32 @@ +package otelmetrics + +import "github.com/jaegertracing/jaeger/pkg/metrics" + +type otelFactory struct{} + +func NewOTELFactory() metrics.Factory { + return &otelFactory{} +} + +func (f *otelFactory) Counter(opts metrics.Options) metrics.Counter { + return newOtelCounter(opts.Name, opts.Tags) +} + +func (f *otelFactory) Gauge(opts metrics.Options) metrics.Gauge { + // TODO: Implement OTEL Gauge + return nil +} + +func (f *otelFactory) Timer(opts metrics.TimerOptions) metrics.Timer { + // TODO: Implement OTEL Timer + return nil +} + +func (f *otelFactory) Histogram(opts metrics.HistogramOptions) metrics.Histogram { + // TODO: Implement OTEL Histogram + return nil +} + +func (f *otelFactory) Namespace(opts metrics.NSOptions) metrics.Factory { + return f +} diff --git a/pkg/metrics/otelmetrics/otelCounter.go b/pkg/metrics/otelmetrics/otelCounter.go new file mode 100644 index 00000000000..971071bd3f7 --- /dev/null +++ b/pkg/metrics/otelmetrics/otelCounter.go @@ -0,0 +1,37 @@ +package otelmetrics + +import ( + "context" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" +) + +type otelCounter struct { + counter metric.Int64Counter + attributeSet attribute.Set +} + +func newOtelCounter(name string, tags map[string]string) *otelCounter { + meter := otel.Meter("jaeger-V2") + counter, err := meter.Int64Counter(name) + if err != nil { + panic(err) + } + + attributes := make([]attribute.KeyValue, 0, len(tags)) + for k, v := range tags { + attributes = append(attributes, attribute.String(k, v)) + } + attributeSet := attribute.NewSet(attributes...) + + return &otelCounter{ + counter: counter, + attributeSet: attributeSet, + } +} + +func (c *otelCounter) Inc(value int64) { + c.counter.Add(context.Background(), value, metric.WithAttributeSet(c.attributeSet)) +} From 7efd9b90558cfe32b5c9a3a485c0c81216524140 Mon Sep 17 00:00:00 2001 From: Saransh Shankar <103821431+Wise-Wizard@users.noreply.github.com> Date: Fri, 21 Jun 2024 19:26:37 +0530 Subject: [PATCH 04/16] Update pkg/metrics/otelmetrics/factory.go Co-authored-by: Yuri Shkuro Signed-off-by: Saransh Shankar <103821431+Wise-Wizard@users.noreply.github.com> --- pkg/metrics/otelmetrics/factory.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/metrics/otelmetrics/factory.go b/pkg/metrics/otelmetrics/factory.go index e57de719a29..b4dce7acfe0 100644 --- a/pkg/metrics/otelmetrics/factory.go +++ b/pkg/metrics/otelmetrics/factory.go @@ -4,7 +4,7 @@ import "github.com/jaegertracing/jaeger/pkg/metrics" type otelFactory struct{} -func NewOTELFactory() metrics.Factory { +func NewFactory() metrics.Factory { return &otelFactory{} } From a70d64a6ccd05402ab9f2c4e38ff42c719e141a0 Mon Sep 17 00:00:00 2001 From: Wise-Wizard Date: Sat, 22 Jun 2024 23:06:41 +0530 Subject: [PATCH 05/16] Created benchmark to compare metric implementation Signed-off-by: Wise-Wizard --- internal/metrics/benchmark_test.go | 32 ++++++++++++++++ .../metrics/otelmetrics/factory.go | 23 +++++++++++- internal/metrics/otelmetrics/otelCounter.go | 17 +++++++++ pkg/metrics/otelmetrics/otelCounter.go | 37 ------------------- 4 files changed, 70 insertions(+), 39 deletions(-) create mode 100644 internal/metrics/benchmark_test.go rename {pkg => internal}/metrics/otelmetrics/factory.go (54%) create mode 100644 internal/metrics/otelmetrics/otelCounter.go delete mode 100644 pkg/metrics/otelmetrics/otelCounter.go diff --git a/internal/metrics/benchmark_test.go b/internal/metrics/benchmark_test.go new file mode 100644 index 00000000000..b1fe44045c5 --- /dev/null +++ b/internal/metrics/benchmark_test.go @@ -0,0 +1,32 @@ +package benchmark_test + +import ( + "testing" + + "github.com/jaegertracing/jaeger/internal/metrics/otelmetrics" + prom "github.com/jaegertracing/jaeger/internal/metrics/prometheus" + "github.com/jaegertracing/jaeger/pkg/metrics" + "github.com/prometheus/client_golang/prometheus" +) + +func benchmarkCounter(b *testing.B, factory metrics.Factory) { + counter := factory.Counter(metrics.Options{ + Name: "test_counter", + Tags: map[string]string{"tag1": "value1"}, + }) + + for i := 0; i < b.N; i++ { + counter.Inc(1) + } +} + +func BenchmarkPrometheusCounter(b *testing.B) { + reg := prometheus.NewRegistry() + factory := prom.New(prom.WithRegisterer(reg)) + benchmarkCounter(b, factory) +} + +func BenchmarkOTELCounter(b *testing.B) { + factory := otelmetrics.NewOTELFactory() + benchmarkCounter(b, factory) +} diff --git a/pkg/metrics/otelmetrics/factory.go b/internal/metrics/otelmetrics/factory.go similarity index 54% rename from pkg/metrics/otelmetrics/factory.go rename to internal/metrics/otelmetrics/factory.go index e57de719a29..6bbfe953f74 100644 --- a/pkg/metrics/otelmetrics/factory.go +++ b/internal/metrics/otelmetrics/factory.go @@ -1,6 +1,10 @@ package otelmetrics -import "github.com/jaegertracing/jaeger/pkg/metrics" +import ( + "github.com/jaegertracing/jaeger/pkg/metrics" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" +) type otelFactory struct{} @@ -9,7 +13,22 @@ func NewOTELFactory() metrics.Factory { } func (f *otelFactory) Counter(opts metrics.Options) metrics.Counter { - return newOtelCounter(opts.Name, opts.Tags) + meter := otel.Meter("jaeger-V2") + counter, err := meter.Int64Counter(opts.Name) + if err != nil { + panic(err) + } + + attributes := make([]attribute.KeyValue, 0, len(opts.Tags)) + for k, v := range opts.Tags { + attributes = append(attributes, attribute.String(k, v)) + } + attributeSet := attribute.NewSet(attributes...) + + return &otelCounter{ + counter: counter, + attributeSet: attributeSet, + } } func (f *otelFactory) Gauge(opts metrics.Options) metrics.Gauge { diff --git a/internal/metrics/otelmetrics/otelCounter.go b/internal/metrics/otelmetrics/otelCounter.go new file mode 100644 index 00000000000..67a41b36273 --- /dev/null +++ b/internal/metrics/otelmetrics/otelCounter.go @@ -0,0 +1,17 @@ +package otelmetrics + +import ( + "context" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" +) + +type otelCounter struct { + counter metric.Int64Counter + attributeSet attribute.Set +} + +func (c *otelCounter) Inc(value int64) { + c.counter.Add(context.Background(), value, metric.WithAttributeSet(c.attributeSet)) +} diff --git a/pkg/metrics/otelmetrics/otelCounter.go b/pkg/metrics/otelmetrics/otelCounter.go deleted file mode 100644 index 971071bd3f7..00000000000 --- a/pkg/metrics/otelmetrics/otelCounter.go +++ /dev/null @@ -1,37 +0,0 @@ -package otelmetrics - -import ( - "context" - - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric" -) - -type otelCounter struct { - counter metric.Int64Counter - attributeSet attribute.Set -} - -func newOtelCounter(name string, tags map[string]string) *otelCounter { - meter := otel.Meter("jaeger-V2") - counter, err := meter.Int64Counter(name) - if err != nil { - panic(err) - } - - attributes := make([]attribute.KeyValue, 0, len(tags)) - for k, v := range tags { - attributes = append(attributes, attribute.String(k, v)) - } - attributeSet := attribute.NewSet(attributes...) - - return &otelCounter{ - counter: counter, - attributeSet: attributeSet, - } -} - -func (c *otelCounter) Inc(value int64) { - c.counter.Add(context.Background(), value, metric.WithAttributeSet(c.attributeSet)) -} From dc2a9edfe5c398a64fe7003f3ff9e4f92dd5365e Mon Sep 17 00:00:00 2001 From: Wise-Wizard Date: Sat, 22 Jun 2024 23:08:59 +0530 Subject: [PATCH 06/16] Resolved conflicts Signed-off-by: Wise-Wizard --- internal/metrics/benchmark_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/metrics/benchmark_test.go b/internal/metrics/benchmark_test.go index b1fe44045c5..6ee2e5ed131 100644 --- a/internal/metrics/benchmark_test.go +++ b/internal/metrics/benchmark_test.go @@ -27,6 +27,6 @@ func BenchmarkPrometheusCounter(b *testing.B) { } func BenchmarkOTELCounter(b *testing.B) { - factory := otelmetrics.NewOTELFactory() + factory := otelmetrics.NewFactory() benchmarkCounter(b, factory) } From 4a9929151f665d36103bf8a0df0a2f3f43bd0be4 Mon Sep 17 00:00:00 2001 From: Yuri Shkuro Date: Sat, 22 Jun 2024 16:27:26 -0400 Subject: [PATCH 07/16] avoid allocations tested via ``` $ go test -benchmem -benchtime=5s -bench=Benchmark ./internal/metrics/ ``` before: ``` BenchmarkPrometheusCounter-10 856818336 6.875 ns/op 0 B/op 0 allocs/op BenchmarkOTELCounter-10 146044255 40.92 ns/op 32 B/op 2 allocs/op ``` after: `` BenchmarkPrometheusCounter-10 855046669 6.924 ns/op 0 B/op 0 allocs/op BenchmarkOTELCounter-10 293330721 21.05 ns/op 16 B/op 1 allocs/op ``` Signed-off-by: Yuri Shkuro --- internal/metrics/otelmetrics/factory.go | 11 ++++++++--- internal/metrics/otelmetrics/otelCounter.go | 8 ++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/internal/metrics/otelmetrics/factory.go b/internal/metrics/otelmetrics/factory.go index ab846c2e43f..6d76dbeb8b8 100644 --- a/internal/metrics/otelmetrics/factory.go +++ b/internal/metrics/otelmetrics/factory.go @@ -1,9 +1,13 @@ package otelmetrics import ( - "github.com/jaegertracing/jaeger/pkg/metrics" + "context" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" + + "github.com/jaegertracing/jaeger/pkg/metrics" ) type otelFactory struct{} @@ -26,8 +30,9 @@ func (f *otelFactory) Counter(opts metrics.Options) metrics.Counter { attributeSet := attribute.NewSet(attributes...) return &otelCounter{ - counter: counter, - attributeSet: attributeSet, + counter: counter, + fixedCtx: context.Background(), + option: metric.WithAttributeSet(attributeSet), } } diff --git a/internal/metrics/otelmetrics/otelCounter.go b/internal/metrics/otelmetrics/otelCounter.go index 67a41b36273..c66e41c2bdf 100644 --- a/internal/metrics/otelmetrics/otelCounter.go +++ b/internal/metrics/otelmetrics/otelCounter.go @@ -3,15 +3,15 @@ package otelmetrics import ( "context" - "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" ) type otelCounter struct { - counter metric.Int64Counter - attributeSet attribute.Set + counter metric.Int64Counter + fixedCtx context.Context + option metric.AddOption } func (c *otelCounter) Inc(value int64) { - c.counter.Add(context.Background(), value, metric.WithAttributeSet(c.attributeSet)) + c.counter.Add(c.fixedCtx, value, c.option) } From 099ba05d5ed5c29b39a8afebda4d51b885274555 Mon Sep 17 00:00:00 2001 From: Wise-Wizard Date: Sun, 23 Jun 2024 02:14:25 +0530 Subject: [PATCH 08/16] Implemented changes Signed-off-by: Wise-Wizard --- internal/metrics/benchmark_test.go | 6 +++++- .../metrics/otelmetrics/{otelCounter.go => counter.go} | 7 +++++++ internal/metrics/otelmetrics/factory.go | 7 ++++++- 3 files changed, 18 insertions(+), 2 deletions(-) rename internal/metrics/otelmetrics/{otelCounter.go => counter.go} (64%) diff --git a/internal/metrics/benchmark_test.go b/internal/metrics/benchmark_test.go index 6ee2e5ed131..f7d5eadf606 100644 --- a/internal/metrics/benchmark_test.go +++ b/internal/metrics/benchmark_test.go @@ -1,12 +1,16 @@ +// Copyright (c) 2024 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + package benchmark_test import ( "testing" + "github.com/prometheus/client_golang/prometheus" + "github.com/jaegertracing/jaeger/internal/metrics/otelmetrics" prom "github.com/jaegertracing/jaeger/internal/metrics/prometheus" "github.com/jaegertracing/jaeger/pkg/metrics" - "github.com/prometheus/client_golang/prometheus" ) func benchmarkCounter(b *testing.B, factory metrics.Factory) { diff --git a/internal/metrics/otelmetrics/otelCounter.go b/internal/metrics/otelmetrics/counter.go similarity index 64% rename from internal/metrics/otelmetrics/otelCounter.go rename to internal/metrics/otelmetrics/counter.go index c66e41c2bdf..eaaf8c0d966 100644 --- a/internal/metrics/otelmetrics/otelCounter.go +++ b/internal/metrics/otelmetrics/counter.go @@ -1,3 +1,6 @@ +// Copyright (c) 2024 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + package otelmetrics import ( @@ -15,3 +18,7 @@ type otelCounter struct { func (c *otelCounter) Inc(value int64) { c.counter.Add(c.fixedCtx, value, c.option) } + +type noopCounter struct{} + +func (c *noopCounter) Inc(value int64) {} \ No newline at end of file diff --git a/internal/metrics/otelmetrics/factory.go b/internal/metrics/otelmetrics/factory.go index 6d76dbeb8b8..3d58725bd9c 100644 --- a/internal/metrics/otelmetrics/factory.go +++ b/internal/metrics/otelmetrics/factory.go @@ -1,7 +1,11 @@ +// Copyright (c) 2024 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + package otelmetrics import ( "context" + "log" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" @@ -20,7 +24,8 @@ func (f *otelFactory) Counter(opts metrics.Options) metrics.Counter { meter := otel.Meter("jaeger-V2") counter, err := meter.Int64Counter(opts.Name) if err != nil { - panic(err) + log.Printf("Error creating OTEL counter: %v", err) + return &noopCounter{} } attributes := make([]attribute.KeyValue, 0, len(opts.Tags)) From 8b47b1227ef24a3ec0ed5610037045609ed81191 Mon Sep 17 00:00:00 2001 From: Wise-Wizard Date: Sun, 23 Jun 2024 17:20:35 +0530 Subject: [PATCH 09/16] Used metrics.NullCounter as return type Signed-off-by: Wise-Wizard --- internal/metrics/otelmetrics/counter.go | 4 ---- internal/metrics/otelmetrics/factory.go | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/internal/metrics/otelmetrics/counter.go b/internal/metrics/otelmetrics/counter.go index eaaf8c0d966..437442306f3 100644 --- a/internal/metrics/otelmetrics/counter.go +++ b/internal/metrics/otelmetrics/counter.go @@ -18,7 +18,3 @@ type otelCounter struct { func (c *otelCounter) Inc(value int64) { c.counter.Add(c.fixedCtx, value, c.option) } - -type noopCounter struct{} - -func (c *noopCounter) Inc(value int64) {} \ No newline at end of file diff --git a/internal/metrics/otelmetrics/factory.go b/internal/metrics/otelmetrics/factory.go index 3d58725bd9c..d596d558d57 100644 --- a/internal/metrics/otelmetrics/factory.go +++ b/internal/metrics/otelmetrics/factory.go @@ -25,7 +25,7 @@ func (f *otelFactory) Counter(opts metrics.Options) metrics.Counter { counter, err := meter.Int64Counter(opts.Name) if err != nil { log.Printf("Error creating OTEL counter: %v", err) - return &noopCounter{} + return metrics.NullCounter } attributes := make([]attribute.KeyValue, 0, len(opts.Tags)) From 8032ce222db94be81aa4440b88dd4d369482b30a Mon Sep 17 00:00:00 2001 From: Wise-Wizard Date: Sun, 23 Jun 2024 18:16:57 +0530 Subject: [PATCH 10/16] Created rough implementation of OTEL SDK Signed-off-by: Wise-Wizard --- internal/metrics/otelmetrics/factory.go | 32 +++++++++++++++++++------ 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/internal/metrics/otelmetrics/factory.go b/internal/metrics/otelmetrics/factory.go index d596d558d57..6b2d298ee77 100644 --- a/internal/metrics/otelmetrics/factory.go +++ b/internal/metrics/otelmetrics/factory.go @@ -7,22 +7,40 @@ import ( "context" "log" + "github.com/jaegertracing/jaeger/pkg/metrics" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric" - - "github.com/jaegertracing/jaeger/pkg/metrics" + metric "go.opentelemetry.io/otel/metric" + sdkmetric "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/resource" + semconv "go.opentelemetry.io/otel/semconv/v1.4.0" ) -type otelFactory struct{} +type otelFactory struct { + meter metric.Meter +} func NewFactory() metrics.Factory { - return &otelFactory{} + res, err := resource.New(context.Background(), + resource.WithAttributes( + semconv.ServiceNameKey.String("jaeger-V2"), + ), + ) + if err != nil { + log.Fatalf("Could not create resource: %v", err) + } + meterProvider := sdkmetric.NewMeterProvider( + sdkmetric.WithResource(res), + sdkmetric.WithReader(sdkmetric.NewManualReader()), + ) + otel.SetMeterProvider(meterProvider) + return &otelFactory{ + meter: otel.Meter("jaeger-V2"), + } } func (f *otelFactory) Counter(opts metrics.Options) metrics.Counter { - meter := otel.Meter("jaeger-V2") - counter, err := meter.Int64Counter(opts.Name) + counter, err := f.meter.Int64Counter(opts.Name) if err != nil { log.Printf("Error creating OTEL counter: %v", err) return metrics.NullCounter From 6ec5ec4b67136cf01a98508c14855c70951c23a9 Mon Sep 17 00:00:00 2001 From: Wise-Wizard Date: Mon, 24 Jun 2024 12:30:35 +0530 Subject: [PATCH 11/16] Fixed initialization errors Signed-off-by: Wise-Wizard --- internal/metrics/benchmark_test.go | 8 +++++++- internal/metrics/otelmetrics/factory.go | 16 +--------------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/internal/metrics/benchmark_test.go b/internal/metrics/benchmark_test.go index f7d5eadf606..74fd4ca353c 100644 --- a/internal/metrics/benchmark_test.go +++ b/internal/metrics/benchmark_test.go @@ -7,6 +7,8 @@ import ( "testing" "github.com/prometheus/client_golang/prometheus" + "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/resource" "github.com/jaegertracing/jaeger/internal/metrics/otelmetrics" prom "github.com/jaegertracing/jaeger/internal/metrics/prometheus" @@ -31,6 +33,10 @@ func BenchmarkPrometheusCounter(b *testing.B) { } func BenchmarkOTELCounter(b *testing.B) { - factory := otelmetrics.NewFactory() + res := resource.NewWithAttributes( + resource.Default().SchemaURL(), + ) + meterProvider := metric.NewMeterProvider(metric.WithResource(res)) + factory := otelmetrics.NewFactory(meterProvider) benchmarkCounter(b, factory) } diff --git a/internal/metrics/otelmetrics/factory.go b/internal/metrics/otelmetrics/factory.go index 6b2d298ee77..e543c0abe59 100644 --- a/internal/metrics/otelmetrics/factory.go +++ b/internal/metrics/otelmetrics/factory.go @@ -12,27 +12,13 @@ import ( "go.opentelemetry.io/otel/attribute" metric "go.opentelemetry.io/otel/metric" sdkmetric "go.opentelemetry.io/otel/sdk/metric" - "go.opentelemetry.io/otel/sdk/resource" - semconv "go.opentelemetry.io/otel/semconv/v1.4.0" ) type otelFactory struct { meter metric.Meter } -func NewFactory() metrics.Factory { - res, err := resource.New(context.Background(), - resource.WithAttributes( - semconv.ServiceNameKey.String("jaeger-V2"), - ), - ) - if err != nil { - log.Fatalf("Could not create resource: %v", err) - } - meterProvider := sdkmetric.NewMeterProvider( - sdkmetric.WithResource(res), - sdkmetric.WithReader(sdkmetric.NewManualReader()), - ) +func NewFactory(meterProvider *sdkmetric.MeterProvider) metrics.Factory { otel.SetMeterProvider(meterProvider) return &otelFactory{ meter: otel.Meter("jaeger-V2"), From 4e7dcbbd37f4754bd7362fa170ec8059706fdcdd Mon Sep 17 00:00:00 2001 From: Wise-Wizard Date: Mon, 24 Jun 2024 22:33:17 +0530 Subject: [PATCH 12/16] Made suggested changes Signed-off-by: Wise-Wizard --- internal/metrics/benchmark_test.go | 6 +----- internal/metrics/otelmetrics/factory.go | 7 ++----- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/internal/metrics/benchmark_test.go b/internal/metrics/benchmark_test.go index 74fd4ca353c..fa176512e13 100644 --- a/internal/metrics/benchmark_test.go +++ b/internal/metrics/benchmark_test.go @@ -8,7 +8,6 @@ import ( "github.com/prometheus/client_golang/prometheus" "go.opentelemetry.io/otel/sdk/metric" - "go.opentelemetry.io/otel/sdk/resource" "github.com/jaegertracing/jaeger/internal/metrics/otelmetrics" prom "github.com/jaegertracing/jaeger/internal/metrics/prometheus" @@ -33,10 +32,7 @@ func BenchmarkPrometheusCounter(b *testing.B) { } func BenchmarkOTELCounter(b *testing.B) { - res := resource.NewWithAttributes( - resource.Default().SchemaURL(), - ) - meterProvider := metric.NewMeterProvider(metric.WithResource(res)) + meterProvider := metric.NewMeterProvider() factory := otelmetrics.NewFactory(meterProvider) benchmarkCounter(b, factory) } diff --git a/internal/metrics/otelmetrics/factory.go b/internal/metrics/otelmetrics/factory.go index e543c0abe59..6f1ab738c92 100644 --- a/internal/metrics/otelmetrics/factory.go +++ b/internal/metrics/otelmetrics/factory.go @@ -8,20 +8,17 @@ import ( "log" "github.com/jaegertracing/jaeger/pkg/metrics" - "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" metric "go.opentelemetry.io/otel/metric" - sdkmetric "go.opentelemetry.io/otel/sdk/metric" ) type otelFactory struct { meter metric.Meter } -func NewFactory(meterProvider *sdkmetric.MeterProvider) metrics.Factory { - otel.SetMeterProvider(meterProvider) +func NewFactory(meterProvider metric.MeterProvider) metrics.Factory { return &otelFactory{ - meter: otel.Meter("jaeger-V2"), + meter: meterProvider.Meter("jaeger-v2"), } } From f29cad5cac4315a2f30148929c62a6be860fc920 Mon Sep 17 00:00:00 2001 From: Wise-Wizard Date: Tue, 25 Jun 2024 00:21:09 +0530 Subject: [PATCH 13/16] Created Prometheus Exporter Signed-off-by: Wise-Wizard --- internal/metrics/benchmark_test.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/internal/metrics/benchmark_test.go b/internal/metrics/benchmark_test.go index fa176512e13..47336ce02be 100644 --- a/internal/metrics/benchmark_test.go +++ b/internal/metrics/benchmark_test.go @@ -4,14 +4,16 @@ package benchmark_test import ( + "log" "testing" - "github.com/prometheus/client_golang/prometheus" + prometheus "github.com/prometheus/client_golang/prometheus" "go.opentelemetry.io/otel/sdk/metric" "github.com/jaegertracing/jaeger/internal/metrics/otelmetrics" prom "github.com/jaegertracing/jaeger/internal/metrics/prometheus" "github.com/jaegertracing/jaeger/pkg/metrics" + promExporter "go.opentelemetry.io/otel/exporters/prometheus" ) func benchmarkCounter(b *testing.B, factory metrics.Factory) { @@ -32,7 +34,14 @@ func BenchmarkPrometheusCounter(b *testing.B) { } func BenchmarkOTELCounter(b *testing.B) { - meterProvider := metric.NewMeterProvider() + registry := prometheus.NewRegistry() + exporter, err := promExporter.New(promExporter.WithRegisterer(registry)) + if err != nil { + log.Fatalf("Failed to create Prometheus exporter: %v", err) + } + meterProvider := metric.NewMeterProvider( + metric.WithReader(exporter), + ) factory := otelmetrics.NewFactory(meterProvider) benchmarkCounter(b, factory) } From 723d74af6c9f0241bd0530f3f81d28ca20912b95 Mon Sep 17 00:00:00 2001 From: Yuri Shkuro Date: Mon, 24 Jun 2024 18:26:56 -0400 Subject: [PATCH 14/16] OTEL / Prom metrics benchmark Signed-off-by: Yuri Shkuro --- internal/metrics/benchmark_test.go | 70 ++++++++++++++++--------- internal/metrics/otelmetrics/counter.go | 20 ------- internal/metrics/otelmetrics/factory.go | 62 ---------------------- 3 files changed, 46 insertions(+), 106 deletions(-) delete mode 100644 internal/metrics/otelmetrics/counter.go delete mode 100644 internal/metrics/otelmetrics/factory.go diff --git a/internal/metrics/benchmark_test.go b/internal/metrics/benchmark_test.go index 47336ce02be..0468c28d5e3 100644 --- a/internal/metrics/benchmark_test.go +++ b/internal/metrics/benchmark_test.go @@ -4,44 +4,66 @@ package benchmark_test import ( - "log" + "context" "testing" - prometheus "github.com/prometheus/client_golang/prometheus" - "go.opentelemetry.io/otel/sdk/metric" + promsdk "github.com/prometheus/client_golang/prometheus" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" + sdkmetric "go.opentelemetry.io/otel/sdk/metric" - "github.com/jaegertracing/jaeger/internal/metrics/otelmetrics" - prom "github.com/jaegertracing/jaeger/internal/metrics/prometheus" - "github.com/jaegertracing/jaeger/pkg/metrics" promExporter "go.opentelemetry.io/otel/exporters/prometheus" ) -func benchmarkCounter(b *testing.B, factory metrics.Factory) { - counter := factory.Counter(metrics.Options{ +func BenchmarkPrometheusCounter(b *testing.B) { + reg := promsdk.NewRegistry() + opts := promsdk.CounterOpts{ Name: "test_counter", - Tags: map[string]string{"tag1": "value1"}, - }) + Help: "help", + } + cv := promsdk.NewCounterVec(opts, []string{"tag1"}) + reg.MustRegister(cv) + counter := cv.WithLabelValues("value1") + b.ResetTimer() for i := 0; i < b.N; i++ { - counter.Inc(1) + counter.Add(1) } } -func BenchmarkPrometheusCounter(b *testing.B) { - reg := prometheus.NewRegistry() - factory := prom.New(prom.WithRegisterer(reg)) - benchmarkCounter(b, factory) +func BenchmarkOTELCounter(b *testing.B) { + counter := otelCounter(b) + ctx := context.Background() + + b.ResetTimer() + for i := 0; i < b.N; i++ { + counter.Add(ctx, 1) + } } -func BenchmarkOTELCounter(b *testing.B) { - registry := prometheus.NewRegistry() - exporter, err := promExporter.New(promExporter.WithRegisterer(registry)) - if err != nil { - log.Fatalf("Failed to create Prometheus exporter: %v", err) +func BenchmarkOTELCounterWithLabel(b *testing.B) { + counter := otelCounter(b) + ctx := context.Background() + attrSet := attribute.NewSet(attribute.String("tag1", "value1")) + attrOpt := metric.WithAttributeSet(attrSet) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + counter.Add(ctx, 1, attrOpt) } - meterProvider := metric.NewMeterProvider( - metric.WithReader(exporter), +} + +func otelCounter(b *testing.B) metric.Int64Counter { + registry := promsdk.NewRegistry() + exporter, err := promExporter.New(promExporter.WithRegisterer(registry)) + require.NoError(b, err) + meterProvider := sdkmetric.NewMeterProvider( + sdkmetric.WithReader(exporter), ) - factory := otelmetrics.NewFactory(meterProvider) - benchmarkCounter(b, factory) + + meter := meterProvider.Meter("test") + counter, err := meter.Int64Counter("test_counter") + require.NoError(b, err) + return counter } diff --git a/internal/metrics/otelmetrics/counter.go b/internal/metrics/otelmetrics/counter.go deleted file mode 100644 index 437442306f3..00000000000 --- a/internal/metrics/otelmetrics/counter.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) 2024 The Jaeger Authors. -// SPDX-License-Identifier: Apache-2.0 - -package otelmetrics - -import ( - "context" - - "go.opentelemetry.io/otel/metric" -) - -type otelCounter struct { - counter metric.Int64Counter - fixedCtx context.Context - option metric.AddOption -} - -func (c *otelCounter) Inc(value int64) { - c.counter.Add(c.fixedCtx, value, c.option) -} diff --git a/internal/metrics/otelmetrics/factory.go b/internal/metrics/otelmetrics/factory.go deleted file mode 100644 index 6f1ab738c92..00000000000 --- a/internal/metrics/otelmetrics/factory.go +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) 2024 The Jaeger Authors. -// SPDX-License-Identifier: Apache-2.0 - -package otelmetrics - -import ( - "context" - "log" - - "github.com/jaegertracing/jaeger/pkg/metrics" - "go.opentelemetry.io/otel/attribute" - metric "go.opentelemetry.io/otel/metric" -) - -type otelFactory struct { - meter metric.Meter -} - -func NewFactory(meterProvider metric.MeterProvider) metrics.Factory { - return &otelFactory{ - meter: meterProvider.Meter("jaeger-v2"), - } -} - -func (f *otelFactory) Counter(opts metrics.Options) metrics.Counter { - counter, err := f.meter.Int64Counter(opts.Name) - if err != nil { - log.Printf("Error creating OTEL counter: %v", err) - return metrics.NullCounter - } - - attributes := make([]attribute.KeyValue, 0, len(opts.Tags)) - for k, v := range opts.Tags { - attributes = append(attributes, attribute.String(k, v)) - } - attributeSet := attribute.NewSet(attributes...) - - return &otelCounter{ - counter: counter, - fixedCtx: context.Background(), - option: metric.WithAttributeSet(attributeSet), - } -} - -func (f *otelFactory) Gauge(opts metrics.Options) metrics.Gauge { - // TODO: Implement OTEL Gauge - return nil -} - -func (f *otelFactory) Timer(opts metrics.TimerOptions) metrics.Timer { - // TODO: Implement OTEL Timer - return nil -} - -func (f *otelFactory) Histogram(opts metrics.HistogramOptions) metrics.Histogram { - // TODO: Implement OTEL Histogram - return nil -} - -func (f *otelFactory) Namespace(opts metrics.NSOptions) metrics.Factory { - return f -} From c8735f6324dc961b2eebd59d0ba083b25119b5eb Mon Sep 17 00:00:00 2001 From: Yuri Shkuro Date: Wed, 26 Jun 2024 13:55:34 -0400 Subject: [PATCH 15/16] add-census Signed-off-by: Yuri Shkuro --- internal/metrics/benchmark_test.go | 39 ++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/internal/metrics/benchmark_test.go b/internal/metrics/benchmark_test.go index 0468c28d5e3..d852158413d 100644 --- a/internal/metrics/benchmark_test.go +++ b/internal/metrics/benchmark_test.go @@ -10,6 +10,7 @@ import ( promsdk "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/bridge/opencensus" "go.opentelemetry.io/otel/metric" sdkmetric "go.opentelemetry.io/otel/sdk/metric" @@ -42,6 +43,16 @@ func BenchmarkOTELCounter(b *testing.B) { } } +func BenchmarkCencusCounter(b *testing.B) { + counter := censusCounter(b) + ctx := context.Background() + + b.ResetTimer() + for i := 0; i < b.N; i++ { + counter.Add(ctx, 1) + } +} + func BenchmarkOTELCounterWithLabel(b *testing.B) { counter := otelCounter(b) ctx := context.Background() @@ -53,6 +64,17 @@ func BenchmarkOTELCounterWithLabel(b *testing.B) { counter.Add(ctx, 1, attrOpt) } } +func BenchmarkCencusCounterWithLabel(b *testing.B) { + counter := censusCounter(b) + ctx := context.Background() + attrSet := attribute.NewSet(attribute.String("tag1", "value1")) + attrOpt := metric.WithAttributeSet(attrSet) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + counter.Add(ctx, 1, attrOpt) + } +} func otelCounter(b *testing.B) metric.Int64Counter { registry := promsdk.NewRegistry() @@ -67,3 +89,20 @@ func otelCounter(b *testing.B) metric.Int64Counter { require.NoError(b, err) return counter } + +func censusCounter(b *testing.B) metric.Int64Counter { + registry := promsdk.NewRegistry() + exporter, err := promExporter.New( + promExporter.WithRegisterer(registry), + promExporter.WithProducer(opencensus.NewMetricProducer()), + ) + require.NoError(b, err) + meterProvider := sdkmetric.NewMeterProvider( + sdkmetric.WithReader(exporter), + ) + + meter := meterProvider.Meter("test") + counter, err := meter.Int64Counter("test_counter") + require.NoError(b, err) + return counter +} From d04050c276e37787b86c9b1b87c2e56207b766b7 Mon Sep 17 00:00:00 2001 From: Yuri Shkuro Date: Tue, 2 Jul 2024 16:14:45 -0400 Subject: [PATCH 16/16] more Signed-off-by: Yuri Shkuro --- internal/metrics/benchmark_test.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/internal/metrics/benchmark_test.go b/internal/metrics/benchmark_test.go index d852158413d..89fb606e9de 100644 --- a/internal/metrics/benchmark_test.go +++ b/internal/metrics/benchmark_test.go @@ -17,6 +17,29 @@ import ( promExporter "go.opentelemetry.io/otel/exporters/prometheus" ) +func BenchmarkVarags(b *testing.B) { + f := func(opts ...string) int { + return len(opts) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + f("x", "y", "z") + } +} + +func BenchmarkAddConfig(b *testing.B) { + attrSet := attribute.NewSet(attribute.String("tag1", "value1")) + attrOpt := metric.WithAttributeSet(attrSet) + f := func(opts ...metric.AddOption) int { + metric.NewAddConfig(opts) + return len(opts) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + f(attrOpt) + } +} + func BenchmarkPrometheusCounter(b *testing.B) { reg := promsdk.NewRegistry() opts := promsdk.CounterOpts{