Connectors

Configure all sixteen runtime connector types, local Git evidence, and native Lens reports.

Connectors are how Horus reads runtime evidence. They are read-only adapters to your existing systems. Horus does not write to production, replace your observability stack, or require you to change your applications.

Source intelligence is separate

Connectors are for runtime evidence. Source intelligence is for code context. You can use one without the other, but investigations are strongest when both are configured. See Source intelligence.

Supported runtime connectors

ConnectorEvidence typeWhen to use it
ElasticsearchLogs and error signaturesYou aggregate application logs in Elasticsearch and want error counts, first/last occurrences, and trace IDs.
GrafanaMetricsYou have dashboards in Grafana and want latency, error-rate, throughput, and queue-growth evidence.
MongoDBApplication stateYou store operational or domain state in MongoDB and want counts, staleness, and anomalous statuses.
Redis / BullMQQueue runtime stateYou run BullMQ on Redis and want queue depths, failed jobs, and worker health.
PostgreSQLApplication stateYou store operational or domain state in PostgreSQL and want counts, staleness, and anomalous rows from allowlisted tables.
SentryError eventsYou track exceptions in Sentry and want grouped errors with a direct seed into the implicated code.
AxiomLogs and error signaturesYou ship structured logs to Axiom and want incident-relevant error signatures (with counts) and recent events folded in as evidence.
ShopifyAdmin / business stateYou run a Shopify store and want order, inventory, and fulfillment state as evidence — supplied via your own read-only Admin GraphQL queries (--shopify-query, or config queries for watch).

Git evidence — recent commits, ownership, and change history — is read from the local repository directly and does not require a connector.

Eight connectors added in v0.23.0

Azure Monitor, CloudWatch Logs, Google Cloud Logging, Prometheus, Azure Service Bus, Kafka, Firestore, and SQL Server ship in v0.23.0. Update with horus update if your install does not recognize them. They collect evidence during investigations; they do not add new alert-trigger adapters or managed background execution.

Connector typeEvidencePrerequisites
azure-monitorLog Analytics eventsAzure CLI (az), read access to a workspace and subscription
cloudwatchCloudWatch log eventsAWS CLI (aws), region, log group, and read permissions
gcp-loggingGoogle Cloud log eventsGoogle Cloud CLI (gcloud) and project log-read access
prometheusConfigured PromQL time seriesPrometheus URL, named queries, optional bearer token
azure-service-busQueue counts and statusAzure CLI, namespace ARM ID, explicit queue allowlist
kafkaTopic and consumer-group offsetsBrokers, explicit topic/group allowlists, optional SASL credentials
firestoreCollection counts and date/status projectionsGoogle Cloud CLI, project ID, explicit collection paths
sqlserverTable counts, dates, and status distributionsConnection string, database, explicit tables, SELECT-only login

Lens is native Cloud evidence rather than a configured runtime connector. Log in and link the repo to read user-filed reports with horus lens; relevant reports are also included by horus investigate. Git is read locally. Neither needs horus connect.

Shared concepts

Every connector is scoped to a project and environment. The horus connect command writes non-secret settings into .horus/config.json and encrypts credentials (AES-256-GCM) into .horus/secrets.local.json. You can have different runtime connector endpoints and resource scopes for staging and production inside the same project.

By default, horus connect tests the connection before saving. Use --no-test to skip the probe, for example when credentials are rotated separately.

bash
horus connect --help

Azure, AWS, and Google Cloud logs

These connectors use your locally authenticated vendor CLI session. Authenticate with az login, your configured AWS credentials/profile, or gcloud auth login before connecting. Horus stores scope settings rather than copying vendor login credentials into its config. Run with no flags for prompts, or use these examples:

bash
horus connect azure-monitor --workspace 11111111-2222-3333-4444-555555555555 --subscription <subscription-id> --tables AppTraces,AppExceptions
horus connect cloudwatch --region eu-central-1 --log-group /app/checkout --profile production
horus connect gcp-logging --gcp-project my-gcp-project --filter 'resource.type="cloud_run_revision"'

