Skip to content

Commit

Permalink
feat(otelsync): init
Browse files Browse the repository at this point in the history
  • Loading branch information
ernado committed Jan 30, 2025
1 parent b4edf93 commit e21115a
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Implements automatic setup of observability and daemonization based on environme
| `gold` | Golden files in tests |
| `app` | Automatic setup observability and run daemon |
| `autometric` | Reflect-based OpenTelemetry metric initializer |
| `otelsync` | OpenTelemetry synchronous adapter for async metrics |

## Environment variables

Expand Down
50 changes: 50 additions & 0 deletions otelsync/adapter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package otelsync

import (
"context"

"go.opentelemetry.io/otel/metric"
)

// Adapter provides a sync adapter over async metric instruments.
type Adapter struct {
meter metric.Meter
gauge []*GaugeInt64
}

func (a *Adapter) callback(_ context.Context, o metric.Observer) error {
for _, v := range a.gauge {
v.observe(o)
}
return nil
}

// Register registers callback.
func (a *Adapter) Register() (metric.Registration, error) {
var in []metric.Observable
for _, v := range a.gauge {
in = append(in, v.Int64ObservableGauge)
}
return a.meter.RegisterCallback(a.callback, in...)
}

// GaugeInt64 returns a new sync int64 gauge. Register must be called after creating all gauges.
func (a *Adapter) GaugeInt64(name string, options ...metric.Int64ObservableGaugeOption) (metric.Int64Observer, error) {
og, err := a.meter.Int64ObservableGauge(name, options...)
if err != nil {
return nil, err
}
g := &GaugeInt64{
Int64ObservableGauge: og,
}
a.gauge = append(a.gauge, g)
return g, nil
}

func NewAdapter(m metric.Meter) *Adapter {
a := &Adapter{
meter: m,
}

return a
}
40 changes: 40 additions & 0 deletions otelsync/gauge.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package otelsync

import (
"sync"

"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/embedded"
)

// GaugeInt64 is a wrapper around metric.Int64ObservableGauge that stores last value
// for each attribute set, providing a sync adapter over async gauge.
type GaugeInt64 struct {
metric.Int64ObservableGauge
embedded.Int64Observer

mux sync.Mutex
values map[attribute.Set]int64
}

// Observe records a last value for attribute set.
func (g *GaugeInt64) Observe(v int64, options ...metric.ObserveOption) {
g.mux.Lock()
defer g.mux.Unlock()

if g.values == nil {
g.values = make(map[attribute.Set]int64)
}

g.values[metric.NewObserveConfig(options).Attributes()] = v
}

func (g *GaugeInt64) observe(o metric.Observer) {
g.mux.Lock()
defer g.mux.Unlock()

for k, v := range g.values {
o.ObserveInt64(g.Int64ObservableGauge, v, metric.WithAttributes(k.ToSlice()...))
}
}

0 comments on commit e21115a

Please sign in to comment.