From d2f3e41ef00902ecb715931f7989284eadd53665 Mon Sep 17 00:00:00 2001 From: Arsene Date: Tue, 24 Sep 2024 21:44:23 +0100 Subject: [PATCH] refactor: remove OpenTelemetry dependency (#472) --- README.md | 19 ++-- actors/actor_system.go | 61 +----------- actors/actor_system_test.go | 85 ++-------------- actors/api.go | 3 - actors/option.go | 15 --- actors/option_test.go | 12 --- actors/pid.go | 107 +++++--------------- actors/pid_option.go | 14 --- actors/pid_option_test.go | 5 - actors/pid_test.go | 80 ++------------- go.mod | 10 +- internal/metric/actor_metric.go | 135 -------------------------- internal/metric/actor_metric_test.go | 48 --------- internal/metric/system_metric.go | 69 ------------- internal/metric/system_metric_test.go | 44 --------- telemetry/option.go | 61 ------------ telemetry/option_test.go | 62 ------------ telemetry/telemetry.go | 92 ------------------ telemetry/telemetry_test.go | 53 ---------- telemetry/version.go | 30 ------ 20 files changed, 52 insertions(+), 953 deletions(-) delete mode 100644 internal/metric/actor_metric.go delete mode 100644 internal/metric/actor_metric_test.go delete mode 100644 internal/metric/system_metric.go delete mode 100644 internal/metric/system_metric_test.go delete mode 100644 telemetry/option.go delete mode 100644 telemetry/option_test.go delete mode 100644 telemetry/telemetry.go delete mode 100644 telemetry/telemetry_test.go delete mode 100644 telemetry/version.go diff --git a/README.md b/README.md index 9965b04b..fabe8241 100644 --- a/README.md +++ b/README.md @@ -322,19 +322,12 @@ Go-Akt offers out of the box features that can help track, monitor and measure t #### Metrics -One can enable/disable metrics on a Go-Akt actor system to collect the following metrics: - -- Actor Metrics: - - Number of children - - Number of messages stashed - - Number of Restarts - - Last message received processing latency in milliseconds -- System Metrics: - - Total Number of Actors - -Go-Akt uses under the hood [OpenTelemetry](https://opentelemetry.io/docs/instrumentation/go/) to instrument a system. -One just need to use the `WithMetric` option when instantiating a Go-Akt actor system and use the default [Telemetry](./telemetry/telemetry.go) -engine or set a custom one with `WithTelemetry` option of the actor system. +The following methods have been implemented to help push some metrics to any observability tool: + - Total Number of children at a given point in time [PID](./actors/pid.go) + - Number of messages stashed at a given point in time [PID](./actors/pid.go) + - Number of Restarts at a given point in time [PID](./actors/pid.go) + - Latest message received processing duration in milliseconds [PID](./actors/pid.go) + - Total Number of Actors at a given point in time [ActorSystem](./actors/actor_system.go) #### Logging diff --git a/actors/actor_system.go b/actors/actor_system.go index 54f075a7..0cdd33c7 100644 --- a/actors/actor_system.go +++ b/actors/actor_system.go @@ -38,9 +38,7 @@ import ( "time" "connectrpc.com/connect" - "connectrpc.com/otelconnect" "github.com/google/uuid" - otelmetric "go.opentelemetry.io/otel/metric" "go.uber.org/atomic" "golang.org/x/sync/errgroup" "google.golang.org/protobuf/proto" @@ -54,11 +52,9 @@ import ( "github.com/tochemey/goakt/v2/internal/http" "github.com/tochemey/goakt/v2/internal/internalpb" "github.com/tochemey/goakt/v2/internal/internalpb/internalpbconnect" - "github.com/tochemey/goakt/v2/internal/metric" "github.com/tochemey/goakt/v2/internal/tcp" "github.com/tochemey/goakt/v2/internal/types" "github.com/tochemey/goakt/v2/log" - "github.com/tochemey/goakt/v2/telemetry" ) // ActorSystem defines the contract of an actor system @@ -175,8 +171,7 @@ type actorSystem struct { actorInitTimeout time.Duration // Specifies the supervisor strategy supervisorDirective SupervisorDirective - // Specifies the telemetry config - telemetry *telemetry.Telemetry + // Specifies whether remoting is enabled. // This allows to handle remote messaging remotingEnabled atomic.Bool @@ -210,9 +205,6 @@ type actorSystem struct { // specifies the message scheduler scheduler *scheduler - // specifies whether metrics is enabled - metricEnabled atomic.Bool - registry types.Registry reflection *reflection @@ -247,7 +239,6 @@ func NewActorSystem(name string, opts ...Option) (ActorSystem, error) { askTimeout: DefaultAskTimeout, actorInitMaxRetries: DefaultInitMaxRetries, supervisorDirective: DefaultSupervisoryStrategy, - telemetry: telemetry.New(), locker: sync.Mutex{}, shutdownTimeout: DefaultShutdownTimeout, stashEnabled: false, @@ -269,7 +260,6 @@ func NewActorSystem(name string, opts ...Option) (ActorSystem, error) { system.started.Store(false) system.remotingEnabled.Store(false) system.clusterEnabled.Store(false) - system.metricEnabled.Store(false) system.reflection = newReflection(system.registry) @@ -286,13 +276,6 @@ func NewActorSystem(name string, opts ...Option) (ActorSystem, error) { } system.scheduler = newScheduler(system.logger, system.shutdownTimeout, withSchedulerCluster(system.cluster)) - - if system.metricEnabled.Load() { - if err := system.registerMetrics(); err != nil { - return nil, err - } - } - return system, nil } @@ -1111,22 +1094,6 @@ func (x *actorSystem) enableClustering(ctx context.Context) error { func (x *actorSystem) enableRemoting(ctx context.Context) { x.logger.Info("enabling remoting...") - var interceptor *otelconnect.Interceptor - var err error - if x.metricEnabled.Load() { - interceptor, err = otelconnect.NewInterceptor( - otelconnect.WithMeterProvider(x.telemetry.MeterProvider()), - ) - if err != nil { - x.logger.Panic(fmt.Errorf("failed to initialize observability feature: %w", err)) - } - } - - var opts []connect.HandlerOption - if interceptor != nil { - opts = append(opts, connect.WithInterceptors(interceptor)) - } - remotingHost, remotingPort, err := tcp.GetHostPort(fmt.Sprintf("%s:%d", x.host, x.port)) if err != nil { x.logger.Panic(fmt.Errorf("failed to resolve remoting TCP address: %w", err)) @@ -1135,8 +1102,8 @@ func (x *actorSystem) enableRemoting(ctx context.Context) { x.host = remotingHost x.port = int32(remotingPort) - remotingServicePath, remotingServiceHandler := internalpbconnect.NewRemotingServiceHandler(x, opts...) - clusterServicePath, clusterServiceHandler := internalpbconnect.NewClusterServiceHandler(x, opts...) + remotingServicePath, remotingServiceHandler := internalpbconnect.NewRemotingServiceHandler(x) + clusterServicePath, clusterServiceHandler := internalpbconnect.NewClusterServiceHandler(x) mux := stdhttp.NewServeMux() mux.Handle(remotingServicePath, remotingServiceHandler) @@ -1160,7 +1127,6 @@ func (x *actorSystem) enableRemoting(ctx context.Context) { // reset the actor system func (x *actorSystem) reset() { - x.telemetry = nil x.actors.reset() x.name = "" x.cluster = nil @@ -1200,22 +1166,6 @@ func (x *actorSystem) janitor() { x.logger.Info("janitor has stopped...") } -// registerMetrics register the PID metrics with OTel instrumentation. -func (x *actorSystem) registerMetrics() error { - meter := x.telemetry.Meter() - metrics, err := metric.NewActorSystemMetric(meter) - if err != nil { - return err - } - - _, err = meter.RegisterCallback(func(_ context.Context, observer otelmetric.Observer) error { - observer.ObserveInt64(metrics.ActorsCount(), int64(x.NumActors())) - return nil - }, metrics.ActorsCount()) - - return err -} - // replicationLoop publishes newly created actor into the cluster when cluster is enabled func (x *actorSystem) replicationLoop() { for actor := range x.actorsChan { @@ -1374,7 +1324,6 @@ func (x *actorSystem) configPID(ctx context.Context, name string, actor Actor) ( withSupervisorDirective(x.supervisorDirective), withEventsStream(x.eventsStream), withInitTimeout(x.actorInitTimeout), - withTelemetry(x.telemetry), } // enable stash @@ -1389,10 +1338,6 @@ func (x *actorSystem) configPID(ctx context.Context, name string, actor Actor) ( pidOpts = append(pidOpts, withPassivationAfter(x.expireActorAfter)) } - if x.metricEnabled.Load() { - pidOpts = append(pidOpts, withMetric()) - } - pid, err := newPID(ctx, addr, actor, diff --git a/actors/actor_system_test.go b/actors/actor_system_test.go index 306686f6..0e0278c5 100644 --- a/actors/actor_system_test.go +++ b/actors/actor_system_test.go @@ -27,7 +27,6 @@ package actors import ( "context" "net" - "sort" "strconv" "sync" "testing" @@ -38,9 +37,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/travisjeffery/go-dynaport" - sdkmetric "go.opentelemetry.io/otel/sdk/metric" - "go.opentelemetry.io/otel/sdk/metric/metricdata" - "go.uber.org/atomic" "google.golang.org/protobuf/proto" "github.com/tochemey/goakt/v2/address" @@ -50,7 +46,6 @@ import ( "github.com/tochemey/goakt/v2/log" clustermocks "github.com/tochemey/goakt/v2/mocks/cluster" testkit "github.com/tochemey/goakt/v2/mocks/discovery" - "github.com/tochemey/goakt/v2/telemetry" "github.com/tochemey/goakt/v2/test/data/testpb" ) @@ -1002,69 +997,6 @@ func TestActorSystem(t *testing.T) { provider.AssertExpectations(t) }) }) - t.Run("With Metric enabled", func(t *testing.T) { - r := sdkmetric.NewManualReader() - mp := sdkmetric.NewMeterProvider(sdkmetric.WithReader(r)) - // create an instance of telemetry - tel := telemetry.New(telemetry.WithMeterProvider(mp)) - - ctx := context.TODO() - sys, _ := NewActorSystem("testSys", - WithMetric(), - WithTelemetry(tel), - WithStash(), - WithLogger(log.DiscardLogger)) - - // start the actor system - err := sys.Start(ctx) - assert.NoError(t, err) - - actor := newTestActor() - actorRef, err := sys.Spawn(ctx, "Test", actor) - assert.NoError(t, err) - assert.NotNil(t, actorRef) - - // create a message to send to the test actor - message := new(testpb.TestSend) - // send the message to the actor - err = Tell(ctx, actorRef, message) - // perform some assertions - require.NoError(t, err) - - // Should collect 4 metrics, 3 for the actor and 1 for the actor system - got := &metricdata.ResourceMetrics{} - err = r.Collect(ctx, got) - require.NoError(t, err) - require.Len(t, got.ScopeMetrics, 1) - require.Len(t, got.ScopeMetrics[0].Metrics, 6) - - expected := []string{ - "actor_child_count", - "actor_stash_count", - "actor_restart_count", - "actors_count", - "actor_processed_count", - "actor_received_duration", - } - // sort the array - sort.Strings(expected) - // get the metrics names - actual := make([]string, len(got.ScopeMetrics[0].Metrics)) - for i, metric := range got.ScopeMetrics[0].Metrics { - actual[i] = metric.Name - } - sort.Strings(actual) - - assert.ElementsMatch(t, expected, actual) - - // stop the actor after some time - lib.Pause(time.Second) - - t.Cleanup(func() { - err = sys.Stop(ctx) - assert.NoError(t, err) - }) - }) t.Run("With cluster events subscription", func(t *testing.T) { // create a context ctx := context.TODO() @@ -1397,16 +1329,15 @@ func TestActorSystem(t *testing.T) { provider.EXPECT().ID().Return("id") system := &actorSystem{ - name: "testSystem", - logger: logger, - cluster: mockedCluster, - clusterEnabled: *atomic.NewBool(true), - telemetry: telemetry.New(), - locker: sync.Mutex{}, - scheduler: newScheduler(logger, time.Second, withSchedulerCluster(mockedCluster)), - clusterConfig: NewClusterConfig(), - registry: types.NewRegistry(), + name: "testSystem", + logger: logger, + cluster: mockedCluster, + locker: sync.Mutex{}, + scheduler: newScheduler(logger, time.Second, withSchedulerCluster(mockedCluster)), + clusterConfig: NewClusterConfig(), + registry: types.NewRegistry(), } + system.clusterEnabled.Store(true) err := system.Start(ctx) require.Error(t, err) diff --git a/actors/api.go b/actors/api.go index 0eabf828..0b066460 100644 --- a/actors/api.go +++ b/actors/api.go @@ -57,10 +57,8 @@ func Ask(ctx context.Context, to *PID, message proto.Message, timeout time.Durat // await patiently to receive the response from the actor select { case response = <-receiveContext.response: - to.recordLatestReceiveDurationMetric(ctx) return case <-time.After(timeout): - to.recordLatestReceiveDurationMetric(ctx) err = ErrRequestTimeout to.toDeadletterQueue(receiveContext, err) return @@ -79,7 +77,6 @@ func Tell(ctx context.Context, to *PID, message proto.Message) error { } to.doReceive(receiveContext) - to.recordLatestReceiveDurationMetric(ctx) return nil } diff --git a/actors/option.go b/actors/option.go index 86f76db0..c8d0215c 100644 --- a/actors/option.go +++ b/actors/option.go @@ -30,7 +30,6 @@ import ( "github.com/tochemey/goakt/v2/discovery" "github.com/tochemey/goakt/v2/hash" "github.com/tochemey/goakt/v2/log" - "github.com/tochemey/goakt/v2/telemetry" ) // Option is the interface that applies a configuration option. @@ -93,13 +92,6 @@ func WithSupervisorDirective(directive SupervisorDirective) Option { }) } -// WithTelemetry sets the custom telemetry -func WithTelemetry(telemetry *telemetry.Telemetry) Option { - return OptionFunc(func(a *actorSystem) { - a.telemetry = telemetry - }) -} - // WithRemoting enables remoting on the actor system func WithRemoting(host string, port int32) Option { return OptionFunc(func(a *actorSystem) { @@ -166,13 +158,6 @@ func WithActorInitTimeout(timeout time.Duration) Option { }) } -// WithMetric enables metrics -func WithMetric() Option { - return OptionFunc(func(system *actorSystem) { - system.metricEnabled.Store(true) - }) -} - // WithPeerStateLoopInterval sets the peer state loop interval func WithPeerStateLoopInterval(interval time.Duration) Option { return OptionFunc(func(system *actorSystem) { diff --git a/actors/option_test.go b/actors/option_test.go index 47571126..aa4b1244 100644 --- a/actors/option_test.go +++ b/actors/option_test.go @@ -33,11 +33,9 @@ import ( "github.com/tochemey/goakt/v2/hash" "github.com/tochemey/goakt/v2/log" - "github.com/tochemey/goakt/v2/telemetry" ) func TestOption(t *testing.T) { - tel := telemetry.New() resumeDirective := NewResumeDirective() var atomicTrue atomic.Bool atomicTrue.Store(true) @@ -88,11 +86,6 @@ func TestOption(t *testing.T) { option: WithShutdownTimeout(2 * time.Second), expected: actorSystem{shutdownTimeout: 2. * time.Second}, }, - { - name: "WithTelemetry", - option: WithTelemetry(tel), - expected: actorSystem{telemetry: tel}, - }, { name: "WithStash", option: WithStash(), @@ -108,11 +101,6 @@ func TestOption(t *testing.T) { option: WithActorInitTimeout(2 * time.Second), expected: actorSystem{actorInitTimeout: 2. * time.Second}, }, - { - name: "WithMetric", - option: WithMetric(), - expected: actorSystem{metricEnabled: atomicTrue}, - }, { name: "WithCluster", option: WithCluster(clusterConfig), diff --git a/actors/pid.go b/actors/pid.go index 77b88b55..585bd434 100644 --- a/actors/pid.go +++ b/actors/pid.go @@ -35,9 +35,7 @@ import ( "time" "connectrpc.com/connect" - "connectrpc.com/otelconnect" "github.com/flowchartsman/retry" - otelmetric "go.opentelemetry.io/otel/metric" "go.uber.org/atomic" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/anypb" @@ -51,11 +49,9 @@ import ( "github.com/tochemey/goakt/v2/internal/http" "github.com/tochemey/goakt/v2/internal/internalpb" "github.com/tochemey/goakt/v2/internal/internalpb/internalpbconnect" - "github.com/tochemey/goakt/v2/internal/metric" "github.com/tochemey/goakt/v2/internal/slice" "github.com/tochemey/goakt/v2/internal/types" "github.com/tochemey/goakt/v2/log" - "github.com/tochemey/goakt/v2/telemetry" ) // specifies the state in which the PID is @@ -150,9 +146,6 @@ type PID struct { // testSupervisor strategy supervisorDirective SupervisorDirective - // observability settings - telemetry *telemetry.Telemetry - // http client httpClient *stdhttp.Client @@ -170,8 +163,6 @@ type PID struct { restartCount *atomic.Int64 childrenCount *atomic.Int64 processedCount *atomic.Int64 - metricEnabled atomic.Bool - metrics *metric.ActorMetric watcherNotificationChan chan error watchersNotificationStopSignal chan types.Unit @@ -204,7 +195,6 @@ func newPID(ctx context.Context, address *address.Address, actor Actor, opts ... supervisorDirective: DefaultSupervisoryStrategy, watchersList: slice.New[*watcher](), watchedList: newPIDMap(10), - telemetry: telemetry.New(), address: address, fieldsLocker: new(sync.RWMutex), stopLocker: new(sync.Mutex), @@ -230,7 +220,6 @@ func newPID(ctx context.Context, address *address.Address, actor Actor, opts ... p.passivateAfter.Store(DefaultPassivationTimeout) p.askTimeout.Store(DefaultAskTimeout) p.initTimeout.Store(DefaultInitTimeout) - p.metricEnabled.Store(false) for _, opt := range opts { opt(p) @@ -250,18 +239,6 @@ func newPID(ctx context.Context, address *address.Address, actor Actor, opts ... go p.passivationLoop() } - if p.metricEnabled.Load() { - metrics, err := metric.NewActorMetric(p.telemetry.Meter()) - if err != nil { - return nil, err - } - - p.metrics = metrics - if err := p.registerMetrics(); err != nil { - return nil, fmt.Errorf("failed to register actor=%s metrics: %w", p.ID(), err) - } - } - p.doReceive(newReceiveContext(ctx, NoSender, p, new(goaktpb.PostStart))) return p, nil @@ -438,6 +415,30 @@ func (pid *PID) Restart(ctx context.Context) error { return nil } +// RestartCount returns the total number of re-starts by the given PID +func (pid *PID) RestartCount() int { + count := pid.restartCount.Load() + return int(count) +} + +// ChildrenCount returns the total number of children for the given PID +func (pid *PID) ChildrenCount() int { + count := pid.childrenCount.Load() + return int(count) +} + +// ProcessedCount returns the total number of messages processed at a given time +func (pid *PID) ProcessedCount() int { + count := pid.processedCount.Load() + return int(count) +} + +// LatestProcessedDuration returns the duration of the latest message processed +func (pid *PID) LatestProcessedDuration() time.Duration { + pid.latestReceiveDuration.Store(time.Since(pid.latestReceiveTime.Load())) + return pid.latestReceiveDuration.Load() +} + // SpawnChild creates a child actor and start watching it for error // When the given child actor already exists its PID will only be returned func (pid *PID) SpawnChild(ctx context.Context, name string, actor Actor) (*PID, error) { @@ -469,10 +470,6 @@ func (pid *PID) SpawnChild(ctx context.Context, name string, actor Actor) (*PID, withShutdownTimeout(pid.shutdownTimeout.Load()), } - if pid.metricEnabled.Load() { - opts = append(opts, withMetric()) - } - cid, err := newPID(ctx, childAddress, actor, @@ -549,10 +546,8 @@ func (pid *PID) Ask(ctx context.Context, to *PID, message proto.Message) (respon select { case result := <-receiveContext.response: - pid.recordLatestReceiveDurationMetric(ctx) return result, nil case <-time.After(timeout): - pid.recordLatestReceiveDurationMetric(ctx) err = ErrRequestTimeout pid.toDeadletterQueue(receiveContext, err) return nil, err @@ -564,9 +559,7 @@ func (pid *PID) Tell(ctx context.Context, to *PID, message proto.Message) error if !to.IsRunning() { return ErrDead } - to.doReceive(newReceiveContext(ctx, pid, to, message)) - pid.recordLatestReceiveDurationMetric(ctx) return nil } @@ -1145,14 +1138,7 @@ func (pid *PID) reset() { pid.initTimeout.Store(DefaultInitTimeout) pid.children.reset() pid.watchersList.Reset() - pid.telemetry = telemetry.New() pid.behaviorStack.Reset() - if pid.metricEnabled.Load() { - if err := pid.registerMetrics(); err != nil { - fmtErr := fmt.Errorf("failed to register actor=%s metrics: %w", pid.ID(), err) - pid.logger.Error(fmtErr) - } - } pid.processedCount.Store(0) } @@ -1415,48 +1401,11 @@ func (pid *PID) toDeadletterQueue(receiveCtx *ReceiveContext, err error) { }) } -// registerMetrics register the PID metrics with OTel instrumentation. -func (pid *PID) registerMetrics() error { - meter := pid.telemetry.Meter() - metrics := pid.metrics - _, err := meter.RegisterCallback(func(_ context.Context, observer otelmetric.Observer) error { - observer.ObserveInt64(metrics.ChildrenCount(), pid.childrenCount.Load()) - observer.ObserveInt64(metrics.StashCount(), int64(pid.StashSize())) - observer.ObserveInt64(metrics.RestartCount(), pid.restartCount.Load()) - observer.ObserveInt64(metrics.ProcessedCount(), pid.processedCount.Load()) - return nil - }, metrics.ChildrenCount(), - metrics.StashCount(), - metrics.ProcessedCount(), - metrics.RestartCount()) - - return err -} - -// clientOptions returns the gRPC client connections options -func (pid *PID) clientOptions() []connect.ClientOption { - var interceptor *otelconnect.Interceptor - if pid.metricEnabled.Load() { - // no need to handle the error because a NoOp trace and meter provider will be - // returned by the telemetry engine when none is provided - interceptor, _ = otelconnect.NewInterceptor( - otelconnect.WithTracerProvider(pid.telemetry.TraceProvider()), - otelconnect.WithMeterProvider(pid.telemetry.MeterProvider())) - } - - var clientOptions []connect.ClientOption - if interceptor != nil { - clientOptions = append(clientOptions, connect.WithInterceptors(interceptor)) - } - return clientOptions -} - // remotingClient returns an instance of the Remote Service client func (pid *PID) remotingClient(host string, port int) internalpbconnect.RemotingServiceClient { return internalpbconnect.NewRemotingServiceClient( pid.httpClient, http.URL(host, port), - pid.clientOptions()..., ) } @@ -1561,11 +1510,3 @@ func (pid *PID) handleRestartDirective(cid *PID, maxRetries uint32, timeout time } pid.Watch(cid) } - -func (pid *PID) recordLatestReceiveDurationMetric(ctx context.Context) { - // record processing time - pid.latestReceiveDuration.Store(time.Since(pid.latestReceiveTime.Load())) - if pid.metricEnabled.Load() { - pid.metrics.LastReceivedDuration().Record(ctx, pid.latestReceiveDuration.Load().Milliseconds()) - } -} diff --git a/actors/pid_option.go b/actors/pid_option.go index 1993806d..2a49fadc 100644 --- a/actors/pid_option.go +++ b/actors/pid_option.go @@ -29,7 +29,6 @@ import ( "github.com/tochemey/goakt/v2/internal/eventstream" "github.com/tochemey/goakt/v2/log" - "github.com/tochemey/goakt/v2/telemetry" ) // pidOption represents the pid @@ -93,13 +92,6 @@ func withPassivationDisabled() pidOption { } } -// withTelemetry sets the custom telemetry -func withTelemetry(telemetry *telemetry.Telemetry) pidOption { - return func(pid *PID) { - pid.telemetry = telemetry - } -} - // withStash sets the actor's stash buffer func withStash() pidOption { return func(pid *PID) { @@ -120,9 +112,3 @@ func withInitTimeout(duration time.Duration) pidOption { pid.initTimeout.Store(duration) } } - -func withMetric() pidOption { - return func(pid *PID) { - pid.metricEnabled.Store(true) - } -} diff --git a/actors/pid_option_test.go b/actors/pid_option_test.go index f185cf01..075d290e 100644 --- a/actors/pid_option_test.go +++ b/actors/pid_option_test.go @@ -101,11 +101,6 @@ func TestPIDOptions(t *testing.T) { option: withInitTimeout(time.Second), expected: &PID{initTimeout: atomicDuration}, }, - { - name: "withMetric", - option: withMetric(), - expected: &PID{metricEnabled: atomicTrue}, - }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { diff --git a/actors/pid_test.go b/actors/pid_test.go index e543c716..b5399b01 100644 --- a/actors/pid_test.go +++ b/actors/pid_test.go @@ -27,7 +27,6 @@ package actors import ( "bytes" "context" - "sort" "sync" "testing" "time" @@ -36,8 +35,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/travisjeffery/go-dynaport" - sdkmetric "go.opentelemetry.io/otel/sdk/metric" - "go.opentelemetry.io/otel/sdk/metric/metricdata" "google.golang.org/protobuf/proto" "github.com/tochemey/goakt/v2/address" @@ -45,7 +42,6 @@ import ( "github.com/tochemey/goakt/v2/internal/eventstream" "github.com/tochemey/goakt/v2/internal/lib" "github.com/tochemey/goakt/v2/log" - "github.com/tochemey/goakt/v2/telemetry" "github.com/tochemey/goakt/v2/test/data/testpb" testspb "github.com/tochemey/goakt/v2/test/data/testpb" ) @@ -86,6 +82,10 @@ func TestReceive(t *testing.T) { pid.doReceive(receiveContext) } + lib.Pause(500 * time.Millisecond) + assert.Zero(t, pid.ChildrenCount()) + assert.NotZero(t, pid.LatestProcessedDuration()) + assert.EqualValues(t, 11, pid.ProcessedCount()) // 1 because of the PostStart message // stop the actor err = pid.Shutdown(ctx) assert.NoError(t, err) @@ -312,6 +312,8 @@ func TestRestart(t *testing.T) { err = pid.Restart(ctx) assert.NoError(t, err) assert.True(t, pid.IsRunning()) + + assert.EqualValues(t, 1, pid.RestartCount()) // let us send 10 public to the actor for i := 0; i < count; i++ { err = Tell(ctx, pid, new(testpb.TestSend)) @@ -1039,7 +1041,6 @@ func TestSpawnChild(t *testing.T) { parent, err := newPID(ctx, actorPath, newTestSupervisor(), withInitMaxRetries(1), - withMetric(), withCustomLogger(log.DiscardLogger), withAskTimeout(replyTimeout)) @@ -1560,75 +1561,6 @@ func TestBatchAsk(t *testing.T) { assert.NoError(t, pid.Shutdown(ctx)) }) } -func TestRegisterMetrics(t *testing.T) { - r := sdkmetric.NewManualReader() - mp := sdkmetric.NewMeterProvider(sdkmetric.WithReader(r)) - // create an instance of telemetry - tel := telemetry.New(telemetry.WithMeterProvider(mp)) - - ctx := context.TODO() - - // create the actor path - ports := dynaport.Get(1) - actorPath := address.New("Test", "sys", "host", ports[0]) - - // create the actor ref - pid, err := newPID( - ctx, - actorPath, - newTestActor(), - withInitMaxRetries(1), - withCustomLogger(log.DiscardLogger), - withTelemetry(tel), - withMetric(), - withAskTimeout(replyTimeout)) - - require.NoError(t, err) - assert.NotNil(t, pid) - - // let us send 10 public to the actor - count := 10 - for i := 0; i < count; i++ { - receiveContext := &ReceiveContext{ - ctx: ctx, - message: new(testpb.TestSend), - sender: NoSender, - self: pid, - } - - pid.doReceive(receiveContext) - } - - // assert some metrics - - // Should collect 3 metrics - got := &metricdata.ResourceMetrics{} - err = r.Collect(ctx, got) - require.NoError(t, err) - assert.Len(t, got.ScopeMetrics, 1) - assert.Len(t, got.ScopeMetrics[0].Metrics, 4) - - expected := []string{ - "actor_child_count", - "actor_stash_count", - "actor_restart_count", - "actor_processed_count", - } - // sort the array - sort.Strings(expected) - // get the metrics names - actual := make([]string, len(got.ScopeMetrics[0].Metrics)) - for i, metric := range got.ScopeMetrics[0].Metrics { - actual[i] = metric.Name - } - sort.Strings(actual) - - assert.ElementsMatch(t, expected, actual) - - // stop the actor - err = pid.Shutdown(ctx) - assert.NoError(t, err) -} func TestRemoteReSpawn(t *testing.T) { t.Run("With actor address not found", func(t *testing.T) { // create the context diff --git a/go.mod b/go.mod index 2cfa808f..9380d253 100644 --- a/go.mod +++ b/go.mod @@ -18,11 +18,6 @@ require ( github.com/stretchr/testify v1.9.0 github.com/travisjeffery/go-dynaport v1.0.0 github.com/zeebo/xxh3 v1.0.2 - go.opentelemetry.io/otel v1.30.0 - go.opentelemetry.io/otel/metric v1.30.0 - go.opentelemetry.io/otel/sdk v1.30.0 - go.opentelemetry.io/otel/sdk/metric v1.30.0 - go.opentelemetry.io/otel/trace v1.30.0 go.uber.org/atomic v1.11.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 @@ -88,6 +83,11 @@ require ( github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/x448/float16 v0.8.4 // indirect + go.opentelemetry.io/otel v1.30.0 // indirect + go.opentelemetry.io/otel/metric v1.30.0 // indirect + go.opentelemetry.io/otel/sdk v1.30.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.30.0 // indirect + go.opentelemetry.io/otel/trace v1.30.0 // indirect golang.org/x/crypto v0.27.0 // indirect golang.org/x/mod v0.21.0 // indirect golang.org/x/oauth2 v0.23.0 // indirect diff --git a/internal/metric/actor_metric.go b/internal/metric/actor_metric.go deleted file mode 100644 index a9ec4d51..00000000 --- a/internal/metric/actor_metric.go +++ /dev/null @@ -1,135 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2022-2024 Tochemey - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package metric - -import ( - "fmt" - - "go.opentelemetry.io/otel/metric" -) - -// ActorMetric defines the actor instrumentation -type ActorMetric struct { - // Specifies the total number of child actors - childrenCount metric.Int64ObservableCounter - // Specifies the total number of stashed messages - stashCount metric.Int64ObservableCounter - // Specifies the total number of restarts - restartCount metric.Int64ObservableCounter - // Specifies the total number of instance created - spawnCount metric.Int64ObservableCounter - // Specifies the last message received processing duration - // This is expressed in milliseconds - lastReceivedDuration metric.Int64Histogram - // Specifies the total number of messages processed - processedCount metric.Int64ObservableCounter -} - -// NewActorMetric creates an instance of ActorMetric -func NewActorMetric(meter metric.Meter) (*ActorMetric, error) { - // create an instance of ActorMetric - actorMetric := new(ActorMetric) - var err error - // set the child count instrument - if actorMetric.childrenCount, err = meter.Int64ObservableCounter( - "actor_child_count", - metric.WithDescription("Total number of child actors"), - ); err != nil { - return nil, fmt.Errorf("failed to create childrenCount instrument, %w", err) - } - // set the stashed messages count instrument - if actorMetric.stashCount, err = meter.Int64ObservableCounter( - "actor_stash_count", - metric.WithDescription("Total number of messages stashed"), - ); err != nil { - return nil, fmt.Errorf("failed to create stashCount instrument, %w", err) - } - - // set the spawn messages count instrument - if actorMetric.spawnCount, err = meter.Int64ObservableCounter( - "actor_spawn_count", - metric.WithDescription("Total number of instances created"), - ); err != nil { - return nil, fmt.Errorf("failed to create spawnCount instrument, %w", err) - } - - // set the spawn messages count instrument - if actorMetric.restartCount, err = meter.Int64ObservableCounter( - "actor_restart_count", - metric.WithDescription("Total number of restart"), - ); err != nil { - return nil, fmt.Errorf("failed to create restartCount instrument, %w", err) - } - - // set the last received message duration instrument - if actorMetric.lastReceivedDuration, err = meter.Int64Histogram( - "actor_received_duration", - metric.WithDescription("The latency of the last message processed in milliseconds"), - metric.WithUnit("ms"), - ); err != nil { - return nil, fmt.Errorf("failed to create lastReceivedDuration instrument, %w", err) - } - - // set the processed count instrument - if actorMetric.processedCount, err = meter.Int64ObservableCounter( - "actor_processed_count", - metric.WithDescription("Total number of messages processed"), - ); err != nil { - return nil, fmt.Errorf("failed to create processedCount instrument, %w", err) - } - - return actorMetric, nil -} - -// ChildrenCount returns the total number of child actors -func (x *ActorMetric) ChildrenCount() metric.Int64ObservableCounter { - return x.childrenCount -} - -// StashCount returns the total number of stashed messages -func (x *ActorMetric) StashCount() metric.Int64ObservableCounter { - return x.stashCount -} - -// RestartCount returns the total number of restart -func (x *ActorMetric) RestartCount() metric.Int64ObservableCounter { - return x.restartCount -} - -// SpawnCount returns the total number of instances created for the given actor -func (x *ActorMetric) SpawnCount() metric.Int64ObservableCounter { - return x.spawnCount -} - -// LastReceivedDuration returns the last message received duration latency in milliseconds -func (x *ActorMetric) LastReceivedDuration() metric.Int64Histogram { - return x.lastReceivedDuration -} - -// ProcessedCount returns the total number of messages processed by the given actor -// at a given time in point -func (x *ActorMetric) ProcessedCount() metric.Int64ObservableCounter { - return x.processedCount -} diff --git a/internal/metric/actor_metric_test.go b/internal/metric/actor_metric_test.go deleted file mode 100644 index b6df6feb..00000000 --- a/internal/metric/actor_metric_test.go +++ /dev/null @@ -1,48 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2022-2024 Tochemey - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package metric - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "go.opentelemetry.io/otel/metric/noop" -) - -func TestNewActorMetric(t *testing.T) { - // create the instance of a meter - meter := noop.NewMeterProvider().Meter("test") - // create an instance of Actor metric - actorMetric, err := NewActorMetric(meter) - require.NoError(t, err) - assert.NotNil(t, actorMetric) - assert.NotNil(t, actorMetric.RestartCount()) - assert.NotNil(t, actorMetric.StashCount()) - assert.NotNil(t, actorMetric.SpawnCount()) - assert.NotNil(t, actorMetric.LastReceivedDuration()) - assert.NotNil(t, actorMetric.ChildrenCount()) - assert.NotNil(t, actorMetric.ProcessedCount()) -} diff --git a/internal/metric/system_metric.go b/internal/metric/system_metric.go deleted file mode 100644 index 2c4ba7de..00000000 --- a/internal/metric/system_metric.go +++ /dev/null @@ -1,69 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2022-2024 Tochemey - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package metric - -import ( - "fmt" - - "go.opentelemetry.io/otel/metric" -) - -// ActorSystemMetric defines the actor system metrics -type ActorSystemMetric struct { - actorsCount metric.Int64ObservableCounter - deadletterCount metric.Int64ObservableCounter -} - -// NewActorSystemMetric creates an instance of ActorSystemMetric -func NewActorSystemMetric(meter metric.Meter) (*ActorSystemMetric, error) { - // create an instance of ActorMetric - systemMetric := new(ActorSystemMetric) - var err error - // set the child count instrument - if systemMetric.actorsCount, err = meter.Int64ObservableCounter( - "actors_count", - metric.WithDescription("Total number of actors"), - ); err != nil { - return nil, fmt.Errorf("failed to create actorsCount instrument, %v", err) - } - // set the stashed messages count instrument - if systemMetric.deadletterCount, err = meter.Int64ObservableCounter( - "actor_system_deadletter_count", - metric.WithDescription("Total number of deadletter messages"), - ); err != nil { - return nil, fmt.Errorf("failed to create deadletterCount instrument, %v", err) - } - return systemMetric, nil -} - -// ActorsCount returns the total number of actors -func (x *ActorSystemMetric) ActorsCount() metric.Int64ObservableCounter { - return x.actorsCount -} - -// DeadletterCount returns the total number of deadletter -func (x *ActorSystemMetric) DeadletterCount() metric.Int64ObservableCounter { - return x.deadletterCount -} diff --git a/internal/metric/system_metric_test.go b/internal/metric/system_metric_test.go deleted file mode 100644 index 23fe20b0..00000000 --- a/internal/metric/system_metric_test.go +++ /dev/null @@ -1,44 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2022-2024 Tochemey - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package metric - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "go.opentelemetry.io/otel/metric/noop" -) - -func TestNewActorSystemMetric(t *testing.T) { - // create the instance of a meter - meter := noop.NewMeterProvider().Meter("test") - // create an instance of Actor metric - systemMetric, err := NewActorSystemMetric(meter) - require.NoError(t, err) - assert.NotNil(t, systemMetric) - assert.NotNil(t, systemMetric.DeadletterCount()) - assert.NotNil(t, systemMetric.ActorsCount()) -} diff --git a/telemetry/option.go b/telemetry/option.go deleted file mode 100644 index 2f2b2358..00000000 --- a/telemetry/option.go +++ /dev/null @@ -1,61 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2022-2024 Tochemey - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package telemetry - -import ( - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/trace" -) - -// Option is the interface that applies a configuration option. -type Option interface { - // Apply sets the Option value of a config. - Apply(config *Telemetry) -} - -var _ Option = OptionFunc(nil) - -// OptionFunc implements the Option interface. -type OptionFunc func(*Telemetry) - -func (f OptionFunc) Apply(c *Telemetry) { - f(c) -} - -// WithTracerProvider specifies a tracer provider to use for creating a tracer. -// If none is specified, the global provider is used. -func WithTracerProvider(provider trace.TracerProvider) Option { - return OptionFunc(func(cfg *Telemetry) { - cfg.tracerProvider = provider - }) -} - -// WithMeterProvider specifies a tracer provider to use for creating a tracer. -// If none is specified, the global provider is used. -func WithMeterProvider(provider metric.MeterProvider) Option { - return OptionFunc(func(cfg *Telemetry) { - cfg.meterProvider = provider - }) -} diff --git a/telemetry/option_test.go b/telemetry/option_test.go deleted file mode 100644 index 5ee0031c..00000000 --- a/telemetry/option_test.go +++ /dev/null @@ -1,62 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2022-2024 Tochemey - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package telemetry - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "go.opentelemetry.io/otel/metric/noop" - sdktrace "go.opentelemetry.io/otel/sdk/trace" -) - -func TestOptions(t *testing.T) { - tracerProvider := sdktrace.NewTracerProvider() - meterProvider := noop.NewMeterProvider() - - testCases := []struct { - name string - option Option - expectedConfig Telemetry - }{ - { - name: "WithTracerProvider", - option: WithTracerProvider(tracerProvider), - expectedConfig: Telemetry{tracerProvider: tracerProvider}, - }, - { - name: "WithMeterProvider", - option: WithMeterProvider(meterProvider), - expectedConfig: Telemetry{meterProvider: meterProvider}, - }, - } - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - var cfg Telemetry - tc.option.Apply(&cfg) - assert.Equal(t, tc.expectedConfig, cfg) - }) - } -} diff --git a/telemetry/telemetry.go b/telemetry/telemetry.go deleted file mode 100644 index 94da9704..00000000 --- a/telemetry/telemetry.go +++ /dev/null @@ -1,92 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2022-2024 Tochemey - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package telemetry - -import ( - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/trace" -) - -const ( - instrumentationName = "github.com/Tochemey/goakt/v2" -) - -// Telemetry encapsulates some settings for an actor -type Telemetry struct { - tracerProvider trace.TracerProvider - tracer trace.Tracer - - meterProvider metric.MeterProvider - meter metric.Meter -} - -// New creates an instance of Telemetry -func New(options ...Option) *Telemetry { - // create a config instance - telemetry := &Telemetry{ - tracerProvider: otel.GetTracerProvider(), - meterProvider: otel.GetMeterProvider(), - } - - // apply the various options - for _, opt := range options { - opt.Apply(telemetry) - } - - // set the tracer - telemetry.tracer = telemetry.tracerProvider.Tracer( - instrumentationName, - trace.WithInstrumentationVersion(Version()), - ) - - // set the meter - telemetry.meter = telemetry.meterProvider.Meter( - instrumentationName, - metric.WithInstrumentationVersion(Version()), - ) - - return telemetry -} - -// TraceProvider returns the trace provider -func (t *Telemetry) TraceProvider() trace.TracerProvider { - return t.tracerProvider -} - -// MeterProvider returns the meter provider -func (t *Telemetry) MeterProvider() metric.MeterProvider { - return t.meterProvider -} - -// Meter returns the meter -func (t *Telemetry) Meter() metric.Meter { - return t.meter -} - -// Tracer returns the tracer -func (t *Telemetry) Tracer() trace.Tracer { - return t.tracer -} diff --git a/telemetry/telemetry_test.go b/telemetry/telemetry_test.go deleted file mode 100644 index cb439e6f..00000000 --- a/telemetry/telemetry_test.go +++ /dev/null @@ -1,53 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2022-2024 Tochemey - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package telemetry - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/trace" -) - -func TestTelemetry(t *testing.T) { - tel := New() - assert.NotNil(t, tel) - globalTracer := otel.GetTracerProvider() - globalMeterProvider := otel.GetMeterProvider() - - actual := tel.TraceProvider() - assert.NotNil(t, actual) - assert.Equal(t, globalTracer, actual) - assert.Equal(t, globalTracer.Tracer(instrumentationName, - trace.WithInstrumentationVersion(Version())), tel.Tracer()) - - actualmp := tel.MeterProvider() - assert.NotNil(t, actualmp) - assert.Equal(t, globalMeterProvider, actualmp) - assert.Equal(t, globalMeterProvider.Meter(instrumentationName, - metric.WithInstrumentationVersion(Version())), tel.Meter()) -} diff --git a/telemetry/version.go b/telemetry/version.go deleted file mode 100644 index d4df9ee7..00000000 --- a/telemetry/version.go +++ /dev/null @@ -1,30 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2022-2024 Tochemey - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package telemetry - -// Version is the current release version of goakt in use. -func Version() string { - return "2.6.1" -}