Mads
Multi-Agent Distributed System
Loading...
Searching...
No Matches
topic_stats.hpp
Go to the documentation of this file.
1/*
2 _____ _ ____ _ _
3 |_ _|__ _ __ (_) ___ / ___|| |_ __ _| |_ ___
4 | |/ _ \| '_ \| |/ __| \___ \| __/ _` | __/ __|
5 | | (_) | |_) | | (__ ___) | || (_| | |_\__ \
6 |_|\___/| .__/|_|\___| |____/ \__\__,_|\__|___/
7 |_|
8
9Pure, sliding-window per-topic activity aggregator for `mads top`. No ZMQ, no
10Agent dependency: callers feed it (topic, bytes[, sample]) tuples with an
11explicit or implicit timestamp, and it reports messages/s and bytes/s
12averaged over a trailing window, plus last-seen/last-sample bookkeeping that
13never expires. This split keeps the counting logic directly unit-testable
14with synthetic timestamps (no sockets, no real sleeps) while `top.cpp` stays
15a thin CLI/subscribe/render loop.
16
17Author(s): Paolo Bosetti
18*/
19#pragma once
20
21#include <chrono>
22#include <deque>
23#include <map>
24#include <mutex>
25#include <string>
26#include <vector>
27
28namespace Mads {
29
34struct TopicStat {
35 std::string topic;
39 size_t window_messages = 0;
40 size_t window_bytes = 0;
41 double messages_per_second = 0.0;
42 double bytes_per_second = 0.0;
44 size_t total_messages = 0;
46 std::chrono::steady_clock::time_point last_seen{};
47 size_t last_size = 0;
50 std::string last_sample;
51};
52
65public:
66 explicit TopicStats(
67 std::chrono::milliseconds window = std::chrono::seconds(5));
68
80 void record(const std::string &topic, size_t bytes,
81 std::string sample = std::string(),
82 std::chrono::steady_clock::time_point now =
83 std::chrono::steady_clock::now());
84
95 std::vector<TopicStat> snapshot(std::chrono::steady_clock::time_point now =
96 std::chrono::steady_clock::now()) const;
97
99 void set_window(std::chrono::milliseconds window);
100 std::chrono::milliseconds window() const;
101
104 void clear();
105
106private:
107 struct Entry {
108 // Ascending by timestamp (append-only in record(), pruned from the
109 // front): (when, bytes) per observed message still within living memory
110 // of the window.
111 std::deque<std::pair<std::chrono::steady_clock::time_point, size_t>>
112 events;
113 size_t total_messages = 0;
114 std::chrono::steady_clock::time_point last_seen{};
115 size_t last_size = 0;
116 std::string last_sample;
117 };
118
119 mutable std::mutex _mtx;
120 std::chrono::milliseconds _window;
121 // map (not unordered_map) so snapshot() iterates in topic-name order with
122 // no extra sort step.
123 std::map<std::string, Entry> _entries;
124};
125
126} // namespace Mads
Thread-safe sliding-window aggregator of per-topic msg/s and bytes/s, fed by record() and read back v...
void set_window(std::chrono::milliseconds window)
Changes the trailing window used by future record()/snapshot() calls.
std::vector< TopicStat > snapshot(std::chrono::steady_clock::time_point now=std::chrono::steady_clock::now()) const
Snapshot of every topic seen so far, as of now.
void record(const std::string &topic, size_t bytes, std::string sample=std::string(), std::chrono::steady_clock::time_point now=std::chrono::steady_clock::now())
Records one observed message for topic.
std::chrono::milliseconds window() const
TopicStats(std::chrono::milliseconds window=std::chrono::seconds(5))
Definition agent.hpp:67
Snapshot of one topic's aggregated activity, as computed by TopicStats::snapshot() at a given instant...
std::string topic
double bytes_per_second
std::chrono::steady_clock::time_point last_seen
Wall-clock-independent instant of the most recent record() call.
std::string last_sample
double messages_per_second
size_t total_messages
Lifetime message count for this topic, never pruned by the window.