diff --git a/cmd/pktvisord/main.cpp b/cmd/pktvisord/main.cpp index 30ede438d..ea6f0dc09 100644 --- a/cmd/pktvisord/main.cpp +++ b/cmd/pktvisord/main.cpp @@ -39,6 +39,7 @@ static const char USAGE[] = --admin-api Enable admin REST API giving complete control plane functionality [default: false] When not specified, the exposed API is read-only access to summarized metrics. When specified, write access is enabled for all modules. + --prometheus Enable native Prometheus metrics at path /metrics -h --help Show this screen -v Verbose log output --no-track Don't send lightweight, anonymous usage metrics. @@ -88,7 +89,11 @@ int main(int argc, char *argv[]) logger->set_level(spdlog::level::debug); } - CoreServer svr(!args["--admin-api"].asBool(), logger); + std::string prometheus_path; + if (args["--prometheus"].asBool()) { + prometheus_path = "/metrics"; + } + CoreServer svr(!args["--admin-api"].asBool(), logger, prometheus_path); svr.set_http_logger([&logger](const auto &req, const auto &res) { logger->info("REQUEST: {} {} {}", req.method, req.path, res.status); if (res.status == 500) { diff --git a/src/AbstractMetricsManager.h b/src/AbstractMetricsManager.h index 054537cf8..ef02f55a3 100644 --- a/src/AbstractMetricsManager.h +++ b/src/AbstractMetricsManager.h @@ -41,6 +41,66 @@ class PeriodException : public std::runtime_error using namespace std::chrono; +class Metric +{ +protected: + std::string _name; + std::string _desc; + +public: + Metric(std::string name, std::string desc) + : _name(std::move(name)) + , _desc(std::move(desc)) + { + } + + virtual void to_json(json &j) const = 0; + virtual void to_prometheus(std::stringstream &out, const std::string &key) const = 0; +}; + +/** + * A Counter metric class which knows how to render its output + * NOTE: intentionally _not_ thread safe; it should be protected by a mutex in the metric bucket + */ +class Counter final : Metric +{ + uint64_t _value = 0; + +public: + Counter(std::string name, std::string desc) + : Metric(std::move(name), std::move(desc)) + { + } + + Counter &operator++() + { + ++_value; + return *this; + } + + uint64_t value() const + { + return _value; + } + + void operator+=(const Counter &other) + { + _value += other._value; + } + + virtual void to_json(json &j) const override + { + j[_name] = _value; + } + + virtual void to_prometheus(std::stringstream &out, const std::string &key) const override + { + out << "# HELP " << key << "_" << _name << ' ' << _desc << std::endl; + out << "# TYPE " << key << "_" << _name << " gauge" << std::endl; + out << key << '_' << _name << ' ' << _value << std::endl; + } +}; + class Rate { public: @@ -112,7 +172,7 @@ class Rate return _rate; } - auto quantile_get_rlocked() const + auto quantile_locked() const { std::shared_lock lock(_sketch_mutex); struct retVals { @@ -124,7 +184,7 @@ class Rate void merge(const Rate &other) { - auto [o_quantile, o_lock] = other.quantile_get_rlocked(); + auto [o_quantile, o_lock] = other.quantile_locked(); std::unique_lock w_lock(_sketch_mutex); _quantile.merge(*o_quantile); // the live rate to simply copied if non zero @@ -142,8 +202,8 @@ class AbstractMetricsBucket { private: mutable std::shared_mutex _base_mutex; - uint64_t _num_samples = 0; - uint64_t _num_events = 0; + Counter _num_samples; + Counter _num_events; Rate _rate_events; @@ -162,7 +222,9 @@ class AbstractMetricsBucket public: AbstractMetricsBucket() - : _rate_events() + : _num_samples("deep_samples", "Total number of deep samples") + , _num_events("total", "Total number of events") + , _rate_events() , _start_tstamp{0, 0} , _end_tstamp{0, 0} { @@ -218,15 +280,16 @@ class AbstractMetricsBucket on_set_read_only(); } - auto event_data() const + auto event_data_locked() const { - std::shared_lock lock(_base_mutex); struct eventData { - uint64_t num_events; - uint64_t num_samples; + const Counter *num_events; + const Counter *num_samples; const Rate *event_rate; + std::shared_lock r_lock; }; - return eventData{_num_events, _num_samples, &_rate_events}; + std::shared_lock lock(_base_mutex); + return eventData{&_num_events, &_num_samples, &_rate_events, std::move(lock)}; } void merge(const AbstractMetricsBucket &other) @@ -254,13 +317,14 @@ class AbstractMetricsBucket // note, currently not enforcing _read_only ++_rate_events; std::unique_lock lock(_base_mutex); - _num_events++; + ++_num_events; if (deep) { - _num_samples++; + ++_num_samples; } } virtual void to_json(json &j) const = 0; + virtual void to_prometheus(std::stringstream &out, const std::string &key) const = 0; }; template @@ -338,7 +402,6 @@ class AbstractMetricsManager static const uint MERGE_CACHE_TTL_MS = 1000; protected: - /** * the "base" event method that should be called on every event before specialized event functionality. sampling will be * chosen, and the time window will be maintained @@ -500,6 +563,25 @@ class AbstractMetricsManager _metric_buckets.at(period)->to_json(j[period_str][key]); } + void window_single_prometheus(std::stringstream &out, const std::string &key, uint64_t period = 0) const + { + std::shared_lock rl(_base_mutex); + std::shared_lock rbl(_bucket_mutex); + + if (period >= _num_periods) { + std::stringstream err; + err << "invalid metrics period, specify [0, " << _num_periods - 1 << "]"; + throw PeriodException(err.str()); + } + if (period >= _metric_buckets.size()) { + std::stringstream err; + err << "requested metrics period has not yet accumulated, current range is [0, " << _metric_buckets.size() - 1 << "]"; + throw PeriodException(err.str()); + } + + _metric_buckets.at(period)->to_prometheus(out, key); + } + void window_merged_json(json &j, const std::string &key, uint64_t period) const { std::shared_lock rl(_base_mutex); diff --git a/src/CoreServer.cpp b/src/CoreServer.cpp index f4be33af1..035a4fb74 100644 --- a/src/CoreServer.cpp +++ b/src/CoreServer.cpp @@ -8,7 +8,7 @@ #include #include -visor::CoreServer::CoreServer(bool read_only, std::shared_ptr logger) +visor::CoreServer::CoreServer(bool read_only, std::shared_ptr logger, const std::string &prometheus_path) : _svr(read_only) , _logger(logger) , _start_time(std::chrono::system_clock::now()) @@ -36,7 +36,7 @@ visor::CoreServer::CoreServer(bool read_only, std::shared_ptr lo _handler_plugins.emplace_back(std::move(mod)); } - _setup_routes(); + _setup_routes(prometheus_path); } void visor::CoreServer::start(const std::string &host, int port) { @@ -72,7 +72,7 @@ visor::CoreServer::~CoreServer() { stop(); } -void visor::CoreServer::_setup_routes() +void visor::CoreServer::_setup_routes(const std::string &prometheus_path) { _logger->info("Initialize server control plane"); @@ -158,4 +158,25 @@ void visor::CoreServer::_setup_routes() res.set_content(e.what(), "text/plain"); } }); + if (!prometheus_path.empty()) { + _logger->info("enabling prometheus metrics on: {}", prometheus_path); + _svr.Get(prometheus_path.c_str(), [&]([[maybe_unused]] const httplib::Request &req, httplib::Response &res) { + std::stringstream output; + try { + auto [handler_modules, hm_lock] = _handler_manager->module_get_all_locked(); + for (auto &[name, mod] : handler_modules) { + auto hmod = dynamic_cast(mod.get()); + if (hmod) { + spdlog::stopwatch sw; + hmod->window_prometheus(output); + _logger->debug("{} elapsed time: {}", hmod->name(), sw); + } + } + res.set_content(output.str(), "text/plain"); + } catch (const std::exception &e) { + res.status = 500; + res.set_content(e.what(), "text/plain"); + } + }); + } } diff --git a/src/CoreServer.h b/src/CoreServer.h index dc8ff112c..68091519c 100644 --- a/src/CoreServer.h +++ b/src/CoreServer.h @@ -39,10 +39,10 @@ class CoreServer std::shared_ptr _logger; std::chrono::system_clock::time_point _start_time; - void _setup_routes(); + void _setup_routes(const std::string &prometheus_path); public: - CoreServer(bool read_only, std::shared_ptr logger); + CoreServer(bool read_only, std::shared_ptr logger, const std::string &prometheus_path); ~CoreServer(); void start(const std::string &host, int port); diff --git a/src/StreamHandler.h b/src/StreamHandler.h index 4ae6a9c0d..d03392aea 100644 --- a/src/StreamHandler.h +++ b/src/StreamHandler.h @@ -25,6 +25,7 @@ class StreamHandler : public AbstractModule virtual ~StreamHandler(){}; virtual void window_json(json &j, uint64_t period, bool merged) = 0; + virtual void window_prometheus(std::stringstream &out) = 0; }; template @@ -58,13 +59,13 @@ class StreamMetricsHandler : public StreamHandler } j["metrics"]["periods"][i]["read_only"] = _metrics->bucket(i)->read_only(); j["metrics"]["periods"][i]["length"] = _metrics->bucket(i)->period_length(); - auto [num_events, num_samples, event_rate] = _metrics->bucket(i)->event_data(); - j["metrics"]["periods"][i]["events"]["total"] = num_events; - j["metrics"]["periods"][i]["events"]["deep_samples"] = num_samples; + auto [num_events, num_samples, event_rate, event_lock] = _metrics->bucket(i)->event_data_locked(); + num_events->to_json(j["metrics"]["periods"][i]["events"]); + num_samples->to_json(j["metrics"]["periods"][i]["events"]); if (!_metrics->bucket(i)->read_only()) { j["metrics"]["periods"][i]["events"]["rates"]["live"] = event_rate->rate(); } - auto [rate_quantile, rate_lock] = event_rate->quantile_get_rlocked(); + auto [rate_quantile, rate_lock] = event_rate->quantile_locked(); auto quantiles = rate_quantile->get_quantiles(fractions, 4); if (quantiles.size()) { j["metrics"]["periods"][i]["events"]["rates"]["p50"] = quantiles[0]; diff --git a/src/handlers/dns/DnsStreamHandler.cpp b/src/handlers/dns/DnsStreamHandler.cpp index 73f546365..a56ef9bc0 100644 --- a/src/handlers/dns/DnsStreamHandler.cpp +++ b/src/handlers/dns/DnsStreamHandler.cpp @@ -200,7 +200,9 @@ void DnsStreamHandler::tcp_connection_end_cb(const pcpp::ConnectionData &connect // remove the connection from the connection manager _tcp_connections.erase(iter); } - +void DnsStreamHandler::window_prometheus(std::stringstream &out) +{ +} void DnsStreamHandler::window_json(json &j, uint64_t period, bool merged) { if (merged) { @@ -271,12 +273,12 @@ void DnsMetricsBucket::to_json(json &j) const const double fractions[4]{0.50, 0.90, 0.95, 0.99}; - auto [num_events, num_samples, event_rate] = event_data(); // thread safe + auto [num_events, num_samples, event_rate, event_lock] = event_data_locked(); // thread safe { if (!read_only()) { j["wire_packets"]["rates"]["total"]["live"] = event_rate->rate(); } - auto [rate_quantile, rate_lock] = event_rate->quantile_get_rlocked(); + auto [rate_quantile, rate_lock] = event_rate->quantile_locked(); auto quantiles = rate_quantile->get_quantiles(fractions, 4); if (quantiles.size()) { j["wire_packets"]["rates"]["total"]["p50"] = quantiles[0]; @@ -288,8 +290,8 @@ void DnsMetricsBucket::to_json(json &j) const std::shared_lock r_lock(_mutex); - j["wire_packets"]["total"] = num_events; - j["wire_packets"]["deep_samples"] = num_samples; + num_events->to_json(j["wire_packets"]); + num_samples->to_json(j["wire_packets"]); j["wire_packets"]["queries"] = _counters.queries; j["wire_packets"]["replies"] = _counters.replies; j["wire_packets"]["tcp"] = _counters.TCP; @@ -543,6 +545,9 @@ void DnsMetricsBucket::new_dns_transaction(bool deep, float to90th, float from90 } } } +void DnsMetricsBucket::to_prometheus(std::stringstream &out, const std::string &key) const +{ +} // the general metrics manager entry point (both UDP and TCP) void DnsMetricsManager::process_dns_layer(DnsLayer &payload, PacketDirection dir, pcpp::ProtocolType l3, pcpp::ProtocolType l4, uint32_t flowkey, uint16_t port, timespec stamp) diff --git a/src/handlers/dns/DnsStreamHandler.h b/src/handlers/dns/DnsStreamHandler.h index 29493deaa..c8d9b997e 100644 --- a/src/handlers/dns/DnsStreamHandler.h +++ b/src/handlers/dns/DnsStreamHandler.h @@ -113,6 +113,7 @@ class DnsMetricsBucket final : public visor::AbstractMetricsBucket // visor::AbstractMetricsBucket void specialized_merge(const AbstractMetricsBucket &other) override; void to_json(json &j) const override; + void to_prometheus(std::stringstream &out, const std::string &key) const override; void process_dns_layer(bool deep, DnsLayer &payload, pcpp::ProtocolType l3, pcpp::ProtocolType l4, uint16_t port); @@ -228,6 +229,7 @@ class DnsStreamHandler final : public visor::StreamMetricsHandlerbucket(0)->counters(); - auto event_data = dns_handler.metrics()->bucket(0)->event_data(); + auto event_data = dns_handler.metrics()->bucket(0)->event_data_locked(); CHECK(dns_handler.metrics()->current_periods() == 1); CHECK(dns_handler.metrics()->start_tstamp().tv_sec == 1567706414); @@ -32,12 +32,12 @@ TEST_CASE("Parse DNS UDP IPv4 tests", "[pcap][ipv4][udp][dns]") CHECK(dns_handler.metrics()->end_tstamp().tv_nsec == 602866000); CHECK(dns_handler.metrics()->bucket(0)->period_length() == 6); - + json j; dns_handler.metrics()->bucket(0)->to_json(j); CHECK(dns_handler.metrics()->current_periods() == 1); - CHECK(event_data.num_events == 140); + CHECK(event_data.num_events->value() == 140); CHECK(counters.UDP == 140); CHECK(counters.IPv4 == 140); CHECK(counters.IPv6 == 0); @@ -61,11 +61,11 @@ TEST_CASE("Parse DNS TCP IPv4 tests", "[pcap][ipv4][tcp][dns]") stream.stop(); auto counters = dns_handler.metrics()->bucket(0)->counters(); - auto event_data = dns_handler.metrics()->bucket(0)->event_data(); + auto event_data = dns_handler.metrics()->bucket(0)->event_data_locked(); json j; dns_handler.metrics()->bucket(0)->to_json(j); - CHECK(event_data.num_events == 420); + CHECK(event_data.num_events->value() == 420); CHECK(counters.TCP == 420); CHECK(counters.IPv4 == 420); CHECK(counters.IPv6 == 0); @@ -90,11 +90,11 @@ TEST_CASE("Parse DNS UDP IPv6 tests", "[pcap][ipv6][udp][dns]") dns_handler.stop(); auto counters = dns_handler.metrics()->bucket(0)->counters(); - auto event_data = dns_handler.metrics()->bucket(0)->event_data(); + auto event_data = dns_handler.metrics()->bucket(0)->event_data_locked(); json j; dns_handler.metrics()->bucket(0)->to_json(j); - CHECK(event_data.num_events == 140); + CHECK(event_data.num_events->value() == 140); CHECK(counters.UDP == 140); CHECK(counters.IPv4 == 0); CHECK(counters.IPv6 == 140); @@ -119,11 +119,11 @@ TEST_CASE("Parse DNS TCP IPv6 tests", "[pcap][ipv6][tcp][dns]") dns_handler.stop(); auto counters = dns_handler.metrics()->bucket(0)->counters(); - auto event_data = dns_handler.metrics()->bucket(0)->event_data(); + auto event_data = dns_handler.metrics()->bucket(0)->event_data_locked(); json j; dns_handler.metrics()->bucket(0)->to_json(j); - CHECK(event_data.num_events == 360); + CHECK(event_data.num_events->value() == 360); CHECK(counters.TCP == 360); CHECK(counters.IPv4 == 0); CHECK(counters.IPv6 == 360); @@ -150,12 +150,12 @@ TEST_CASE("Parse DNS random UDP/TCP tests", "[pcap][net]") dns_handler.stop(); auto counters = dns_handler.metrics()->bucket(0)->counters(); - auto event_data = dns_handler.metrics()->bucket(0)->event_data(); + auto event_data = dns_handler.metrics()->bucket(0)->event_data_locked(); // confirmed with wireshark. there are 14 TCP retransmissions which are counted differently in our state machine // and account for some minor differences in TCP based stats - CHECK(event_data.num_events == 5851); // wireshark: 5838 - CHECK(event_data.num_samples == 5851); + CHECK(event_data.num_events->value() == 5851); // wireshark: 5838 + CHECK(event_data.num_samples->value() == 5851); CHECK(counters.TCP == 2880); // wireshark: 2867 CHECK(counters.UDP == 2971); CHECK(counters.IPv4 == 5851); // wireshark: 5838 @@ -178,7 +178,7 @@ TEST_CASE("Parse DNS random UDP/TCP tests", "[pcap][net]") CHECK(j["cardinality"]["qname"] == 2055); // flame was run with 1000 randoms x2 (udp+tcp) CHECK(j["top_qname2"][0]["name"] == ".test.com"); - CHECK(j["top_qname2"][0]["estimate"] == event_data.num_events); + CHECK(j["top_qname2"][0]["estimate"] == event_data.num_events->value()); CHECK(j["top_rcode"][0]["name"] == "NOERROR"); CHECK(j["top_rcode"][0]["estimate"] == counters.NOERROR); diff --git a/src/handlers/net/NetStreamHandler.cpp b/src/handlers/net/NetStreamHandler.cpp index 5c04e1612..3e2f0a9b5 100644 --- a/src/handlers/net/NetStreamHandler.cpp +++ b/src/handlers/net/NetStreamHandler.cpp @@ -82,6 +82,14 @@ void NetStreamHandler::info_json(json &j) const { _common_info_json(j); } +void NetStreamHandler::window_prometheus(std::stringstream &out) +{ + if (_metrics->current_periods() > 1) { + _metrics->window_single_prometheus(out, schema_key(), 1); + } else { + _metrics->window_single_prometheus(out, schema_key(), 0); + } +} void NetworkMetricsBucket::specialized_merge(const AbstractMetricsBucket &o) { @@ -119,6 +127,25 @@ void NetworkMetricsBucket::specialized_merge(const AbstractMetricsBucket &o) _topASN.merge(other._topASN); } +void NetworkMetricsBucket::to_prometheus(std::stringstream &out, const std::string &key) const +{ + + std::shared_lock r_lock(_mutex); + + auto [num_events, num_samples, event_rate, event_lock] = event_data_locked(); // thread safe + + num_events->to_prometheus(out, key); + num_samples->to_prometheus(out, key); + + _counters.UDP.to_prometheus(out, key); + _counters.TCP.to_prometheus(out, key); + _counters.OtherL4.to_prometheus(out, key); + _counters.IPv4.to_prometheus(out, key); + _counters.IPv6.to_prometheus(out, key); + _counters.total_in.to_prometheus(out, key); + _counters.total_out.to_prometheus(out, key); +} + void NetworkMetricsBucket::to_json(json &j) const { @@ -129,7 +156,7 @@ void NetworkMetricsBucket::to_json(json &j) const if (!read_only()) { j["rates"]["pps_in"]["live"] = _rate_in.rate(); } - auto [rate_quantile, rate_lock] = _rate_in.quantile_get_rlocked(); + auto [rate_quantile, rate_lock] = _rate_in.quantile_locked(); auto quantiles = rate_quantile->get_quantiles(fractions, 4); if (quantiles.size()) { j["rates"]["pps_in"]["p50"] = quantiles[0]; @@ -143,7 +170,7 @@ void NetworkMetricsBucket::to_json(json &j) const if (!read_only()) { j["rates"]["pps_out"]["live"] = _rate_out.rate(); } - auto [rate_quantile, rate_lock] = _rate_out.quantile_get_rlocked(); + auto [rate_quantile, rate_lock] = _rate_out.quantile_locked(); auto quantiles = rate_quantile->get_quantiles(fractions, 4); if (quantiles.size()) { j["rates"]["pps_out"]["p50"] = quantiles[0]; @@ -153,13 +180,13 @@ void NetworkMetricsBucket::to_json(json &j) const } } - auto [num_events, num_samples, event_rate] = event_data(); // thread safe + auto [num_events, num_samples, event_rate, event_lock] = event_data_locked(); // thread safe { if (!read_only()) { j["rates"]["pps_total"]["live"] = event_rate->rate(); } - auto [rate_quantile, rate_lock] = event_rate->quantile_get_rlocked(); + auto [rate_quantile, rate_lock] = event_rate->quantile_locked(); auto quantiles = rate_quantile->get_quantiles(fractions, 4); if (quantiles.size()) { j["rates"]["pps_total"]["p50"] = quantiles[0]; @@ -171,15 +198,15 @@ void NetworkMetricsBucket::to_json(json &j) const std::shared_lock r_lock(_mutex); - j["total"] = num_events; - j["deep_samples"] = num_samples; - j["udp"] = _counters.UDP; - j["tcp"] = _counters.TCP; - j["other_l4"] = _counters.OtherL4; - j["ipv4"] = _counters.IPv4; - j["ipv6"] = _counters.IPv6; - j["in"] = _counters.total_in; - j["out"] = _counters.total_out; + num_events->to_json(j); + num_samples->to_json(j); + _counters.UDP.to_json(j); + _counters.TCP.to_json(j); + _counters.OtherL4.to_json(j); + _counters.IPv4.to_json(j); + _counters.IPv6.to_json(j); + _counters.total_in.to_json(j); + _counters.total_out.to_json(j); j["cardinality"]["src_ips_in"] = lround(_srcIPCard.get_estimate()); j["cardinality"]["dst_ips_out"] = lround(_dstIPCard.get_estimate()); diff --git a/src/handlers/net/NetStreamHandler.h b/src/handlers/net/NetStreamHandler.h index 6f27e8165..038837a18 100644 --- a/src/handlers/net/NetStreamHandler.h +++ b/src/handlers/net/NetStreamHandler.h @@ -4,7 +4,6 @@ #pragma once - #include "AbstractMetricsManager.h" #include "PcapInputStream.h" #include "StreamHandler.h" @@ -42,13 +41,23 @@ class NetworkMetricsBucket final : public visor::AbstractMetricsBucket // total numPackets is tracked in base class num_events struct counters { - uint64_t UDP = 0; - uint64_t TCP = 0; - uint64_t OtherL4 = 0; - uint64_t IPv4 = 0; - uint64_t IPv6 = 0; - uint64_t total_in = 0; - uint64_t total_out = 0; + Counter UDP; + Counter TCP; + Counter OtherL4; + Counter IPv4; + Counter IPv6; + Counter total_in; + Counter total_out; + counters() + : UDP("udp", "Count of UDP packets") + , TCP("tcp", "Count of TCP packets") + , OtherL4("other_l4", "Count of packets which are not UDP or TCP") + , IPv4("ipv4", "Count of IPv4 packets") + , IPv6("ipv6", "Count of IPv6 packets") + , total_in("in", "Count of total ingress packets") + , total_out("out", "Count of total egress packets") + { + } }; counters _counters; @@ -78,6 +87,7 @@ class NetworkMetricsBucket final : public visor::AbstractMetricsBucket // visor::AbstractMetricsBucket void specialized_merge(const AbstractMetricsBucket &other) override; void to_json(json &j) const override; + void to_prometheus(std::stringstream &out, const std::string &key) const override; // must be thread safe as it is called from time window maintenance thread void on_set_read_only() override @@ -140,7 +150,7 @@ class NetStreamHandler final : public visor::StreamMetricsHandlerbucket(0)->counters(); - auto event_data = net_handler.metrics()->bucket(0)->event_data(); + auto event_data = net_handler.metrics()->bucket(0)->event_data_locked(); CHECK(net_handler.metrics()->current_periods() == 1); CHECK(net_handler.metrics()->start_tstamp().tv_sec == 1567706414); @@ -33,10 +33,10 @@ TEST_CASE("Parse net (dns) UDP IPv4 tests", "[pcap][ipv4][udp][net]") CHECK(net_handler.metrics()->bucket(0)->period_length() == 6); - CHECK(event_data.num_events == 140); - CHECK(counters.UDP == 140); - CHECK(counters.IPv4 == 140); - CHECK(counters.IPv6 == 0); + CHECK(event_data.num_events->value() == 140); + CHECK(counters.UDP.value() == 140); + CHECK(counters.IPv4.value() == 140); + CHECK(counters.IPv6.value() == 0); } TEST_CASE("Parse net (dns) TCP IPv4 tests", "[pcap][ipv4][tcp][net]") @@ -53,14 +53,14 @@ TEST_CASE("Parse net (dns) TCP IPv4 tests", "[pcap][ipv4][tcp][net]") stream.stop(); auto counters = net_handler.metrics()->bucket(0)->counters(); - auto event_data = net_handler.metrics()->bucket(0)->event_data(); + auto event_data = net_handler.metrics()->bucket(0)->event_data_locked(); CHECK(net_handler.metrics()->start_tstamp().tv_sec == 1567706433); CHECK(net_handler.metrics()->start_tstamp().tv_nsec == 56403000); - CHECK(event_data.num_events == 2100); - CHECK(counters.TCP == 2100); - CHECK(counters.IPv4 == 2100); - CHECK(counters.IPv6 == 0); + CHECK(event_data.num_events->value() == 2100); + CHECK(counters.TCP.value() == 2100); + CHECK(counters.IPv4.value() == 2100); + CHECK(counters.IPv6.value() == 0); } TEST_CASE("Parse net (dns) UDP IPv6 tests", "[pcap][ipv6][udp][net]") @@ -78,14 +78,14 @@ TEST_CASE("Parse net (dns) UDP IPv6 tests", "[pcap][ipv6][udp][net]") net_handler.stop(); auto counters = net_handler.metrics()->bucket(0)->counters(); - auto event_data = net_handler.metrics()->bucket(0)->event_data(); + auto event_data = net_handler.metrics()->bucket(0)->event_data_locked(); CHECK(net_handler.metrics()->start_tstamp().tv_sec == 1567706365); CHECK(net_handler.metrics()->start_tstamp().tv_nsec == 513271000); - CHECK(event_data.num_events == 140); - CHECK(counters.UDP == 140); - CHECK(counters.IPv4 == 0); - CHECK(counters.IPv6 == 140); + CHECK(event_data.num_events->value() == 140); + CHECK(counters.UDP.value() == 140); + CHECK(counters.IPv4.value() == 0); + CHECK(counters.IPv6.value() == 140); } TEST_CASE("Parse net (dns) TCP IPv6 tests", "[pcap][ipv6][tcp][net]") @@ -103,14 +103,14 @@ TEST_CASE("Parse net (dns) TCP IPv6 tests", "[pcap][ipv6][tcp][net]") net_handler.stop(); auto counters = net_handler.metrics()->bucket(0)->counters(); - auto event_data = net_handler.metrics()->bucket(0)->event_data(); + auto event_data = net_handler.metrics()->bucket(0)->event_data_locked(); CHECK(net_handler.metrics()->start_tstamp().tv_sec == 1567706308); CHECK(net_handler.metrics()->start_tstamp().tv_nsec == 958184000); - CHECK(event_data.num_events == 1800); - CHECK(counters.TCP == 1800); - CHECK(counters.IPv4 == 0); - CHECK(counters.IPv6 == 1800); + CHECK(event_data.num_events->value() == 1800); + CHECK(counters.TCP.value() == 1800); + CHECK(counters.IPv4.value() == 0); + CHECK(counters.IPv6.value() == 1800); } TEST_CASE("Parse net (dns) random UDP/TCP tests", "[pcap][net]") @@ -130,21 +130,21 @@ TEST_CASE("Parse net (dns) random UDP/TCP tests", "[pcap][net]") net_handler.stop(); auto counters = net_handler.metrics()->bucket(0)->counters(); - auto event_data = net_handler.metrics()->bucket(0)->event_data(); + auto event_data = net_handler.metrics()->bucket(0)->event_data_locked(); CHECK(net_handler.metrics()->start_tstamp().tv_sec == 1614874231); CHECK(net_handler.metrics()->start_tstamp().tv_nsec == 565771000); // confirmed with wireshark - CHECK(event_data.num_events == 16147); - CHECK(event_data.num_samples == 16147); - CHECK(counters.TCP == 13176); - CHECK(counters.UDP == 2971); - CHECK(counters.IPv4 == 16147); - CHECK(counters.IPv6 == 0); - CHECK(counters.OtherL4 == 0); - CHECK(counters.total_in == 6648); - CHECK(counters.total_out == 9499); + CHECK(event_data.num_events->value() == 16147); + CHECK(event_data.num_samples->value() == 16147); + CHECK(counters.TCP.value() == 13176); + CHECK(counters.UDP.value() == 2971); + CHECK(counters.IPv4.value() == 16147); + CHECK(counters.IPv6.value() == 0); + CHECK(counters.OtherL4.value() == 0); + CHECK(counters.total_in.value() == 6648); + CHECK(counters.total_out.value() == 9499); nlohmann::json j; net_handler.metrics()->bucket(0)->to_json(j);