]> git.proxmox.com Git - pmg-api.git/blob - PMG/API2/Statistics.pm
PMG/API2/Statistics.pm - implement domain statistics
[pmg-api.git] / PMG / API2 / Statistics.pm
1 package PMG::API2::Statistics;
2
3 use strict;
4 use warnings;
5 use Data::Dumper;
6
7 use PVE::Tools;
8 use PVE::SafeSyslog;
9 use PVE::INotify;
10 use PVE::Exception qw(raise_param_exc);
11 use PVE::RESTHandler;
12 use PMG::RESTEnvironment;
13 use PVE::JSONSchema qw(get_standard_option);
14
15 use PMG::Utils;
16 use PMG::RuleDB;
17 use PMG::Statistic;
18
19 use base qw(PVE::RESTHandler);
20
21 __PACKAGE__->register_method ({
22 name => 'index',
23 path => '',
24 method => 'GET',
25 description => "Directory index.",
26 permissions => { check => [ 'admin', 'qmanager', 'audit'] },
27 parameters => {
28 additionalProperties => 0,
29 properties => {},
30 },
31 returns => {
32 type => 'array',
33 items => {
34 type => "object",
35 properties => {},
36 },
37 links => [ { rel => 'child', href => "{name}" } ],
38 },
39 code => sub {
40 my ($param) = @_;
41
42 return [
43 { name => "domains" },
44 { name => "mail" },
45 { name => "mailcount" },
46 { name => "maildistribution" },
47 { name => "spamscores" },
48 { name => "virus" },
49 ];
50 }});
51
52 __PACKAGE__->register_method ({
53 name => 'domains',
54 path => 'domains',
55 method => 'GET',
56 description => "Mail Domains Statistics.",
57 permissions => { check => [ 'admin', 'qmanager', 'audit'] },
58 parameters => {
59 additionalProperties => 0,
60 properties => {
61 starttime => get_standard_option('pmg-starttime'),
62 endtime => get_standard_option('pmg-endtime'),
63 },
64 },
65 returns => {
66 type => 'array',
67 items => {
68 type => "object",
69 properties => {
70 domain => {
71 description => "Domain name.",
72 type => 'string',
73 },
74 count_in => {
75 description => "Incoming mail count.",
76 type => 'number',
77 },
78 count_out => {
79 description => "Outgoing mail count.",
80 type => 'number',
81 },
82 spamcount_in => {
83 description => "Incoming spam mails.",
84 type => 'number',
85 },
86 spamcount_out => {
87 description => "Outgoing spam mails.",
88 type => 'number',
89 },
90 mbytes_in => {
91 description => "Incoming mail traffic (Mebibytes).",
92 type => 'number',
93 },
94 mbytes_out => {
95 description => "Outgoing mail traffic (Mebibytes).",
96 type => 'number',
97 },
98 viruscount_in => {
99 description => "Number of incoming virus mails.",
100 type => 'number',
101 },
102 viruscount_out => {
103 description => "Number of outgoing virus mails.",
104 type => 'number',
105 },
106 },
107 },
108 },
109 code => sub {
110 my ($param) = @_;
111
112 my $restenv = PMG::RESTEnvironment->get();
113 my $cinfo = $restenv->{cinfo};
114
115 my $start = $param->{starttime} // (time - 86400);
116 my $end = $param->{endtime} // ($start + 86400);
117
118 my $stat = PMG::Statistic->new($start, $end);
119 my $rdb = PMG::RuleDB->new();
120
121 #PMG::Statistic::update_stats_domainstat_in($rdb->{dbh}, $cinfo);
122 #PMG::Statistic::update_stats_domainstat_out($rdb->{dbh}, $cinfo);
123
124 my $res = $stat->total_domain_stat($rdb);
125
126
127 return $res;
128 }});
129
130 __PACKAGE__->register_method ({
131 name => 'mail',
132 path => 'mail',
133 method => 'GET',
134 description => "General Mail Statistics.",
135 permissions => { check => [ 'admin', 'qmanager', 'audit'] },
136 parameters => {
137 additionalProperties => 0,
138 properties => {
139 starttime => get_standard_option('pmg-starttime'),
140 endtime => get_standard_option('pmg-endtime'),
141 },
142 },
143 returns => {
144 type => "object",
145 properties => {
146 avptime => {
147 description => "Average mail processing time in seconds.",
148 type => 'number',
149 },
150 bounces_in => {
151 description => "Incoming bounce mail count (sender = <>).",
152 type => 'number',
153 },
154 bounces_out => {
155 description => "Outgoing bounce mail count (sender = <>).",
156 type => 'number',
157 },
158 count => {
159 description => "Overall mail count (in and out).",
160 type => 'number',
161 },
162 count_in => {
163 description => "Incoming mail count.",
164 type => 'number',
165 },
166 count_out => {
167 description => "Outgoing mail count.",
168 type => 'number',
169 },
170 glcount => {
171 description => "Number of greylisted mails.",
172 type => 'number',
173 },
174 junk_in => {
175 description => "Incoming junk mail count (viruscount_in + spamcount_in + glcount + spfcount).",
176 type => 'number',
177 },
178 junk_out => {
179 description => "Outgoing junk mail count (viruscount_out + spamcount_out).",
180 type => 'number',
181 },
182 spamcount_in => {
183 description => "Incoming spam mails.",
184 type => 'number',
185 },
186 spamcount_out => {
187 description => "Outgoing spam mails.",
188 type => 'number',
189 },
190 spfcount => {
191 description => "Mails rejected by SPF.",
192 type => 'number',
193 },
194 bytes_in => {
195 description => "Incoming mail traffic (bytes).",
196 type => 'number',
197 },
198 bytes_out => {
199 description => "Outgoing mail traffic (bytes).",
200 type => 'number',
201 },
202 viruscount_in => {
203 description => "Number of incoming virus mails.",
204 type => 'number',
205 },
206 viruscount_out => {
207 description => "Number of outgoing virus mails.",
208 type => 'number',
209 },
210 },
211 },
212 code => sub {
213 my ($param) = @_;
214
215 my $restenv = PMG::RESTEnvironment->get();
216 my $cinfo = $restenv->{cinfo};
217
218 my $start = $param->{starttime} // (time - 86400);
219 my $end = $param->{endtime} // ($start + 86400);
220
221 my $stat = PMG::Statistic->new($start, $end);
222 my $rdb = PMG::RuleDB->new();
223
224 my $res = $stat->total_mail_stat($rdb);
225
226 return $res;
227 }});
228
229 __PACKAGE__->register_method ({
230 name => 'mailcount',
231 path => 'mailcount',
232 method => 'GET',
233 description => "Mail Count Statistics.",
234 permissions => { check => [ 'admin', 'qmanager', 'audit'] },
235 parameters => {
236 additionalProperties => 0,
237 properties => {
238 starttime => get_standard_option('pmg-starttime'),
239 endtime => get_standard_option('pmg-endtime'),
240 timespan => {
241 description => "Return Mails/<timespan>, when <timespan> is specified in seconds.",
242 type => 'integer',
243 minimum => 3600,
244 maximum => 366*86400,
245 optional => 1,
246 default => 3600,
247 }
248 },
249 },
250 returns => {
251 type => 'array',
252 items => {
253 type => "object",
254 properties => {
255 index => {
256 description => "Time index.",
257 type => 'integer',
258 },
259 time => {
260 description => "Time (Unix epoch).",
261 type => 'integer',
262 },
263 count => {
264 description => "Overall mail count (in and out).",
265 type => 'number',
266 },
267 count_in => {
268 description => "Incoming mail count.",
269 type => 'number',
270 },
271 count_out => {
272 description => "Outgoing mail count.",
273 type => 'number',
274 },
275 spamcount_in => {
276 description => "Incoming spam mails (spamcount_in + glcount + spfcount).",
277 type => 'number',
278 },
279 spamcount_out => {
280 description => "Outgoing spam mails.",
281 type => 'number',
282 },
283 viruscount_in => {
284 description => "Number of incoming virus mails.",
285 type => 'number',
286 },
287 viruscount_out => {
288 description => "Number of outgoing virus mails.",
289 type => 'number',
290 },
291 bounces_in => {
292 description => "Incoming bounce mail count (sender = <>).",
293 type => 'number',
294 },
295 bounces_out => {
296 description => "Outgoing bounce mail count (sender = <>).",
297 type => 'number',
298 },
299 },
300 },
301 },
302 code => sub {
303 my ($param) = @_;
304
305 my $restenv = PMG::RESTEnvironment->get();
306 my $cinfo = $restenv->{cinfo};
307
308 my $start = $param->{starttime} // (time - 86400);
309 my $end = $param->{endtime} // ($start + 86400);
310
311 my $span = $param->{timespan} // 3600;
312
313 my $count = ($end - $start)/$span;
314
315 die "too many entries - try to increase parameter 'span'\n" if $count > 5000;
316
317 my $stat = PMG::Statistic->new($start, $end);
318 my $rdb = PMG::RuleDB->new();
319
320 #PMG::Statistic::update_stats_dailystat($rdb->{dbh}, $cinfo);
321
322 my $res = $stat->traffic_stat_graph ($rdb, $span);
323
324 return $res;
325 }});
326
327 __PACKAGE__->register_method ({
328 name => 'virus',
329 path => 'virus',
330 method => 'GET',
331 description => "Get Statistics about detected Viruses.",
332 permissions => { check => [ 'admin', 'qmanager', 'audit'] },
333 parameters => {
334 additionalProperties => 0,
335 properties => {
336 starttime => get_standard_option('pmg-starttime'),
337 endtime => get_standard_option('pmg-endtime'),
338 },
339 },
340 returns => {
341 type => 'array',
342 items => {
343 type => "object",
344 properties => {
345 name => {
346 description => 'Virus name.',
347 type => 'string',
348 },
349 count => {
350 description => 'Detection count.',
351 type => 'integer',
352 },
353 },
354 }
355 },
356 code => sub {
357 my ($param) = @_;
358
359 my $restenv = PMG::RESTEnvironment->get();
360 my $cinfo = $restenv->{cinfo};
361
362 my $start = $param->{starttime} // (time - 86400);
363 my $end = $param->{endtime} // ($start + 86400);
364
365 my $stat = PMG::Statistic->new($start, $end);
366 my $rdb = PMG::RuleDB->new();
367
368 my $res = $stat->total_virus_stat($rdb);
369
370 return $res;
371 }});
372
373 __PACKAGE__->register_method ({
374 name => 'spamscores',
375 path => 'spamscores',
376 method => 'GET',
377 description => "Get the count of spam mails grouped by spam score. " .
378 "Count for score 10 includes mails with spam score > 10.",
379 permissions => { check => [ 'admin', 'qmanager', 'audit'] },
380 parameters => {
381 additionalProperties => 0,
382 properties => {
383 starttime => get_standard_option('pmg-starttime'),
384 endtime => get_standard_option('pmg-endtime'),
385 },
386 },
387 returns => {
388 type => 'array',
389 items => {
390 type => "object",
391 properties => {
392 level => {
393 description => 'Spam level.',
394 type => 'string',
395 },
396 count => {
397 description => 'Detection count.',
398 type => 'integer',
399 },
400 ratio => {
401 description => 'Portion of overall mail count.',
402 type => 'number',
403 },
404 },
405 }
406 },
407 code => sub {
408 my ($param) = @_;
409
410 my $restenv = PMG::RESTEnvironment->get();
411 my $cinfo = $restenv->{cinfo};
412
413 my $start = $param->{starttime} // (time - 86400);
414 my $end = $param->{endtime} // ($start + 86400);
415
416 my $stat = PMG::Statistic->new($start, $end);
417 my $rdb = PMG::RuleDB->new();
418
419 my $totalstat = $stat->total_mail_stat ($rdb);
420 my $spamstat = $stat->total_spam_stat($rdb);
421
422 my $res = [];
423
424 my $count_in = $totalstat->{count_in};
425 my $rest = $totalstat->{spamcount_in};
426
427 my $levelcount = {};
428 foreach my $ref (@$spamstat) {
429 my $level = $ref->{spamlevel} // 0;
430 next if $level >= 10 || $level < 1;
431 $rest -= $ref->{count} if $level >= 3;
432 $levelcount->{$level} = $ref->{count};
433 }
434
435 $levelcount->{0} = $totalstat->{count_in} - $totalstat->{spamcount_in};
436 $levelcount->{10} = $rest if $rest;
437
438 for (my $i = 0; $i <= 10; $i++) {
439 my $count = $levelcount->{$i} // 0;
440 my $ratio = $count_in ? $count/$count_in : 0;
441 push @$res, { level => $i, count => $count, ratio => $ratio };
442 }
443
444 return $res;
445 }});
446
447 __PACKAGE__->register_method ({
448 name => 'maildistribution',
449 path => 'maildistribution',
450 method => 'GET',
451 description => "Get the count of spam mails grouped by spam score. " .
452 "Count for score 10 includes mails with spam score > 10.",
453 permissions => { check => [ 'admin', 'qmanager', 'audit'] },
454 parameters => {
455 additionalProperties => 0,
456 properties => {
457 starttime => get_standard_option('pmg-starttime'),
458 endtime => get_standard_option('pmg-endtime'),
459 },
460 },
461 returns => {
462 type => 'array',
463 items => {
464 type => "object",
465 properties => {
466 index => {
467 description => "Hour (0-23).",
468 type => 'integer',
469 },
470 count => {
471 description => "Overall mail count (in and out).",
472 type => 'number',
473 },
474 count_in => {
475 description => "Incoming mail count.",
476 type => 'number',
477 },
478 count_out => {
479 description => "Outgoing mail count.",
480 type => 'number',
481 },
482 spamcount_in => {
483 description => "Incoming spam mails (spamcount_in + glcount + spfcount).",
484 type => 'number',
485 },
486 spamcount_out => {
487 description => "Outgoing spam mails.",
488 type => 'number',
489 },
490 viruscount_in => {
491 description => "Number of incoming virus mails.",
492 type => 'number',
493 },
494 viruscount_out => {
495 description => "Number of outgoing virus mails.",
496 type => 'number',
497 },
498 bounces_in => {
499 description => "Incoming bounce mail count (sender = <>).",
500 type => 'number',
501 },
502 bounces_out => {
503 description => "Outgoing bounce mail count (sender = <>).",
504 type => 'number',
505 },
506 },
507 },
508 },
509 code => sub {
510 my ($param) = @_;
511
512 my $restenv = PMG::RESTEnvironment->get();
513 my $cinfo = $restenv->{cinfo};
514
515 my $start = $param->{starttime} // (time - 86400);
516 my $end = $param->{endtime} // ($start + 86400);
517
518 my $stat = PMG::Statistic->new($start, $end);
519 my $rdb = PMG::RuleDB->new();
520
521 #PMG::Statistic::update_stats_dailystat($rdb->{dbh}, $cinfo);
522
523 my $res = $stat->traffic_stat_day_dist ($rdb);
524
525 return $res;
526 }});
527
528 1;