{"id":45999345,"url":"https://github.com/biaks/prometheus-cpp-lite","last_synced_at":"2026-03-03T00:05:36.333Z","repository":{"id":48556278,"uuid":"381477443","full_name":"biaks/prometheus-cpp-lite","owner":"biaks","description":"C++ header-only prometheus client library for quickly and easily adding metric (and profiling) functionality to C++ projects.","archived":false,"fork":false,"pushed_at":"2026-02-12T08:58:57.000Z","size":83,"stargazers_count":42,"open_issues_count":1,"forks_count":19,"subscribers_count":4,"default_branch":"master","last_synced_at":"2026-02-12T17:54:34.107Z","etag":null,"topics":["cpp11","cpp14","cpp17","crossplatform","header-only","metrics","metrics-library","prometheus","prometheus-client","prometheus-metrics"],"latest_commit_sha":null,"homepage":"","language":"C++","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/biaks.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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-06-29T19:36:16.000Z","updated_at":"2026-02-12T08:59:02.000Z","dependencies_parsed_at":"2023-02-05T22:16:54.133Z","dependency_job_id":null,"html_url":"https://github.com/biaks/prometheus-cpp-lite","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/biaks/prometheus-cpp-lite","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/biaks%2Fprometheus-cpp-lite","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/biaks%2Fprometheus-cpp-lite/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/biaks%2Fprometheus-cpp-lite/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/biaks%2Fprometheus-cpp-lite/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/biaks","download_url":"https://codeload.github.com/biaks/prometheus-cpp-lite/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/biaks%2Fprometheus-cpp-lite/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29953212,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-28T18:42:55.706Z","status":"ssl_error","status_checked_at":"2026-02-28T18:42:48.811Z","response_time":90,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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":["cpp11","cpp14","cpp17","crossplatform","header-only","metrics","metrics-library","prometheus","prometheus-client","prometheus-metrics"],"created_at":"2026-02-28T22:04:27.409Z","updated_at":"2026-03-03T00:05:36.267Z","avatar_url":"https://github.com/biaks.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# prometheus-cpp-lite\n\n[![Build examples](https://github.com/biaks/prometheus-cpp-lite/actions/workflows/cmake.yml/badge.svg)](https://github.com/biaks/prometheus-cpp-lite/actions/workflows/cmake.yml)\n[![Build multi-platform](https://github.com/biaks/prometheus-cpp-lite/actions/workflows/cmake-multi-platform.yml/badge.svg)](https://github.com/biaks/prometheus-cpp-lite/actions/workflows/cmake-multi-platform.yml)\n\n\n**Crossplatform header-only C++ library for quickly adding metrics (and profiling) functionality to C++ projects — simple, fast, dependency-free.**\n\n**Simplest usage — global registry, no boilerplate:**\n\n```cpp\n#include \u003cprometheus/prometheus.h\u003e\n\nint main() {\n  prometheus::counter_metric_t requests (\"http_requests_total\", \"Total HTTP requests\");\n  prometheus::http_server.start (\"127.0.0.1:9100\");\n\n  for (;;) {\n    std::this_thread::sleep_for(std::chrono::seconds(1));\n    requests++;\n  }\n}\n```\n\n**Full control — registry, families, labels, value types:**\n\n```cpp\n#include \u003cprometheus/prometheus.h\u003e\nusing namespace prometheus;\n\nint main() {\n  registry_t         registry;\n  family_t           reqs   (registry, \"http_requests\", \"HTTP requests\", {{\"host\", \"web01\"}});\n  counter_t\u003cdouble\u0026\u003e get    (reqs,     {{\"method\", \"GET\"},  {\"status\", \"200\"}});\n  counter_t\u003cdouble\u0026\u003e post   (reqs,     {{\"method\", \"POST\"}, {\"status\", \"201\"}});\n  gauge_metric_t     conn   (registry, \"connections\", \"Open connections\", {{\"host\", \"web01\"}});\n  http_server_t      server (registry, \"127.0.0.1:9100\", \"/metrics\", log_e::info);\n\n  for (;;) {\n    std::this_thread::sleep_for(std::chrono::seconds(1));\n    get  += 1.5;\n    post += 0.75;\n    conn  = 10 + std::rand() % 50;\n  }\n}\n```\n\n---\n\n\n\n## Why another Prometheus library for C++?\n\nThe main C++ Prometheus library - [jupp0r/prometheus-cpp](https://github.com/jupp0r/prometheus-cpp) - is mature and battle-tested, but it was designed with a Java mindset:\n\n|                     | **prometheus-cpp**                 | **prometheus-cpp-lite**                                           |\n|---------------------|------------------------------------|-------------------------------------------------------------------|\n| Architecture        | Split into 3 libraries (`core`, `pull`, `push`) with separate `.h`/`.cpp` pairs per class | Single header-only library - just copy the headers |\n| Dependencies        | zlib, libcurl, civetweb (or beast) | **None**                                                          |\n| Build system        | Bazel (primary) + CMake            | CMake or **just copy files**                                      |\n| Minimum boilerplate | ~20 lines to create one counter    | **2 lines** to create a counter and expose it (with global registry, see below) |\n| Value types         | `double` only                      | `uint64_t` (default), `double`, `int64_t`, or any arithmetic type |\n| Metric types        | `counter`, `gauge`, `histogram`, `summary`, `info` | [`counter`](examples/test_counter.cpp), [`gauge`](examples/test_gauge.cpp), [`histogram`](examples/test_histogram.cpp), [`summary`](examples/test_summary.cpp), `info`, **[`benchmark`](examples/test_benchmark.cpp)** - or [make your own](examples/add_custom_metric_class.cpp) |\n| C++ standard        | C++11                              | C++11                                                             |\n| Thread-safe         | Yes                                | Yes                                                               |\n\n**prometheus-cpp-lite is not a fork.** It is a ground-up rewrite focused on C++ idioms:\noperators instead of `.Increment()`, RAII instead of manual registration, zero-copy\nreference handles instead of raw pointers.\n\n**Full prometheus-cpp compatibility.** The library supports the same API style\nused by prometheus-cpp (`BuildCounter()`, `Family`, `Registry`, `Add()`, raw\nreferences). If you are migrating from prometheus-cpp, your existing patterns\nwill work.\n\n---\n\n\n\n## Features\n\n- **Header-only**                       - no libraries to build, no linker flags, no package manager required\n- **Cross-platform**                    - works on Linux and Windows with any C++11 and higher compiler\n- **Zero dependencies**                 - pure C++ standard library (networking uses a bundled copy of [ip-sockets-cpp-lite](https://github.com/biaks/ip-sockets-cpp-lite))\n- **Low entry barrier**                 - a working counter with HTTP export is 2 lines of code (with global registry, see below)\n- **Gradual complexity**                - start simple, add families/labels/registries/custom types when needed\n- **Multiple value types**              - `uint64_t` (fast integer), `double` (Prometheus-compatible), `int64_t`, or custom\n- **Six metric types**                  - [`counter`](examples/test_counter.cpp), [`gauge`](examples/test_gauge.cpp), [`histogram`](examples/test_histogram.cpp), [`summary`](examples/test_summary.cpp), `info`, [`benchmark`](examples/test_benchmark.cpp)\n- **Three export modes**                - HTTP pull server, HTTP push (Pushgateway), file (node_exporter textfile)\n- **Simplest way with global_registry** - add metrics anywhere in your code without passing registry references\n- **prometheus-cpp compatible**         - supports the same Builder/Family/Registry API style\n- **Extensible**                        - each metric type is self-contained in one header; **you can [add your own](examples/add_custom_metric_class.cpp) metric by following the same pattern**\n- **Detailed examples**                 - see the [examples](examples) folder for usage patterns\n\n---\n\n\n\n## Quick start\n\n### Installation\n\n**Option A - Copy headers (simplest):**\n\nCopy the `include/prometheus` directory into your project and add it to\ninclude paths. If you need HTTP pull or push support, also copy the headers\nfrom `3rdparty/ip-sockets-cpp-lite/include/`.\n\n**Option B - CMake subdirectory:**\n\n```cmake\nadd_subdirectory(prometheus-cpp-lite)\n\n# Header-only (you define global_registry yourself if you need it):\ntarget_link_libraries(your_target prometheus-cpp-lite)\n\n# Or with pre-defined global objects (global_registry, file_saver, http_pusher, http_server):\ntarget_link_libraries(your_target prometheus-cpp-lite-full)\n```\n\n**Option C - CMake FetchContent:**\n\n```cmake\ninclude(FetchContent)\nFetchContent_Declare(\n  prometheus-cpp-lite\n  GIT_REPOSITORY https://github.com/biaks/prometheus-cpp-lite.git\n  GIT_TAG        main\n)\nFetchContent_MakeAvailable(prometheus-cpp-lite)\ntarget_link_libraries(your_target prometheus-cpp-lite)\n```\n\n### All metric types at a glance\n\n```cpp\n#include \u003cprometheus/prometheus.h\u003e\n\nusing namespace prometheus;\n\nint main() {\n  registry_t         registry;\n\n  counter_metric_t   requests (registry, \"http_requests_total\",  \"Total requests\");\n  gauge_metric_t     active   (registry, \"active_connections\",   \"Open connections\");\n  histogram_metric_t latency  (registry, \"request_duration_sec\", \"Request latency\", {}, {0.01, 0.05, 0.1, 0.5, 1.0});\n  summary_metric_t   response (registry, \"response_time_sec\",    \"Response time\",   {}, {{0.5,0.05},{0.9,0.01},{0.99,0.001}});\n  benchmark_metric_t uptime   (registry, \"uptime_sec\",           \"Process uptime\");\n  info_metric_t      info     (registry, \"build_info\",           \"Build information\", {{\"version\", \"1.0.0\"}, {\"commit\", \"abc123\"}});\n\n  http_server_t      server   (registry, {{127,0,0,1}, 9100});\n\n  // curl http://localhost:9100/metrics\n\n  uptime.start();\n  for (int i = 0; i \u003c 60; ++i) {\n    std::this_thread::sleep_for(std::chrono::seconds(1));\n    requests++;\n    active.Set      (10    +  std::rand() % 50);\n    latency.Observe (0.001 * (std::rand() % 1000));\n    response.Observe(0.001 * (std::rand() % 500));\n  }\n  uptime.stop();\n}\n```\n\n---\n\n\n\n## Three ways to export metrics\n\n### 1. HTTP pull (recommended for long-running services)\n\nThe application runs an HTTP server. Prometheus scrapes it periodically ([example](examples/provide_via_http_pull_simple.cpp)).\n\n```cpp\n#include \u003cprometheus/prometheus.h\u003e\n\nprometheus::registry_t       registry;\nprometheus::counter_metric_t metric (registry, \"my_counter\", \"Example counter\");\nprometheus::http_server_t    server (registry, \"127.0.0.1:9100\");\n// → http://localhost:9100/metrics\n```\n\n**Multiple endpoints** for different metric domains ([example](examples/provide_via_http_pull_advanced.cpp)):\n\n```cpp\nusing namespace prometheus;\nauto app_registry = std::make_shared\u003cregistry_t\u003e();\nauto sys_registry = std::make_shared\u003cregistry_t\u003e();\n\nhttp_server_t server;\nserver.add_endpoint(app_registry, \"/metrics/app\");\nserver.add_endpoint(sys_registry, \"/metrics/sys\");\nserver.start({{127,0,0,1}, 9200});\n// → http://localhost:9200/metrics/app\n// → http://localhost:9200/metrics/sys\n```\n\n### 2. HTTP push (for short-lived jobs, edge devices)\n\nMetrics are POSTed to a Pushgateway or VictoriaMetrics at a fixed interval ([example](examples/provide_via_http_push_simple.cpp)).\n\n```cpp\n#include \u003cprometheus/prometheus.h\u003e\n\nprometheus::registry_t       registry;\nprometheus::counter_metric_t metric (registry, \"my_counter\", \"Example counter\");\nprometheus::http_pusher_t    pusher (registry, std::chrono::seconds(5),\n                                               \"http://localhost:9091/metrics/job/myapp\");\n```\n\n### 3. File export (for node_exporter textfile collector)\n\nMetrics are written to a `.prom` file at a fixed interval ([example](examples/provide_via_textfile.cpp)).\n\n```cpp\n#include \u003cprometheus/prometheus.h\u003e\n\nprometheus::registry_t       registry;\nprometheus::counter_metric_t metric (registry, \"my_counter\", \"Example counter\");\nprometheus::file_saver_t     saver  (registry, std::chrono::seconds(5), \"./metrics.prom\");\n```\n\n---\n\n## Labels (dimensional data)\n\n### Using a family\n\n```cpp\nfamily_t         requests   (registry, \"http_requests\", \"Requests by method\", {{\"host\", \"dev\"}});\ncounter_metric_t get_count  (requests, {{\"method\", \"GET\"}});\ncounter_metric_t post_count (requests, {{\"method\", \"POST\"}});\n\nget_count++;\npost_count += 5;\n```\n\nOutput:\n\n```\n# HELP http_requests HTTP requests by method\n# TYPE http_requests counter\nhttp_requests{host=\"dev\", method=\"GET\"} 1\nhttp_requests{host=\"dev\", method=\"POST\"} 5\n```\n\n---\n\n\n\n## Choosing a value type\n\nThe default counter uses `uint64_t` for maximum performance.\nThe default gauge uses `int64_t`.\nBoth can be overridden with `double` or any other arithmetic type.\n\n**Why `uint64_t` is faster than `double` for atomics:**\n`std::atomic\u003cuint64_t\u003e` supports lock-free `fetch_add` on most platforms -\na single CPU instruction.\n`std::atomic\u003cdouble\u003e` typically lacks native `fetch_add`, so every increment\nrequires a compare-and-swap (CAS) loop: load the current value, compute the\nnew value, attempt to store it, and retry if another thread modified it in\nbetween. Under contention this can be significantly slower.\n\nprometheus-cpp uses `double` for all metric types. prometheus-cpp-lite\ndefaults to integer atomics where it makes sense (counters, gauges) and\nuses `double` where fractional values are required (histograms, summaries,\nbenchmarks).\n\n```cpp\n// Default: uint64_t - lock-free fetch_add, fastest for integer counters\ncounter_metric_t integer_counter (registry, \"requests_total\", \"Total requests\");\ninteger_counter++;\n\n// Floating-point counter - CAS loop, use when you need fractional values\ncounter_t\u003cdouble\u0026\u003e fp_counter (registry, \"duration_seconds_total\", \"Total duration\");\nfp_counter += 0.42;\n```\n\n---\n\n\n\n## Global registry — add metrics to existing code in seconds\n\nThe global registry is designed for the most common real-world scenario:\n**you already have a large codebase and want to add metrics without\nrestructuring it.**\n\nNormally, adding metrics to existing code is painful. You need to figure out\nhow to pass a registry or metric objects through your class hierarchy,\nmodify constructors, add member variables, and thread references through\nlayers of code that were never designed for observability.\n\nWith prometheus-cpp-lite's global registry approach, none of that is\nnecessary. The `prometheus-cpp-lite-full` CMake target provides ready-made\nglobal objects — `global_registry`, `file_saver`, `http_pusher`, and\n`http_server` — so you can create metrics anywhere in your code and start\nexposing them with a single call from any place ([example](examples/check_global_objects.cpp)).\nNo plumbing required.\n\n### The workflow\n\n**1. Link against `prometheus-cpp-lite-full` in your CMakeLists.txt:**\n\n```cmake\ntarget_link_libraries(your_target prometheus-cpp-lite-full)\n```\n\n**2. Sprinkle metrics anywhere in your codebase — any file, any class, any function:**\n\n```cpp\n#include \u003cprometheus/counter.h\u003e\n\nvoid handle_request() {\n  prometheus::counter_metric_t requests (\"http_requests_total\", \"Total requests\");\n  requests++;\n}\n\nvoid handle_error() {\n  prometheus::counter_metric_t errors   (\"http_errors_total\",   \"Total errors\");\n  prometheus::counter_metric_t requests (\"http_requests_total\", \"Total requests\");\n  // ^ same metric as in handle_request() — same name, same global registry\n  errors++;\n  requests++;\n}\n```\n\nMetrics with the same name automatically refer to the same underlying\nmetric in the global registry. No constructor changes, no member\nvariables, no passing references around.\n\n**3. Start exposing metrics — one line, anywhere in your code:**\n\n```cpp\n#include \u003cprometheus/prometheus.h\u003e\n\n// Call this once at startup, e.g. in main():\nprometheus::http_server.start(\"127.0.0.1:9100\");\n// → http://localhost:9100/metrics — all metrics from all files are here\n```\n\nThat's it. Every metric you created in step 2 is automatically available\nat the HTTP endpoint ([example](examples/use_metrics_in_class_simple.cpp)).\nYou can also use the other pre-defined global\nexporters:\n\n```cpp\n#include \u003cprometheus/prometheus.h\u003e\n\n// Write metrics to a .prom file every 5 seconds:\nprometheus::file_saver.start(std::chrono::seconds(5), \"./metrics.prom\");\n\n// Push metrics to Pushgateway every 10 seconds:\nprometheus::http_pusher.start(std::chrono::seconds(10), \"http://pushgateway:9091/metrics/job/myapp\");\n```\n\n### If you prefer pure header-only (no extra .cpp files)\n\nIf you don't want any pre-compiled translation units in your project, link\nagainst the header-only target instead:\n\n```cmake\ntarget_link_libraries(your_target prometheus-cpp-lite)\n```\n\nIn this case, define the global objects yourself — once, in any `.cpp` file:\n\n```cpp\n#include \u003cprometheus/prometheus.h\u003e\n\n// Define once, in a single .cpp file:\nnamespace prometheus {\n  registry_t    global_registry;\n  http_server_t http_server (global_registry);\n}\n\nint main() {\n  prometheus::http_server.start(\"127.0.0.1:9100\");\n  // ... rest of your application ...\n}\n```\n\nAfter that, metrics created anywhere via the two-argument constructor\n(`counter_metric_t m (\"name\", \"help\")`) automatically use `global_registry`,\nand the behavior is identical to `prometheus-cpp-lite-full`.\n\n---\n\n### Quick profiling with benchmark metrics\n\nThe `benchmark_t` metric is especially powerful with the global registry.\nYou can wrap any function call or code block with `start()`/`stop()` to\nmeasure its wall-clock time — without touching the function's signature,\nclass hierarchy, or build dependencies. Just add two lines around the code\nyou want to profile:\n\n```cpp\n#include \u003cprometheus/benchmark.h\u003e\n\nvoid process_order(const Order\u0026 order) {\n  prometheus::benchmark_metric_t timer (\"process_order_seconds\", \"Time spent in process_order\");\n  timer.start();\n\n  // ... existing code, unchanged ...\n\n  timer.stop();\n}\n```\n\nThe accumulated elapsed time is immediately available at your `/metrics`\nendpoint — no separate profiling tool, no recompilation with special flags,\nno post-hoc analysis. You get real production latency data from live traffic\n([example](examples/use_benchmark_in_class_simple.cpp)).\n\n**Best practice for multithreaded code:** the `start()`/`stop()` state\nmachine is local to each metric instance and is intentionally not\nthread-safe — this avoids lock overhead in hot paths. When multiple threads\nexecute the same function, give each thread its own metric instance by\nadding a distinguishing label (e.g. thread index or thread name):\n\n```cpp\n#include \u003cprometheus/benchmark.h\u003e\n\n// Shared family — defined once (e.g. at file scope or in a class).\nprometheus::family_t worker_time (\"worker_duration_seconds\", \"Per-thread processing time\");\n\nvoid worker_thread_func(int thread_id) {\n  // Each thread owns its own metric — no start/stop contention.\n  prometheus::benchmark_metric_t my_timer (worker_time, {{\"thread\", std::to_string(thread_id)}});\n  for (;;) {\n    my_timer.start();\n    // ... do work ...\n    my_timer.stop();\n  }\n}\n```\n\nThis produces separate time series per thread, which you can aggregate in\nPromQL (`sum`, `avg`, `max`) or inspect individually in Grafana:\n\n```\n# HELP worker_duration_seconds Per-thread processing time\n# TYPE worker_duration_seconds counter\nworker_duration_seconds{thread=\"0\"} 12.345\nworker_duration_seconds{thread=\"1\"} 11.892\nworker_duration_seconds{thread=\"2\"} 13.017\n```\n\nThis is invaluable when instrumenting legacy code — from personal\nexperience, it turns a multi-day refactoring task into a few minutes of\nwork.\n\n---\n\n## Info metric - expose build metadata\n\nThe `info_t` metric is a gauge permanently set to `1` whose labels carry\nmetadata such as version, commit hash, or build date. This is a standard\nPrometheus pattern for exposing build information that can be joined with\nother metrics in PromQL or Grafana.\n\n```cpp\n#include \u003cprometheus/info.h\u003e\nprometheus::info_metric_t build_info (registry, \"build_info\", \"Build information\",\n                          {{\"version\", \"1.0.0\"}, {\"commit\", \"abc123\"}, {\"branch\", \"main\"}});\n```\n\nOutput:\n\n```\n# HELP build_info Build information\n# TYPE build_info gauge\nbuild_info{branch=\"main\",commit=\"abc123\",version=\"1.0.0\"} 1\n```\n\n---\n\n\n\n## Drop-in compatibility with `prometheus-cpp`\n\nprometheus-cpp-lite ships shim headers and class aliases that make it\n**a transparent replacement** for [jupp0r/prometheus-cpp](https://github.com/jupp0r/prometheus-cpp).\nCode written for prometheus-cpp compiles and works **without any changes** —\nnot even the `#include` lines need to be modified.\n\n| prometheus-cpp                                  | prometheus-cpp-lite       | Shim header                               |\n|-------------------------------------------------|---------------------------|-------------------------------------------|\n| `#include \u003cprometheus/exposer.h\u003e`               | ✔ provided                | redirects to `\u003cprometheus/http_puller.h\u003e` |\n| `#include \u003cprometheus/gateway.h\u003e`               | ✔ provided                | redirects to `\u003cprometheus/http_pusher.h\u003e` |\n| `#include \u003cprometheus/family.h\u003e`                | ✔ provided                | redirects to `\u003cprometheus/core.h\u003e`        |\n| `#include \u003cprometheus/registry.h\u003e`              | ✔ provided                | redirects to `\u003cprometheus/core.h\u003e`        |\n| `#include \u003cprometheus/text_serializer.h\u003e`       | ✔ provided                | redirects to `\u003cprometheus/core.h\u003e`        |\n| `#include \u003cprometheus/client_metric.h\u003e`         | ✔ provided                | redirects to `\u003cprometheus/core.h\u003e`        |\n| `prometheus::Exposer`                           | alias for `http_server_t` | defined in `\u003cprometheus/http_puller.h\u003e`   |\n| `prometheus::Gateway`                           | alias for `http_pusher_t` | defined in `\u003cprometheus/http_pusher.h\u003e`   |\n| `prometheus::Registry`                          | same class                | defined in `\u003cprometheus/core.h\u003e`          |\n| `prometheus::Family`                            | same class                | defined in `\u003cprometheus/core.h\u003e`          |\n| `prometheus::BuildCounter()`                    | same function             | defined in `\u003cprometheus/counter.h\u003e`       |\n| `prometheus::BuildGauge()`                      | same function             | defined in `\u003cprometheus/gauge.h\u003e`         |\n| `prometheus::BuildHistogram()`                  | same function             | defined in `\u003cprometheus/histogram.h\u003e`     |\n| `prometheus::BuildSummary()`                    | same function             | defined in `\u003cprometheus/summary.h\u003e`       |\n| `Add()`, `Increment()`, `RegisterCollectable()` | same API                  |                                           |\n\n### Example 1: Exposer (HTTP pull)\n\nThe code below is **[valid prometheus-cpp code](examples/legacy_prometheus_cpp.cpp)**. It compiles and runs with\nprometheus-cpp-lite without touching a single line — just swap the library\nin your build system:\n\n```cpp\n#include \u003cprometheus/counter.h\u003e\n#include \u003cprometheus/exposer.h\u003e\n#include \u003cprometheus/registry.h\u003e\n\nint main() {\n  prometheus::Exposer exposer{\"127.0.0.1:8080\"};\n  auto registry = std::make_shared\u003cprometheus::Registry\u003e();\n\n  auto\u0026 family = prometheus::BuildCounter()\n                   .Name(\"http_reqs\")\n                   .Help(\"HTTP requests\")\n                   .Register(*registry);\n\n  auto\u0026 counter = family.Add({{\"method\", \"GET\"}});\n  exposer.RegisterCollectable(registry);\n\n  counter.Increment();\n}\n```\n\n**The same thing in prometheus-cpp-lite native API — 6 lines instead of 13:**\n\n```cpp\n#include \u003cprometheus/prometheus.h\u003e\n\nint main() {\n  prometheus::registry_t       registry;\n  prometheus::http_server_t    server  (registry, \"127.0.0.1:8080\");\n  prometheus::counter_metric_t counter (registry, \"http_reqs\", \"HTTP requests\", {{\"method\",\"GET\"}});\n\n  counter++;\n}\n```\n\n### Example 2: Gateway (HTTP push)\n\nAgain — **unmodified prometheus-cpp code**, works as-is:\n\n```cpp\n#include \u003cprometheus/counter.h\u003e\n#include \u003cprometheus/gateway.h\u003e\n#include \u003cprometheus/registry.h\u003e\n\nint main() {\n  prometheus::Gateway gateway{\"localhost\", \"9091\", \"my_job\", {{\"instance\", \"host1\"}}};\n  auto registry = std::make_shared\u003cprometheus::Registry\u003e();\n\n  auto\u0026 family = prometheus::BuildGauge()\n                   .Name(\"cpu_usage_percent\")\n                   .Help(\"CPU usage\")\n                   .Register(*registry);\n\n  auto\u0026 cpu_usage = family.Add({{\"core\", \"0\"}});\n  gateway.RegisterCollectable(registry);\n\n  cpu_usage.Set(0.54);\n  cpu_usage.Increment(0.09);\n  gateway.Push();\n}\n```\n\n**The same thing in prometheus-cpp-lite native API:**\n\n```cpp\n#include \u003cprometheus/prometheus.h\u003e\n\nint main() {\n  prometheus::registry_t       registry;\n  prometheus::http_pusher_t    pusher    (registry, std::chrono::seconds(5), \"localhost\", \"9091\", \"my_job\", {{\"instance\", \"host1\"}});\n  prometheus::gauge_t\u003cdouble\u0026\u003e cpu_usage (registry, \"cpu_usage_percent\", \"CPU usage\", {{\"core\", \"0\"}});\n\n  cpu_usage  = 0.54;\n  cpu_usage += 0.09;\n}\n```\n\nBoth styles can coexist in the same project — all metrics end up in the same\nregistry and are serialized identically.\n\n---\n\n\n\n## API levels\n\nprometheus-cpp-lite supports several API styles. Start with the simplest and\nmove to more explicit forms only when you need fine-grained control:\n\n| Level                              | Description                                         | Example                                                            |\n|------------------------------------|-----------------------------------------------------|--------------------------------------------------------------------|\n| **Simple** with `global_registry`  | Global registry, implicit family, operator syntax   | `counter_metric_t m (\"name\", \"help\", {{\"k\",\"v\"}});`\u003cbr\u003e`m++;` |\n| **Simple** with explicit `registry`| Explicit registry, implicit family, operator syntax | `registry_t r;`\u003cbr\u003e`counter_metric_t m (r, \"name\", \"help\", {{\"k\",\"v\"}});`\u003cbr\u003e`m++;` |\n| **Family** with `global_registry`  | Global registry, explicit family with family labels | `family_t f (\"name\", \"help\", {{\"k\",\"v\"}});`\u003cbr\u003e`counter_metric_t m (f, {{\"k\",\"v\"}});`\u003cbr\u003e`m++;` |\n| **Family** with explicit `registry`| Explicit registry and family with family labels     | `registry_t r;`\u003cbr\u003e`family_t f (r, \"name\", \"help\", {{\"k\",\"v\"}});`\u003cbr\u003e`counter_metric_t m (f, {{\"k\",\"v\"}});`\u003cbr\u003e`m++;` |\n| **Custom family**                  | Compile-time type safety for families               | `counter_family_t f (\"name\", \"help\", {{\"k\",\"v\"}});`\u003cbr\u003e`counter_metric_t m (f, {{\"k\",\"v\"}});`\u003cbr\u003e`m++;` |\n| **Custom types of metric values**  | Customisation values types of metrics               | `counter_t\u003cdouble\u0026\u003e m (\"name\", \"help\", {{\"k\",\"v\"}});`\u003cbr\u003e`m++;` |\n| **`prometheus-cpp` compatible**    | Builder pattern, raw references                     | `auto  r = std::make_shared\u003cprometheus::Registry\u003e();`\u003cbr\u003e`auto\u0026 f = BuildCounter().Name(\"nm\").Help(\"hlp\").Labels({{\"k\",\"v\"}}).Register(r)`\u003cbr\u003e`auto\u0026 m = f.Add({{\"k\",\"v\"}});`\u003cbr\u003e`m.Increment();` |\n\nAll levels are interoperable - metrics created with any style end up in the\nsame registry and are serialized together.\n\nSee the [`examples/`](examples/) directory for complete working programs\ndemonstrating every API level (`test_*` files).\n\n---\n\n\n\n\n## Migrating from prometheus-cpp-lite v1.0\n\nprometheus-cpp-lite v2.0 is a major update that simplifies the project\nstructure, unifies the API, and adds new features — while preserving full\nbackward compatibility. **Your existing v1.0 code will compile and work\nwithout changes.** You will only see deprecation warnings guiding you\ntoward the updated API.\n\n### Structural changes\n\n|                           | v1.0                                                          | v2.0                                                   |\n|---------------------------|---------------------------------------------------------------|--------------------------------------------------------|\n| Directory layout          | `core/include/`, `simpleapi/`, `3rdpatry/`                    | `include/`, `src/`, `3rdparty/`                        |\n| CMake targets             | `prometheus-cpp-lite-core` (header-only)                      | `prometheus-cpp-lite` (header-only, simpleapi)         |\n|                           | `prometheus-cpp-simpleapi` (simpleapi, static, with globals)  | `prometheus-cpp-lite-full` (static, with globals)      |\n| Core headers              | Split: `registry.h`, `family.h`, `metric.h`, `builder.h`, …   | Unified: `core.h` (one header for all core types)      |\n| Metric headers            | Same                                                          | Same (`counter.h`, `gauge.h`, etc.)                    |\n| Umbrella header           | `simpleapi.h` (includes + global objects + simpleapi aliases) | `prometheus.h` (includes + global object declarations) |\n| Networking                | separate `Gateway` and `PushToServer`,\u003cbr\u003e no HTTP pull server    | rewritten `http_pusher_t` (POST/PUT/DELETE,\u003cbr\u003esync + async, periodic + on-demand, `Gateway`-compatible)\u003cbr\u003e+ new `http_server_t` (HTTP pull, multi-endpoint, index page, `Exposer`-compatible) |\n| Networking library        | `http-client-lite` (bundled)                                  | `ip-sockets-cpp-lite` (bundled)                        |\n| Networking headers        | `save_to_file.h`, `push_to_server.h`, `gateway.h`             | `file_saver.h`, `http_pusher.h`, `http_puller.h`       |\n| Collect values            | standalone classes for storing and serializing metric values  | each metric collects and serializes values itself      |\n| Metric ownership model    | separate classes for owning metrics and referencing them      | single template: `metric_t\u003cT\u003e` owns the value, `metric_t\u003cT\u0026\u003e`\u003cbr\u003e is a zero-copy reference — same class, same API |\n| Add custom metric classes | not possible                                                  | support users custom metric classes — follow the existing metric pattern  |\n\n### API changes\n\n|                            | v1.0                                                 | v2.0                                                                      |\n|----------------------------|------------------------------------------------------|---------------------------------------------------------------------------|\n| simpleAPI primary namespace| `prometheus::simpleapi::`                            | `prometheus::`                                                            |\n| Creating a family          | `simpleapi::counter_family_t f {\"name\", \"help\", {{\"k\",\"v\"}}};` | `family_t f {\"name\", \"help\", {{\"k\",\"v\"}}};`\u003cbr\u003e`family_t f {registry, \"name\", \"help\", {{\"k\",\"v\"}}};`\u003cbr\u003e`counter_family_t f {\"name\", \"help\", {{\"k\",\"v\"}}};`\u003cbr\u003e`counter_family_t f {registry, \"name\", \"help\", {{\"k\",\"v\"}}};` |\n| Creating a metric (simple) | `simpleapi::counter_metric_t m {\"name\", \"help\", {{\"k\",\"v\"}}};` | `counter_metric_t m {\"name\", \"help\", {{\"k\",\"v\"}}};`\u003cbr\u003e`counter_metric_t m {registry, \"name\", \"help\", {{\"k\",\"v\"}}};` |\n| Creating a metric in family| `simpleapi::counter_metric_t m {family.Add(l)};`     | `counter_metric_t m {family, {{\"k\",\"v\"}}};`\u003cbr\u003e`counter_metric_t m {family.Add({{\"k\",\"v\"}})};` |\n| Networking classes         | `SaveToFile`, `PushToServer`                         | `file_saver_t`, `http_pusher_t`                                           |\n| HTTP pull server           | not available                                        | `http_server_t` (new)                                                     |\n| `prometheus-cpp` compat    | partial                                              | full (added `Exposer` and `Gateway` aliases)                              |\n| New metric types           | —                                                    | `info_t`                                                                  |\n\n### What stayed the same (backward compatibility)\n\nEverything below continues should to work in v2.0 — no code changes required:\n\n- **Old CMake target names.** `prometheus-cpp-lite-core` and\n  `prometheus-cpp-simpleapi` are aliases for the new targets.\n- **Old header names.** Shim headers (`registry.h`, `family.h`, `metric.h`,\n  `builder.h`, `hash.h`, `collectable.h`, `client_metric.h`,\n  `metric_family.h`, `text_serializer.h`, `save_to_file.h`,\n  `push_to_server.h`, `gateway.h`) redirect to the new headers with a\n  one-time `#pragma message` deprecation notice.\n- **Old class names.** `SaveToFile` → `file_saver_t`, `PushToServer` →\n  `http_pusher_t`, `Gateway` → `http_pusher_t` — all available as\n  `[[deprecated]]` type aliases.\n- **`prometheus::simpleapi::` namespace.** All type aliases (`counter_metric_t`,\n  `counter_family_t`, `gauge_metric_t`, etc.) are preserved with\n  `[[deprecated]]` attributes pointing to the `prometheus::` equivalents.\n- **`#include \u003cprometheus/simpleapi.h\u003e`** still works. It includes the new\n  umbrella header `\u003cprometheus/prometheus.h\u003e` (which pulls in all metric\n  headers, networking headers, and global object declarations) and provides\n  the deprecated `prometheus::simpleapi::` aliases. A `#pragma message`\n  notice suggests switching to `\u003cprometheus/prometheus.h\u003e`.\n\n### Step-by-step migration guide\n\nAll steps are optional. Your code compiles without them — these changes\nonly silence deprecation warnings and modernize your codebase.\n\n#### Step 1 — Update CMakeLists.txt\n\nReplace:\n\n```cmake\n# v1.0\nadd_subdirectory(\"prometheus-cpp-lite\")\n\n# If you need SimpleAPI and pre-defined global objects (global_registry, file_saver, etc.):\ntarget_link_libraries(your_target prometheus-cpp-simpleapi)\n\n# If you use only ComplexAPI or Java liked legacy API from prometheus-cpp and use local registries:\ntarget_link_libraries(your_target prometheus-cpp-lite-core)\n```\n\nWith:\n\n```cmake\n# v2.0\nadd_subdirectory(\"prometheus-cpp-lite\")\n\n# If you need pre-defined global objects (global_registry, file_saver, http_pusher, http_server):\ntarget_link_libraries(your_target prometheus-cpp-lite-full)\n\n# If you need any type of API and you define global_registry yourself or use local registries only:\ntarget_link_libraries(your_target prometheus-cpp-lite)\n```\n\n#### Step 2 — Update `#include` directives\n\n| Old (v1.0)                       | New (v2.0)                   | Notes                                                                  |\n|----------------------------------|------------------------------|------------------------------------------------------------------------|\n| `\u003cprometheus/simpleapi.h\u003e`       | `\u003cprometheus/prometheus.h\u003e`  | Umbrella header: all metrics + networking + global object declarations |\n| `\u003cprometheus/registry.h\u003e`        | `\u003cprometheus/core.h\u003e`        | Or just include a metric header — it pulls in `core.h` automatically   |\n| `\u003cprometheus/family.h\u003e`          | `\u003cprometheus/core.h\u003e`        |                                                                        |\n| `\u003cprometheus/metric.h\u003e`          | `\u003cprometheus/core.h\u003e`        |                                                                        |\n| `\u003cprometheus/builder.h\u003e`         | `\u003cprometheus/core.h\u003e`        |                                                                        |\n| `\u003cprometheus/hash.h\u003e`            | `\u003cprometheus/core.h\u003e`        |                                                                        |\n| `\u003cprometheus/collectable.h\u003e`     | `\u003cprometheus/core.h\u003e`        |                                                                        |\n| `\u003cprometheus/client_metric.h\u003e`   | `\u003cprometheus/core.h\u003e`        |                                                                        |\n| `\u003cprometheus/metric_family.h\u003e`   | `\u003cprometheus/core.h\u003e`        |                                                                        |\n| `\u003cprometheus/text_serializer.h\u003e` | `\u003cprometheus/core.h\u003e`        |                                                                        |\n| `\u003cprometheus/save_to_file.h\u003e`    | `\u003cprometheus/file_saver.h\u003e`  |                                                                        |\n| `\u003cprometheus/push_to_server.h\u003e`  | `\u003cprometheus/http_pusher.h\u003e` |                                                                        |\n| `\u003cprometheus/gateway.h\u003e`         | `\u003cprometheus/http_pusher.h\u003e` |                                                                        |\n\n\u003e **Tip:** You don't need to include `\u003cprometheus/core.h\u003e` explicitly —\n\u003e every metric header (e.g. `\u003cprometheus/counter.h\u003e`) already includes it.\n\u003e If you want everything at once, use `\u003cprometheus/prometheus.h\u003e`.\n\n#### Step 3 — Update namespace and class names\n\n```cpp\n// v1.0 SimpleAPI style:\nprometheus::simpleapi::counter_family_t family  { \"name\", \"help\" };\nprometheus::simpleapi::counter_metric_t metric1 { family.Add(labels) };\nprometheus::simpleapi::counter_metric_t metric2 { \"standalone\", \"help\", labels };\n\n// v2.0 (with global_registry)\nprometheus::family_t         family  (\"name\", \"help\");\nprometheus::counter_metric_t metric1 (family, labels);\nprometheus::counter_metric_t metric2 (\"standalone\", \"help\", labels);\n\n// v2.0 (with explicit registry)\nprometheus::registry_t       registry;\nprometheus::family_t         family  (registry, \"name\", \"help\");\nprometheus::counter_metric_t metric1 (family, labels);\nprometheus::counter_metric_t metric2 (registry, \"standalone\", \"help\", labels);\n```\n\n### Quick reference: v1.0 → v2.0 name mapping\n\n| v1.0                                      | v2.0                                 | Notes                                        |\n|-------------------------------------------|--------------------------------------|----------------------------------------------|\n| `#include \u003cprometheus/simpleapi.h\u003e`       | `#include \u003cprometheus/prometheus.h\u003e` | Umbrella header                              |\n| `prometheus::simpleapi::counter_metric_t` | `prometheus::counter_metric_t`       | All metrics moved to main namespace          |\n| `prometheus::simpleapi::counter_metric_t` | `prometheus::counter_t\u003cuint64_t\u0026\u003e`   | Fast template to use custom type             |\n| `prometheus::simpleapi::counter_family_t` | `prometheus::counter_family_t`       | All metrics families moved to main namespace |\n| `prometheus::simpleapi::counter_family_t` | `prometheus::family_t`               | New simple class with check type in runtime  |\n| `prometheus::SaveToFile`                  | `prometheus::file_saver_t`           | Change class name                            |\n| `prometheus::PushToServer`                | `prometheus::http_pusher_t`          | Change class name                            |\n| `prometheus::Gateway`                     | `prometheus::http_pusher_t`          | `prometheus-cpp` compat alias also available |\n\n---\n\n\n\n## Examples\n\nAll examples are in the [`examples/`](examples/) directory. Build them with:\n\n```\ncmake -B build -G Ninja -DPROMETHEUS_BUILD_EXAMPLES=ON\ncmake --build build\n```\n\n\n| Example | Description |\n|---------|-------------|\n| **Quick start** | |\n| [`quick_start.cpp`](examples/quick_start.cpp) | All metric types + HTTP server in one file. The code from the README \"All metric types at a glance\" section. |\n| **Export modes** | |\n| [`provide_via_http_pull_simple.cpp`](examples/provide_via_http_pull_simple.cpp) | Shortest HTTP pull server — 3 lines of setup, `curl http://localhost:9100/metrics`. |\n| [`provide_via_http_pull_advanced.cpp`](examples/provide_via_http_pull_advanced.cpp) | Single-registry and multi-path (multiple registries at different URLs) HTTP pull examples. |\n| [`provide_via_http_push_simple.cpp`](examples/provide_via_http_push_simple.cpp) | Shortest periodic push to Pushgateway — 3 lines of setup. |\n| [`provide_via_http_push_advanced.cpp`](examples/provide_via_http_push_advanced.cpp) | Periodic push, on-demand Push/PushAdd/Delete (Gateway API), and async push examples. |\n| [`provide_via_textfile.cpp`](examples/provide_via_textfile.cpp) | Periodic save to `.prom` file for node_exporter textfile collector. |\n| **Metric types — all API levels** | |\n| [`test_counter.cpp`](examples/test_counter.cpp) | Counter (`uint64_t`) — every way to create: global/explicit registry, untyped/typed family, all legacy APIs. |\n| [`test_gauge.cpp`](examples/test_gauge.cpp) | Gauge (`int64_t`) — same full set of API variants. |\n| [`test_histogram.cpp`](examples/test_histogram.cpp) | Histogram (`double`) — buckets, custom boundaries, same full set of API variants. |\n| [`test_summary.cpp`](examples/test_summary.cpp) | Summary (`double`) — quantiles, custom quantile definitions, same full set of API variants. |\n| [`test_benchmark.cpp`](examples/test_benchmark.cpp) | Benchmark (`double`) — profile method execution time, same full set of API variants. |\n| **Global objects** | |\n| [`check_global_objects.cpp`](examples/check_global_objects.cpp) | Uses `prometheus-cpp-lite-full` cmake target with pre-defined globals: `global_registry`, `file_saver`, `http_server`, `http_pusher`. |\n| **Using metrics in classes** | |\n| [`use_metrics_in_class_simple.cpp`](examples/use_metrics_in_class_simple.cpp) | Simplest way to add metrics to a class — declare as members, increment in methods, expose via `http_server.start()`. |\n| [`use_benchmark_in_class_simple.cpp`](examples/use_benchmark_in_class_simple.cpp) | Profile method execution time with `benchmark_metric_t` — `start()`/`stop()` around code phases. |\n| [`use_metrics_in_class_advanced.cpp`](examples/use_metrics_in_class_advanced.cpp) | Dynamic per-instance metrics with labels — connection pool where each connection creates metrics at runtime via `make_metric\u003c\u003e()` without storing families. |\n| **Compatibility** | |\n| [`legacy_prometheus_cpp.cpp`](examples/legacy_prometheus_cpp.cpp) |  Unmodified prometheus-cpp code (`Exposer`, `BuildCounter`, `Registry`) — compiles as-is with prometheus-cpp-lite. |\n| **Extensibility** | |\n| [`add_custom_metric_class.cpp`](examples/add_custom_metric_class.cpp) | How to create your own metric type (`min_max_t` — tracks min/max of observed values). Demonstrates owning/reference forms, all family wrappers, and the Builder API. |\n\n\n\n\n---\n\n## Networking\n\nHTTP pull and push functionality uses\n[ip-sockets-cpp-lite](https://github.com/biaks/ip-sockets-cpp-lite) - a\nheader-only, dependency-free, cross-platform C++ sockets library by the same\nauthor. A copy of its headers is bundled in\n[`3rdparty/ip-sockets-cpp-lite/`](3rdparty/ip-sockets-cpp-lite/) so that\nprometheus-cpp-lite remains self-contained with zero external dependencies.\n\nIf you only need the core metrics and serialization (e.g. you have your own\nHTTP server or use file export only), the socket headers are not required.\n\n---\n\n## Supported exposition format\n\nPrometheus Text Exposition Format (`text/plain; version=0.0.4`).\n\n---\n\n## License\n\nMIT License. See [LICENSE](LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbiaks%2Fprometheus-cpp-lite","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbiaks%2Fprometheus-cpp-lite","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbiaks%2Fprometheus-cpp-lite/lists"}