radicale 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. # This file is related to Radicale - CalDAV and CardDAV server
  2. # for logwatch (script)
  3. # Copyright © 2024-2024 Peter Bieringer <pb@bieringer.de>
  4. #
  5. # Detail levels
  6. # >= 5: Logins
  7. # >= 10: ResponseTimes
  8. $Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'} || 0;
  9. my %ResponseTimes;
  10. my %Responses;
  11. my %Requests;
  12. my %Logins;
  13. my %Loglevel;
  14. my %OtherEvents;
  15. my $sum;
  16. my $length;
  17. sub ResponseTimesMinMaxSum($$) {
  18. my $req = $_[0];
  19. my $time = $_[1];
  20. $ResponseTimes{$req}->{'cnt'}++;
  21. if (! defined $ResponseTimes{$req}->{'min'}) {
  22. $ResponseTimes{$req}->{'min'} = $time;
  23. } elsif ($ResponseTimes->{$req}->{'min'} > $time) {
  24. $ResponseTimes{$req}->{'min'} = $time;
  25. }
  26. if (! defined $ResponseTimes{$req}->{'max'}) {
  27. $ResponseTimes{$req}{'max'} = $time;
  28. } elsif ($ResponseTimes{$req}->{'max'} < $time) {
  29. $ResponseTimes{$req}{'max'} = $time;
  30. }
  31. $ResponseTimes{$req}->{'sum'} += $time;
  32. }
  33. sub Sum($) {
  34. my $phash = $_[0];
  35. my $sum = 0;
  36. foreach my $entry (keys %$phash) {
  37. $sum += $phash->{$entry};
  38. }
  39. return $sum;
  40. }
  41. sub MaxLength($) {
  42. my $phash = $_[0];
  43. my $length = 0;
  44. foreach my $entry (keys %$phash) {
  45. $length = length($entry) if (length($entry) > $length);
  46. }
  47. return $length;
  48. }
  49. while (defined($ThisLine = <STDIN>)) {
  50. # count loglevel
  51. if ( $ThisLine =~ /\[(DEBUG|INFO|WARNING|ERROR|CRITICAL)\] /o ) {
  52. $Loglevel{$1}++
  53. }
  54. # parse log for events
  55. if ( $ThisLine =~ /Radicale server ready/o ) {
  56. $OtherEvents{"Radicale server started"}++;
  57. }
  58. elsif ( $ThisLine =~ /Stopping Radicale/o ) {
  59. $OtherEvents{"Radicale server stopped"}++;
  60. }
  61. elsif ( $ThisLine =~ / (\S+) response status/o ) {
  62. my $req = $1;
  63. if ( $ThisLine =~ / \S+ response status for .* with depth '(\d)' in ([0-9.]+) seconds: (\d+)/o ) {
  64. $req .= ":D=" . $1 . ":R=" . $3;
  65. ResponseTimesMinMaxSum($req, $2) if ($Detail >= 10);
  66. } elsif ( $ThisLine =~ / \S+ response status for .* in ([0-9.]+) seconds: (\d+)/ ) {
  67. $req .= ":R=" . $2;
  68. ResponseTimesMinMaxSum($req, $1) if ($Detail >= 10);
  69. }
  70. $Responses{$req}++;
  71. }
  72. elsif ( $ThisLine =~ / (\S+) request for/o ) {
  73. my $req = $1;
  74. if ( $ThisLine =~ / \S+ request for .* with depth '(\d)' received/o ) {
  75. $req .= ":D=" . $1;
  76. }
  77. $Requests{$req}++;
  78. }
  79. elsif ( $ThisLine =~ / (Successful login): '([^']+)'/o ) {
  80. $Logins{$2}++ if ($Detail >= 5);
  81. $OtherEvents{$1}++;
  82. }
  83. elsif ( $ThisLine =~ / (Failed login attempt) /o ) {
  84. $OtherEvents{$1}++;
  85. }
  86. elsif ( $ThisLine =~ /\[(DEBUG|INFO)\] /o ) {
  87. # skip if DEBUG+INFO
  88. }
  89. else {
  90. # Report any unmatched entries...
  91. $ThisLine =~ s/^\[\d+(\/Thread-\d+)?\] //; # remove process/Thread ID
  92. chomp($ThisLine);
  93. $OtherList{$ThisLine}++;
  94. }
  95. }
  96. if ($Started) {
  97. print "\nStatistics:\n";
  98. print " Radicale started: $Started Time(s)\n";
  99. }
  100. if (keys %Loglevel) {
  101. $sum = Sum(\%Loglevel);
  102. print "\n**Loglevel counters**\n";
  103. printf "%-18s | %7s | %5s |\n", "Loglevel", "cnt", "ratio";
  104. print "-" x38 . "\n";
  105. foreach my $level (sort keys %Loglevel) {
  106. printf "%-18s | %7d | %3d%% |\n", $level, $Loglevel{$level}, int(($Loglevel{$level} * 100) / $sum);
  107. }
  108. print "-" x38 . "\n";
  109. printf "%-18s | %7d | %3d%% |\n", "", $sum, 100;
  110. }
  111. if (keys %Requests) {
  112. $sum = Sum(\%Requests);
  113. print "\n**Request counters (D=<depth>)**\n";
  114. printf "%-18s | %7s | %5s |\n", "Request", "cnt", "ratio";
  115. print "-" x38 . "\n";
  116. foreach my $req (sort keys %Requests) {
  117. printf "%-18s | %7d | %3d%% |\n", $req, $Requests{$req}, int(($Requests{$req} * 100) / $sum);
  118. }
  119. print "-" x38 . "\n";
  120. printf "%-18s | %7d | %3d%% |\n", "", $sum, 100;
  121. }
  122. if (keys %Responses) {
  123. $sum = Sum(\%Responses);
  124. print "\n**Response result counters ((D=<depth> R=<result>)**\n";
  125. printf "%-18s | %7s | %5s |\n", "Response", "cnt", "ratio";
  126. print "-" x38 . "\n";
  127. foreach my $req (sort keys %Responses) {
  128. printf "%-18s | %7d | %3d%% |\n", $req, $Responses{$req}, int(($Responses{$req} * 100) / $sum);
  129. }
  130. print "-" x38 . "\n";
  131. printf "%-18s | %7d | %3d%% |\n", "", $sum, 100;
  132. }
  133. if (keys %Logins) {
  134. $sum = Sum(\%Logins);
  135. $length = MaxLength(\%Logins);
  136. print "\n**Successful login counters**\n";
  137. printf "%-" . $length . "s | %7s | %5s |\n", "Login", "cnt", "ratio";
  138. print "-" x($length + 20) . "\n";
  139. foreach my $login (sort keys %Logins) {
  140. printf "%-" . $length . "s | %7d | %3d%% |\n", $login, $Logins{$login}, int(($Logins{$login} * 100) / $sum);
  141. }
  142. print "-" x($length + 20) . "\n";
  143. printf "%-" . $length . "s | %7d | %3d%% |\n", "", $sum, 100;
  144. }
  145. if (keys %ResponseTimes) {
  146. print "\n**Response timings (counts, seconds) (D=<depth> R=<result>)**\n";
  147. printf "%-18s | %7s | %7s | %7s | %7s |\n", "Response", "cnt", "min", "max", "avg";
  148. print "-" x60 . "\n";
  149. foreach my $req (sort keys %ResponseTimes) {
  150. printf "%-18s | %7d | %7.3f | %7.3f | %7.3f |\n", $req
  151. , $ResponseTimes{$req}->{'cnt'}
  152. , $ResponseTimes{$req}->{'min'}
  153. , $ResponseTimes{$req}->{'max'}
  154. , $ResponseTimes{$req}->{'sum'} / $ResponseTimes{$req}->{'cnt'};
  155. }
  156. print "-" x60 . "\n";
  157. }
  158. if (keys %OtherEvents) {
  159. print "\n**Other Events**\n";
  160. foreach $ThisOne (sort keys %OtherEvents) {
  161. print "$ThisOne: $OtherEvents{$ThisOne} Time(s)\n";
  162. }
  163. }
  164. if (keys %OtherList) {
  165. print "\n**Unmatched Entries**\n";
  166. foreach $ThisOne (sort keys %OtherList) {
  167. print "$ThisOne: $OtherList{$ThisOne} Time(s)\n";
  168. }
  169. }
  170. exit(0);
  171. # vim: shiftwidth=3 tabstop=3 syntax=perl et smartindent