{"id":21948166,"url":"https://github.com/evolution-gaming/smetrics","last_synced_at":"2025-04-23T00:17:24.002Z","repository":{"id":38357503,"uuid":"193057562","full_name":"evolution-gaming/smetrics","owner":"evolution-gaming","description":"Generic interface to abstract from metrics vendors and their implementations","archived":false,"fork":false,"pushed_at":"2025-04-14T08:17:25.000Z","size":286,"stargazers_count":10,"open_issues_count":22,"forks_count":9,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-23T00:17:17.605Z","etag":null,"topics":["cats","cats-effect","prometheus","scala"],"latest_commit_sha":null,"homepage":null,"language":"Scala","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/evolution-gaming.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}},"created_at":"2019-06-21T08:04:10.000Z","updated_at":"2025-04-14T08:16:03.000Z","dependencies_parsed_at":"2024-01-15T11:07:18.880Z","dependency_job_id":"d0260ef9-65d2-410b-96e8-917fdcffc461","html_url":"https://github.com/evolution-gaming/smetrics","commit_stats":null,"previous_names":[],"tags_count":43,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evolution-gaming%2Fsmetrics","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evolution-gaming%2Fsmetrics/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evolution-gaming%2Fsmetrics/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evolution-gaming%2Fsmetrics/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/evolution-gaming","download_url":"https://codeload.github.com/evolution-gaming/smetrics/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250343960,"owners_count":21415042,"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":["cats","cats-effect","prometheus","scala"],"created_at":"2024-11-29T05:12:15.080Z","updated_at":"2025-04-23T00:17:23.959Z","avatar_url":"https://github.com/evolution-gaming.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SMetrics\n\n[![Build Status](https://github.com/evolution-gaming/smetrics/workflows/CI/badge.svg)](https://github.com/evolution-gaming/smetrics/actions?query=workflow%3ACI)\n[![Coverage Status](https://coveralls.io/repos/evolution-gaming/smetrics/badge.svg)](https://coveralls.io/r/evolution-gaming/smetrics)\n[![Codacy Badge](https://api.codacy.com/project/badge/Grade/04fb0fd38072413cb032d8a5e7c9def5)](https://www.codacy.com/app/evolution-gaming/smetrics?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=evolution-gaming/smetrics\u0026amp;utm_campaign=Badge_Grade)\n[![Version](https://img.shields.io/badge/version-click-blue)](https://evolution.jfrog.io/artifactory/api/search/latestVersion?g=com.evolutiongaming\u0026a=smetrics_2.13\u0026repos=public)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellowgreen.svg)](https://opensource.org/licenses/MIT)\n\n## Features:\n* tagless final api via [cats](https://typelevel.org/cats/)\n* improved abstraction for matching labels names and label values\n* resource safety\n* detaching metrics backend - prometheus dependency is one of the backend implementations\n\n## Example of http metrics\n\nlet's declare interface for metrics, that seems reasonable for http client \n\n```scala\n\ntrait HttpMetrics[F[_]] {\n\n  def latency(client: String, method: String, resource: String, duration: FiniteDuration): F[Unit]\n\n  def count(client: String, method: String, resource: String, success: Boolean): F[Unit]\n\n  def enqueue(client: String): F[Unit]\n\n  def dequeue(client: String): F[Unit]\n}\n```\n\nnow let's implement `HttpMetrics` using `CollectorRegistry`\n\n```scala\n  import com.evolutiongaming.smetrics.MetricsHelper._\n  import com.evolutiongaming.smetrics.{CollectorRegistry, LabelNames, Quantile, Quantiles}\n\n  def httpMetrics[F[_]: Monad](collectorRegistry: CollectorRegistry[F]): Resource[F, HttpMetrics[F]] = {\n    for {\n      latencySummary \u003c- collectorRegistry.summary(\n        \"http_client_latency\",\n        \"Latency of HTTP requests processing in seconds\",\n        Quantiles(\n          Quantile(value = 0.5, error = 0.05),\n          Quantile(value = 0.9, error = 0.05),\n          Quantile(value = 0.99, error = 0.005)),\n        LabelNames(\"client_name\", \"method\", \"resource\"))\n      \n      resultCounter \u003c- collectorRegistry.counter(\n        \"http_client_response_result\",\n        \"Status of HTTP responses\",\n        LabelNames(\"client_name\", \"method\", \"resource\", \"result\"))\n      \n      queueGauge \u003c- collectorRegistry.gauge(\n        \"http_client_queue\",\n        \"Queue of incoming http calls\",\n        LabelNames(\"client_name\"))\n    } yield {\n      new HttpMetrics[F] {\n    \n        def latency(client: String, method: String, resource: String, duration: FiniteDuration) = {\n          latencySummary\n            .labels(client, method, resource)\n            .observe(duration.toNanos.nanosToSeconds)\n        }\n    \n        def count(client: String, method: String, resource: String, success: Boolean) = {\n          resultCounter\n            .labels(client, method, resource, if (success) \"success\" else \"error\")\n            .inc()\n        }\n    \n        def enqueue(client: String) = {\n          queueGauge\n            .labels(client)\n            .inc()\n        }\n    \n        def dequeue(client: String) = {\n          queueGauge\n            .labels(client)\n            .dec()\n        }\n      }\n    }\n  }\n```\n\nSo you can see, `httpMetrics` function requires instance of `CollectorRegistry`.\nRight now there are two options available:\n* `CollectorRegistry.empty` - often used in tests\n* `CollectorRegistryPrometheus` - which will create `smetrics.CollectorRegistry` out of `io.prometheus.CollectorRegistry` using [prometheus/client_java](github.com/prometheus/client_java) under the hood\n\nReturn type is `Resource[F, _]` rather than `F[_]` because most often underlying metrics implementation upon a call registers your metrics with shared registry.\nHence `release` hook of `Resource` being used in order to de-register particular metrics from shared registry.\n\n## Setup\n\n```scala\naddSbtPlugin(\"com.evolution\" % \"sbt-artifactory-plugin\" % \"0.0.2\")\n\nlibraryDependencies += \"com.evolutiongaming\" %% \"smetrics\" % \"0.3.1\"\n\nlibraryDependencies += \"com.evolutiongaming\" %% \"smetrics-prometheus\" % \"0.3.1\"\n``` \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevolution-gaming%2Fsmetrics","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fevolution-gaming%2Fsmetrics","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevolution-gaming%2Fsmetrics/lists"}