{"id":13566419,"url":"https://github.com/setten-io/ecg","last_synced_at":"2025-04-04T00:30:42.784Z","repository":{"id":47217726,"uuid":"497442517","full_name":"setten-io/ecg","owner":"setten-io","description":" Cosmos validators dead man's switch","archived":false,"fork":false,"pushed_at":"2023-03-06T14:09:57.000Z","size":161,"stargazers_count":8,"open_issues_count":8,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-28T15:03:32.144Z","etag":null,"topics":["cosmos","heartbeat","monitor","monitoring","uptime","validator"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/setten-io.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}},"created_at":"2022-05-28T22:45:18.000Z","updated_at":"2024-03-01T01:56:31.000Z","dependencies_parsed_at":"2024-01-19T07:21:46.407Z","dependency_job_id":null,"html_url":"https://github.com/setten-io/ecg","commit_stats":{"total_commits":75,"total_committers":3,"mean_commits":25.0,"dds":"0.19999999999999996","last_synced_commit":"22d0aebe6c72cc11904d69cda08f8764d00bcc33"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/setten-io%2Fecg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/setten-io%2Fecg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/setten-io%2Fecg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/setten-io%2Fecg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/setten-io","download_url":"https://codeload.github.com/setten-io/ecg/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247103306,"owners_count":20884023,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["cosmos","heartbeat","monitor","monitoring","uptime","validator"],"created_at":"2024-08-01T13:02:09.301Z","updated_at":"2025-04-04T00:30:42.112Z","avatar_url":"https://github.com/setten-io.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://user-images.githubusercontent.com/26155267/183662242-e463b043-c58f-449b-a9fb-0130ee8bb57d.png\" alt=\"ecg\"\u003e\u003c/img\u003e\n\u003c/p\u003e\n\n[![Integration](https://github.com/setten-io/ecg/actions/workflows/integration.yaml/badge.svg)](https://github.com/setten-io/ecg/actions/workflows/integration.yaml)\n[![Delivery](https://github.com/setten-io/ecg/actions/workflows/delivery.yaml/badge.svg)](https://github.com/setten-io/ecg/actions/workflows/delivery.yaml)\n[![Crate](https://img.shields.io/crates/v/ecg)](https://crates.io/crates/ecg)\n[![License](https://img.shields.io/github/license/setten-io/ecg?no-cache)](https://github.com/setten-io/ecg/blob/main/LICENSE)\n\n`ecg` is a cosmos validators [Dead Man's Switch](https://en.wikipedia.org/wiki/Dead_man%27s_switch).\n\n---\n\nAs long as the monitor is receiving heartbeats from ecg, alerting will not be triggered.\nThis \"failure as default\" approach makes this kind of monitoring resilient to failures that might otherwise prevent you from receiving any alert.\n\nExamples:\n\n- Your whole infra loses connectivity\n- Monitoring services is down at the same time as the validator\n- Monitoring service can't access the validator\n- Monitoring service lose access to its data source (ie: LCD)\n\n\u003e **Warning**\n\u003e\n\u003e Monitoring is essential.\n\u003e Ecg and heartbeat style monitoring are complementary to other monitoring tools and methods.\n\u003e We recommend ecg as an aditional failsafe alongside more proactive tools.\n\nThere are multiple SaaS platforms like [Better Uptime](https://betteruptime.com) or [Dead Man's Snitch](https://deadmanssnitch.com) that implement heartbeat monitoring.\n\n## Features\n\n`ecg` will:\n\n1. For each target, fetch a state from all clients\n2. Keep the freshest one (highest block height)\n3. Run checks on it \n4. If they all pass, send heartbeat\n\nChecks include:\n\n- block height increased\n- validator block misses didn't increase\n- validator isn't jailed\n- validator isn't tombstoned\n\n## Getting Started\n\nThis tool is installable as a crate.\n\n```bash\ncargo install ecg\n```\n\nOr available as a Docker image.\n\n```bash\ndocker pull ghcr.io/setten-io/ecg\n```\n\n## Usage\n\n```md\necg\nHeartbeats for cosmos validators\n\nUSAGE:\n    ecg [OPTIONS]\n\nOPTIONS:\n    -h, --help           Print help information\n    -p, --path \u003cPATH\u003e    Path to yaml config [env: ECG_CONFIG_PATH=] [default: ecg.yaml]\n    -V, --version        Print version information\n```\n\nIt is possible to change ecg logging level through the `ECG_LOG` env var, or for all/any module through the `RUST_LOG` env var.\n\n## Configuration\n\n`ecg` is configured through a yaml file.\n\nThe default path is `./ecg.yaml` but can be specified through the `-p/--path` flag or the `ECG_CONFIG_PATH` env var.\n\n### Example\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003eecg.yaml\u003c/code\u003e\u003c/summary\u003e\n\u003cbr\u003e\n\n```yaml\ntargets:\n  phoenix:\n    url: https://betteruptime.com/api/v1/heartbeat/fFKHCd3YNkayv8Fr6MJAFE3w\n    valcons_address: terravalcons1qqyfhs9oacvteimwdpbt77fis88mie5gx6gxf2\n    interval: 10\n    clients:\n      - type: lcd\n        url: https://phoenix-lcd.terra.dev\n      - type: lcd\n        url: https://terra-api.polkachu.com\n      - type: setten-lcd\n        project_id: ea08855653b64998bb47b2c03bf66de7\n        key: 02215b36969446c28b22059e63b4301b\n        network: phoenix\n        blockchain: terra\n  kaiyo:\n    url: https://betteruptime.com/api/v1/heartbeat/t6xm2P7Ujfjz3ph5TNBFti8X\n    valcons_address: kujiravalcons14rt55jpahf4giiupxrxivy85ecog2onb29a2ev\n    interval: 2\n    clients:\n      - type: lcd\n        url: https://lcd.kaiyo.kujira.setten.io\n      - type: lcd\n        url: https://kujira-api.polkachu.com\n```\n\n\u003c/details\u003e\n\n\n### Specification\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003etargets.\u0026lt;name\u0026gt;\u003c/code\u003e\u003c/summary\u003e\n\u003cbr\u003e\n\nThe name of your target;\nShould be self-explanatory.\n\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003etargets.\u0026lt;name\u0026gt;.url\u003c/code\u003e\u003c/summary\u003e\n\u003cbr\u003e\n\nThe url of the monitor to send `GET` http heartbeat requests to.\n\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003etargets.\u0026lt;name\u0026gt;.valcons_address\u003c/code\u003e\u003c/summary\u003e\n\u003cbr\u003e\n\nThe validator valcons address.\n\nIt can be found using the cosmos sdk chain binary cli:\n\n```bash\nterrad tendermint show-address\n```\n\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003etargets.\u0026lt;name\u0026gt;.interval\u003c/code\u003e\u003c/summary\u003e\n\u003cbr\u003e\n\n\u003e Optional, default to 30\n\nInterval in seconds between each cycle (run checks + send heartbeat).\n\nYou must set this in accordance to the heartbeat frequency your monitor is expecting to receive and the chain block time.\n\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003etargets.\u0026lt;name\u0026gt;.clients\u003c/code\u003e\u003c/summary\u003e\n\u003cbr\u003e\n\nArray of redundant clients to querry in parallel.\n\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003etargets.\u0026lt;name\u0026gt;.clients[*].type\u003c/code\u003e\u003c/summary\u003e\n\u003cbr\u003e\n\nType defines the kind of clients and the configuration keys that will be available.\n\nAvailable client types and their configurations:\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003elcd\u003c/code\u003e\u003c/summary\u003e\n\u003cbr\u003e\n\n* `url` - LCD endpoint to query (ex: `https://kujira-api.polkachu.com`)\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003esetten-lcd\u003c/code\u003e\u003c/summary\u003e\n\u003cbr\u003e\n\n* `project_id` - Setten project id (ex: `ea08855653b64998bb47b2c03bf66de7`)\n* `key` - Setten project key (ex: `02215b36969446c28b22059e63b4301b`)\n* `network` - Setten network slug (ex: `phoenix`)\n* `blockchain` - Setten blockchain slug (ex: `terra`)\n\nFor network and blockchain slugs, please see [Setten's docs](https://docs.setten.io/concepts/products-and-networks#supported-networks)\n\n\u003c/details\u003e\n\n\u003c/details\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsetten-io%2Fecg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsetten-io%2Fecg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsetten-io%2Fecg/lists"}