Zum Inhalt springen
Deutsch

Stock-Metriken

Wenn die Metrics-Extension aktiviert ist, zeichnet das Framework automatisch eine Basislinie an Metriken auf, die den Actor-Lebenszyklus, die Nachrichtenverarbeitung, beschränkte Mailboxen und den Cluster abdecken.

import { ActorSystem, MetricsExtensionId } from 'actor-ts';
const metrics = system.extension(MetricsExtensionId).enable();
// Stock-Metriken zeichnen jetzt in die Live-Registry auf — kein weiteres Setup

Das sind die Metriken, die du dir sonst selbst schreiben würdest. Sie Out-of-the-Box auszuliefern erlaubt dir, sofort ein Dashboard zu verdrahten.

Metriken für Actor-Lebenszyklus und Nachrichtenverarbeitung, systemweit aufgezeichnet — jede ist eine einzelne Serie ohne Labels:

MetrikTypLabelsBedeutung
actor_created_totalcounterErfolgreich gestartete Actor.
actor_terminated_totalcounterGestoppte Actor (sauberer Stopp oder nach einem Fehler).
actor_restarted_totalcounterSupervisor-getriebene Restarts.
actor_messages_delivered_totalcounterAn onReceive zugestellte User-Nachrichten.
actor_message_handler_secondshistogramZeit in onReceive-Handlern, in Sekunden.

actor_message_handler_seconds nutzt die standardmäßigen Sekunden-Buckets; sein p99 ist dein Signal „wie langsam ist ein Handler”.

MetrikTypLabelsBedeutung
actor_mailbox_sizegaugeclass, pathWartende User-Nachrichten, gesampelt. Nur Actors ab 10 000 sind vertreten.
actor_mailbox_dropped_totalcounterclass, path, reasonVon der Overflow-Policy einer beschränkten Mailbox verworfene Nachrichten.

actor_mailbox_size ist das Rückstau-Signal. Mailboxes sind per Default unbounded, ein zurückfallender Actor sammelt also an, statt abzuwerfen — und eine Serie entsteht erst, wenn einer 10 000 wartende Nachrichten überschreitet. Ihr Vorhandensein ist damit der Alarm: auf einem gesunden System ist die Metrik leer. Eine Mailbox, die wieder unter die Schwelle fällt, liest 0 statt ihres letzten Ausschlags, und dieselbe Schwelle erzeugt eine Log-Warnung (wiederholt bei jeder Verdopplung), unabhängig davon ob Metriken aktiv sind.

actor_mailbox_dropped_total ist das Abwurf-Signal und taucht nur für Actors auf, deren Mailbox etwas verwirft — da der Default unbounded ist, also für Actors, die jemand bewusst begrenzt hat. Das reason-Label hält die ausgelöste Policy fest (drop-head / drop-new). Beide Wege, zu begrenzen, sind abgedeckt: withMailboxCapacity und eine selbst gebaute Mailbox aus withMailbox.

MetrikTypLabelsBedeutung
cluster_members_upgaugeMitglieder aktuell im Zustand up (Sicht dieses Knotens).
cluster_gossip_rounds_totalcounterVon diesem Knoten initiierte Gossip-Push-Runden.
cluster_gossip_records_refused_totalcounterreasonVon einer Merge-Pfad-Wache abgelehnte gegossipte Member-Records.

Zum Monitoring der Cluster-Gesundheit:

  • cluster_members_up sollte deiner konfigurierten Replica-Anzahl entsprechen; ein dauerhafter Fehlbetrag heißt, Mitglieder sind down oder unerreichbar.
  • Die Rate von cluster_gossip_rounds_total bestätigt, dass Gossip fließt — eine flache Linie heißt, dieser Knoten hat aufgehört zu gossippen.
  • cluster_gossip_records_refused_total sollte bei null liegen. Bewegung auf reason="version-skew" heißt, gegossipte Versionen liegen weiter vor der Uhr dieses Knotens als maxVersionSkewMs — entweder ist die Uhr eines Peers abgedriftet, oder jemand versucht, eine Adresse vorab zu beanspruchen. Bewegung auf reason="map-cap" heißt, max-members / max-tombstones ist voll. Der Zähler wird einmal pro Frame um dessen Anzahl erhöht, und die Label-Menge ist auf diese zwei Werte geschlossen.

Der Quorum-Pfad des CRDT-Replikators — updateAsync / getAsync — und sein Wire-Decoder. Jede Label-Menge hier ist fest und winzig, die vier Familien tragen also insgesamt sechs Serien bei:

MetrikTypLabelsBedeutung
distributed_data_quorum_pendinggaugeQuorum-Reads und -Writes, die auf dieser Replika gerade auf Peer-Antworten warten.
distributed_data_quorum_timeouts_totalcounteroperationQuorum-Requests, die ihre Deadline erreichten, bevor genug Replikas antworteten.
distributed_data_quorum_rejected_totalcounteroperationQuorum-Requests, die abgelehnt wurden, weil max-pending-quorum-requests erreicht war.
distributed_data_dropped_values_totalcounterVon Peers gelieferte CRDT-Werte, die diese Replika nicht dekodieren wollte.

operation ist write oder read — diese beiden Werte und keine anderen.

  • distributed_data_quorum_pending dicht an deinem konfigurierten max-pending-quorum-requests heißt, dass der nächste Aufrufer gleich abgelehnt wird; entweder haben Peers aufgehört zu acken oder das Cap ist für die Last zu niedrig.
  • distributed_data_quorum_rejected_total und ..._timeouts_total trennen die beiden Fehlerformen: abgelehnt heißt, der Request hat nie begonnen; Timeout heißt, er hat begonnen und niemand antwortete rechtzeitig. Siehe Quorum-Reads und -Writes.
  • distributed_data_dropped_values_total ist gar kein Tuning-Signal — ein Peer schickt Payloads, die diese Replika nicht dekodieren kann, also ein kaputter oder feindlicher Knoten.

Es gibt kein Opt-out-Flag — Stock-Metriken sind immer im Framework verdrahtet. Bis du .enable() aufrufst, löst jeder Instrumentierungsaufruf gegen eine Noop-Registry auf (ein einzelner Objekt-Lookup, der nichts aufzeichnet), sodass die Kosten vernachlässigbar sind. Das Aktivieren der Extension tauscht die Live-Registry ein und dieselben Aufrufe beginnen aufzuzeichnen.