{"id":13585636,"url":"https://github.com/gistart/prometheus-push-client","last_synced_at":"2026-01-14T08:13:29.406Z","repository":{"id":51306333,"uuid":"363989153","full_name":"gistart/prometheus-push-client","owner":"gistart","description":"Push Prometheus metrics to VictoriaMetrics or other exporters","archived":false,"fork":false,"pushed_at":"2021-05-17T07:17:33.000Z","size":86,"stargazers_count":19,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-23T21:16:59.986Z","etag":null,"topics":["influxdb","prometheus","pushgateway","python","victoriametrics"],"latest_commit_sha":null,"homepage":"","language":"Python","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/gistart.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}},"created_at":"2021-05-03T16:16:29.000Z","updated_at":"2025-01-14T06:25:56.000Z","dependencies_parsed_at":"2022-09-10T02:23:42.898Z","dependency_job_id":null,"html_url":"https://github.com/gistart/prometheus-push-client","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/gistart/prometheus-push-client","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gistart%2Fprometheus-push-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gistart%2Fprometheus-push-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gistart%2Fprometheus-push-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gistart%2Fprometheus-push-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gistart","download_url":"https://codeload.github.com/gistart/prometheus-push-client/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gistart%2Fprometheus-push-client/sbom","scorecard":{"id":427754,"data":{"date":"2025-08-11","repo":{"name":"github.com/gistart/prometheus-push-client","commit":"fcaddb31e81d5c04d86c01d219f73b7d2e1736ed"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.1,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/17 approved changesets -- score normalized to 0","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":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","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":"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":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yml:40: update your workflow using https://app.stepsecurity.io/secureworkflow/gistart/prometheus-push-client/tests.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yml:42: update your workflow using https://app.stepsecurity.io/secureworkflow/gistart/prometheus-push-client/tests.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/tests.yml:59: update your workflow using https://app.stepsecurity.io/secureworkflow/gistart/prometheus-push-client/tests.yml/master?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/tests.yml:47","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   0 out of   1 pipCommand dependencies pinned"],"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":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/tests.yml:1","Info: no jobLevel write permissions found"],"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":"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":"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":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"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":"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":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact 0.0.8 not signed: https://api.github.com/repos/gistart/prometheus-push-client/releases/43019414","Warn: release artifact 0.0.7 not signed: https://api.github.com/repos/gistart/prometheus-push-client/releases/42872829","Warn: release artifact 0.0.8 does not have provenance: https://api.github.com/repos/gistart/prometheus-push-client/releases/43019414","Warn: release artifact 0.0.7 does not have provenance: https://api.github.com/repos/gistart/prometheus-push-client/releases/42872829"],"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 6 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"}}]},"last_synced_at":"2025-08-19T02:36:58.583Z","repository_id":51306333,"created_at":"2025-08-19T02:36:58.584Z","updated_at":"2025-08-19T02:36:58.584Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28413669,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T05:26:33.345Z","status":"ssl_error","status_checked_at":"2026-01-14T05:21:57.251Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: 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":["influxdb","prometheus","pushgateway","python","victoriametrics"],"created_at":"2024-08-01T15:05:03.356Z","updated_at":"2026-01-14T08:13:29.380Z","avatar_url":"https://github.com/gistart.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"[![test-all](https://github.com/gistart/prometheus-push-client/actions/workflows/tests.yml/badge.svg?branch=master)](https://github.com/gistart/prometheus-push-client/actions)\n[![codecov](https://codecov.io/gh/gistart/prometheus-push-client/branch/master/graph/badge.svg?token=6K4G8CDU2R)](https://codecov.io/gh/gistart/prometheus-push-client)\n\n# prometheus-push-client\n\nPush metrics from your periodic long-running jobs to existing Prometheus/VictoriaMetrics monitoring system.\n\nCurrently supports pushes directly to `VictoriaMetrics`:\n- via HTTP in OpenMetrics format [in import mode](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#how-to-import-data-in-prometheus-exposition-format);\n- via UDP and HTTP using InfluxDB line protocol as [described here](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html?highlight=telegraf#how-to-send-data-from-influxdb-compatible-agents-such-as-telegraf).\n\nFor `pure Prometheus` setups, several options are supported:\n- to [pushgateway](https://github.com/prometheus/pushgateway) or [prom-aggregation-gateway](https://github.com/weaveworks/prom-aggregation-gateway) in OpenMetrics format via HTTP. Please read corresponding docs about appropriate use cases and limitations;\n- to [StatsD](https://github.com/statsd/statsd) or [statsd-exporter](https://github.com/prometheus/statsd_exporter#with-statsd) in StatsD format via UDP. Prometheus and StatsD metric types are not fully compatible, so currenly all metrics become StatsD gauges, but `rate`, `increase`, `histogram_quantile` and other PromQL functions produce same results as if types never changed.\n\nInstall it via pip:\n\n```sh\npip install prometheus-push-client\n```\n\n## Metrics\n\nThis library uses `prometheus-client` metric implementation, but adds some minor tweaks.\n\n### Separate registry\n\nNew metric constructors use separate `PUSH_REGISTRY` as a default, not to interfere with other metrics already defined and monitored in existing projects.\n\n### Default labelvalues\n\nWith regular `prometheus_client`, defaults may be defined for either _none_ or _all_ the labels (with `labelvalues`), but that's not enough. Moreover `labelvalues` sometimes doesn't work as expected.\n\nWe probably want to define _some_ defaults, like `hostname`, or more importantly, **if we use VictoriaMetrics cluster**, `VictoriaMetrics_AccountID=\u003ctenant_id\u003e` (try 0 as a default) label must always be set, and metrics without it will be ignored.\n\nFollowing example shows how to use defaults, and how to override them if necessary.\n\n```python\nimport prometheus_push_client as ppc\n\n\ncounter1 = ppc.Counter(\n    name=\"c1\",\n    labelnames=[\"VictoriaMetrics_AccountID\", \"host\", \"event_type\"],\n    default_labelvalues={\n        \"VictoriaMetrics_AccountID\": 0,\n        \"host\": socket.gethostname(),\n    }\n)\n\n\n# regular usage\ncounter1.labels(event_type=\"login\").inc()\n\n# overriding defaults\ncounter1.labels(host=\"non-default\", event_type=\"login\").inc()\n# same effect as above: defaults are applied in `labelvalues`\n# order for \"missing\" labels in the beginning\ncounter1.labels(\"non-default\", \"login\").inc()\n```\n\nMetrics with no labels are initialized at creation time. This can have unpleasant side-effect: if we initialize lots of metrics not used in currently running job, batch clients will have to push their non-changing values in every synchronization session.\n\nTo avoid that we'll have to properly isolate each task's metrics, which can be impossible or rather tricky, or we can create metrics with default, non-changing labels (like `hostname`). Such metrics will be initialized on first use (inc), and we'll be pushing only those we actually utilized.\n\n## Clients\n\n### Batch clients\n\nBatch clients spawn synchronization jobs \"in background\" (meaning in a thread or asyncio task) to periodically send all metrics from `ppc.PUSH_REGISTRY` to the destination.\n\nClients will attempt to stop gracefully, synchronizing registry \"one last time\" after job exits or crashes. Sometimes this _may_ mess up sampling, but the worst case I could artifically create looks like this:\n\n![graceful push effect](./docs/img/graceful_stop_effect01.png)\n\nBest way to use them is via decorators / context managers. These clients are intended to be used with long running, but finite tasks, which could be spawned anywhere, therefor not easily accessible by the scraper. If that's not the case -- just use \"passive mode\" w/ the scraper instead.\n\n``` python\ndef influx_udp_async(host, port, period=15.0):\ndef influx_udp_thread(host, port, period=15.0):\ndef statsd_udp_async(host, port, period=15.0):\ndef statsd_udp_thread(host, port, period=15.0):\ndef influx_http_async(url, verb=\"POST\", period=15.0):\ndef influx_http_thread(url, verb=\"POST\", period=15.0):\ndef openmetrics_http_async(url, verb=\"POST\", period=15.0):\ndef openmetrics_http_thread(url, verb=\"POST\", period=15.0):\n```\n\nUsage example:\n\n```python\nimport prometheus_push_client as ppc\n\n\nreq_hist = ppc.Histogram(\n    name=\"external_requests\",\n    namespace=\"acme\"\n    subsystem=\"job123\",\n    unit=\"seconds\",\n    labelnames=[\"service\"]\n)\n\n\n@ppc.influx_udp_async(\"victoria.acme.inc.net\", 9876, period=15)\nasync def main(urls):\n    # the job ...\n    req_hist.labels(gethostname(url)).observe(response.elapsed)\n\n# OR\n\nasync def main(urls):\n    async with ppc.influx_udp_async(\"victoria.acme.inc.net\", 9876, period=15):\n        # the job ...\n        req_hist.labels(gethostname(url)).observe(response.elapsed)\n```\n\nPlease read about mandatory `job` tag within url while [using pushgateway](https://github.com/prometheus/pushgateway#url).\n\n\n### Streaming clients\n\nIf for some reason every metric change needs to be synced, UDP streaming clients are implemented in this library.\n\n```python\ndef influx_udp_aiostream(host, port):\ndef influx_udp_stream(host, port):\ndef statsd_udp_aiostream(host, port):\ndef statsd_udp_stream(host, port):\n```\n\nUsage is completely identical to batch clients' decorators / context managers.\n\n:warning: Histogram and Summary `.time() decorator` doesn't work in this mode atm, because it can't be monkey-patched easily.\n\n\n## Transports\n\nMain goal is not to interrupt measured jobs with errors from monitoring code. Therefor all transports will attempt to catch all network errors, logging error info and corresponding tracebacks to stdout.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgistart%2Fprometheus-push-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgistart%2Fprometheus-push-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgistart%2Fprometheus-push-client/lists"}