{"id":13471640,"url":"https://github.com/grpc-ecosystem/go-grpc-prometheus","last_synced_at":"2026-01-15T01:36:44.999Z","repository":{"id":43441219,"uuid":"58739665","full_name":"grpc-ecosystem/go-grpc-prometheus","owner":"grpc-ecosystem","description":"Prometheus monitoring for your gRPC Go servers.","archived":true,"fork":false,"pushed_at":"2023-04-05T09:31:42.000Z","size":144,"stargazers_count":1339,"open_issues_count":31,"forks_count":166,"subscribers_count":30,"default_branch":"master","last_synced_at":"2025-10-05T11:42:22.961Z","etag":null,"topics":["golang","grpc","interceptor","metrics","monitoring","prometheus"],"latest_commit_sha":null,"homepage":null,"language":"Go","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/grpc-ecosystem.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":null,"security":null,"support":null,"governance":null}},"created_at":"2016-05-13T12:45:02.000Z","updated_at":"2025-09-20T07:56:54.000Z","dependencies_parsed_at":"2023-07-13T16:30:50.757Z","dependency_job_id":null,"html_url":"https://github.com/grpc-ecosystem/go-grpc-prometheus","commit_stats":{"total_commits":88,"total_committers":22,"mean_commits":4.0,"dds":0.6363636363636364,"last_synced_commit":"a5446fa2489078304671617eeebd4c5e457dcf07"},"previous_names":["mwitkow/go-grpc-prometheus"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/grpc-ecosystem/go-grpc-prometheus","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grpc-ecosystem%2Fgo-grpc-prometheus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grpc-ecosystem%2Fgo-grpc-prometheus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grpc-ecosystem%2Fgo-grpc-prometheus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grpc-ecosystem%2Fgo-grpc-prometheus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/grpc-ecosystem","download_url":"https://codeload.github.com/grpc-ecosystem/go-grpc-prometheus/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grpc-ecosystem%2Fgo-grpc-prometheus/sbom","scorecard":{"id":446632,"data":{"date":"2025-08-11","repo":{"name":"github.com/grpc-ecosystem/go-grpc-prometheus","commit":"a5446fa2489078304671617eeebd4c5e457dcf07"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.9,"checks":[{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":9,"reason":"Found 12/13 approved changesets -- score normalized to 9","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"project is archived","details":["Warn: Repository is archived."],"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"15 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GO-2022-0322 / GHSA-cg3q-j54f-5p7p","Warn: Project is vulnerable to: GO-2022-0536 / GHSA-39qc-96h7-956f / GHSA-hgr8-6h9x-f7q9","Warn: Project is vulnerable to: GO-2022-0236 / GHSA-h86h-8ppg-mxmh","Warn: Project is vulnerable to: GO-2021-0238 / GHSA-83g2-8m93-v3w7","Warn: Project is vulnerable to: GO-2022-0288","Warn: Project is vulnerable to: GO-2022-0969 / GHSA-69cg-p879-7622","Warn: Project is vulnerable to: GO-2022-1144 / GHSA-xrjj-mj9h-534m","Warn: Project is vulnerable to: GO-2023-1571 / GHSA-vvpx-j8f3-3w6h","Warn: Project is vulnerable to: GO-2023-1988 / GHSA-2wrh-6pvc-2jm9","Warn: Project is vulnerable to: GO-2023-2102 / GHSA-4374-p667-p6c8","Warn: Project is vulnerable to: GO-2023-2153 / GHSA-m425-mq94-257g / GHSA-qppj-fm5r-hxr3","Warn: Project is vulnerable to: GO-2024-2687 / GHSA-4v7x-pqxf-cx7m","Warn: Project is vulnerable to: GO-2024-3333","Warn: Project is vulnerable to: GO-2025-3503 / GHSA-qxp5-gwg8-xv66","Warn: Project is vulnerable to: GO-2025-3595 / GHSA-vvgc-356p-c3xw"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-19T06:53:36.133Z","repository_id":43441219,"created_at":"2025-08-19T06:53:36.133Z","updated_at":"2025-08-19T06:53:36.133Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28441031,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-15T00:55:22.719Z","status":"ssl_error","status_checked_at":"2026-01-15T00:55:20.945Z","response_time":107,"last_error":"SSL_read: 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":["golang","grpc","interceptor","metrics","monitoring","prometheus"],"created_at":"2024-07-31T16:00:47.739Z","updated_at":"2026-01-15T01:36:44.979Z","avatar_url":"https://github.com/grpc-ecosystem.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# (Deprecated) Go gRPC Interceptors for Prometheus monitoring \n\n[![Go Report Card](https://goreportcard.com/badge/github.com/grpc-ecosystem/go-grpc-prometheus)](http://goreportcard.com/report/grpc-ecosystem/go-grpc-prometheus)\n[![GoDoc](http://img.shields.io/badge/GoDoc-Reference-blue.svg)](https://godoc.org/github.com/grpc-ecosystem/go-grpc-prometheus)\n[![SourceGraph](https://sourcegraph.com/github.com/grpc-ecosystem/go-grpc-prometheus/-/badge.svg)](https://sourcegraph.com/github.com/grpc-ecosystem/go-grpc-prometheus/?badge)\n[![codecov](https://codecov.io/gh/grpc-ecosystem/go-grpc-prometheus/branch/master/graph/badge.svg)](https://codecov.io/gh/grpc-ecosystem/go-grpc-prometheus)\n[![Slack](https://img.shields.io/badge/join%20slack-%23go--grpc--prometheus-brightgreen.svg)](https://join.slack.com/t/improbable-eng/shared_invite/enQtMzQ1ODcyMzQ5MjM4LWY5ZWZmNGM2ODc5MmViNmQ3ZTA3ZTY3NzQwOTBlMTkzZmIxZTIxODk0OWU3YjZhNWVlNDU3MDlkZGViZjhkMjc)\n[![Apache 2.0 License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)\n\n\u003e :warning: This project is depreacted and archived as the functionality moved to [go-grpc-middleware](https://github.com/grpc-ecosystem/go-grpc-middleware) repo since [provider/prometheus@v1.0.0-rc.0](https://github.com/grpc-ecosystem/go-grpc-middleware/releases/tag/providers%2Fprometheus%2Fv1.0.0-rc.0) release. You can pull it using `go get github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus`. The API is simplified and morernized, yet functionality is similar to what v1.2.0 offered. All questions and issues you can submit [here](https://github.com/grpc-ecosystem/go-grpc-middleware/issues).\n\n[Prometheus](https://prometheus.io/) monitoring for your [gRPC Go](https://github.com/grpc/grpc-go) servers and clients.\n\nA sister implementation for [gRPC Java](https://github.com/grpc/grpc-java) (same metrics, same semantics) is in [grpc-ecosystem/java-grpc-prometheus](https://github.com/grpc-ecosystem/java-grpc-prometheus).\n\n## Interceptors\n\n[gRPC Go](https://github.com/grpc/grpc-go) recently acquired support for Interceptors, i.e. middleware that is executed\nby a gRPC Server before the request is passed onto the user's application logic. It is a perfect way to implement\ncommon patterns: auth, logging and... monitoring.\n\nTo use Interceptors in chains, please see [`go-grpc-middleware`](https://github.com/mwitkow/go-grpc-middleware).\n\nThis library requires Go 1.9 or later.\n\n## Usage\n\nThere are two types of interceptors: client-side and server-side. This package provides monitoring Interceptors for both.\n\n### Server-side\n\n```go\nimport \"github.com/grpc-ecosystem/go-grpc-prometheus\"\n...\n    // Initialize your gRPC server's interceptor.\n    myServer := grpc.NewServer(\n        grpc.StreamInterceptor(grpc_prometheus.StreamServerInterceptor),\n        grpc.UnaryInterceptor(grpc_prometheus.UnaryServerInterceptor),\n    )\n    // Register your gRPC service implementations.\n    myservice.RegisterMyServiceServer(s.server, \u0026myServiceImpl{})\n    // After all your registrations, make sure all of the Prometheus metrics are initialized.\n    grpc_prometheus.Register(myServer)\n    // Register Prometheus metrics handler.    \n    http.Handle(\"/metrics\", promhttp.Handler())\n...\n```\n\n### Client-side\n\n```go\nimport \"github.com/grpc-ecosystem/go-grpc-prometheus\"\n...\n   clientConn, err = grpc.Dial(\n       address,\n\t\t   grpc.WithUnaryInterceptor(grpc_prometheus.UnaryClientInterceptor),\n\t\t   grpc.WithStreamInterceptor(grpc_prometheus.StreamClientInterceptor)\n   )\n   client = pb_testproto.NewTestServiceClient(clientConn)\n   resp, err := client.PingEmpty(s.ctx, \u0026myservice.Request{Msg: \"hello\"})\n...\n```\n\n# Metrics\n\n## Labels\n\nAll server-side metrics start with `grpc_server` as Prometheus subsystem name. All client-side metrics start with `grpc_client`. Both of them have mirror-concepts. Similarly all methods\ncontain the same rich labels:\n  \n  * `grpc_service` - the [gRPC service](http://www.grpc.io/docs/#defining-a-service) name, which is the combination of protobuf `package` and\n    the `grpc_service` section name. E.g. for `package = mwitkow.testproto` and \n     `service TestService` the label will be `grpc_service=\"mwitkow.testproto.TestService\"`\n  * `grpc_method` - the name of the method called on the gRPC service. E.g.  \n    `grpc_method=\"Ping\"`\n  * `grpc_type` - the gRPC [type of request](http://www.grpc.io/docs/guides/concepts.html#rpc-life-cycle). \n    Differentiating between the two is important especially for latency measurements.\n\n     - `unary` is single request, single response RPC\n     - `client_stream` is a multi-request, single response RPC\n     - `server_stream` is a single request, multi-response RPC\n     - `bidi_stream` is a multi-request, multi-response RPC\n    \n\nAdditionally for completed RPCs, the following labels are used:\n\n  * `grpc_code` - the human-readable [gRPC status code](https://github.com/grpc/grpc-go/blob/master/codes/codes.go).\n    The list of all statuses is to long, but here are some common ones:\n      \n      - `OK` - means the RPC was successful\n      - `IllegalArgument` - RPC contained bad values\n      - `Internal` - server-side error not disclosed to the clients\n      \n## Counters\n\nThe counters and their up to date documentation is in [server_reporter.go](server_reporter.go) and [client_reporter.go](client_reporter.go) \nthe respective Prometheus handler (usually `/metrics`). \n\nFor the purpose of this documentation we will only discuss `grpc_server` metrics. The `grpc_client` ones contain mirror concepts.\n\nFor simplicity, let's assume we're tracking a single server-side RPC call of [`mwitkow.testproto.TestService`](examples/testproto/test.proto),\ncalling the method `PingList`. The call succeeds and returns 20 messages in the stream.\n\nFirst, immediately after the server receives the call it will increment the\n`grpc_server_started_total` and start the handling time clock (if histograms are enabled). \n\n```jsoniq\ngrpc_server_started_total{grpc_method=\"PingList\",grpc_service=\"mwitkow.testproto.TestService\",grpc_type=\"server_stream\"} 1\n```\n\nThen the user logic gets invoked. It receives one message from the client containing the request \n(it's a `server_stream`):\n\n```jsoniq\ngrpc_server_msg_received_total{grpc_method=\"PingList\",grpc_service=\"mwitkow.testproto.TestService\",grpc_type=\"server_stream\"} 1\n```\n\nThe user logic may return an error, or send multiple messages back to the client. In this case, on \neach of the 20 messages sent back, a counter will be incremented:\n\n```jsoniq\ngrpc_server_msg_sent_total{grpc_method=\"PingList\",grpc_service=\"mwitkow.testproto.TestService\",grpc_type=\"server_stream\"} 20\n```\n\nAfter the call completes, its status (`OK` or other [gRPC status code](https://github.com/grpc/grpc-go/blob/master/codes/codes.go)) \nand the relevant call labels increment the `grpc_server_handled_total` counter.\n\n```jsoniq\ngrpc_server_handled_total{grpc_code=\"OK\",grpc_method=\"PingList\",grpc_service=\"mwitkow.testproto.TestService\",grpc_type=\"server_stream\"} 1\n```\n\n## Histograms\n\n[Prometheus histograms](https://prometheus.io/docs/concepts/metric_types/#histogram) are a great way\nto measure latency distributions of your RPCs. However, since it is bad practice to have metrics\nof [high cardinality](https://prometheus.io/docs/practices/instrumentation/#do-not-overuse-labels)\nthe latency monitoring metrics are disabled by default. To enable them please call the following\nin your server initialization code:\n\n```jsoniq\ngrpc_prometheus.EnableHandlingTimeHistogram()\n```\n\nAfter the call completes, its handling time will be recorded in a [Prometheus histogram](https://prometheus.io/docs/concepts/metric_types/#histogram)\nvariable `grpc_server_handling_seconds`. The histogram variable contains three sub-metrics:\n\n * `grpc_server_handling_seconds_count` - the count of all completed RPCs by status and method \n * `grpc_server_handling_seconds_sum` - cumulative time of RPCs by status and method, useful for \n   calculating average handling times\n * `grpc_server_handling_seconds_bucket` - contains the counts of RPCs by status and method in respective\n   handling-time buckets. These buckets can be used by Prometheus to estimate SLAs (see [here](https://prometheus.io/docs/practices/histograms/))\n\nThe counter values will look as follows:\n\n```jsoniq\ngrpc_server_handling_seconds_bucket{grpc_code=\"OK\",grpc_method=\"PingList\",grpc_service=\"mwitkow.testproto.TestService\",grpc_type=\"server_stream\",le=\"0.005\"} 1\ngrpc_server_handling_seconds_bucket{grpc_code=\"OK\",grpc_method=\"PingList\",grpc_service=\"mwitkow.testproto.TestService\",grpc_type=\"server_stream\",le=\"0.01\"} 1\ngrpc_server_handling_seconds_bucket{grpc_code=\"OK\",grpc_method=\"PingList\",grpc_service=\"mwitkow.testproto.TestService\",grpc_type=\"server_stream\",le=\"0.025\"} 1\ngrpc_server_handling_seconds_bucket{grpc_code=\"OK\",grpc_method=\"PingList\",grpc_service=\"mwitkow.testproto.TestService\",grpc_type=\"server_stream\",le=\"0.05\"} 1\ngrpc_server_handling_seconds_bucket{grpc_code=\"OK\",grpc_method=\"PingList\",grpc_service=\"mwitkow.testproto.TestService\",grpc_type=\"server_stream\",le=\"0.1\"} 1\ngrpc_server_handling_seconds_bucket{grpc_code=\"OK\",grpc_method=\"PingList\",grpc_service=\"mwitkow.testproto.TestService\",grpc_type=\"server_stream\",le=\"0.25\"} 1\ngrpc_server_handling_seconds_bucket{grpc_code=\"OK\",grpc_method=\"PingList\",grpc_service=\"mwitkow.testproto.TestService\",grpc_type=\"server_stream\",le=\"0.5\"} 1\ngrpc_server_handling_seconds_bucket{grpc_code=\"OK\",grpc_method=\"PingList\",grpc_service=\"mwitkow.testproto.TestService\",grpc_type=\"server_stream\",le=\"1\"} 1\ngrpc_server_handling_seconds_bucket{grpc_code=\"OK\",grpc_method=\"PingList\",grpc_service=\"mwitkow.testproto.TestService\",grpc_type=\"server_stream\",le=\"2.5\"} 1\ngrpc_server_handling_seconds_bucket{grpc_code=\"OK\",grpc_method=\"PingList\",grpc_service=\"mwitkow.testproto.TestService\",grpc_type=\"server_stream\",le=\"5\"} 1\ngrpc_server_handling_seconds_bucket{grpc_code=\"OK\",grpc_method=\"PingList\",grpc_service=\"mwitkow.testproto.TestService\",grpc_type=\"server_stream\",le=\"10\"} 1\ngrpc_server_handling_seconds_bucket{grpc_code=\"OK\",grpc_method=\"PingList\",grpc_service=\"mwitkow.testproto.TestService\",grpc_type=\"server_stream\",le=\"+Inf\"} 1\ngrpc_server_handling_seconds_sum{grpc_code=\"OK\",grpc_method=\"PingList\",grpc_service=\"mwitkow.testproto.TestService\",grpc_type=\"server_stream\"} 0.0003866430000000001\ngrpc_server_handling_seconds_count{grpc_code=\"OK\",grpc_method=\"PingList\",grpc_service=\"mwitkow.testproto.TestService\",grpc_type=\"server_stream\"} 1\n```\n\n\n## Useful query examples\n\nPrometheus philosophy is to provide raw metrics to the monitoring system, and\nlet the aggregations be handled there. The verbosity of above metrics make it possible to have that\nflexibility. Here's a couple of useful monitoring queries:\n\n\n### request inbound rate\n```jsoniq\nsum(rate(grpc_server_started_total{job=\"foo\"}[1m])) by (grpc_service)\n```\nFor `job=\"foo\"` (common label to differentiate between Prometheus monitoring targets), calculate the\nrate of requests per second (1 minute window) for each gRPC `grpc_service` that the job has. Please note\nhow the `grpc_method` is being omitted here: all methods of a given gRPC service will be summed together.\n\n### unary request error rate\n```jsoniq\nsum(rate(grpc_server_handled_total{job=\"foo\",grpc_type=\"unary\",grpc_code!=\"OK\"}[1m])) by (grpc_service)\n```\nFor `job=\"foo\"`, calculate the per-`grpc_service` rate of `unary` (1:1) RPCs that failed, i.e. the \nones that didn't finish with `OK` code.\n\n### unary request error percentage\n```jsoniq\nsum(rate(grpc_server_handled_total{job=\"foo\",grpc_type=\"unary\",grpc_code!=\"OK\"}[1m])) by (grpc_service)\n / \nsum(rate(grpc_server_started_total{job=\"foo\",grpc_type=\"unary\"}[1m])) by (grpc_service)\n * 100.0\n```\nFor `job=\"foo\"`, calculate the percentage of failed requests by service. It's easy to notice that\nthis is a combination of the two above examples. This is an example of a query you would like to\n[alert on](https://prometheus.io/docs/alerting/rules/) in your system for SLA violations, e.g.\n\"no more than 1% requests should fail\".\n\n### average response stream size\n```jsoniq\nsum(rate(grpc_server_msg_sent_total{job=\"foo\",grpc_type=\"server_stream\"}[10m])) by (grpc_service)\n /\nsum(rate(grpc_server_started_total{job=\"foo\",grpc_type=\"server_stream\"}[10m])) by (grpc_service)\n```\nFor `job=\"foo\"` what is the `grpc_service`-wide `10m` average of messages returned for all `\nserver_stream` RPCs. This allows you to track the stream sizes returned by your system, e.g. allows \nyou to track when clients started to send \"wide\" queries that ret\nNote the divisor is the number of started RPCs, in order to account for in-flight requests.\n\n### 99%-tile latency of unary requests\n```jsoniq\nhistogram_quantile(0.99, \n  sum(rate(grpc_server_handling_seconds_bucket{job=\"foo\",grpc_type=\"unary\"}[5m])) by (grpc_service,le)\n)\n```\nFor `job=\"foo\"`, returns an 99%-tile [quantile estimation](https://prometheus.io/docs/practices/histograms/#quantiles)\nof the handling time of RPCs per service. Please note the `5m` rate, this means that the quantile\nestimation will take samples in a rolling `5m` window. When combined with other quantiles\n(e.g. 50%, 90%), this query gives you tremendous insight into the responsiveness of your system \n(e.g. impact of caching).\n\n### percentage of slow unary queries (\u003e250ms)\n```jsoniq\n100.0 - (\nsum(rate(grpc_server_handling_seconds_bucket{job=\"foo\",grpc_type=\"unary\",le=\"0.25\"}[5m])) by (grpc_service)\n / \nsum(rate(grpc_server_handling_seconds_count{job=\"foo\",grpc_type=\"unary\"}[5m])) by (grpc_service)\n) * 100.0\n```\nFor `job=\"foo\"` calculate the by-`grpc_service` fraction of slow requests that took longer than `0.25` \nseconds. This query is relatively complex, since the Prometheus aggregations use `le` (less or equal)\nbuckets, meaning that counting \"fast\" requests fractions is easier. However, simple maths helps.\nThis is an example of a query you would like to alert on in your system for SLA violations, \ne.g. \"less than 1% of requests are slower than 250ms\".\n\n\n## Status\n\nThis code has been used since August 2015 as the basis for monitoring of *production* gRPC micro services  at [Improbable](https://improbable.io).\n\n## License\n\n`go-grpc-prometheus` is released under the Apache 2.0 license. See the [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrpc-ecosystem%2Fgo-grpc-prometheus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgrpc-ecosystem%2Fgo-grpc-prometheus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrpc-ecosystem%2Fgo-grpc-prometheus/lists"}