Skip to content

Commit f579a4d

Browse files
committed
Add class instrumentation examples; add configurable socket log level to http_server_t/http_pusher_t; update example file headers and console output
1 parent 3b159cc commit f579a4d

21 files changed

Lines changed: 742 additions & 207 deletions

3rdparty/ip-sockets-cpp-lite/readme.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# ip-sockets-cpp-lite 🔌
22

33
[![Build examples](https://github.com/biaks/ip-sockets-cpp-lite/actions/workflows/cmake.yml/badge.svg)](https://github.com/biaks/ip-sockets-cpp-lite/actions/workflows/cmake.yml)
4+
[![Build multi-platform](https://github.com/biaks/ip-sockets-cpp-lite/actions/workflows/cmake-multi-platform.yml/badge.svg)](https://github.com/biaks/ip-sockets-cpp-lite/actions/workflows/cmake-multi-platform.yml)
5+
46

57
**Simple. Lightweight. Cross-platform.**
68

@@ -107,9 +109,9 @@ Keep it simple. Keep it portable.
107109
108110
from /include folder copy:
109111
110-
* `ip_address.h`
111-
* `udp_socket.h`
112-
* `tcp_socket.h`
112+
* [`ip_address.h`](include/ip_address.h)
113+
* [`udp_socket.h`](include/udp_socket.h)
114+
* [`tcp_socket.h`](include/tcp_socket.h)
113115
114116
**Option 2 — Use CMake**
115117
@@ -255,13 +257,12 @@ if (server.open("0.0.0.0:8080") == no_error) {
255257
```
256258

257259
### 📚 More Examples
258-
Check out the `examples/` directory for complete working examples:
259-
* `ip_address.cpp` - all IP address manipulation features
260-
* `udp_socket.cpp` - UDP client-server interaction
261-
* `tcp_socket.cpp` - TCP client-server interaction
262-
* `resolve_host.cpp` - resolving host to ipv4/ipv6 address example
263-
* `http_server.cpp` - compact multi-page HTTP server
264-
260+
Check out the [`examples/`](examples) directory for complete working examples:
261+
* [`ip_address.cpp`](examples/ip_address.cpp) - all IP address manipulation features
262+
* [`udp_socket.cpp`](examples/udp_socket.cpp) - UDP client-server interaction
263+
* [`tcp_socket.cpp`](examples/tcp_socket.cpp) - TCP client-server interaction
264+
* [`resolve_host.cpp`](examples/resolve_host.cpp) - resolving host to ipv4/ipv6 address example
265+
* [`http_server.cpp`](examples/http_server.cpp) - compact multi-page HTTP server
265266
---
266267

267268
## 🤔 Why is this convenient?

README.md

Lines changed: 86 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@
33
[![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)
44
[![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)
55

6-
**Crossplatform header-only C++ library for quickly adding metrics (and profiling) functionality to C++ projects - simple, fast, dependency-free.**
6+
7+
**Crossplatform header-only C++ library for quickly adding metrics (and profiling) functionality to C++ projects — simple, fast, dependency-free.**
8+
9+
**Simplest usage — global registry, no boilerplate:**
710

811
```cpp
912
#include <prometheus/prometheus.h>
1013

1114
int main() {
12-
prometheus::registry_t registry;
13-
prometheus::counter_metric_t requests (registry, "http_requests_total", "Total HTTP requests");
14-
prometheus::http_server_t server (registry, "127.0.0.1:9100");
15-
16-
// metrics are now available at http://localhost:9100/metrics
15+
prometheus::counter_metric_t requests ("http_requests_total", "Total HTTP requests");
16+
prometheus::http_server.start ("127.0.0.1:9100");
1717

1818
for (;;) {
1919
std::this_thread::sleep_for(std::chrono::seconds(1));
@@ -22,6 +22,29 @@ int main() {
2222
}
2323
```
2424

25+
**Full control — registry, families, labels, value types:**
26+
27+
```cpp
28+
#include <prometheus/prometheus.h>
29+
using namespace prometheus;
30+
31+
int main() {
32+
registry_t registry;
33+
family_t reqs (registry, "http_requests", "HTTP requests", {{"host", "web01"}});
34+
counter_t<double&> get (reqs, {{"method", "GET"}, {"status", "200"}});
35+
counter_t<double&> post (reqs, {{"method", "POST"}, {"status", "201"}});
36+
gauge_metric_t conn (registry, "connections", "Open connections", {{"host", "web01"}});
37+
http_server_t server (registry, "127.0.0.1:9100", "/metrics", log_e::info);
38+
39+
for (;;) {
40+
std::this_thread::sleep_for(std::chrono::seconds(1));
41+
get += 1.5;
42+
post += 0.75;
43+
conn = 10 + std::rand() % 50;
44+
}
45+
}
46+
```
47+
2548
---
2649

2750

@@ -37,7 +60,7 @@ The main C++ Prometheus library - [jupp0r/prometheus-cpp](https://github.com/jup
3760
| Build system | Bazel (primary) + CMake | CMake or **just copy files** |
3861
| Minimum boilerplate | ~20 lines to create one counter | **2 lines** to create a counter and expose it (with global registry, see below) |
3962
| Value types | `double` only | `uint64_t` (default), `double`, `int64_t`, or any arithmetic type |
40-
| Metric types | counter, gauge, histogram, summary | `counter`, `gauge`, `histogram`, `summary`, `info`, **`benchmark`** or you can make your own custom metric class (see `add_custom_metric_class.cpp` for a complete working example of a new user-defined metric `min_max_t`) |
63+
| 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) |
4164
| C++ standard | C++11 | C++11 |
4265
| Thread-safe | Yes | Yes |
4366

@@ -62,12 +85,12 @@ will work.
6285
- **Low entry barrier** - a working counter with HTTP export is 2 lines of code (with global registry, see below)
6386
- **Gradual complexity** - start simple, add families/labels/registries/custom types when needed
6487
- **Multiple value types** - `uint64_t` (fast integer), `double` (Prometheus-compatible), `int64_t`, or custom
65-
- **Six metric types** - `counter`, `gauge`, `histogram`, `summary`, `benchmark`, `info`
88+
- **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)
6689
- **Three export modes** - HTTP pull server, HTTP push (Pushgateway), file (node_exporter textfile)
6790
- **Simplest way with global_registry** - add metrics anywhere in your code without passing registry references
6891
- **prometheus-cpp compatible** - supports the same Builder/Family/Registry API style
69-
- **Extensible** - each metric type is self-contained in one header; **you can add your own metric by following the same pattern** (see `add_custom_metric_class.cpp` example)
70-
- **Detailed examples** - see the examples folder for usage patterns
92+
- **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**
93+
- **Detailed examples** - see the [examples](examples) folder for usage patterns
7194

7295
---
7396

@@ -123,7 +146,7 @@ int main() {
123146
histogram_metric_t latency (registry, "request_duration_sec", "Request latency", {}, {0.01, 0.05, 0.1, 0.5, 1.0});
124147
summary_metric_t response (registry, "response_time_sec", "Response time", {}, {{0.5,0.05},{0.9,0.01},{0.99,0.001}});
125148
benchmark_metric_t uptime (registry, "uptime_sec", "Process uptime");
126-
info_metric_t info (registry, "build_info", "Build information", {{"version", "1.0.0"}, {"commit", "abc123"}});
149+
info_metric_t info (registry, "build_info", "Build information", {{"version", "1.0.0"}, {"commit", "abc123"}});
127150

128151
http_server_t server (registry, {{127,0,0,1}, 9100});
129152

@@ -149,7 +172,7 @@ int main() {
149172

150173
### 1. HTTP pull (recommended for long-running services)
151174

152-
The application runs an HTTP server. Prometheus scrapes it periodically.
175+
The application runs an HTTP server. Prometheus scrapes it periodically ([example](examples/provide_via_http_pull_simple.cpp)).
153176

154177
```cpp
155178
#include <prometheus/prometheus.h>
@@ -160,7 +183,7 @@ prometheus::http_server_t server (registry, "127.0.0.1:9100");
160183
// → http://localhost:9100/metrics
161184
```
162185
163-
**Multiple endpoints** for different metric domains:
186+
**Multiple endpoints** for different metric domains ([example](examples/provide_via_http_pull_advanced.cpp)):
164187
165188
```cpp
166189
using namespace prometheus;
@@ -177,19 +200,20 @@ server.start({{127,0,0,1}, 9200});
177200

178201
### 2. HTTP push (for short-lived jobs, edge devices)
179202

180-
Metrics are POSTed to a Pushgateway or VictoriaMetrics at a fixed interval.
203+
Metrics are POSTed to a Pushgateway or VictoriaMetrics at a fixed interval ([example](examples/provide_via_http_push_simple.cpp)).
181204

182205
```cpp
183206
#include <prometheus/prometheus.h>
184207

185208
prometheus::registry_t registry;
186209
prometheus::counter_metric_t metric (registry, "my_counter", "Example counter");
187-
prometheus::http_pusher_t pusher (registry, std::chrono::seconds(5), "http://localhost:9091/metrics/job/myapp");
210+
prometheus::http_pusher_t pusher (registry, std::chrono::seconds(5),
211+
"http://localhost:9091/metrics/job/myapp");
188212
```
189213
190214
### 3. File export (for node_exporter textfile collector)
191215
192-
Metrics are written to a `.prom` file at a fixed interval.
216+
Metrics are written to a `.prom` file at a fixed interval ([example](examples/provide_via_textfile.cpp)).
193217
194218
```cpp
195219
#include <prometheus/prometheus.h>
@@ -206,7 +230,7 @@ prometheus::file_saver_t saver (registry, std::chrono::seconds(5), "./metri
206230
### Using a family
207231

208232
```cpp
209-
family_t requests (registry, "http_requests", "HTTP requests by method", {{"host", "dev"}});
233+
family_t requests (registry, "http_requests", "Requests by method", {{"host", "dev"}});
210234
counter_metric_t get_count (requests, {{"method", "GET"}});
211235
counter_metric_t post_count (requests, {{"method", "POST"}});
212236

@@ -275,7 +299,8 @@ With prometheus-cpp-lite's global registry approach, none of that is
275299
necessary. The `prometheus-cpp-lite-full` CMake target provides ready-made
276300
global objects — `global_registry`, `file_saver`, `http_pusher`, and
277301
`http_server` — so you can create metrics anywhere in your code and start
278-
exposing them with a single call from any place. No plumbing required.
302+
exposing them with a single call from any place ([example](examples/check_global_objects.cpp)).
303+
No plumbing required.
279304

280305
### The workflow
281306

@@ -319,7 +344,8 @@ prometheus::http_server.start("127.0.0.1:9100");
319344
```
320345

321346
That's it. Every metric you created in step 2 is automatically available
322-
at the HTTP endpoint. You can also use the other pre-defined global
347+
at the HTTP endpoint ([example](examples/use_metrics_in_class_simple.cpp)).
348+
You can also use the other pre-defined global
323349
exporters:
324350

325351
```cpp
@@ -387,7 +413,8 @@ void process_order(const Order& order) {
387413

388414
The accumulated elapsed time is immediately available at your `/metrics`
389415
endpoint — no separate profiling tool, no recompilation with special flags,
390-
no post-hoc analysis. You get real production latency data from live traffic.
416+
no post-hoc analysis. You get real production latency data from live traffic
417+
([example](examples/use_benchmark_in_class_simple.cpp)).
391418

392419
**Best practice for multithreaded code:** the `start()`/`stop()` state
393420
machine is local to each metric instance and is intentionally not
@@ -481,7 +508,7 @@ not even the `#include` lines need to be modified.
481508

482509
### Example 1: Exposer (HTTP pull)
483510

484-
The code below is **valid prometheus-cpp code**. It compiles and runs with
511+
The code below is **[valid prometheus-cpp code](examples/legacy_prometheus_cpp.cpp)**. It compiles and runs with
485512
prometheus-cpp-lite without touching a single line — just swap the library
486513
in your build system:
487514

@@ -495,8 +522,8 @@ int main() {
495522
auto registry = std::make_shared<prometheus::Registry>();
496523

497524
auto& family = prometheus::BuildCounter()
498-
.Name("http_requests_total")
499-
.Help("Total HTTP requests")
525+
.Name("http_requests")
526+
.Help("HTTP requests")
500527
.Register(*registry);
501528

502529
auto& counter = family.Add({{"method", "GET"}});
@@ -514,7 +541,7 @@ int main() {
514541
int main() {
515542
prometheus::registry_t registry;
516543
prometheus::http_server_t server (registry, "127.0.0.1:8080");
517-
prometheus::counter_metric_t counter (registry, "http_requests_total", "Total HTTP requests", {{"method", "GET"}});
544+
prometheus::counter_metric_t counter (registry, "http_requests", "HTTP requests", {{"method", "GET"}});
518545

519546
counter++;
520547
}
@@ -672,7 +699,7 @@ add_subdirectory("prometheus-cpp-lite")
672699
# If you need SimpleAPI and pre-defined global objects (global_registry, file_saver, etc.):
673700
target_link_libraries(your_target prometheus-cpp-simpleapi)
674701
675-
# If you use only ComplexAPI or Java liked legacy API from prometheus-cpp and use local registries only:
702+
# If you use only ComplexAPI or Java liked legacy API from prometheus-cpp and use local registries:
676703
target_link_libraries(your_target prometheus-cpp-lite-core)
677704
```
678705

@@ -748,16 +775,45 @@ prometheus::counter_metric_t metric2 (registry, "standalone", "help", labels);
748775
749776
750777
751-
## Building examples
778+
## Examples
752779
753-
```cmake
780+
All examples are in the [`examples/`](examples/) directory. Build them with:
781+
782+
```
754783
cmake -B build -G Ninja -DPROMETHEUS_BUILD_EXAMPLES=ON
755784
cmake --build build
756785
```
757786
758-
The examples use `prometheus-cpp-lite` (header-only target) and define
759-
`global_registry` in each `.cpp` file. To use the pre-defined global
760-
objects instead, link against `prometheus-cpp-lite-full`.
787+
788+
| Example | Description |
789+
|---------|-------------|
790+
| **Quick start** | |
791+
| [`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. |
792+
| **Export modes** | |
793+
| [`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`. |
794+
| [`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. |
795+
| [`provide_via_http_push_simple.cpp`](examples/provide_via_http_push_simple.cpp) | Shortest periodic push to Pushgateway — 3 lines of setup. |
796+
| [`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. |
797+
| [`provide_via_textfile.cpp`](examples/provide_via_textfile.cpp) | Periodic save to `.prom` file for node_exporter textfile collector. |
798+
| **Metric types — all API levels** | |
799+
| [`test_counter.cpp`](examples/test_counter.cpp) | Counter (`uint64_t`) — every way to create: global/explicit registry, untyped/typed family, all legacy APIs. |
800+
| [`test_gauge.cpp`](examples/test_gauge.cpp) | Gauge (`int64_t`) — same full set of API variants. |
801+
| [`test_histogram.cpp`](examples/test_histogram.cpp) | Histogram (`double`) — buckets, custom boundaries, same full set of API variants. |
802+
| [`test_summary.cpp`](examples/test_summary.cpp) | Summary (`double`) — quantiles, custom quantile definitions, same full set of API variants. |
803+
| [`test_benchmark.cpp`](examples/test_benchmark.cpp) | Benchmark (`double`) — profile method execution time, same full set of API variants. |
804+
| **Global objects** | |
805+
| [`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`. |
806+
| **Using metrics in classes** | |
807+
| [`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()`. |
808+
| [`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. |
809+
| [`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<>()` without storing families. |
810+
| **Compatibility** | |
811+
| [`legacy_prometheus_cpp.cpp`](examples/legacy_prometheus_cpp.cpp) | Unmodified prometheus-cpp code (`Exposer`, `BuildCounter`, `Registry`) — compiles as-is with prometheus-cpp-lite. |
812+
| **Extensibility** | |
813+
| [`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. |
814+
815+
816+
761817
762818
---
763819

examples/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,8 @@ if(PROMETHEUS_USE_IP_SOCKETS)
2626
add_example(provide_via_http_push_advanced prometheus-cpp-lite)
2727
add_example(legacy_prometheus_cpp prometheus-cpp-lite)
2828
add_example(check_global_objects prometheus-cpp-lite-full)
29+
add_example(use_benchmark_in_class_simple prometheus-cpp-lite-full)
30+
add_example(use_metrics_in_class_simple prometheus-cpp-lite-full)
31+
add_example(use_metrics_in_class_advanced prometheus-cpp-lite-full)
2932
endif()
3033

0 commit comments

Comments
 (0)