Monitor Azure Service Bus with Sluicio
Build a small custom OpenTelemetry Collector that bundles the community Azure Service Bus receiver, scrape queue / topic / subscription depth, dead-letter and size metrics, and export them to Sluicio over OTLP.
Azure Service Bus is a managed message broker — queues, topics and subscriptions. To watch it in Sluicio you want its depth, dead-letter counts and sizes as metrics, so you can see a backlog building or messages piling up in a dead-letter queue.
There’s no Azure Service Bus receiver in the stock OpenTelemetry Collector distributions, so you build a small custom Collector that bundles the community azureservicebusreceiver and exports to Sluicio:
Azure Service Bus ──scrape──▶ custom OTel Collector ──OTLP/HTTP──▶ Sluicio ingest (azureservicebusreceiver (with ingest key) + otlphttp exporter)Building a custom Collector is lighter than it sounds — the OpenTelemetry Collector Builder (ocb) compiles a single binary from a short manifest.
What you’ll collect
Section titled “What you’ll collect”All gauges, scraped every collection_interval (attributes in brackets):
| Scope | Metrics | Attributes |
|---|---|---|
| Queues | servicebus.queue.active_messages, .deadletter_messages, .scheduled_messages, .current_size, .max_size | queue |
| Topics | servicebus.topic.scheduled_messages, .current_size, .max_size | topic |
| Subscriptions | servicebus.topic.subscription.active_messages, .deadletter_messages | topic, subscription |
Sizes are in bytes, counts in messages, and every metric carries the servicebus.namespace.name resource attribute.
Prerequisites
Section titled “Prerequisites”- An Azure Service Bus namespace, and a way to read its metadata — a managed identity or service principal with a reader role on the namespace (recommended over a connection string).
- Go 1.23+ to run the builder, or Docker (the Dockerfile below builds it for you).
- A running Sluicio cell and admin access to mint an ingest key.
1 · Mint a Sluicio ingest key
Section titled “1 · Mint a Sluicio ingest key”In Sluicio, open Settings → Ingestion, create a key, and copy it (shown once). The same screen shows your cell’s ingest URL (e.g. https://<your-cell>-ingest.example.com) — you’ll need both.
2 · Build a custom Collector
Section titled “2 · Build a custom Collector”The receiver isn’t in the stock Collector, so assemble one with the OpenTelemetry Collector Builder (ocb). Save this manifest:
dist: name: sluicio-servicebus-collector description: Custom OTel Collector with the Azure Service Bus receiver, exporting to Sluicio output_path: ./collector version: 0.1.0
receivers: - gomod: github.com/Integrio/azureservicebusreceiver v0.1.0
processors: - gomod: go.opentelemetry.io/collector/processor/batchprocessor v0.121.0 - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourceprocessor v0.121.0
exporters: - gomod: go.opentelemetry.io/collector/exporter/otlphttpexporter v0.121.0 - gomod: go.opentelemetry.io/collector/exporter/debugexporter v0.121.0 # optional, for local debugging
providers: - gomod: go.opentelemetry.io/collector/confmap/provider/envprovider v1.27.0 - gomod: go.opentelemetry.io/collector/confmap/provider/fileprovider v1.27.0Then build it (the ocb version must match the Collector release the components target — v0.121.0 here):
# install the builder once (also distributed as a prebuilt `ocb` binary)go install go.opentelemetry.io/collector/cmd/builder@v0.121.0
# compile → ./collector/sluicio-servicebus-collectorbuilder --config build_config.yaml3 · Configure the Collector
Section titled “3 · Configure the Collector”The Collector scrapes Service Bus, tags the metrics with a service.name so they land as a tidy service in Sluicio, batches, and exports over OTLP/HTTP:
receivers: azureservicebus: namespace_fqdn: yournamespace.servicebus.windows.net collection_interval: 1m auth: default_credentials # see the auth options below
processors: resource: attributes: - key: service.name value: azure-service-bus # how it appears in Sluicio action: upsert batch: send_batch_size: 512 timeout: 5s
exporters: otlphttp: # your cell's ingest base URL (Settings → Ingestion); the exporter # appends /v1/metrics itself. endpoint: https://<your-cell>-ingest.example.com headers: Authorization: "Bearer ${env:SLUICIO_INGEST_KEY}"
service: pipelines: metrics: receivers: [azureservicebus] processors: [resource, batch] exporters: [otlphttp]Notes:
otlphttp, nototlp. Sluicio ingests OTLP over HTTP/protobuf only — no gRPC — so the exporter must beotlphttp.- Only a metrics pipeline: this receiver produces metrics, not traces or logs.
- The
resourceprocessor setsservice.name— without it the metrics land underunknown_service. See Give every source a service name.
Authentication options
Section titled “Authentication options”Set auth to one of the following (avoid connection_string where you can):
# default_credentials — Azure DefaultAzureCredential# (managed identity in Azure, or `az login` locally). Simplest in-cloud.auth: default_credentials
# managed_identity — a specific user-assigned identityauth: managed_identityclient_id: ${env:CLIENT_ID}
# service_principal — app registration with a client secretauth: service_principaltenant_id: ${env:TENANT_ID}client_id: ${env:CLIENT_ID}client_secret: ${env:CLIENT_SECRET}
# connection_string — not recommended (a shared secret with broad rights)auth: connection_stringconnection_string: ${env:CONNECTION_STRING}4 · Run it (Docker)
Section titled “4 · Run it (Docker)”A multi-stage image builds the custom Collector and runs it:
# ---- build the custom collector ----FROM golang:1.23 AS buildRUN go install go.opentelemetry.io/collector/cmd/builder@v0.121.0WORKDIR /srcCOPY build_config.yaml .RUN builder --config build_config.yaml
# ---- runtime ----FROM gcr.io/distroless/static:nonrootCOPY --from=build /src/collector/sluicio-servicebus-collector /collectorCOPY run_config.yaml /etc/otel/config.yamlENTRYPOINT ["/collector"]CMD ["--config=/etc/otel/config.yaml"]services: servicebus-collector: build: . restart: unless-stopped environment: SLUICIO_INGEST_KEY: ${SLUICIO_INGEST_KEY:?set SLUICIO_INGEST_KEY in your environment} # service-principal auth (or use a managed identity when running in Azure): TENANT_ID: ${TENANT_ID:-} CLIENT_ID: ${CLIENT_ID:-} CLIENT_SECRET: ${CLIENT_SECRET:-}export SLUICIO_INGEST_KEY="<the key you copied>"docker compose up -d --buildWithin a collection interval, an azure-service-bus service appears in Sluicio carrying the queue / topic / subscription metrics.
Alerting on depth and dead-letters
Section titled “Alerting on depth and dead-letters”Once the metrics are flowing, add metric-based alert rules for the failure shapes that matter — for example servicebus.queue.deadletter_messages climbing above zero, or servicebus.queue.active_messages staying above a backlog threshold. This is the same pattern as the RabbitMQ and ActiveMQ Artemis guides, just with Service Bus metrics.
Where to go next
Section titled “Where to go next”- Point the Collector at Sluicio — the general Collector → Sluicio reference (auth headers, signal paths,
service.name). - Track RabbitMQ queue depth and Monitor ActiveMQ Artemis — the same queue-depth pattern for other brokers.
- What you get from your telemetry — what Sluicio does with these metrics once they arrive.