Skip to main content
GoAkt provides built-in observability through metrics (system and per-actor), event streams, and dead letters. Metrics are available as programmatic snapshots and, when configured, as OpenTelemetry instruments for integration with dashboards and exporters.

Overview

MechanismPurpose
System metricsNode-level statistics via ActorSystem.Metric(ctx)
Per-actor metricsActor-level statistics via pid.Metric(ctx)
Event streamSystem and cluster events (lifecycle, membership, dead letters)
OpenTelemetryMetrics exported when WithMetrics() is used
All metrics are localβ€”they reflect the current node only. Metrics are point-in-time snapshots; values do not update after the struct is returned.

System metrics

ActorSystem.Metric(ctx) returns a *Metric struct with node-level statistics. Returns nil when the actor system is not started.
FieldTypeDescription
DeadlettersCount()int64Total messages dropped to dead letters on this node
ActorsCount()int64Total number of live actors on this node
Uptime()int64Seconds since the actor system started
MemoryUsed()uint64Used memory in bytes (host)
MemorySize()uint64Total memory in bytes (host)
MemoryAvailable()uint64Available memory in bytes (host)
m := sys.Metric(ctx)
if m != nil {
    log.Printf("actors=%d deadletters=%d uptime=%ds",
    m.ActorsCount(), m.DeadlettersCount(), m.Uptime())
}

Per-actor metrics

pid.Metric(ctx) returns an *ActorMetric struct with actor-level statistics. Returns nil when the actor is not running. For remote actors, metrics are fetched via remoting; the same fields are available.
FieldTypeDescription
ProcessedCount()uint64Cumulative messages processed (excludes PostStart; excludes stashed/dropped)
ChidrenCount()uint64Number of direct child actors
RestartCount()uint64Cumulative restarts (supervision)
Uptime()int64Seconds since actor started (resets on restart)
LatestProcessedDuration()time.DurationDuration of the most recent message processing
StashSize()uint64Current number of stashed messages
DeadlettersCount()uint64Messages sent to dead letters by this actor
FailureCount()uint64Cumulative failures (panics, errors triggering supervision)
ReinstateCount()uint64Cumulative reinstatements (suspended β†’ resumed)
m := pid.Metric(ctx)
if m != nil {
    log.Printf("actors=%s processed=%d restarts=%d stash=%d",
    pid.Name(), m.ProcessedCount(), m.RestartCount(), m.StashSize())
}

Event stream

The event stream publishes system and cluster events (lifecycle, membership, dead letters). It is separate from application-level PubSub. See Event Streams for full documentation.
subscriber, err := sys.Subscribe()
if err != nil {
    return err
}
defer sys.Unsubscribe(subscriber)

for msg := range subscriber.Iterator() {
    switch e := msg.Payload().(type) {
        case *actor.ActorStarted:
        // ...
        case *actor.Deadletter:
        // ...
    }
}
Event types: ActorStarted, ActorStopped, ActorChildCreated, ActorPassivated, ActorRestarted, ActorSuspended, ActorReinstated, Deadletter, NodeJoined, NodeLeft.

Dead letters

Messages sent to stopped or non-existent actors are captured by the dead-letter actor and published to the event stream. The Deadletter payload includes sender, receiver, message, and reason. Subscribe to the event stream to observe or log dead letters.

OpenTelemetry

When WithMetrics() is passed at actor system creation, the framework registers OpenTelemetry observable counters. You must initialize the OpenTelemetry SDK (MeterProvider, exporter) before starting the actor system; otherwise metrics are not exported.

System-level instruments

InstrumentTypeDescription
actorsystem.deadletters.countInt64ObservableCounterTotal dead letters on this node
actorsystem.actors.countInt64ObservableCounterTotal live actors on this node
actorsystem.uptimeInt64ObservableCounter (s)Actor system uptime in seconds
actorsystem.peers.countInt64ObservableCounterConnected peers (cluster mode)

Per-actor instruments

Attributes: actor.system, actor.name, actor.kind, actor.address.
InstrumentTypeDescription
actor.children.countInt64ObservableCounterTotal child actors
actor.stash.sizeInt64ObservableCounterMessages stashed
actor.deadletters.countInt64ObservableCounterDead letters sent by this actor
actor.restart.countInt64ObservableCounterRestarts
actor.last.received.durationInt64ObservableCounter (ms)Duration of last message processing
actor.processed.countInt64ObservableCounterMessages processed
actor.uptimeInt64ObservableCounter (s)Actor uptime in seconds
actor.failure.countInt64ObservableCounterFailures
actor.reinstate.countInt64ObservableCounterReinstatements

Example

import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp"
"go.opentelemetry.io/otel/sdk/metric"
)

// Initialize SDK before creating actor system
exporter, _ := otlpmetrichttp.New(context.Background(), otlpmetrichttp.WithInsecure())
provider := metric.NewMeterProvider(metric.WithReader(metric.NewPeriodicReader(exporter)))
otel.SetMeterProvider(provider)

sys, _ := actor.NewActorSystem("app", actor.WithMetrics())