{"id":26186978,"url":"https://github.com/ivarref/healthy","last_synced_at":"2025-10-09T07:06:10.083Z","repository":{"id":137669548,"uuid":"473558978","full_name":"ivarref/healthy","owner":"ivarref","description":"A simple Clojure (JVM) library for doing health checks over a given duration.","archived":false,"fork":false,"pushed_at":"2022-09-18T18:37:37.000Z","size":26,"stargazers_count":13,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-09T07:03:12.299Z","etag":null,"topics":["clojure","health","health-check","healthcheck"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ivarref.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}},"created_at":"2022-03-24T10:32:48.000Z","updated_at":"2023-11-02T06:19:06.000Z","dependencies_parsed_at":null,"dependency_job_id":"5310849b-2075-4460-9534-ae87c8a15e89","html_url":"https://github.com/ivarref/healthy","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/ivarref/healthy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivarref%2Fhealthy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivarref%2Fhealthy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivarref%2Fhealthy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivarref%2Fhealthy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ivarref","download_url":"https://codeload.github.com/ivarref/healthy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivarref%2Fhealthy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279000986,"owners_count":26082971,"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","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["clojure","health","health-check","healthcheck"],"created_at":"2025-03-11T23:35:58.547Z","updated_at":"2025-10-09T07:06:10.052Z","avatar_url":"https://github.com/ivarref.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# healthy\n\nA simple Clojure (JVM) library for doing health checks over a given duration.\n\n## Installation\n\n[![Clojars Project](https://img.shields.io/clojars/v/com.github.ivarref/healthy.svg)](https://clojars.org/com.github.ivarref/healthy)\n\n## 1-minute example\n\n```clojure\n(require '[com.github.ivarref.healthy :as h])\n\n; Initialize. Set the duration to keep errors for to be 1 minute:\n(h/init! {:duration \"PT1M\"})\n; :duration is given as a ISO 8601 duration: \n; https://en.wikipedia.org/wiki/ISO_8601#Durations\n; :duration must be at least 60 seconds.\n\n; Add an error:\n(h/add-error!)\n; =\u003e 1 ; error count\n\n; Add another error:\n(h/add-error!)\n; =\u003e 2 ; error count\n\n(h/add-error!)\n; =\u003e 3 ; error count\n\n; Add an OK event:\n(h/add-ok!)\n; =\u003e 1 ; ok count\n\n; Get error percentage:\n(h/error-percentage)\n; =\u003e 75.0\n\n; Or alternatively get the error count:\n(h/error-count)\n; =\u003e 3\n\n; Wait 1 minute. Then get error percentage (or error count) again:\n(h/error-percentage)\n; Yes, this function changes state though there is no bang!\n; =\u003e 0.0\n```\n\n## Example usage for HTTP server backends\n\nThe idea is that you may for example want to invoke `(h/add-error!)` if a request takes\ntoo long to finish or fails in some unexpected way. \nInvoke `(h/add-ok!)` otherwise if the request is fine.\n\nYour `/health` endpoint or similar may return healthy (or not) based on `(h/error-percentage)`\nlike the following:\n\n```clojure\n(defn healthcheck [{:keys [response]}]\n  (let [error-percentage (h/error-percentage)]\n    (if (\u003e= error-percentage 5.0) ; if more than 5% of requests failed, return unhealthy\n      (do\n        (log/warn \"Error percentage is\" error-percentage \", returning unhealthy\")\n        (assoc response\n          :status 503\n          :body {:status \"Unhealthy, too many errors\"}))\n      (assoc response\n        :status 200\n        :body {:status \"OK\"}))))\n```\n\nIf you use this example, make sure that `(h/add-error!)` is *not* invoked \nwhen `/health` returns unhealthy, otherwise your service may not be able to recover.\nYes, I did that mistake ¯\\\\\\_(ツ)\\_/¯.\n\n## Change log\n\n#### 2022-09-18 v0.1.18 [diff](https://github.com/ivarref/healthy/compare/v0.1.17...v0.1.18)\nAdd `com.github.ivarref.healthy2` namespace, allowing any number of health checks.\n\nExample usage documented in the tests:\n\n```clojure\n(deftest basics\n  (let [now-ms (atom 0)\n        x (h2/init {:duration \"PT60M\"\n                    :ok?      #(\u003c= % 1000)\n                    :now-ms   (fn [] @now-ms)\n                    :healthy? (fn [{:keys [error-percentage]}]\n                                (not (\u003e= error-percentage 5)))})]\n    (is (true? @x))\n    (x 100)\n    (is (true? @x))\n    (x 10000)\n    (is (false? @x))\n    (swap! now-ms (partial + (dec (.toMillis (Duration/ofHours 1)))))\n    (is (false? @x))\n    (swap! now-ms inc)\n    (is (true? @x))))\n```\n\n#### 2022-09-07 v0.1.17 [diff](https://github.com/ivarref/healthy/compare/v0.1.16...v0.1.17)\nAdd concept of error-percentage.\n\nChanged internal bucket storage size from 60 seconds to 1 second.\n\n#### 2022-03-24 v0.1.16\nInitial public release.\n\n## License\n\nCopyright © 2022 Ivar Refsdal\n\nThis program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0.\n\nThis Source Code may also be made available under the following Secondary Licenses when the conditions for such availability set forth in the Eclipse Public License, v. 2.0 are satisfied: GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version, with the GNU Classpath Exception which is available at https://www.gnu.org/software/classpath/license.html.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivarref%2Fhealthy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fivarref%2Fhealthy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivarref%2Fhealthy/lists"}