Azure Monitor requires --workspace; --subscription selects the Azure subscription, and --tables replaces the default Log Analytics tables (AppTraces, AppExceptions, ContainerAppConsoleLogs_CL). CloudWatch requires --region and --log-group; --profile is optional. Google Cloud Logging requires --gcp-project; --filter narrows the scope. --executable overrides the vendor CLI path. All accept --env and --no-test.

Each read is a bounded sample of up to 200 log events in the investigation window. Horus normalizes timestamps, severity, messages, service names, and correlation identifiers into log evidence. Empty results or access failures do not prove the service is healthy. These samples are not a complete log export or durable alert cursor.

Direct Prometheus metrics

Connect directly to Prometheus when you do not need Grafana dashboard discovery. Supply named PromQL queries. During an investigation Horus runs the queries whose title or expression matches the hint (if none match, it runs them all and keeps only series whose labels match the hint), comparing each window with the preceding window of equal length. Keep the query list scoped to the service you are investigating.

bash
horus connect prometheus --url https://prometheus.example.com \
  --queries '[{"title":"checkout error rate","expr":"rate(checkout_errors_total[5m])"}]'

Required: --url and --queries, a JSON array of {title, expr} entries (1–20). Add --token if the endpoint needs bearer authentication. Investigation evidence uses the same anomaly analysis as Grafana. The standalone horus metrics command remains the Grafana interface; use horus investigate to collect these configured Prometheus queries.

Azure Service Bus queue counts

bash
horus connect azure-service-bus \
  --namespace-id /subscriptions/<subscription-id>/resourceGroups/production/providers/Microsoft.ServiceBus/namespaces/checkout \
  --queues checkout-jobs,retries

Required: a full namespace ARM ID and an explicit comma-separated queue allowlist. The locally authenticated Azure CLI reads management-plane queue status and active, dead-letter, scheduled, and transfer counts. It never receives, completes, or moves messages. Counts do not establish active worker health or prove starvation. --executable overrides az.

Kafka offsets and lag

bash
horus connect kafka --brokers kafka.example.com:9093 --topics checkout-events --groups checkout-workers

Required: --brokers, --topics, and --groups, all comma-separated lists. TLS defaults on; --no-ssl is for a trusted local broker. SASL requires both --username and --password; --mechanism accepts plain, scram-sha-256, or scram-sha-512. Credentials are encrypted locally.

Horus reads log-end and committed offsets per partition and reports point-in-time lag. It never consumes messages, commits offsets, or creates topics. An absent or invalid committed offset produces unknown lag, not zero. Use horus investigate to correlate this evidence with other sources, or horus queues --live for a standalone view of configured BullMQ, Kafka, and Service Bus providers.

Firestore state

bash
horus connect firestore --gcp-project my-gcp-project --collections jobs,orders

Required: --gcp-project and explicit collection paths. --database defaults to (default); --executable overrides gcloud. Horus obtains an access token through your local Google Cloud CLI, then reads collection aggregates and supported date/status fields, without exporting complete customer documents. Nested collection paths are accepted.

Status discovery samples up to 200 projected documents and counts up to 25 discovered statuses. It is a bounded summary, not exhaustive status coverage; some queries may require Firestore indexes. Configure an account with read access to the selected collections.

SQL Server state

bash
horus connect sqlserver --url 'Server=tcp:sql.example.com,1433;User Id=horus;Password=<password>;Encrypt=true' \
  --database checkout --schema dbo --tables jobs,orders

Required: --url, --database, and an explicit comma-separated table allowlist. --schema defaults to dbo. The connection string is encrypted locally. Horus issues fixed SELECT queries for counts, newest supported dates, and the top 25 status groups; it does not offer arbitrary SQL. Use a SELECT-only database login: read-only routing intent is not an authorization boundary. The standalone horus state command remains MongoDB-specific; use horus investigate for Firestore, SQL Server, and PostgreSQL evidence.

