feat: opentelemetry for tracing and metrics

This commit is contained in:
Jon Lundy
2022-08-13 13:34:13 -06:00
parent 868d41de9f
commit 72d07276cd
15 changed files with 1245 additions and 1655 deletions

View File

@@ -9,7 +9,11 @@ import (
"strings"
"github.com/tidwall/wal"
"go.opentelemetry.io/otel/metric/instrument/syncint64"
"go.uber.org/multierr"
"github.com/sour-is/ev/internal/logz"
"github.com/sour-is/ev/pkg/cache"
"github.com/sour-is/ev/pkg/es"
"github.com/sour-is/ev/pkg/es/driver"
"github.com/sour-is/ev/pkg/es/event"
@@ -17,25 +21,49 @@ import (
"github.com/sour-is/ev/pkg/math"
)
const CachSize = 1000
type lockedWal = locker.Locked[wal.Log]
type openlogs struct {
logs map[string]*locker.Locked[wal.Log]
logs *cache.Cache[string, *lockedWal]
}
type diskStore struct {
path string
openlogs *locker.Locked[openlogs]
Mdisk_open syncint64.Counter
Mdisk_evict syncint64.Counter
}
const AppendOnly = es.AppendOnly
const AllEvents = es.AllEvents
func Init(ctx context.Context) error {
es.Register(ctx, "file", &diskStore{})
return nil
m := logz.Meter(ctx)
var err, errs error
Mdisk_open, err := m.SyncInt64().Counter("disk_open")
errs = multierr.Append(errs, err)
Mdisk_evict, err := m.SyncInt64().Counter("disk_evict")
errs = multierr.Append(errs, err)
es.Register(ctx, "file", &diskStore{
Mdisk_open: Mdisk_open,
Mdisk_evict: Mdisk_evict,
})
return errs
}
var _ driver.Driver = (*diskStore)(nil)
func (diskStore) Open(_ context.Context, dsn string) (driver.Driver, error) {
func (d *diskStore) Open(ctx context.Context, dsn string) (driver.Driver, error) {
ctx, span := logz.Span(ctx)
defer span.End()
d.Mdisk_open.Add(ctx, 1)
scheme, path, ok := strings.Cut(dsn, ":")
if !ok {
return nil, fmt.Errorf("expected scheme")
@@ -51,16 +79,34 @@ func (diskStore) Open(_ context.Context, dsn string) (driver.Driver, error) {
return nil, err
}
}
c, err := cache.NewWithEvict(CachSize, func(ctx context.Context, s string, l *lockedWal) {
l.Modify(ctx, func(w *wal.Log) error {
// logz.Mdisk_evict.Add(ctx, 1)
logs := &openlogs{logs: make(map[string]*locker.Locked[wal.Log])}
return &diskStore{path: path, openlogs: locker.New(logs)}, nil
err := w.Close()
if err != nil {
log.Print(err)
}
return nil
})
})
if err != nil {
return nil, err
}
logs := &openlogs{logs: c}
return &diskStore{
path: path,
openlogs: locker.New(logs),
Mdisk_open: d.Mdisk_open,
Mdisk_evict: d.Mdisk_evict,
}, nil
}
func (ds *diskStore) EventLog(ctx context.Context, streamID string) (driver.EventLog, error) {
el := &eventLog{streamID: streamID}
return el, ds.openlogs.Modify(ctx, func(openlogs *openlogs) error {
if events, ok := openlogs.logs[streamID]; ok {
el.events = events
if events, ok := openlogs.logs.Get(streamID); ok {
el.events = *events
return nil
}
@@ -69,7 +115,7 @@ func (ds *diskStore) EventLog(ctx context.Context, streamID string) (driver.Even
return err
}
el.events = locker.New(l)
openlogs.logs[streamID] = el.events
openlogs.logs.Add(ctx, streamID, el.events)
return nil
})
}

View File

@@ -6,9 +6,12 @@ import (
"fmt"
"strings"
"github.com/sour-is/ev/internal/logz"
"github.com/sour-is/ev/pkg/es/driver"
"github.com/sour-is/ev/pkg/es/event"
"github.com/sour-is/ev/pkg/locker"
"go.opentelemetry.io/otel/metric/instrument/syncint64"
"go.uber.org/multierr"
)
type config struct {
@@ -23,20 +26,56 @@ var (
)
func Register(ctx context.Context, name string, d driver.Driver) error {
return drivers.Modify(ctx, func(c *config) error {
ctx, span := logz.Span(ctx)
defer span.End()
m := logz.Meter(ctx)
var err, errs error
Mes_open, err = m.SyncInt64().Counter("es_open")
errs = multierr.Append(errs, err)
Mes_read, err = m.SyncInt64().Counter("es_read")
errs = multierr.Append(errs, err)
Mes_load, err = m.SyncInt64().Counter("es_load")
errs = multierr.Append(errs, err)
Mes_save, err = m.SyncInt64().Counter("es_save")
errs = multierr.Append(errs, err)
Mes_append, err = m.SyncInt64().Counter("es_append")
errs = multierr.Append(errs, err)
err = drivers.Modify(ctx, func(c *config) error {
if _, set := c.drivers[name]; set {
return fmt.Errorf("driver %s already set", name)
}
c.drivers[name] = d
return nil
})
return multierr.Append(errs, err)
}
type EventStore struct {
driver.Driver
}
var (
Mes_open syncint64.Counter
Mes_read syncint64.Counter
Mes_load syncint64.Counter
Mes_save syncint64.Counter
Mes_append syncint64.Counter
)
func Open(ctx context.Context, dsn string, options ...Option) (*EventStore, error) {
ctx, span := logz.Span(ctx)
defer span.End()
Mes_open.Add(ctx, 1)
name, _, ok := strings.Cut(dsn, ":")
if !ok {
return nil, fmt.Errorf("%w: no scheme", ErrNoDriver)
@@ -68,6 +107,11 @@ type Option interface {
}
func (es *EventStore) Save(ctx context.Context, agg event.Aggregate) (uint64, error) {
ctx, span := logz.Span(ctx)
defer span.End()
Mes_save.Add(ctx, 1)
l, err := es.EventLog(ctx, agg.StreamID())
if err != nil {
return 0, err
@@ -83,6 +127,11 @@ func (es *EventStore) Save(ctx context.Context, agg event.Aggregate) (uint64, er
return count, err
}
func (es *EventStore) Load(ctx context.Context, agg event.Aggregate) error {
ctx, span := logz.Span(ctx)
defer span.End()
Mes_load.Add(ctx, 1)
l, err := es.Driver.EventLog(ctx, agg.StreamID())
if err != nil {
return err
@@ -97,6 +146,11 @@ func (es *EventStore) Load(ctx context.Context, agg event.Aggregate) error {
return nil
}
func (es *EventStore) Read(ctx context.Context, streamID string, pos, count int64) (event.Events, error) {
ctx, span := logz.Span(ctx)
defer span.End()
Mes_read.Add(ctx, 1)
l, err := es.Driver.EventLog(ctx, streamID)
if err != nil {
return nil, err
@@ -104,6 +158,11 @@ func (es *EventStore) Read(ctx context.Context, streamID string, pos, count int6
return l.Read(ctx, pos, count)
}
func (es *EventStore) Append(ctx context.Context, streamID string, events event.Events) (uint64, error) {
ctx, span := logz.Span(ctx)
defer span.End()
Mes_append.Add(ctx, 1)
l, err := es.Driver.EventLog(ctx, streamID)
if err != nil {
return 0, err
@@ -111,6 +170,9 @@ func (es *EventStore) Append(ctx context.Context, streamID string, events event.
return l.Append(ctx, events, AppendOnly)
}
func (es *EventStore) FirstIndex(ctx context.Context, streamID string) (uint64, error) {
ctx, span := logz.Span(ctx)
defer span.End()
l, err := es.Driver.EventLog(ctx, streamID)
if err != nil {
return 0, err
@@ -118,6 +180,9 @@ func (es *EventStore) FirstIndex(ctx context.Context, streamID string) (uint64,
return l.FirstIndex(ctx)
}
func (es *EventStore) LastIndex(ctx context.Context, streamID string) (uint64, error) {
ctx, span := logz.Span(ctx)
defer span.End()
l, err := es.Driver.EventLog(ctx, streamID)
if err != nil {
return 0, err
@@ -138,7 +203,7 @@ func (es *EventStore) EventStream() driver.EventStream {
}
func Unwrap[T any](t T) T {
if unwrap, ok := any(t).(interface{Unwrap() T}); ok {
if unwrap, ok := any(t).(interface{ Unwrap() T }); ok {
return unwrap.Unwrap()
} else {
var zero T