/
weird-stats.zeek
104 lines (80 loc) · 2.65 KB
/
weird-stats.zeek
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
##! Log weird statistics.
@load base/frameworks/sumstats
@load base/frameworks/cluster
module WeirdStats;
export {
redef enum Log::ID += { LOG };
global log_policy: Log::PolicyHook;
## How often stats are reported.
const weird_stat_interval = 15min &redef;
type Info: record {
## Timestamp for the measurement.
ts: time &log;
## Name of the weird.
name: string &log;
## Number of times weird was seen since the last stats interval.
num_seen: count &log;
};
global log_weird_stats: event(rec: Info);
}
global this_epoch_weirds: table[string] of double;
global last_epoch_weirds: table[string] of double;
function weird_epoch_results(ts: time, key: SumStats::Key, result: SumStats::Result)
{
this_epoch_weirds[key$str]=result["weirds.encountered"]$sum;
}
function weird_epoch_finished(ts: time)
{
for ( n, v in this_epoch_weirds )
{
local last_count: double = 0.0;
if ( n in last_epoch_weirds )
last_count = last_epoch_weirds[n];
local num_seen: double = v - last_count;
if ( num_seen > 0.0 )
Log::write(LOG, Info($ts = ts, $name = n,
$num_seen = double_to_count(num_seen)));
}
last_epoch_weirds = this_epoch_weirds;
this_epoch_weirds = table();
}
event zeek_init() &priority=5
{
Log::create_stream(WeirdStats::LOG,
[$columns = Info, $ev = log_weird_stats,
$path="weird_stats", $policy=log_policy]);
local r1 = SumStats::Reducer($stream = "weirds.encountered",
$apply = set(SumStats::SUM));
SumStats::create([$name = "weirds.statistics",
$epoch = weird_stat_interval, $reducers = set(r1),
$epoch_result = weird_epoch_results,
$epoch_finished = weird_epoch_finished]);
}
module SumStats;
function observe_weird_stats()
{
local rs = get_reporter_stats();
for ( n, v in rs$weirds_by_type )
SumStats::observe("weirds.encountered", SumStats::Key($str = n),
SumStats::Observation($dbl=(v + 0.0)));
}
@if ( Cluster::is_enabled() )
# I'm not sure if this is a hack or not: the manager will generate this
# event at the end of its epoch so workers can handle it just in time to
# generate the necessary stats. Alternative may be workers generating the
# stats individually/proactively in their own finish_epoch, but that may be
# less synchronized?
event SumStats::cluster_ss_request(uid: string, ss_name: string, cleanup: bool) &priority=10
{
if ( ss_name != "weirds.statistics" )
return;
observe_weird_stats();
}
@else
event SumStats::finish_epoch(ss: SumStat) &priority=10
{
if ( ss$name != "weirds.statistics" )
return;
observe_weird_stats();
}
@endif