Troubleshooting the new connectors

Run horus status --env production for provider health. Verify vendor login, resource scope, and read permissions when probes fail. If a CLI executable is missing, install the vendor CLI or set --executable. A successful probe checks access; it does not guarantee relevant evidence for a particular hint or window.

Elasticsearch logs

The Elasticsearch connector reads log indices and turns them into error-signature evidence. It groups similar log lines, counts occurrences, finds the first and last timestamps, and extracts trace and request IDs when available.

When to use it

  • Your services ship logs to Elasticsearch.
  • You want to know whether an error is new, worsening, or correlated with a deployment.
  • You need trace IDs to correlate log lines across services.

Setup

bash
horus connect elasticsearch --url https://es.example.com:9200 --username horus --password $ES_PASSWORD --index-pattern 'my-service-*' --service my-service-prod

Required: --url and --index-pattern. --service scopes log queries to a single service.

Field presets

Horus ships two built-in field mappings: meritt (default) and ecs, selected with preset. You can override individual fields under the environment's connectors.elasticsearch.fields in .horus/config.json (or config/horus.config.js) if your indices use custom field names.

How it appears in investigations

During an investigation, Elasticsearch evidence shows up as error signatures: message patterns, counts, time range, and trace/request IDs. It supports correlation by trace ID, not full distributed tracing.

Troubleshooting

SymptomFix
horus connect fails with 401Check username, password, and that the user has read access to the target indices.
Investigation returns no log evidenceVerify --service matches the value stored in your logs and that --index-pattern covers the right time range.
Wrong timestamp or level field usedOverride the field mapping under connectors.elasticsearch.fields in .horus/config.json (or config/horus.config.js) or set preset to ecs if your logs follow ECS.

Grafana metrics

The Grafana connector queries metrics through Grafana's datasource proxy. It discovers dashboards and panels matching an incident hint, then surfaces latency spikes, error-rate changes, throughput drops, and queue growth.

When to use it

  • Your team already uses Grafana dashboards.
  • You want metric evidence tied to the same services and time windows as your investigation.
  • You need hints like 'latency spike' or 'error rate' resolved to concrete panels.

Setup

bash
horus connect grafana --url https://grafana.example.com --username horus --password $GRAFANA_PASSWORD --dashboard abc123

Required: --url. --dashboard sets a default dashboard UID; Horus can also discover dashboards automatically during an investigation.

How it appears in investigations

Metric evidence includes panel titles, datasource queries, detected anomalies, and the time window covered. It is evidence, not a replacement for your Grafana UI.

Troubleshooting

SymptomFix
horus connect cannot reach GrafanaConfirm the URL and credentials. Check that the datasource proxy is accessible.
No panels match the hintBroaden the hint or set a relevant default dashboard with --dashboard.
Queries return empty seriesVerify the Prometheus/Loki/other datasource behind Grafana covers the service and time range.

MongoDB state

The MongoDB connector reads application and operational state from allowlisted collections. It is intentionally scoped: you specify which databases and collections Horus can query, and Horus only runs read-only, allowlisted operations.

When to use it

  • You store operational state in MongoDB that helps explain incidents: job statuses, user states, event records.
  • You want to detect stale documents, anomalous status distributions, or recent spikes in collection counts.

Setup

bash
horus connect mongodb --url mongodb://horus:password@mongodb.example.com:27017 --database my_app --collections users,orders,jobs

Required: --url and --database. --collections is optional: omit it to auto-discover and allow all collections in the database, or supply it to restrict the allowlist. Use a read-only database account to enforce permissions independently of config.

How it appears in investigations

MongoDB evidence shows collection counts, stale-document counts, and unusual status distributions. It is summarized; Horus does not dump full documents into the report.

Troubleshooting

SymptomFix
horus connect fails with authentication errorCheck the connection string, user, password, and authSource if you use one.
Investigation cannot see a collectionAdd the collection to --collections and re-run horus connect.
Counts look wrongVerify the MongoDB user has read permission on the allowlisted collections.

