Monitoring System 0.1.0
System resource monitoring with pluggable collectors and alerting
Loading...
Searching...
No Matches
Tutorial: Metrics Collection

Goal

Collect system and custom metrics using monitoring_system's collector and factory pattern, then store them for later analysis.

Prerequisites

  • monitoring_system installed and linked (kcenon::monitoring_system)
  • Familiarity with Result<T> from common_system

Step 1: Use a built-in system collector

System collectors ship with the library and require no custom code. Register one and it starts emitting metrics on its own schedule.

auto collector = std::make_shared<system_resource_collector>();
collector->set_interval(std::chrono::seconds(5));
collector->start();
// Later...
auto snapshot = collector->latest();
std::cout << "CPU: " << snapshot.cpu_percent
<< "% | RSS: " << snapshot.memory_rss_mb << " MB\n";
System resource collector for CPU, memory, and disk metrics.

Step 2: Define a custom metric

For domain-specific measurements, derive from metric_base and populate values on a tick callback or push path.

class queue_depth_metric : public metric_base {
public:
explicit queue_depth_metric(const job_queue& q) : q_(q) {}
metric_sample collect() override {
return metric_sample{
.name = "queue.depth",
.value = static_cast<double>(q_.size()),
.timestamp = std::chrono::system_clock::now()
};
}
private:
const job_queue& q_;
};

Step 3: Register via the factory

The factory pattern centralizes creation and lets the app pick which collectors run based on configuration, not code.

auto& factory = metric_factory::instance();
factory.register_type<queue_depth_metric>("queue.depth");
// Later, from config:
auto collector = factory.create("queue.depth", queue_context);
registry.add(collector);

Step 4: Time-series storage

Collected samples can be written to an in-memory ring buffer, a local file, or exported via OTLP. See Tutorial: Distributed Tracing for the OTLP path.

Common Mistakes

  • Collecting too frequently. Sub-second intervals on cheap metrics are fine; on expensive ones you'll dominate CPU with measurement overhead.
  • Unbounded tag cardinality. Tagging metrics with user IDs or request paths creates an explosion of time series. Keep tag values to a bounded set.
  • Forgetting to start the collector. Registration alone does nothing — you must call start().

Next Steps