Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

rspamd_stats.pl 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #!/usr/bin/env perl
  2. use Data::Dumper;
  3. use Getopt::Long;
  4. use warnings;
  5. use strict;
  6. use Time::Piece;
  7. my @symbols_search;
  8. my $start = "";
  9. my $end = "";
  10. my $reject_score = 30.0;
  11. my $junk_score = 7.5;
  12. my $log_file = "/var/log/rspamd/rspamd.log";
  13. my $dateformat = "%Y-%m-%d %H:%M:%S";
  14. GetOptions(
  15. "reject-score=f" => \$reject_score,
  16. "junk-score=f" => \$junk_score,
  17. "start=s" => \$start,
  18. "end=s" => \$end,
  19. "symbol=s@" => \@symbols_search,
  20. "log=s" => \$log_file,
  21. "dateformat=s" => \$dateformat);
  22. # Global vars
  23. my $total = 0;
  24. my $total_spam = 0;
  25. my $total_junk = 0;
  26. my $junk_symbols = 0;
  27. my $spam_symbols = 0;
  28. my $ham_symbols = 0;
  29. my $ham_spam_change = 0;
  30. my $ham_junk_change = 0;
  31. my $diff_alpha = 0.1;
  32. my %sym_res;
  33. my $st = 0;
  34. my $ed = 0;
  35. if ($start ne "") {
  36. $st = Time::Piece->strptime($start, $dateformat);
  37. }
  38. if ($end ne "") {
  39. $ed = Time::Piece->strptime($end, $dateformat);
  40. }
  41. my $rspamd_log;
  42. if ($log_file eq '-') {
  43. $rspamd_log = \*STDIN;
  44. }
  45. else {
  46. open($rspamd_log, '<', $log_file) or die "cannot open $log_file";
  47. }
  48. foreach my $s (@symbols_search) {
  49. $sym_res{$s} = {
  50. hits => 0,
  51. spam_hits => 0,
  52. junk_hits => 0,
  53. spam_change => 0,
  54. junk_change => 0,
  55. weight => 0,
  56. };
  57. }
  58. while(<$rspamd_log>) {
  59. if (/^.*rspamd_task_write_log.*$/) {
  60. my @elts = split /\s+/;
  61. my $ts = $elts[0] . ' ' . $elts[1];
  62. if ($st or $ed) {
  63. my $dt = Time::Piece->strptime($ts, $dateformat) or die "cannot parse $ts";
  64. if ($dt) {
  65. if ($st != 0 && $dt < $st) {
  66. next;
  67. }
  68. if ($ed != 0 && $dt > $ed) {
  69. next;
  70. }
  71. }
  72. }
  73. if ($_ !~ /\[(-?\d+(?:\.\d+)?)\/(-?\d+(?:\.\d+)?)\]\s+\[([^\]]+)\]/) {
  74. #print "BAD\n";
  75. next;
  76. }
  77. $total ++;
  78. my $score = $1 * 1.0;
  79. if ($score >= $reject_score) {
  80. $total_spam ++;
  81. }
  82. elsif ($score >= $junk_score) {
  83. $total_junk ++;
  84. }
  85. # Symbols
  86. my @symbols = split /,/, $3;
  87. foreach my $s (@symbols_search) {
  88. my @selected = grep /$s/, @symbols;
  89. if (scalar(@selected) > 0) {
  90. $selected[0] =~ /^[^\(]+\(([^\)]+)\).*$/;
  91. my $sym_score = $1;
  92. if ($sym_score < $diff_alpha) {
  93. next;
  94. }
  95. my $r = $sym_res{$s};
  96. $r->{hits} ++;
  97. $r->{weight} += $sym_score;
  98. my $is_spam = 0;
  99. my $is_junk = 0;
  100. if ($score >= $reject_score) {
  101. $is_spam = 1;
  102. $r->{spam_hits} ++;
  103. }
  104. elsif ($score >= $junk_score) {
  105. $is_junk = 1;
  106. $r->{junk_hits} ++;
  107. }
  108. my $score_without = $score - $sym_score;
  109. if ($is_spam && $score_without < $reject_score) {
  110. $r->{spam_change} ++;
  111. }
  112. if ($is_junk && $score_without < $junk_score) {
  113. $r->{junk_change} ++;
  114. }
  115. }
  116. }
  117. }
  118. }
  119. my $total_ham = $total - ($total_spam + $total_junk);
  120. if ($total > 0) {
  121. while (my ($s, $r) = each(%sym_res)) {
  122. if ($r->{hits} > 0) {
  123. my $th = $r->{hits};
  124. my $sh = $r->{spam_hits};
  125. my $jh = $r->{junk_hits};
  126. my $hh = $r->{hits} - $sh - $jh;
  127. my $htp = $hh * 100.0 / $total_ham if $total_ham != 0;
  128. my $stp = $sh * 100.0 / $total_spam if $total_spam != 0;
  129. my $jtp = $jh * 100.0 / $total_junk if $total_junk != 0;
  130. printf "Symbol: %s (weight %.3f) (%d hits, %.3f%%)\nHam hits: %d (%.3f%%), total ham: %d (ham with $s: %.3f%%)\nSpam hits: %d (%.3f%%), total spam: %d (spam with $s: %.3f%%)\nJunk hits: %d (%.3f%%), total junk: %d (junk with $s: %.3f%%)\n",
  131. $s, $r->{weight} / $r->{hits}, $th, ($th / $total * 100.0),
  132. $hh, ($hh / $th * 100.0), $total_ham, ($htp or 0),
  133. $sh, ($sh / $th * 100.0), $total_spam, ($stp or 0),
  134. $jh, ($jh / $th * 100.0), $total_junk, ($jtp or 0);
  135. my $schp = $r->{spam_change} / $total_spam * 100.0 if $total_spam;
  136. my $jchp = $r->{junk_change} / $total_junk * 100.0 if $total_junk;
  137. printf "Spam changes (ham/junk -> spam): %d (%.3f%%), total percentage (changes / spam hits): %.3f%%\nJunk changes (ham -> junk): %d (%.3f%%), total percentage (changes / junk hits): %.3f%%\n",
  138. $r->{spam_change}, ($r->{spam_change} / $th * 100.0), ($schp or 0),
  139. $r->{junk_change}, ($r->{junk_change} / $th * 100.0), ($jchp or 0);
  140. }
  141. else {
  142. print "Symbol $s has not been met\n";
  143. }
  144. print '*' x 20 . "\n";
  145. }
  146. }