Redis / BullMQ queues

The Redis connector is used by the BullMQ provider to read queue runtime state. It reports queue depths, failed-job counts and error breakdowns, delayed-job counts, oldest-job age, and possible worker starvation (waiting jobs with none active). It does not modify jobs, queues, or Redis keys.

When to use it

  • You run BullMQ on Redis and want queue evidence in investigations.
  • You suspect a backlog, worker crash, or job failure cascade.

Setup

bash
horus connect redis --url redis://:password@redis.example.com:6379

Required: --url. For authenticated Redis, embed the password in the URL as redis://:password@host:port. The CLI connect type is redis; the runtime provider is BullMQ. For several logical DBs, pass --db <n>:<roles> (repeatable, e.g. --db 0:cache,state --db 1:bullmq,queues) and --bullmq-prefix if your BullMQ prefix is not bull; interactive runs instead offer a read-only scan of DBs 0–15 (skip with --no-scan-dbs).

How it appears in investigations

Queue evidence appears alongside source-intelligence queue stitching. You can see which queue is backing up, how many jobs failed, and whether jobs are waiting with none active. Use horus queues --live for a standalone queue status view.

Troubleshooting

SymptomFix
horus connect cannot reach RedisCheck the URL, password, network, and TLS settings.
Queue evidence is missingConfirm the queue names match between code and Redis, and that horus init has built the queue map.
Counts differ from BullMQ DashboardHorus reads the same Redis keys but may sample or summarize differently. Treat its numbers as evidence, not canonical ops metrics.

PostgreSQL state

The PostgreSQL connector reads application and operational state from allowlisted tables. Like MongoDB, it is intentionally scoped: you specify the schema and tables Horus may query, and Horus runs only read-only, allowlisted operations.

When to use it

  • You store operational or domain state in PostgreSQL: job rows, order status, user state, outbox tables.
  • You want to detect stale rows, anomalous status distributions, or recent spikes in table counts.

Setup

bash
horus connect postgres --url postgres://horus:password@db.example.com:5432/my_app --schema public --tables orders,jobs,users

Required: --url. --schema defaults to public; --tables allowlists which tables Horus may read (omit to allow all in the schema). Use a SELECT-only role to enforce permissions. Run horus connect postgres with no flags for an interactive prompt.

How it appears in investigations

PostgreSQL evidence shows table counts, stale-row counts, and unusual status distributions, tagged as state. It is summarized; Horus does not dump full rows into the report.

Troubleshooting

SymptomFix
horus connect fails to connectCheck the connection string, credentials, SSL mode, and that the host is reachable.
Investigation cannot see a tableAdd it to --tables (and confirm the --schema), then re-run horus connect postgres.
Counts look wrongVerify the Postgres role has SELECT on the allowlisted tables.

Sentry errors

The Sentry connector reads grouped exceptions (issues) from your Sentry project and turns them into error evidence. Each issue is summarized with its count and time range, and seeded with the top in-app stack frame so Horus can point directly at the implicated code.

When to use it

  • You track exceptions in Sentry and want them correlated with code and other evidence during an investigation.
  • You want a direct jump from a production error to the function and file most likely responsible.

Setup

bash
horus connect sentry --org my-org --sentry-project my-project --auth-token $SENTRY_AUTH_TOKEN

Required: --org, --sentry-project, and --auth-token. For self-hosted Sentry, pass --url https://sentry.example.com. Use a read-only auth token. Running horus connect sentry with no flags prompts interactively.

How it appears in investigations

Sentry evidence is tagged logs (kind log) — the same source tier as Elasticsearch and Axiom — carrying the group's event count, first/last seen, and a code seed from the top in-app frame. It is evidence, not a replacement for the Sentry UI.

Troubleshooting

