Metric Naming Conventions
All Excalibur packages follow consistent naming patterns for OpenTelemetry meters, metric instruments, and tags. This document catalogs every meter name, explains the naming pattern, and notes any known inconsistencies.
Meter Naming Pattern
Meters follow a hierarchical dot-separated convention matching the package namespace:
Excalibur.{Domain}.{Component}
Where:
- Domain is the top-level area (
Dispatch,Data,EventSourcing,LeaderElection) - Component is the specific subsystem (
Core,Transport,CircuitBreaker, etc.)
Examples
| Package | Meter Name | Pattern |
|---|---|---|
| Dispatch core | Excalibur.Dispatch.Core | Excalibur.Dispatch.{Component} |
| Transport layer | Excalibur.Dispatch.Transport | Excalibur.Dispatch.Transport |
| Transport-specific | Excalibur.Dispatch.Transport.Kafka | Excalibur.Dispatch.Transport.{Provider} |
| Data layer | Excalibur.Data.Cdc | Excalibur.Data.{Component} |
| Event sourcing | Excalibur.EventSourcing.EventStore | Excalibur.EventSourcing.{Component} |
| Leader election | Excalibur.LeaderElection | Excalibur.LeaderElection |
Complete Meter Catalog
Dispatch Domain
| Meter Name | Package | Constants Class |
|---|---|---|
Excalibur.Dispatch.Core | Excalibur.Dispatch | DispatchTelemetryConstants.Meters.Core |
Excalibur.Dispatch.Pipeline | Excalibur.Dispatch | DispatchTelemetryConstants.Meters.Pipeline |
Excalibur.Dispatch.TimePolicy | Excalibur.Dispatch | DispatchTelemetryConstants.Meters.TimePolicy |
Excalibur.Dispatch.BatchProcessor | Excalibur.Dispatch | DispatchTelemetryConstants.Meters.BatchProcessor |
Excalibur.Dispatch.Streaming | Excalibur.Dispatch | StreamingHandlerTelemetryConstants.MeterName |
Excalibur.Dispatch.Transport | Excalibur.Dispatch.Transport.Abstractions | TransportMeter.MeterName |
Excalibur.Dispatch.DeadLetterQueue | Excalibur.Dispatch.Observability | DeadLetterQueueMetrics.MeterName |
Excalibur.Dispatch.CircuitBreaker | Excalibur.Dispatch.Observability | CircuitBreakerMetrics.MeterName |
Excalibur.Dispatch.Observability.Context | Excalibur.Dispatch.Observability | ContextObservabilityTelemetryConstants.MeterName |
Excalibur.Dispatch.Compliance | Excalibur.Dispatch.Compliance | ComplianceMetrics.MeterName |
Excalibur.Dispatch.Compliance.Erasure | Excalibur.Dispatch.Compliance | ErasureTelemetryConstants.MeterName |
Excalibur.Dispatch.Encryption | Excalibur.Dispatch.Compliance | EncryptionTelemetry.MeterName |
Excalibur.Dispatch.BackgroundServices | Excalibur.Outbox | BackgroundServiceMetrics.MeterName |
Excalibur.Dispatch.Sagas | Excalibur.Saga | SagaMetrics.MeterName |
Excalibur.Dispatch.WriteStores | Excalibur.Data.Abstractions | WriteStoreTelemetry.MeterName |
Transport-Specific Meters
Transport meters use the pattern Excalibur.Dispatch.Transport.{TransportName}, generated by TransportTelemetryConstants.MeterName(name):
| Meter Name | Package |
|---|---|
Excalibur.Dispatch.Transport.RabbitMQ | Excalibur.Dispatch.Transport.RabbitMQ |
Excalibur.Dispatch.Transport.Kafka | Excalibur.Dispatch.Transport.Kafka |
Excalibur.Dispatch.Transport.AzureServiceBus | Excalibur.Dispatch.Transport.AzureServiceBus |
Excalibur.Dispatch.Transport.GooglePubSub | Excalibur.Dispatch.Transport.GooglePubSub |
Excalibur.Dispatch.Transport.AwsSqs | Excalibur.Dispatch.Transport.AwsSqs |
Google Pub/Sub components share a single consolidated meter name via GooglePubSubTelemetryConstants.MeterName. All other transports create their meter instance during AddXxxTransport() DI registration.
Data Domain
| Meter Name | Package | Constants Class |
|---|---|---|
Excalibur.Data.Cdc | Excalibur.Data.SqlServer | CdcTelemetryConstants.MeterName |
Excalibur.Data.Audit | Excalibur.Data.ElasticSearch | AuditTelemetryConstants.MeterName |
Excalibur.Data.Persistence | Excalibur.Data | String literal in DefaultPersistenceMetrics |
Excalibur.Data.SqlServer.Persistence | Excalibur.Data.SqlServer | String literal in SqlServerPersistenceMetrics |
Excalibur.Data.Postgres.Persistence | Excalibur.Data.Postgres | String literal in PostgresPersistenceMetrics |
Excalibur.Data.Postgres.Outbox | Excalibur.Data.Postgres | String literal in PostgresOutboxStoreMetrics |
Event Sourcing Domain
| Meter Name | Package | Constants Class |
|---|---|---|
Excalibur.EventSourcing.EventStore | Excalibur.EventSourcing | EventSourcingMeters.EventStore |
Excalibur.EventSourcing.SnapshotStore | Excalibur.EventSourcing | EventSourcingMeters.SnapshotStore |
Excalibur.EventSourcing.MaterializedViews | Excalibur.EventSourcing | MaterializedViewMetrics.MeterName |
Leader Election Domain
| Meter Name | Package | Constants Class |
|---|---|---|
Excalibur.LeaderElection | Excalibur.LeaderElection | LeaderElectionTelemetryConstants.MeterName |
Activity Source Naming
Activity source names follow the same pattern as meter names. The framework registers these centrally via AddAllDispatchTracing():
| Activity Source Name | Package |
|---|---|
Excalibur.Dispatch.Core | Dispatch |
Excalibur.Dispatch.Pipeline | Dispatch |
Excalibur.Dispatch.TimePolicy | Dispatch |
Excalibur.Dispatch.Streaming | Dispatch |
Excalibur.Dispatch.Compliance.Erasure | Compliance |
Excalibur.Data.Cdc | Data.SqlServer |
Excalibur.Data.Audit | Data.ElasticSearch |
Excalibur.LeaderElection | LeaderElection |
Excalibur.EventSourcing.EventStore | EventSourcing |
Excalibur.EventSourcing.SnapshotStore | EventSourcing |
Transport-specific activity sources follow Excalibur.Dispatch.Transport.{TransportName}, matching the meter naming.
Metric Instrument Naming
Individual metric instruments (counters, histograms, gauges) follow a lower-case dot-separated convention:
{prefix}.{component}.{measurement}
Prefix Patterns
| Prefix | Used By | Example |
|---|---|---|
dispatch.messages.* | Core dispatch | dispatch.messages.processed |
dispatch.transport.* | Transport layer | dispatch.transport.messages.sent |
dispatch.circuitbreaker.* | Circuit breaker | dispatch.circuitbreaker.state_changes |
dispatch.leaderelection.* | Leader election | dispatch.leaderelection.acquisitions |
excalibur.streaming.* | Streaming handlers | excalibur.streaming.documents.processed |
excalibur.cdc.* | CDC processing | excalibur.cdc.events.processed |
excalibur.audit.* | Audit logging | excalibur.audit.events.recorded |
excalibur.erasure.* | GDPR erasure | excalibur.erasure.requests.submitted |
excalibur.eventsourcing.* | Event sourcing | excalibur.eventsourcing.eventstore.operations |
Tag Naming
Tags use dot-separated lowercase names following OpenTelemetry semantic conventions:
| Pattern | Example | Used By |
|---|---|---|
message.* | message.type, message.id | Core dispatch |
dispatch.transport.* | dispatch.transport.name, dispatch.transport.destination | Transport layer |
error.* | error.type, error.retryable | All components |
aggregate.* | aggregate.id, aggregate.type | Event sourcing |
store.* | store.type, store.provider | Persistence |
cdc.* | cdc.capture_instance, cdc.operation | CDC |
audit.* | audit.event_type, audit.severity | Audit |
erasure.* | erasure.scope, erasure.result_status | GDPR erasure |
Subscribing with Wildcards
Use OpenTelemetry's wildcard support for broad meter subscriptions:
builder.Services.AddOpenTelemetry()
.WithMetrics(metrics =>
{
// All Dispatch meters
metrics.AddMeter("Excalibur.Dispatch.*");
// All data layer meters
metrics.AddMeter("Excalibur.Data.*");
// All event sourcing meters
metrics.AddMeter("Excalibur.EventSourcing.*");
// Everything
metrics.AddMeter("Excalibur.*");
});
Or use the convenience method which registers all known meters by name:
builder.Services.AddOpenTelemetry()
.AddAllDispatchMetrics();
Known Naming Inconsistencies
The following meters use ad-hoc string literals instead of shared constants classes. These are tracked for future harmonization:
| Meter Name | Issue |
|---|---|
Excalibur.Data.Persistence | Uses string literal in DefaultPersistenceMetrics, no constants class |
Excalibur.Data.SqlServer.Persistence | Uses string literal in SqlServerPersistenceMetrics, no constants class |
Excalibur.Data.Postgres.Persistence | Uses string literal in PostgresPersistenceMetrics, no constants class |
Excalibur.Data.Postgres.Outbox | Uses string literal in PostgresOutboxStoreMetrics, no constants class |
Additionally, some metric instrument name prefixes are inconsistent:
- Core dispatch uses
dispatch.*prefix (e.g.,dispatch.messages.processed) - Streaming uses
excalibur.streaming.*prefix (e.g.,excalibur.streaming.documents.processed) - CDC/audit/erasure use
excalibur.*prefix (e.g.,excalibur.cdc.events.processed)
The recommended pattern for new instruments is excalibur.{component}.{measurement}.
See Also
- Telemetry Configuration -- How to configure OpenTelemetry registration
- Metrics Reference -- Complete catalog of 100+ individual metrics
- Production Observability Guide -- Which metrics matter and what to alert on