{"id":15138633,"url":"https://github.com/sksamuel/cohort","last_synced_at":"2025-04-04T12:07:03.085Z","repository":{"id":38210366,"uuid":"342731382","full_name":"sksamuel/cohort","owner":"sksamuel","description":"Ktor/Vertx spring-actuator style library - healthchecks, logging, database","archived":false,"fork":false,"pushed_at":"2025-02-06T01:13:42.000Z","size":859,"stargazers_count":138,"open_issues_count":1,"forks_count":9,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-03-28T11:07:00.749Z","etag":null,"topics":["actuator","kotlin","ktor","vertx"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sksamuel.png","metadata":{"files":{"readme":"README.md","changelog":"changelog.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-27T00:02:14.000Z","updated_at":"2025-03-27T03:06:48.000Z","dependencies_parsed_at":"2025-01-25T04:22:33.182Z","dependency_job_id":"ef4c557d-bb92-473b-b09e-34754947991b","html_url":"https://github.com/sksamuel/cohort","commit_stats":null,"previous_names":["sksamuel/healthcheck"],"tags_count":44,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sksamuel%2Fcohort","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sksamuel%2Fcohort/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sksamuel%2Fcohort/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sksamuel%2Fcohort/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sksamuel","download_url":"https://codeload.github.com/sksamuel/cohort/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247174407,"owners_count":20896076,"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":["actuator","kotlin","ktor","vertx"],"created_at":"2024-09-26T07:42:37.708Z","updated_at":"2025-04-04T12:07:03.075Z","avatar_url":"https://github.com/sksamuel.png","language":"Kotlin","funding_links":[],"categories":["Ktor Projects","容错组件"],"sub_categories":["Socials"],"readme":"# Cohort\n\n![main](https://github.com/sksamuel/cohort/workflows/main/badge.svg)\n[\u003cimg src=\"https://img.shields.io/maven-central/v/com.sksamuel.cohort/cohort-api.svg?label=latest%20release\"/\u003e](http://search.maven.org/#search%7Cga%7C1%7Ccohort)\n[\u003cimg src=\"https://img.shields.io/nexus/s/https/s01.oss.sonatype.org/com.sksamuel.cohort/cohort-api.svg?label=latest%20snapshot\u0026style=plastic\"/\u003e](https://s01.oss.sonatype.org/content/repositories/snapshots/com/sksamuel/cohort/)\n\nCohort is a [Spring Actuator](https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html) style\nreplacement for [Ktor](https://ktor.io) and [Vertx](https://vertx.io). It provides health checks for orchestrators like Kubernetes and management of logging, databases, JVM settings, memory and threads in production.\n\nSee [changelog](changelog.md)\n\n## Features\n\n**All features are disabled by default**.\n\n* **Comprehensive system healthchecks:** Expose healthcheck endpoints that check for thread deadlocks, memory usage,\n  disk space, cpu usage, garbage collection and more.\n* **Resource healthchecks:** Additional modules to monitor the health of Redis, Kafka, Elasticsearch, databases and\n  other resources.\n* **Micrometer integration:** Send healthcheck metrics to a [micrometer registry](#micrometer), so you can see which\n  healthchecks are consistently failing or flakely.\n* **Database pools:** See runtime metrics such as active and idle connections in database pools such as Hikari\n  Connection Pool.\n* **JVM Info:** Enable endpoints to export system properties, JVM arguments and version information, and O/S name /\n  version.\n* **Thread and heap dumps:** Optional endpoints to export a thread dump or heap dump, in the standard JVM format, for\n  analysis locally.\n* **Database migrations:** See the status of applied and pending database migrations from\n  either [Flyway](https://flywaydb.org/) or [Liquibase](https://liquibase.org/).\n* **Logging configuration:** View configured loggers and levels and modify log levels at runtime.\n\n## How to use\n\n### For ktor projects:\n\nInclude the following dependencies in your build:\n\n* `com.sksamuel.cohort:cohort-ktor:\u003cversion\u003e`\n\nThen to wire into Ktor, install the `Cohort` plugin, and enable whichever features / endpoints we want to expose.\nRemember, endpoints are disabled by default for security, and you must enable them.\n\nHere is a sample configuration with each feature enabled.\n\n```kotlin\ninstall(Cohort) {\n\n   // enable an endpoint to display operating system name and version\n   operatingSystem = true\n\n   // enable runtime JVM information such as vm options and vendor name\n   jvmInfo = true\n\n   // configure the Logback log manager to show effective log levels and allow runtime adjustment\n   logManager = LogbackManager\n\n   // show connection pool information\n   dataSources = listOf(HikariDataSourceManager(ds))\n\n   // show current system properties\n   sysprops = true\n\n   // enable an endpoint to dump the heap in hprof format\n   heapdump = true\n\n   // enable an endpoint to dump threads\n   threaddump = true\n\n   // set to true to return the detailed status of the healthcheck response\n   verboseHealthCheckResponse = true\n\n   // enable healthchecks for kubernetes\n   // each of these is optional and can map to any healthcheck url you wish\n   // for example if you just want a single health endpoint, you could use /health\n   healthcheck(\"/liveness\", livechecks)\n   healthcheck(\"/readiness\", readychecks)\n   healthcheck(\"/startup\", startupchecks)\n}\n```\n\n### For vertx projects:\n\nInclude the following dependencies in your build:\n\n* `com.sksamuel.cohort:cohort-vertx:\u003cversion\u003e`\n\nThen in your app, create a `cohort` object using the `initializeCohort` function. Then pass that object to the `router.cohort` extension function.\nNote: If you are deploying multiple instances of a verticle, be sure to initialize cohort outside of the verticle and pass in the instance. Otherwise, each verticle will create its own set of background checks.\n\nHere is a sample configuration with each feature enabled.\n\n```kotlin\nval cohort = initializeCohort {\n\n   // enable an endpoint to display operating system name and version\n   operatingSystem = true\n\n   // enable runtime JVM information such as vm options and vendor name\n   jvmInfo = true\n\n   // configure the Logback log manager to show effective log levels and allow runtime adjustment\n   logManager = LogbackManager\n\n   // show connection pool information\n   dataSources = listOf(HikariDataSourceManager(ds))\n\n   // show current system properties\n   sysprops = true\n\n   // enable an endpoint to dump the heap in hprof format\n   heapdump = true\n\n   // enable an endpoint to dump threads\n   threaddump = true\n\n   // enable healthchecks for kubernetes\n   // each of these is optional and can map to any healthcheck url you wish\n   // for example if you just want a single health endpoint, you could use /health\n   healthcheck(\"/liveness\", livenessChecks)\n   healthcheck(\"/readiness\", readinessChecks)\n   healthcheck(\"/startup\", startupChecks)\n}\n\nval vertx = Vertx.vertx()\nval router = Router.router(vertx)\nrouter.cohort(cohort)\n```\n\n### Other modules\n\nFinally, add any additional modules for any features you wish to activate. For example the kafka module\nrequires `com.sksamuel.cohort:cohort-kafka:\u003cversion\u003e`.\n\n\n\n## Healthchecks\n\nCohort provides `HealthCheck`s for a variety of JVM metrics such as memory and thread deadlocks as well as connectivity\nto services such as Kafka and Elasticsearch and databases.\n\nWe use health checks by adding them to a `HealthCheckRegistry` instance, along with an interval of how often to run the\nchecks. A registry requires a _coroutine dispatcher_ to execute the checks on. Healthchecks can take advantage of\ncoroutines to suspend if they need to do something IO based. Cohort will periodically run these healthchecks based on\nthe passed schedule and record if they are healthy or unhealthy.\n\nFor example:\n\n```kotlin\nval checks = HealthCheckRegistry(Dispatchers.Default) {\n\n   // detects if threads are mutually blocked on each others locks\n   register(ThreadDeadlockHealthCheck(), 1.minutes)\n\n   // checks that we always have at least one database connection open\n   register(HikariConnectionsHealthCheck(ds, 1), 5.seconds)\n}\n```\n\nWith the registry created, we register it with Cohort by invoking the `healthcheck` method along with an endpoint url to\nexpose it on.\n\nFor example:\n\n```kotlin\ninstall(Cohort) {\n   healthcheck(\"/healthcheck\", checks)\n}\n```\n\nWhenever the endpoint is accessed, a `200` is returned if all health checks are currently reporting healthy, and a `500`\notherwise.\n\nWhich healthchecks you use is entirely up to you, and you may want to use some healthchecks for startup probes, some for\nreadiness checks and some for liveness checks. See the section on [kubernetes](#Kubernetes) for discussion on how to\nstructure healthchecks in a kubernetes environment.\n\nIf you wish to output the results of each metric scan, you can hook into [micrometer](#micrometer).\n\n### Available Healthchecks\n\nThis table lists the available health checks and their uses.\n\n| Healthcheck                            | Module              | Details                                                                                                                                                                                                                                          |\n|----------------------------------------|:--------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `AvailableCoresHealthCheck`            | `cohort-core`       | Checks for a minimum number of available CPU cores. While the number of cores won't change during the lifetime of a pod, this check can be useful to avoid accidentally deploying pods into environments that don't have the required resources. |\n| `DaemonThreadsHealthCheck`             | `cohort-core`       | Checks that the number of daemon threads does not exceed a threshold.                                                                                                                                                                            |\n| `DatabaseConnectionHealthCheck`        | `cohort-core`       | Checks that a database connection can be retrieved from a `DataSource` and that the connection is valid. This healthcheck is useful to determine if a `DataSource` is becoming contended and cannnot return a connection in a timely manner.     |\n| `DbcpConnectionsHealthCheck`           | `cohort-dbcp`       | Checks that the number of connections in an Apache DBCP2 connection pool is at least equal to a min value.                                                                                                                                       |\n| `DbcpMinIdleHealthCheck`               | `cohort-dbcp`       | Checks that the number of idle connections in an Apache DBCP2 connection pool is at least equal to a min value.                                                                                                                                  |\n| `DiskSpaceHealthCheck`                 | `cohort-core`       | Checks that the available disk space on a filestore is below a threshold.                                                                                                                                                                        |\n| `DynamoDBHealthCheck`                  | `cohort-aws-dynamo` | Checks connectivity to an AWS DynamoDB instance.                                                                                                                                                                                                 |\n| `ElasticClusterHealthCheck`            | `cohort-elastic`    | Checks that an elasticsearch cluster is reachable and the cluster is in \"green\" state.                                                                                                                                                           |\n| `ElasticClusterCommandCheck`           | `cohort-elastic`    | Executes an arbitrary command against an elasticsearch cluster.                                                                                                                                                                                  |\n| `ElasticIndexHealthCheck`              | `cohort-elastic`    | Checks that a topic exists on an elastic cluster, with an optional setting to fail if the topic is empty.                                                                                                                                        |\n| `FreememHealthCheck`                   | `cohort-core`       | Checks that the available freemem is above a threshold.                                                                                                                                                                                          |\n| `GarbageCollectionTimeCheck`           | `cohort-core`       | Checks that the time spent in GC is below a threshold. The time is specified as a percentage and is calculated as the period between invocations.                                                                                                |\n| `HikariConnectionsHealthCheck`         | `cohort-hikari`     | Confirms that the number of connections in a Hikari DataSource connection pool is equal or above a threshold. This is useful to ensure a required number of connections are open before accepting traffic.                                       |\n| `HikariMinIdleHealthCheck`             | `cohort-hikari`     | Checks that the number of idle connections in an Hikari DataSource connection pool is at least equal to a min value.                                                                                                                             |\n| `HikariPendingThreadsHealthCheck`      | `cohort-hikari`     | Checks that the number of threads awaiting a connection from a Hikari DataSource is below a threshold. This is useful to detect when queries are running slowly and causing threads to back up waiting for a connection                          |\n| `HotSpotCompilationTimeHealthCheck`    | `cohort-core`       | Is healthy once a specified HotSpot compilation time is reached                                                                                                                                                                                  |\n| `HttpHealthCheck`                      | `cohort-http`       | Attempts to connect to a given HTTP host/port/method.                                                                                                                                                                                            |\n| `KafkaClusterHealthCheck`              | `cohort-kafka`      | Confirms that a Kafka client can connect to a Kafka cluster.                                                                                                                                                                                     |\n| `KafkaLastPollHealthCheck`             | `cohort-kafka`      | Asserts the last poll time for a Kafka Consumer was within a set threshold.                                                                                                                                                                      |\n| `KafkaConsumerCountHealthCheck`        | `cohort-kafka`      | Checks that a Kafka Consumer is consuming a minimum number of records between health checks.                                                                                                                                                     |\n| `KafkaProducerCountHealthCheck`        | `cohort-kafka`      | Checks that a Kafka Producer is producing a minimum number of records between health checks.                                                                                                                                                     |\n| `KafkaTopicHealthCheck`                | `cohort-kafka`      | Confirms that a Kafka cluster can be reached and a topic exists.                                                                                                                                                                                 |\n| `KafkaConsumerSubscriptionHealthCheck` | `cohort-kafka`      | Checks that a Kafka consumer is subscribed to specified (or any) topic.                                                                                                                                                                          |\n| `LiveThreadsHealthCheck`               | `cohort-core`       | Checks that the number of live threads does not exceed a value                                                                                                                                                                                   |\n| `LoadedClassesHealthCheck`             | `cohort-core`       | Checks that the number of loaded classes is below a threshold                                                                                                                                                                                    |\n| `MaxFileDescriptorsHealthCheck`        | `cohort-core`       | Checks that the number of max file descriptors is at least a required level.                                                                                                                                                                     |\n| `OpenFileDescriptorsHealthCheck`       | `cohort-core`       | Checks that the number of open file descriptors is below a threshold.                                                                                                                                                                            |\n| `PeakThreadsHealthCheck`               | `cohort-core`       | Checks that the number of peak threads does not exceed a threshold.                                                                                                                                                                              |\n| `MongoConnectionHealthCheck`           | `cohort-mongo`      | Checks for connectivity to a Mongo instance.                                                                                                                                                                                                     |\n| `ProcessCpuHealthCheck`                | `cohort-core`       | Checks that the process cpu is below a threshold.                                                                                                                                                                                                |\n| `RabbitConnectionHealthCheck`          | `cohort-rabbit`     | Checks for connectivity to a RabbitMQ instance.                                                                                                                                                                                                  |\n| `RabbitQueueHealthCheck`               | `cohort-rabbit`     | Checks for connectivity to, and existence of, a RabbitMQ queue.                                                                                                                                                                                  |\n| `RedisClusterHealthCheck`              | `cohort-redis`      | Confirms that a connection can be opened to a Redis cluster using a Jedis client. Can optionally execute an arbitrary command.                                                                                                                   |\n| `RedisHealthCheck`                     | `cohort-redis`      | Confirms that a connection can be opened to a Redis instance using a Jedis client. Can optionally execute an arbitrary command.                                                                                                                  |\n| `RedisClusterHealthCheck`              | `cohort-lettuce`    | Confirms that a connection can be opened to a Redis cluster using a Lettuce client. Can optionally execute an arbitrary command.                                                                                                                 |\n| `RedisHealthCheck`                     | `cohort-lettuce`    | Confirms that a connection can be opened to a Redis instance using a Lettuce client. Can optionally execute an arbitrary command.                                                                                                                |\n| `StartedThreadsHealthCheck`            | `cohort-core`       | that the number of created and started threads does not exceed a threshold.                                                                                                                                                                      |\n| `S3ReadBucketHealthCheck`              | `cohort-aws-s3`     | Checks for connectivity and permissions to read from an S3 bucket.                                                                                                                                                                               |\n| `SQSQueueHealthCheck`                  | `cohort-aws-sqs`    | Checks for connectivity and existence of an SQS queue.                                                                                                                                                                                           |\n| `SNSHealthCheck`                       | `cohort-aws-sns`    | Checks for connectivity and existence of an SQS queue.                                                                                                                                                                                           |\n| `SystemCpuHealthCheck`                 | `cohort-core`       | Checks that the maximum system cpu is below a threshold.                                                                                                                                                                                         |\n| `SystemLoadHealthCheck`                | `cohort-core`       | Checks that the maximum system load is below a threshold.                                                                                                                                                                                        |\n| `TcpHealthCheck`                       | `cohort-core`       | Attempts to ping a given host and port within a time period. Can be used to check connectivity to an arbitrary socket.                                                                                                                           |\n| `ThreadDeadlockHealthCheck`            | `cohort-core`       | Checks for the presence of deadlocked threads. A single deadlocked thread marks this check as unhealthy.                                                                                                                                         |\n| `ThreadStateHealthCheck`               | `cohort-core`       | Checks that the the number of threads in a given state does not exceed a value. For example, you could specify that the max number of BLOCKED threads is 100.                                                                                    |\n\n### Kubernetes\n\nA Kubernetes kubelet offers three kinds of probes to know the status of a container.\n\n* _liveness_ - Indicates whether the container is running. If the liveness probe fails, the kubelet kills the\n  container (and restarts subject to the restart policy).\n* _readiness_ - Indicates whether the container is ready to respond to requests. If the readiness probe fails, the\n  kubelet removes the pod from receiving traffic.\n* _startup_ - Indicates whether the application within the container has started. All other probes are disabled if a\n  startup probe is provided, until it succeeds.\n\nThe kubelet uses liveness probes to know when to restart a container. Liveness probes help catch a situation where an\napplication is running but is no longer useful. One such example is if a thread has stopped and the application does not\nhave code to detect and restart the thread. Restarting a container in such a state can make the application available\nagain despite the presence of bugs.\n\nThe kubelet uses readiness probes to know when a container should receive traffic. A pod is considered ready when all of\nits containers are ready. One use of this signal is to temporarily remove traffic from backends when they are unable to\nhandle any more requests. For example, a service may have received more requests than it can handle, and so it's backlog\nof requests is growing. Taking that pod out of the load balancers while it catches up can avoid the service crashing or\nneeding a restart. A pod with containers reporting that they are not ready does not receive traffic through Kubernetes\nServices.\n\nReadiness probes are not a substitute for proper scaling (either HPA or manually) but they can avoid a situation where\nall pods are killed, and a service is completely unavailable.\n\nThe kubelet uses startup probes to know when a container application has fully started. If such a probe is configured,\nit disables liveness and readiness checks until it succeeds, making sure those probes don't interfere with the\napplication startup. Startup probes are very useful if an application needs to perform slow initialization work and\nuntil that is complete, a liveness check would fail. This avoids situation where the failing liveness checks result in\nthe kubelet killing the pod before it is ready.\n\n### Healthcheck Endpoint Output\n\nHere is an example of output from a health check with a series of configured health checks.\n\n```json\n[\n   {\n      \"name\": \"com.sksamuel.cohort.memory.FreememHealthCheck\",\n      \"healthy\": true,\n      \"lastCheck\": \"2022-03-15T03:01:09.445932Z\",\n      \"message\": \"Freemem is above threshold [433441040 \u003e= 67108864]\",\n      \"cause\": null,\n      \"consecutiveSuccesses\": 75,\n      \"consecutiveFailures\": 0\n   },\n   {\n      \"name\": \"com.sksamuel.cohort.system.OpenFileDescriptorsHealthCheck\",\n      \"healthy\": true,\n      \"lastCheck\": \"2022-03-15T03:01:09.429469Z\",\n      \"message\": \"Open file descriptor count within threshold [209 \u003c= 16000]\",\n      \"cause\": null,\n      \"consecutiveSuccesses\": 25,\n      \"consecutiveFailures\": 0\n   },\n   {\n      \"name\": \"com.sksamuel.cohort.memory.GarbageCollectionTimeCheck\",\n      \"healthy\": true,\n      \"lastCheck\": \"2022-03-15T03:00:54.422194Z\",\n      \"message\": \"GC Collection time was 0% [Max is 25]\",\n      \"cause\": null,\n      \"consecutiveSuccesses\": 6,\n      \"consecutiveFailures\": 0\n   },\n   {\n      \"name\": \"writer connections\",\n      \"healthy\": true,\n      \"lastCheck\": \"2022-03-15T03:01:09.445868Z\",\n      \"message\": \"Database connections is equal or above threshold [8 \u003e= 8]\",\n      \"cause\": null,\n      \"consecutiveSuccesses\": 75,\n      \"consecutiveFailures\": 0\n   },\n   {\n      \"name\": \"reader connections\",\n      \"healthy\": true,\n      \"lastCheck\": \"2022-03-15T03:01:09.445841Z\",\n      \"message\": \"Database connections is equal or above threshold [8 \u003e= 8]\",\n      \"cause\": null,\n      \"consecutiveSuccesses\": 75,\n      \"consecutiveFailures\": 0\n   },\n   {\n      \"name\": \"com.sksamuel.cohort.system.SystemCpuHealthCheck\",\n      \"healthy\": true,\n      \"lastCheck\": \"2022-03-15T03:01:09.463421Z\",\n      \"message\": \"System CPU is below threshold [0.12667261373773417 \u003c 0.9]\",\n      \"cause\": null,\n      \"consecutiveSuccesses\": 75,\n      \"consecutiveFailures\": 0\n   },\n   {\n      \"name\": \"com.sksamuel.cohort.threads.ThreadDeadlockHealthCheck\",\n      \"healthy\": true,\n      \"lastCheck\": \"2022-03-15T03:00:54.419733Z\",\n      \"message\": \"There are 0 deadlocked threads\",\n      \"cause\": null,\n      \"consecutiveSuccesses\": 6,\n      \"consecutiveFailures\": 0\n   }\n]\n```\n\n## Micrometer\n\nCohort will send healthcheck metrics to micrometer if configured. Add the `cohort-micrometer` module and then bind an\ninstance of `CohortMetrics` to both your healthcheck registry, and the micrometer registry.\n\nFor example:\n\n```kotlin\n\nval micrometerRegistry = DatadogMeterRegistry(..) // or any other registry\n\nval healthcheckRegistry = HealthCheckRegistry(Dispatchers.Default) {\n   register(\"foo\", FooHealthCheck, 5.seconds)\n   register(\"bar\", BarHealthCheck, 3.seconds)\n}\n\nCohortMetrics(healthcheckRegistry).bindTo(micrometerRegistry)\n```\n\nEach health check will emit a metric under the key _cohort.healthcheck_ with a `name`, `type` and `healthy` tag.\n\n## Logging\n\nCohort allows you to view the current logging configuration and update log levels at runtime.\n\nTo enable this, pass an instance of the `LogManager` interface for the logging framework you are using to\nthe `logManager`parameter in the Cohort plugin configuration.\n\nOnce enabled, the endpoint `GET /cohort/logging` can be used to show current log information\nand `PUT /cohort/logging/{name}/{level}` can be used to modify a log level at runtime.\n\nCohort currently supports two `LogManager` implementations:\n\n* `LogbackManager` - add module `com.sksamuel.cohort:cohort-logback:\u003cversion\u003e`\n* `Log4j2Manager` - add module `com.sksamuel.cohort:cohort-log4j2:\u003cversion\u003e`\n\nFor example, for projects that use logback, you can configure like this:\n\n```kotlin\ninstall(Cohort) {\n   logManager = LogbackManager\n}\n```\n\nHere is the example output of which shows the logging configuration:\n\n```json\n{\n   \"levels\": [\n      \"DEBUG\",\n      \"TRACE\",\n      \"INFO\",\n      \"ERROR\",\n      \"OFF\",\n      \"WARN\"\n   ],\n   \"loggers\": [\n      {\n         \"name\": \"ROOT\",\n         \"level\": \"INFO\"\n      },\n      {\n         \"name\": \"com\",\n         \"level\": \"INFO\"\n      },\n      {\n         \"name\": \"com.sksamuel\",\n         \"level\": \"INFO\"\n      },\n      {\n         \"name\": \"ktor\",\n         \"level\": \"INFO\"\n      },\n      {\n         \"name\": \"ktor.application\",\n         \"level\": \"INFO\"\n      },\n      {\n         \"name\": \"org\",\n         \"level\": \"INFO\"\n      },\n      {\n         \"name\": \"org.apache\",\n         \"level\": \"INFO\"\n      },\n      {\n         \"name\": \"org.apache.kafka\",\n         \"level\": \"WARN\"\n      }\n   ]\n}\n```\n\n## Jvm Info\n\nDisplays information about the JVM state, including VM options, JVM version, and vendor name.\n\nTo enable, set `jvmInfo` to true inside the `Cohort` ktor configuration block:\n\n```kotlin\ninstall(Cohort) {\n   jvmInfo = true\n}\n```\n\n```json\n{\n   \"name\": \"106637@sam-H310M-A-2-0\",\n   \"pid\": 106637,\n   \"vmOptions\": [\n      \"-Dvisualvm.id=32227655111670\",\n      \"-javaagent:/home/sam/development/idea-IU-213.5744.125/lib/idea_rt.jar=36667:/home/sam/development/idea-IU-213.5744.125/bin\",\n      \"-Dfile.encoding=UTF-8\"\n   ],\n   \"classPath\": \"/home/sam/development/workspace/......\",\n   \"specName\": \"Java Virtual Machine Specification\",\n   \"specVendor\": \"Oracle Corporation\",\n   \"specVersion\": \"11\",\n   \"vmName\": \"OpenJDK 64-Bit Server VM\",\n   \"vmVendor\": \"AdoptOpenJDK\",\n   \"vmVersion\": \"11.0.10+9\",\n   \"startTime\": 1647315704746,\n   \"uptime\": 405278\n}\n```\n\n## Operating System\n\nDisplays the running os and version.\n\nTo enable, set `operatingSystem` to true inside the `Cohort` ktor configuration block:\n\n```kotlin\ninstall(Cohort) {\n   operatingSystem = true\n}\n```\n\n```json\n{\n   \"arch\": \"amd64\",\n   \"name\": \"Linux\",\n   \"version\": \"5.13.0-35-generic\"\n}\n```\n\n## Datasources\n\nBy passing one or more database pools to Cohort, you can see at runtime the current state of the pool(s). Once enabled,\na GET request to `/cohort/datasources` will return information such as idle connection count, max pool size, connection\ntimeouts and so on.\n\nCohort supports two connection pool libraries:\n\n* Apache Commons DBCP - add module `com.sksamuel.cohort:cohort-dbcp`\n* HikariCP - add module `com.sksamuel.cohort:cohort-hikari`\n\nTo activate this feature, wrap your `DataSource` in an appropriate _DataSourceManager_ instance and pass through to the\nCohort plugin.\n\nFor example, if we had two connection pools, a writer pool using Hikari, and a reader pool using Apache DBCP, then we\ncould configure like this:\n\n```kotlin\ninstall(Cohort) {\n   dataSources = listOf(\n      ApacheDBCPDataSourceManager(reader),\n      HikariDataSourceManager(writer),\n   )\n}\n```\n\nHere is an example output for the above datasources:\n\n```json\n[\n   {\n      \"name\": \"writer\",\n      \"activeConnections\": 0,\n      \"idleConnections\": 8,\n      \"totalConnections\": 8,\n      \"threadsAwaitingConnection\": 0,\n      \"connectionTimeout\": 30000,\n      \"idleTimeout\": 600000,\n      \"maxLifetime\": 1800000,\n      \"leakDetectionThreshold\": 0,\n      \"maximumPoolSize\": 16,\n      \"validationTimeout\": 5000\n   },\n   {\n      \"name\": \"reader\",\n      \"activeConnections\": 0,\n      \"idleConnections\": 8,\n      \"totalConnections\": 8,\n      \"threadsAwaitingConnection\": 0,\n      \"connectionTimeout\": 30000,\n      \"idleTimeout\": 600000,\n      \"maxLifetime\": 1800000,\n      \"leakDetectionThreshold\": 0,\n      \"maximumPoolSize\": 16,\n      \"validationTimeout\": 5000\n   }\n]\n```\n\n## System Properties\n\nSend a GET request to `/cohort/sysprops` to return the current system properties.\n\nTo enable, set `sysprops` to true inside the `Cohort` plugin configuration block:\n\n```kotlin\ninstall(Cohort) {\n   sysprops = true\n}\n```\n\nHere is an example of the output:\n\n```json\n{\n   \"sun.jnu.encoding\": \"UTF-8\",\n   \"java.vm.vendor\": \"AdoptOpenJDK\",\n   \"java.vendor.url\": \"https://adoptopenjdk.net/\",\n   \"user.timezone\": \"America/Chicago\",\n   \"os.name\": \"Linux\",\n   \"java.vm.specification.version\": \"11\",\n   \"user.country\": \"US\",\n   \"sun.boot.library.path\": \"/home/sam/.sdkman/candidates/java/11.0.10.hs-adpt/lib\",\n   \"sun.java.command\": \"com.myapp.MainKt\",\n   \"user.home\": \"/home/sam\",\n   \"java.version.date\": \"2021-01-19\",\n   \"java.home\": \"/home/sam/.sdkman/candidates/java/11.0.10.hs-adpt\",\n   \"file.separator\": \"/\",\n   \"java.vm.compressedOopsMode\": \"Zero based\",\n   \"line.separator\": \"\\n\",\n   \"java.specification.name\": \"Java Platform API Specification\",\n   \"java.vm.specification.vendor\": \"Oracle Corporation\",\n   \"sun.management.compiler\": \"HotSpot 64-Bit Tiered Compilers\",\n   \"java.runtime.version\": \"11.0.10+9\",\n   \"user.name\": \"sam\",\n   \"path.separator\": \":\",\n   \"file.encoding\": \"UTF-8\",\n   \"java.vm.name\": \"OpenJDK 64-Bit Server VM\",\n   \"user.dir\": \"/home/sam/development/workspace/myapp\",\n   \"os.arch\": \"amd64\",\n   \"java.vm.specification.name\": \"Java Virtual Machine Specification\",\n   \"java.awt.printerjob\": \"sun.print.PSPrinterJob\",\n   \"java.class.version\": \"55.0\"\n}\n```\n\n## Heap Dump\n\nSend a GET request to `/cohort/heapdump` to retrieve a heap dump for all live objects.\n\nThe file returned is in the format used by [hprof](https://docs.oracle.com/javase/7/docs/technotes/samples/hprof.html).\n\nTo enable, set `heapdump` to true inside the `Cohort` plugin configuration block:\n\n```kotlin\ninstall(Cohort) {\n   heapdump = true\n}\n```\n\n## Thread Dump\n\nSend a GET request to `/cohort/threaddump` to retrieve a thread dump for all current threads.\n\nTo enable, set `threaddump` to true inside the `Cohort` plugin configuration block:\n\n```kotlin\ninstall(Cohort) {\n   threaddump = true\n}\n```\n\nExample output:\n\n```text\n\"main\" prio=5 Id=1 WAITING on io.netty.channel.AbstractChannel$CloseFuture@291c536c\n\tat java.base@11.0.10/java.lang.Object.wait(Native Method)\n\t-  waiting on io.netty.channel.AbstractChannel$CloseFuture@291c536c\n\tat java.base@11.0.10/java.lang.Object.wait(Object.java:328)\n\tat app//io.netty.util.concurrent.DefaultPromise.await(DefaultPromise.java:253)\n\tat app//io.netty.channel.DefaultChannelPromise.await(DefaultChannelPromise.java:131)\n\tat app//io.netty.channel.DefaultChannelPromise.await(DefaultChannelPromise.java:30)\n\tat app//io.netty.util.concurrent.DefaultPromise.sync(DefaultPromise.java:404)\n\tat app//io.netty.channel.DefaultChannelPromise.sync(DefaultChannelPromise.java:119)\n\tat app//io.netty.channel.DefaultChannelPromise.sync(DefaultChannelPromise.java:30)\n\t...\n\n\"Reference Handler\" daemon prio=10 Id=2 RUNNABLE\n\tat java.base@11.0.10/java.lang.ref.Reference.waitForReferencePendingList(Native Method)\n\tat java.base@11.0.10/java.lang.ref.Reference.processPendingReferences(Reference.java:241)\n\tat java.base@11.0.10/java.lang.ref.Reference$ReferenceHandler.run(Reference.java:213)\n\n\"Finalizer\" daemon prio=8 Id=3 WAITING on java.lang.ref.ReferenceQueue$Lock@1392e5c7\n\tat java.base@11.0.10/java.lang.Object.wait(Native Method)\n\t-  waiting on java.lang.ref.ReferenceQueue$Lock@1392e5c7\n\tat java.base@11.0.10/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:155)\n\tat java.base@11.0.10/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:176)\n\tat java.base@11.0.10/java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:170)\n\n\"Signal Dispatcher\" daemon prio=9 Id=4 RUNNABLE\n\n\"Common-Cleaner\" daemon prio=8 Id=19 TIMED_WAITING on java.lang.ref.ReferenceQueue$Lock@78e1959d\n\tat java.base@11.0.10/java.lang.Object.wait(Native Method)\n\t-  waiting on java.lang.ref.ReferenceQueue$Lock@78e1959d\n\tat java.base@11.0.10/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:155)\n\tat java.base@11.0.10/jdk.internal.ref.CleanerImpl.run(CleanerImpl.java:148)\n\tat java.base@11.0.10/java.lang.Thread.run(Thread.java:834)\n\tat java.base@11.0.10/jdk.internal.misc.InnocuousThread.run(InnocuousThread.java:134)\n```\n\n## Verbose healthcheck response\n\nBy settings the verbose parameter to false the response of the healthcheck is being reduced.\n\nTo enable, set `verboseHealthCheckResponse` to false inside the `Cohort` plugin configuration block, its set to true by default:\n\n```kotlin\ninstall(Cohort) {\n   verboseHealthCheckResponse = false\n}\n```\n\nOutput is being reduced to \n```\n\"OK\" or \"Service unavailable\"\n```\n\n instead of:\n\n```\n{\n      \"name\": \"com.sksamuel.cohort.threads.ThreadDeadlockHealthCheck\",\n      \"healthy\": true,\n      \"lastCheck\": \"2022-03-15T03:00:54.419733Z\",\n      \"message\": \"There are 0 deadlocked threads\",\n      \"cause\": null,\n      \"consecutiveSuccesses\": 6,\n      \"consecutiveFailures\": 0\n   }\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsksamuel%2Fcohort","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsksamuel%2Fcohort","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsksamuel%2Fcohort/lists"}