SymptomFix
horus connect returns 401 or 403Check the auth token scope (issues and events read) and that the org and project slugs are correct.
No issues appearConfirm the project slug and that the incident window overlaps recent Sentry activity.
Self-hosted Sentry not reachablePass --url with your Sentry base URL and verify network access.

Axiom logs

The Axiom connector reads structured logs from an Axiom dataset and turns them into log evidence. It is incident-aware: rather than dumping the freshest lines, it queries the top error signatures over the window — grouped by message and level, highest-volume first, with occurrence counts — alongside a few recent raw error rows for grounding. When no error-level rows match, it falls back to a recent all-levels sample so non-error datasets still produce evidence.

Requires CLI 0.11.0 or newer

The Axiom connector shipped in Horus CLI 0.11.0. Run horus --version and update if needed.

When to use it

  • You ship application logs to Axiom and want error counts and signatures correlated with code during an investigation.
  • You want a high-volume error storm surfaced as one ranked signature with its real count, not buried under newer info lines.
  • You query Axiom with APL today and want the same datasets folded into Horus evidence.

Setup

Run horus connect axiom with no flags for the interactive flow: it prompts for your API token (hidden input), lets you pick the region — US (api.axiom.co) or EU (api.eu.axiom.co), or a custom base URL — then lists your datasets live so you can select one (discover-then-select). If the dataset list cannot be fetched, you can type the name manually.

bash
# Interactive: token (hidden) -> region -> pick a dataset from the live list
horus connect axiom

# Non-interactive
horus connect axiom --token $AXIOM_TOKEN --dataset my-logs
horus connect axiom --token $AXIOM_TOKEN --dataset my-logs --url https://api.eu.axiom.co

