{"id":24461013,"url":"https://github.com/kilnfi/cardano-validator-watcher","last_synced_at":"2026-04-17T18:04:24.417Z","repository":{"id":264059460,"uuid":"892210566","full_name":"kilnfi/cardano-validator-watcher","owner":"kilnfi","description":null,"archived":false,"fork":false,"pushed_at":"2026-04-17T16:40:21.000Z","size":1007,"stargazers_count":5,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-17T17:29:32.839Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kilnfi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-11-21T17:41:11.000Z","updated_at":"2026-04-17T16:39:04.000Z","dependencies_parsed_at":"2024-11-21T19:34:28.639Z","dependency_job_id":"ea4d0e23-a4ee-4d66-a9e0-1dfecb4bb703","html_url":"https://github.com/kilnfi/cardano-validator-watcher","commit_stats":null,"previous_names":["kilnfi/cardano-validator-watcher"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/kilnfi/cardano-validator-watcher","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kilnfi%2Fcardano-validator-watcher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kilnfi%2Fcardano-validator-watcher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kilnfi%2Fcardano-validator-watcher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kilnfi%2Fcardano-validator-watcher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kilnfi","download_url":"https://codeload.github.com/kilnfi/cardano-validator-watcher/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kilnfi%2Fcardano-validator-watcher/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31939800,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-17T17:29:20.459Z","status":"ssl_error","status_checked_at":"2026-04-17T17:28:47.801Z","response_time":62,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-01-21T04:17:02.905Z","updated_at":"2026-04-17T18:04:24.408Z","avatar_url":"https://github.com/kilnfi.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Cardano Validator Watcher\n\n**Cardano Validator Watcher** is a Prometheus exporter designed to help you monitor your Cardano validator nodes. It periodically collects essential metrics, providing valuable insights into the performance and health of your infrastructure. These exported metrics can be used to build monitoring dashboards _(e.g with Grafana)_ and configure alerting rules to stay notified when something goes wrong.\n\n\u003cimg src=\"./docs/images/banner.jpg\" alt=\"banner\" style=\"width:100%;\"\u003e\n\n## Dependencies\n\nThis project use the following dependencies:\n\n- [BlockFrost](https://blockfrost.dev/). You need to have a account and a subscription.\n- [cncli](https://github.com/cardano-community/cncli) to calculate the slot leaders.\n- [cardano-cli](https://github.com/IntersectMBO/cardano-cli) to query additional data from a RPC node.\n- A valid RPC node.\n- Download the [Genesis configuration files](https://book.world.dev.cardano.org/environments.html) and provide the VRF signing key for each monitored pool.\n\n## Usage\n\nThe watcher needs access to your Cardano node's socket. Two options are available:\n\n### Option A — socat sidecar (watcher has direct socket access)\n\nRun socat alongside the watcher to expose the node socket locally:\n\n```bash\n# With Kubernetes\nkubectl port-forward pod/\u003cPOD_NAME\u003e 3002 \u0026\nsocat UNIX-LISTEN:/tmp/cardano.socket,fork,reuseaddr,unlink-early TCP:127.0.0.1:3002\n\n# Without Kubernetes\nsocat UNIX-LISTEN:/tmp/cardano.socket,fork,reuseaddr,unlink-early TCP:\u003cIP\u003e:\u003cPORT\u003e\n```\n\nThen configure `socket-path` in the watcher config.\n\n### Option B — Go socket proxy (no socat needed in the watcher pod)\n\nIf socat is already running on the node pod (exposing the socket over TCP), the watcher can connect directly without a local socat sidecar. Configure `node-host` and `socat-port` and the watcher will manage the proxy internally.\n\nEnsure that you have downloaded the [Genesis configuration files](https://book.world.dev.cardano.org/environments.html). You also need to provide the VRF signing key for each monitored pool.\n\nThen, to start the watcher, execute the following command:\n\n```bash\n./cardano-validator-watcher [flags]\n```\n\n### Flags\n\n| Flag                                  | Description                                                                           | Default Value             | Required |\n|---------------------------------------|---------------------------------------------------------------------------------------|---------------------------|----------|\n| `--config`                            | Path to the configuration file                                                        | `config.yml`              | No       |\n| `--log-level`                         | Log Level                                                                             | `info`                    | No       |\n| `--http-server-host`                  | Host on which the HTTP server should listen                                           | `127.0.0.1`               | No       |\n| `--http-server-port`                  | Port on which the HTTP server should listen                                           | `8080`                    | No       |\n| `--network`                           | Cardano network ID                                                                    | `preprod`                 | Yes      |\n| `--database-path`                     | Path to the local database mainly used by the Cardano client                          | `watcher.db`              | No       |\n| `--cardano-config-dir`                | Path to the directory where Cardano configuration files are stored                    | `/config`                 | No       |\n| `--cardano-timezone`                  | Timezone to use with cardano-cli                                                      | `UTC`                     | No       |\n| `--cardano-socket-path`               | Path of the socket to communicate with a Cardano node (Option A)                      | `/var/run/cardano.socket` | No       |\n| `--cardano-node-host`                 | Hostname/IP of the cardano-node service (Option B)                                    |                           | No       |\n| `--cardano-socat-port`                | TCP port where socat on the node pod exposes the Unix socket (Option B)               |                           | No       |\n| `--blockfrost-project-id`             | Blockfrost project ID                                                                 |                           | Yes      |\n| `--blockfrost-endpoint`               | Blockfrost API endpoint                                                               |                           | Yes      |\n| `--blockfrost-max-routines`           | Number of routines used by Blockfrost to perform concurrent actions                   | `10`                      | No       |\n| `--blockfrost-timeout`                | Timeout for requests to the Blockfrost API (in seconds)                               | `60`                      | No       |\n| `--block-watcher-enabled`             | Enable block watcher                                                                  | `True`                    | No       |\n| `--block-watcher-refresh-interval`    | Interval at which the block watcher collects and processes slots (in seconds)         | `60`                      | No       |\n| `--pool-watcher-enabled`              | Enable pool watcher                                                                   | `True`                    | No       |\n| `--pool-watcher-refresh-interval`     | Interval at which the pool watcher collects data on monitored pools (in seconds)      | `60`                      | No       |\n| `--network-watcher-enabled`           | Enable network watcher                                                                | `True`                    | No       |\n| `--network-watcher-refresh-interval`  | Interval at which the network watcher collects data related to network (in seconds)   | `60`                      | No       |\n| `--status-watcher-refresh-interval`   | Interval at which the status watcher collects data related to health (in seconds)     | `15`                      | No       |\n\n## Configuration\n\nThe watcher uses a `config.yaml` file in the current working directory by default. Use the `--config` flag to specify a different configuration file.\n\n### Full Example\n```yaml\npools:\n  - instance: \"cardano-producer-pool-0\"\n    id: \"pool1abcd1234efgh5678ijklmnopqrstuvwx\"\n    name: \"pool-0\"\n    key: \"config/pool-0.vrf.skey\"\n  - instance: \"cardano-producer-pool-1\"\n    id: \"pool2abcd1234efgh5678ijklmnopqrstuvwx\"\n    name: \"pool-1\"\n    key: \"config/pool-1.vrf.skey\"\n    exclude: true\n    allow-empty-slots: true\nnetwork: \"mainnet\"\nblock-watcher:\n  enabled: true\n  refresh-interval: 30\npool-watcher:\n  enabled: true\n  refresh-interval: 30\nnetwork-watcher:\n  enabled: true\n  refresh-interval: 30\nstatus-watcher:\n  enabled: true\n  refresh-interval: 15\ndatabase:\n  path: \"watcher.db\"\nblockfrost:\n  project-id: \"thisissecret\"\n  endpoint: \"https://cardano-mainnet.blockfrost.io/api/v0\"\n  max-routines: 10\n  timeout: 60\nhttp:\n  host: \"0.0.0.0\"\n  port: 8080\ncardano:\n  config-dir: \"config\"\n  socket-path: \"/tmp/cardano.socket\"\n  timezone: \"UTC\"\n```\n\n### Pools Settings\n\n| Field                     | Description                                               | Example                                                             |\n|---------------------------|-----------------------------------------------------------|---------------------------------------------------------------------|\n| `instance`                | Name of the instance                                      | `\"cardano-producer-pool-0\"`                                 |\n| `id`                      | Pool ID                                                   | `\"pool1abcd1234efgh5678ijklmnopqrstuvwx\"`        |\n| `name`                    | Name of the pool                                          | `\"pool-0\"`                                                          |\n| `key`                     | Path to the key file                                      | `\"config/pool-0.vrf.skey\"`                                          |\n| `exclude`                 | Exclude the pool from monitoring                          | `true`                                                              |\n| `allow-empty-slots`       | Pools is allowed to not have slot leaders                 | `false`                                          |\n\n\n### Global Settings\n\n| Field      | Description             | Example       |\n|------------|-------------------------|---------------|\n| `network`  | Name of the network     | `\"mainnet\"`   |\n\n```yaml\nnetwork: \"mainnet\"\n```\n\n### Block Watcher Settings\n\n| Field                 | Description                                                             | Example   |\n|-----------------------|-------------------------------------------------------------------------|-----------|\n| `enabled`             | Enable block watcher                                                    | `True`      |\n| `refresh-interval`    | Time, in seconds, between two consecutive collections of block data     | `60`      |\n\n```yaml\nblock-watcher:\n  enabled: true\n  refresh-interval: 30\n```\n\n### Pool Watcher Settings\n\n| Field                 | Description                                                             | Example   |\n|-----------------------|-------------------------------------------------------------------------|-----------|\n| `enabled`             | Enable pool watcher                                                     | `True`    |\n| `refresh-interval`    | Time, in seconds, between two consecutive collections of pool data      | `60`      |\n\n```yaml\npool-watcher:\n  enabled: true\n  refresh-interval: 30\n```\n\n### Status Watcher Settings\n\n| Field                 | Description                                                             | Example   |\n|-----------------------|-------------------------------------------------------------------------|-----------|\n| `refresh-interval`    | Time, in seconds, between two consecutive collections of status data    | `60`      |\n\n```yaml\nstatus-watcher:\n  refresh-interval: 30\n```\n\n### Network Watcher Settings\n\n| Field                 | Description                                                             | Example   |\n|-----------------------|-------------------------------------------------------------------------|-----------|\n| `enabled`             | Enable network watcher                                                  | `True`    |\n| `refresh-interval`    | Time, in seconds, between two consecutive collections of network data   | `60`      |\n\n```yaml\nnetwork-watcher:\n  enabled: true\n  refresh-interval: 30\n```\n\n### Database Settings\n\n| Field      | Description                                  | Example        |\n|------------|----------------------------------------------|----------------|\n| `path`     | Path to the database file                    | `\"watcher.db\"` |\n\n```yaml\ndatabase:\n  path: \"watcher.db\"\n```\n\n### Blockfrost Settings\n\n| Field         | Description                                                                 | Example                                                 |\n|---------------|-----------------------------------------------------------------------------|---------------------------------------------------------|\n| `project-id`  | Blockfrost project ID                                                       | `\"thisissecret\"`                                        |\n| `endpoint`    | Blockfrost API endpoint                                                     | `\"https://cardano-mainnet.blockfrost.io/api/v0\"`        |\n| `max-routines`| Number of routines used by Blockfrost to perform concurrent actions         | `10`                                                    |\n| `timeout`     | Timeout for requests to the Blockfrost API (in seconds)                     | `60`                                                    |\n\n```yaml\nblockfrost:\n  project-id: \"thisissecret\"\n  endpoint: \"https://cardano-mainnet.blockfrost.io/api/v0\"\n  max-routines: 10\n  timeout: 60\n```\n\n### HTTP Server Settings\n\n| Field      | Description                                      | Example   |\n|------------|--------------------------------------------------|-----------|\n| `port`     | Port on which the HTTP server should listen      | `8080`    |\n\n```yaml\nhttp:\n  host: \"0.0.0.0\"\n  port: 8080\n```\n\n### Cardano Settings\n\n| Field          | Description                                                              | Example                      |\n|----------------|--------------------------------------------------------------------------|------------------------------|\n| `config-dir`   | Path to the directory where Cardano configuration files are stored       | `\"config\"`                   |\n| `timezone`     | Timezone to use with cardano-cli                                         | `\"UTC\"`                      |\n| `socket-path`  | Path of the socket to communicate with a Cardano node (Option A)         | `\"/tmp/cardano.socket\"`      |\n| `node-host`    | Hostname/IP of the cardano-node service (Option B)                       | `\"cardano-node-service\"`     |\n| `socat-port`   | TCP port where socat on the node pod exposes the Unix socket (Option B)  | `3002`                       |\n\n```yaml\n# Option A: socat sidecar in the watcher pod\ncardano:\n  config-dir: \"config\"\n  timezone: \"UTC\"\n  socket-path: \"/tmp/cardano.socket\"\n\n# Option B: Go-managed proxy, no socat needed in the watcher pod\ncardano:\n  config-dir: \"config\"\n  timezone: \"UTC\"\n  node-host: \"cardano-node-service\"\n  socat-port: 3002\n```\n\n## Metrics\n\n| Metric Name                                                       | Description          | Type | Labels |\n| ----------------------------------------------------------------- | -------------------- |---- | --- |\n| `cardano_validator_watcher_pool_relay_count`                      | Number of relays associated with each pool                                  | GaugeVec    | `pool_name`, `pool_id`, `pool_instance` |\n| `cardano_validator_watcher_pool_pledge_met`                       | Indicates whether the pool has met its pledge requirements or not (0 or 1)  | GaugeVec    | `pool_name`, `pool_id`, `pool_instance` |\n| `cardano_validator_watcher_pool_saturation_level`                 | The current saturation level of the pool in percent                         | GaugeVec    | `pool_name`, `pool_id`, `pool_instance` |\n| `cardano_validator_watcher_pool_drep_registered`                  | Whether the pool owner is registered to a DRep (0 or 1)                    | GaugeVec    | `pool_name`, `pool_id`, `pool_instance` |\n| `cardano_validator_watcher_next_epoch_start_time`                 | Start time of the next epoch in seconds                                     | Gauge       | - |\n| `cardano_validator_watcher_monitored_validators_count`            | Number of validators monitored by the watcher                               | Gauge       | - |\n| `cardano_validator_watcher_missed_blocks`                         | Number of missed blocks in the current epoch                                | CounterVec  | `pool_name`, `pool_id`, `pool_instance`, `epoch` |\n| `cardano_validator_watcher_consecutive_missed_blocks`             | Number of blocks missed consecutively.                                      | GaugeVec    | `pool_name`, `pool_id`, `pool_instance`, `epoch` |\n| `cardano_validator_watcher_validated_blocks`                      | Number of validated blocks in the current epoch                             | CounterVec  | `pool_name`, `pool_id`, `pool_instance`, `epoch` |\n| `cardano_validator_watcher_orphaned_blocks`                       | Number of orphaned blocks in the current epoch                              | CounterVec  | `pool_name`, `pool_id`, `pool_instance`, `epoch` |\n| `cardano_validator_watcher_expected_blocks`                       | Number of expected blocks in the current epoch                              | CounterVec  | `pool_name`, `pool_id`, `pool_instance`, `epoch` |\n| `cardano_validator_watcher_latest_slot_processed_by_block_watcher`| Latest slot processed by block watcher                                      | Gauge       | - |\n| `cardano_validator_watcher_next_slot_leader`                      | Next slot leader for each monitored pool                                    | GaugeVec    | `pool_name`, `pool_id`, `pool_instance`, `epoch` |\n| `cardano_validator_watcher_epoch_duration`                        | Duration of an epoch in days                                                | Gauge       | - |\n| `cardano_validator_watcher_network_epoch`                         | Current epoch number                                                        | Gauge       | - |\n| `cardano_validator_watcher_network_block_height`                  | Latest known block height                                                   | Gauge       | - |\n| `cardano_validator_watcher_network_slot`                          | Latest known slot                                                           | Gauge       | - |\n| `cardano_validator_watcher_network_epoch_slot`                    | Latest known epoch slot                                                     | Gauge       | - |\n| `cardano_validator_watcher_network_network_pools_total`           | Total number of pools in the network                                        | Gauge       | - |\n| `cardano_validator_watcher_network_blocks_proposed_current_epoch` | Number of blocks proposed in the current epoch by the network               | Gauge       | - |\n| `cardano_validator_watcher_network_active_stake`                  | Total active stake in the network                                           | Gauge       | - |\n| `cardano_validator_watcher_chain_id`                              | ID of the chain                                                             | Gauge       | - |\n| `cardano_validator_watcher_health_status`                         | Health status of the Cardano validator watcher: 1 = healthy, 0 = unhealthy  | Gauge       | - |\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkilnfi%2Fcardano-validator-watcher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkilnfi%2Fcardano-validator-watcher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkilnfi%2Fcardano-validator-watcher/lists"}