Rework stats to store handles to the counters

This commit is contained in:
Tim Wojtulewicz 2021-04-19 10:38:43 -07:00
parent 63fd1611ca
commit ca553fda27
4 changed files with 94 additions and 53 deletions

View file

@ -132,6 +132,17 @@ public:
analyzer::Analyzer* FindAnalyzer(const char* name); // find first in tree. analyzer::Analyzer* FindAnalyzer(const char* name); // find first in tree.
TransportProto ConnTransport() const { return proto; } TransportProto ConnTransport() const { return proto; }
std::string TransportIdentifier() const override
{
if ( proto == TRANSPORT_TCP )
return "tcp";
else if ( proto == TRANSPORT_UDP )
return "udp";
else if ( proto == TRANSPORT_ICMP )
return "icmp";
else
return "unknown";
}
// FIXME: Now this is in Analyzer and should eventually be removed here. // FIXME: Now this is in Analyzer and should eventually be removed here.
// //

View file

@ -191,6 +191,12 @@ public:
*/ */
void DeleteTimer(double t); void DeleteTimer(double t);
/**
* Returns a string representation of the transport protocol referenced by the
* session. This is used by SessionManager for statistics.
*/
virtual std::string TransportIdentifier() const = 0;
protected: protected:
friend class detail::SessionTimer; friend class detail::SessionTimer;
@ -239,7 +245,6 @@ protected:
unsigned int is_active:1; unsigned int is_active:1;
unsigned int record_packets:1, record_contents:1; unsigned int record_packets:1, record_contents:1;
unsigned int record_current_packet:1, record_current_content:1; unsigned int record_current_packet:1, record_current_content:1;
}; };
namespace detail { namespace detail {

View file

@ -36,13 +36,6 @@ zeek::SessionManager*& zeek::sessions = zeek::session_mgr;
namespace zeek { namespace zeek {
SessionManager::SessionManager()
: stats(telemetry_mgr->GaugeFamily("zeek", "session_stats",
{"tcp", "udp", "icmp"},
"Zeek Session Stats", "1", false))
{
}
SessionManager::~SessionManager() SessionManager::~SessionManager()
{ {
Clear(); Clear();
@ -361,17 +354,9 @@ void SessionManager::Remove(Session* s)
if ( session_map.erase(key) == 0 ) if ( session_map.erase(key) == 0 )
reporter->InternalWarning("connection missing"); reporter->InternalWarning("connection missing");
else else
switch ( c->ConnTransport() ) { {
case TRANSPORT_TCP: if ( auto* stat_block = stats.GetCounters(c->TransportIdentifier()) )
stats.GetOrAdd({{"tcp", "num_conns"}}).Dec(); stat_block->num.Dec();
break;
case TRANSPORT_UDP:
stats.GetOrAdd({{"udp", "num_conns"}}).Dec();
break;
case TRANSPORT_ICMP:
stats.GetOrAdd({{"icmp", "num_conns"}}).Dec();
break;
case TRANSPORT_UNKNOWN: break;
} }
s->ClearKey(); s->ClearKey();
@ -425,17 +410,20 @@ void SessionManager::Clear()
void SessionManager::GetStats(SessionStats& s) void SessionManager::GetStats(SessionStats& s)
{ {
s.max_TCP_conns = stats.GetOrAdd({{"tcp", "max_conns"}}).Value(); auto* tcp_stats = stats.GetCounters("tcp");
s.num_TCP_conns = stats.GetOrAdd({{"tcp", "num_conns"}}).Value(); s.max_TCP_conns = tcp_stats->max;
s.cumulative_TCP_conns = stats.GetOrAdd({{"tcp", "cumulative_conns"}}).Value(); s.num_TCP_conns = tcp_stats->num.Value();
s.cumulative_TCP_conns = tcp_stats->total.Value();
s.max_UDP_conns = stats.GetOrAdd({{"udp", "max_conns"}}).Value(); auto* udp_stats = stats.GetCounters("udp");
s.num_UDP_conns = stats.GetOrAdd({{"udp", "num_conns"}}).Value(); s.max_UDP_conns = udp_stats->max;
s.cumulative_UDP_conns = stats.GetOrAdd({{"udp", "cumulative_conns"}}).Value(); s.num_UDP_conns = udp_stats->num.Value();
s.cumulative_UDP_conns = udp_stats->total.Value();
s.max_ICMP_conns = stats.GetOrAdd({{"icmp", "max_conns"}}).Value(); auto* icmp_stats = stats.GetCounters("icmp");
s.num_ICMP_conns = stats.GetOrAdd({{"icmp", "num_conns"}}).Value(); s.max_ICMP_conns = icmp_stats->max;
s.cumulative_ICMP_conns = stats.GetOrAdd({{"icmp", "cumulative_conns"}}).Value(); s.num_ICMP_conns = icmp_stats->num.Value();
s.cumulative_ICMP_conns = icmp_stats->total.Value();
s.num_fragments = detail::fragment_mgr->Size(); s.num_fragments = detail::fragment_mgr->Size();
s.max_fragments = detail::fragment_mgr->MaxFragments(); s.max_fragments = detail::fragment_mgr->MaxFragments();
@ -649,31 +637,15 @@ void SessionManager::InsertSession(detail::SessionKey key, Session* session)
key.CopyData(); key.CopyData();
session_map.insert_or_assign(std::move(key), session); session_map.insert_or_assign(std::move(key), session);
std::string protocol; std::string protocol = session->TransportIdentifier();
switch ( static_cast<Connection*>(session)->ConnTransport() )
{
case TRANSPORT_TCP:
protocol = "tcp";
break;
case TRANSPORT_UDP:
protocol = "udp";
break;
case TRANSPORT_ICMP:
protocol = "icmp";
break;
default:
break;
}
if ( ! protocol.empty() ) if ( auto* stat_block = stats.GetCounters(protocol) )
{ {
auto max = stats.GetOrAdd({{protocol, "max_conns"}}); stat_block->num.Inc();
auto num = stats.GetOrAdd({{protocol, "num_conns"}}); stat_block->total.Inc();
num.Inc();
stats.GetOrAdd({{protocol, "cumulative_conns"}}).Inc(); if ( stat_block->num.Value() > stat_block->max )
if ( num.Value() > max.Value() ) stat_block->max++;
max.Inc();
} }
} }

View file

@ -9,7 +9,7 @@
#include "zeek/Frag.h" #include "zeek/Frag.h"
#include "zeek/NetVar.h" #include "zeek/NetVar.h"
#include "zeek/analyzer/protocol/tcp/Stats.h" #include "zeek/analyzer/protocol/tcp/Stats.h"
#include "zeek/telemetry/Gauge.h" #include "zeek/telemetry/Manager.h"
#include "zeek/Hash.h" #include "zeek/Hash.h"
#include "zeek/Session.h" #include "zeek/Session.h"
@ -42,7 +42,7 @@ struct SessionStats {
class SessionManager final { class SessionManager final {
public: public:
SessionManager(); SessionManager() = default;
~SessionManager(); ~SessionManager();
void Done(); // call to drain events before destructing void Done(); // call to drain events before destructing
@ -141,6 +141,59 @@ public:
private: private:
class StatBlocks {
public:
struct Block {
telemetry::IntGauge num;
telemetry::IntCounter total;
size_t max = 0;
Block(telemetry::IntGaugeFamily num_family,
telemetry::IntCounterFamily total_family,
std::string protocol) : num(num_family.GetOrAdd({{"protocol", protocol}})),
total(total_family.GetOrAdd({{"protocol", protocol}}))
{
}
};
using BlockMap = std::map<std::string, Block>;
BlockMap::iterator InitCounters(std::string protocol)
{
telemetry::IntGaugeFamily num_family = telemetry_mgr->GaugeFamily(
"zeek", "open-sessions", {"protocol"}, "Active Zeek Sessions");
telemetry::IntCounterFamily total_family = telemetry_mgr->CounterFamily(
"zeek", "sessions", {"protocol"},
"Total number of sessions", "1", true);
auto [it, inserted] = entries.insert(
{protocol, Block{num_family, total_family, protocol}});
if ( inserted )
return it;
return entries.end();
}
Block* GetCounters(std::string protocol)
{
auto it = entries.find(protocol);
if ( it == entries.end() )
it = InitCounters(protocol);
if ( it != entries.end() )
return &(it->second);
return nullptr;
}
private:
BlockMap entries;
};
using SessionMap = std::map<detail::SessionKey, Session*>; using SessionMap = std::map<detail::SessionKey, Session*>;
Connection* NewConn(const detail::ConnIDKey& k, double t, const ConnID* id, Connection* NewConn(const detail::ConnIDKey& k, double t, const ConnID* id,
@ -177,7 +230,7 @@ private:
void InsertSession(detail::SessionKey key, Session* session); void InsertSession(detail::SessionKey key, Session* session);
SessionMap session_map; SessionMap session_map;
telemetry::IntGaugeFamily stats; StatBlocks stats;
}; };
// Manager for the currently active sessions. // Manager for the currently active sessions.