Required: --token and --dataset. --url selects the region or a self-hosted base URL and defaults to the US region (https://api.axiom.co); only a non-default URL is persisted to .horus/config.json. Supply the token via an environment variable rather than committing it.

How it appears in investigations

Axiom evidence is tagged logs. Each row becomes one log evidence item with its fields on the payload, a redacted message in the title, and provenance (the dataset query plus a collection timestamp). High-volume error signatures carry their occurrence count and latest-seen time in the title, and relevance is weighted by hint-term match, recency, and log level.

Troubleshooting

SymptomFix
horus connect cannot list datasetsCheck the token, network, and region. You can also enter the dataset name manually, or pass --dataset directly.
No log evidence appearsConfirm the dataset name and that the incident window overlaps recent events. Verify the region with --url (EU is https://api.eu.axiom.co).
horus connect axiom is not recognizedUpdate the CLI — the Axiom connector requires version 0.11.0 or newer.

Shopify Admin state

The Shopify connector reads admin and business data — orders, inventory, fulfillment, customers, and more — from the Shopify Admin GraphQL API and folds each query result into an investigation as state evidence. It embeds no queries of its own: you supply the GraphQL document, either with --shopify-query at investigate time or as named default queries in .horus/config.json that horus watch runs each cycle. It is strictly read-only.

Requires CLI 0.19.0 or newer

The Shopify Admin connector shipped in Horus CLI 0.19.0. Run horus --version and update if needed.

When to use it

  • You run a Shopify store and want admin state — order, fulfillment, and inventory counts and statuses — correlated with code and other evidence.
  • You want horus watch to poll named Shopify queries each cycle and fold the results in as evidence.

Setup

Shopify supports two auth models: a static Admin API access token (a Custom App shpat_… token used directly, with no access id), or a client-credentials app (client_id + client_secret, exchanged for a short-lived token that Horus caches and refreshes on 401).

bash
# Static Admin API access token
horus connect shopify --store acme-store --secret $SHOPIFY_TOKEN

# Client-credentials app
horus connect shopify --store acme-store --access-id $SHOPIFY_CLIENT_ID --secret $SHOPIFY_CLIENT_SECRET

Required: --store and --secret. --store is the subdomain only (acme-store); Horus appends .myshopify.com automatically, and a full domain is also accepted. --access-id is the app client_id — omit it for a static token. --api-version defaults to 2025-10. The secret is encrypted at rest into .horus/secrets.local.json, never config.json. Running horus connect shopify with no flags prompts interactively and asks which auth model to use.

Supplying queries

At investigate time, pass your own read-only Admin GraphQL document: --shopify-query is repeatable and accepts @file, - (stdin), or a raw GraphQL string; --shopify-variables (@file or inline JSON object) applies to every query. $from and $to in the query are auto-bound to the investigation window.

bash
horus investigate "orders stuck unfulfilled" \
  --shopify-query @orders.graphql \
  --shopify-variables '{"status":"OPEN"}'

For horus watch, declare default queries under connectors.shopify.queries[] in .horus/config.json. Each entry has a name, a verbatim read-only query, optional variables, a kind (state | log | metric, default state), a relevance (0–1), and bindWindow to auto-bind the investigation window.

How it appears in investigations

Each query result becomes one evidence item, tagged state by default (a query may map to logs or metrics via its kind). The title reads Shopify <store> <query name>: N results · <time> (redacted), the GraphQL data rides on the payload, and provenance is shopify <store> <query name>. Relevance seeds at 0.6 (or the query's relevance), gains +0.2 on a hint-term match, and is clamped to 0.5–0.95. A configured Shopify connector with no queries contributes no evidence; it does not establish that the store is healthy.

Troubleshooting

SymptomFix
Token exchange returns 401Client-credentials: check --access-id/--secret and that the app is installed with the read scopes it needs. Static token: confirm the shpat_… token is valid and unexpired.
No Shopify evidence appearsSupply at least one query — --shopify-query at investigate time, or connectors.shopify.queries[] for horus watch. With no query the connector returns nothing.
Requests are slow or rate-limitedThe client bounds every request to 8s and retries HTTP 429 and GraphQL THROTTLED responses with backoff; reduce query scope if throttling persists.

How connector evidence appears together

During horus investigate, Horus asks every configured connector for evidence related to the hint. Each piece is tagged by source: logs (Elasticsearch, Axiom, Sentry, Azure Monitor, CloudWatch, Google Cloud Logging, Lens), metrics (Grafana, Prometheus), state (MongoDB, PostgreSQL, Firestore, SQL Server, Shopify, Redis), queue (BullMQ, Service Bus, Kafka), and history (git). The report surfaces only the evidence that is relevant and non-empty.

Connector evidence is combined with source-intelligence evidence and git evidence. The scoring engine ranks causes based on the full set; no single source overrides another.

Security and permissions

  • All connectors are read-only.
  • Use dedicated read-only users where possible.
  • Connector credentials are AES-256-GCM encrypted at rest into .horus/secrets.local.json (never config.json), unlocked by a master key from HORUS_SECRET_KEY, your OS keychain, or a fallback ~/.horus/keyring/master.key file. horus connect adds .horus/ to the repo-local .git/info/exclude, never your tracked .gitignore; manage the store with horus secrets status|migrate|key.
  • MongoDB collections and PostgreSQL tables can be allowlisted with --collections/--tables; an empty allowlist auto-discovers all. The allowlist narrows Horus queries; database permissions are the authorization boundary.
  • The Redis connection URL (including any embedded password) is itself an encrypted secret at rest.
  • Shopify uses a client_secret or static Admin API token, encrypted at rest; env fallbacks are SHOPIFY_ACCESS_ID / SHOPIFY_SECRET.
  • Sentry uses a read-only auth token; supply it via an environment variable rather than committing it.
  • Axiom uses an API token; supply it via an environment variable rather than committing it.

What is not a runtime connector

These capabilities are handled differently and are not configured through horus connect:

  • Source intelligence — configured via horus init (use --source to point at an external host).
  • Git evidence — read from the local repository; no URL or credentials needed.
  • Distributed tracing — Horus can correlate by trace ID when present in logs, but it does not ingest trace spans directly today.

Next steps

See Getting started for the first-run workflow, Source intelligence for code context, and CLI reference for every horus connect option.