1 |
slords |
1.1 |
diff -Nur -x '*.orig' -x '*.rej' smeserver-qpsmtpd-1.2.1/root/var/service/qpsmtpd/log/run mezzanine_patched_smeserver-qpsmtpd-1.2.1/root/var/service/qpsmtpd/log/run |
2 |
|
|
--- smeserver-qpsmtpd-1.2.1/root/var/service/qpsmtpd/log/run 2005-04-20 22:35:31.000000000 -0600 |
3 |
|
|
+++ mezzanine_patched_smeserver-qpsmtpd-1.2.1/root/var/service/qpsmtpd/log/run 2007-06-07 09:41:00.000000000 -0600 |
4 |
|
|
@@ -24,4 +24,4 @@ |
5 |
|
|
exec \ |
6 |
|
|
/usr/local/bin/setuidgid smelog \ |
7 |
|
|
/usr/local/bin/multilog t s5000000 \ |
8 |
|
|
- /var/log/qpsmtpd |
9 |
|
|
+ !/usr/local/bin/qplogsumm.pl /var/log/qpsmtpd |
10 |
|
|
diff -Nur -x '*.orig' -x '*.rej' usr/local/bin/qplogsumm.pl mezzanine_patched_usr/local/bin/qplogsumm.pl |
11 |
|
|
--- usr/local/bin/qplogsumm.pl 1969-12-31 17:00:00.000000000 -0700 |
12 |
|
|
+++ mezzanine_patched_usr/local/bin/qplogsumm.pl 2007-06-07 09:37:09.000000000 -0600 |
13 |
|
|
@@ -0,0 +1,272 @@ |
14 |
|
|
+#!/usr/bin/perl |
15 |
|
|
+# |
16 |
|
|
+ |
17 |
|
|
+=pod |
18 |
|
|
+ |
19 |
|
|
+=head1 SUMMARY |
20 |
|
|
+ |
21 |
|
|
+Works with multilog to analyse and summarise log entries generated by the logterse plugin. It is designed |
22 |
|
|
+to be invoked by multilog at log-rotation time. This is specified by an argument to multilog similar to: |
23 |
|
|
+ |
24 |
|
|
+=over 4 |
25 |
|
|
+ |
26 |
|
|
+multilog t !/path/to/qplogsumm ./main |
27 |
|
|
+ |
28 |
|
|
+=back |
29 |
|
|
+ |
30 |
|
|
+When qplogsumm is invoked, each line will be echoed, meaning the stored log is unchanged, but summary |
31 |
|
|
+information will be written to fd 5 and so stored in the 'state' file by multilog. |
32 |
|
|
+ |
33 |
|
|
+This file is fed in on fd 4 at the beginning of the next log rotation, so running totals, etc can be maintained. |
34 |
|
|
+ |
35 |
|
|
+=head1 State file format: |
36 |
|
|
+ |
37 |
|
|
+One entry per line containing three fields separated by whitespace: |
38 |
|
|
+ |
39 |
|
|
+=over 4 |
40 |
|
|
+ |
41 |
|
|
+=item 1. Disposition (plugin) name. |
42 |
|
|
+ |
43 |
|
|
+=item 2. tai64n timestamp recording the first time it was seen in a log. |
44 |
|
|
+ |
45 |
|
|
+=item 3. long-term running total. |
46 |
|
|
+ |
47 |
|
|
+=back |
48 |
|
|
+ |
49 |
|
|
+A disposition is effectively the plugin name that called DENY or the string 'queued' for |
50 |
|
|
+messages that made it through. |
51 |
|
|
+ |
52 |
|
|
+A line containing a disposition name of LOGFILE_EPOCH and a timestamp for the earliest known log entry. |
53 |
|
|
+ |
54 |
|
|
+Other derived data, such as percentages etc. can also appear in the file, commented |
55 |
|
|
+by a # character. This will be ignored on the next intake. |
56 |
|
|
+ |
57 |
|
|
+=head1 AUTHOR |
58 |
|
|
+ |
59 |
|
|
+Charles Butcher |
60 |
|
|
+ |
61 |
|
|
+=head1 VERSION |
62 |
|
|
+ |
63 |
|
|
+This is release 1.0 |
64 |
|
|
+ |
65 |
|
|
+=cut |
66 |
|
|
+ |
67 |
|
|
+use strict; |
68 |
|
|
+use POSIX qw(strftime); |
69 |
|
|
+ |
70 |
|
|
+ |
71 |
|
|
+my $FS = "\t"; # field separator used by logterse plugin |
72 |
|
|
+my %disp; # hash of dispositions |
73 |
|
|
+ |
74 |
|
|
+if (open PREVIOUS, "<&4") |
75 |
|
|
+{ |
76 |
|
|
+ while (<PREVIOUS>) |
77 |
|
|
+ { |
78 |
|
|
+ chomp(); |
79 |
|
|
+ next if m/^#/; |
80 |
|
|
+ next if m/^\s*$/; |
81 |
|
|
+ my ($plug_name, $plug_epoch, $plug_cumulative) = split /\s/; |
82 |
|
|
+ my $c = { epoch => $plug_epoch, cum => $plug_cumulative, curr => 0 }; |
83 |
|
|
+ $disp{$plug_name} = $c; |
84 |
|
|
+ } |
85 |
|
|
+ |
86 |
|
|
+ close PREVIOUS; |
87 |
|
|
+} |
88 |
|
|
+ |
89 |
|
|
+my $first_timestamp = 0; |
90 |
|
|
+my $last_timestamp = 0; |
91 |
|
|
+ |
92 |
|
|
+ |
93 |
|
|
+while (<>) |
94 |
|
|
+{ |
95 |
|
|
+ print; |
96 |
|
|
+ chomp; |
97 |
|
|
+ next unless m/terse plugin/; |
98 |
|
|
+ |
99 |
|
|
+ my ($timestamp_part, $log_part) = split '`'; |
100 |
|
|
+ my ($current_timestamp) = split /\s/, $timestamp_part; |
101 |
|
|
+ $first_timestamp = $current_timestamp unless $first_timestamp; |
102 |
|
|
+ $last_timestamp = $current_timestamp; |
103 |
|
|
+ |
104 |
|
|
+ my (@log_items) = split $FS, $log_part; |
105 |
|
|
+ my $disposition = $log_items[5]; |
106 |
|
|
+ next unless defined $disposition; |
107 |
|
|
+ |
108 |
|
|
+ if ($disp{$disposition}) |
109 |
|
|
+ { |
110 |
|
|
+ $disp{$disposition}->{curr} = 1; |
111 |
|
|
+ } |
112 |
|
|
+ else # a new plugin -- make a note of when it first appeared |
113 |
|
|
+ { |
114 |
|
|
+ my $c = { epoch => $current_timestamp, cum => 0, curr => 1 }; |
115 |
|
|
+ $disp{$disposition} = $c; |
116 |
|
|
+ } |
117 |
|
|
+} |
118 |
|
|
+ |
119 |
|
|
+ |
120 |
|
|
+# |
121 |
|
|
+# Set overall epoch |
122 |
|
|
+# |
123 |
|
|
+if (!exists $disp{'LOGFILE_EPOCH'}) |
124 |
|
|
+{ |
125 |
|
|
+ my $c = { epoch => $first_timestamp, cum => 0, curr => 0}; |
126 |
|
|
+ $disp{'LOGFILE_EPOCH'} = $c; |
127 |
|
|
+} |
128 |
|
|
+ |
129 |
|
|
+my $current_total = 0; |
130 |
|
|
+my $cumulative_total = 0; |
131 |
|
|
+ |
132 |
|
|
+open HOLDOVER, ">&5" and select HOLDOVER; |
133 |
|
|
+ |
134 |
|
|
+# |
135 |
|
|
+# Output cumulative values for intake the next time a log is processed |
136 |
|
|
+# |
137 |
|
|
+for my $c (keys %disp) |
138 |
|
|
+{ |
139 |
|
|
+ $disp{$c}->{cum} = $disp{$c}->{curr}; |
140 |
|
|
+ $current_total = $disp{$c}->{curr}; |
141 |
|
|
+ $cumulative_total = $disp{$c}->{cum}; |
142 |
|
|
+ |
143 |
|
|
+ printf "%-30.30s %s %12d\n", $c, $disp{$c}->{epoch}, $disp{$c}->{cum}; |
144 |
|
|
+} |
145 |
|
|
+ |
146 |
|
|
+# |
147 |
|
|
+# Output current logfile stats |
148 |
|
|
+# |
149 |
|
|
+ |
150 |
|
|
+my $current_elapsed = tai64diff($last_timestamp, $first_timestamp); |
151 |
|
|
+ |
152 |
|
|
+printf "# |
153 |
|
|
+# Most recent logfile |
154 |
|
|
+# ------------------- |
155 |
|
|
+# |
156 |
|
|
+# Start : %s |
157 |
|
|
+# Finish : %s |
158 |
|
|
+# Elapsed: %s |
159 |
|
|
+# |
160 |
|
|
+# Total transactions : %9d |
161 |
|
|
+# Average tx per hour: %9d |
162 |
|
|
+", |
163 |
|
|
+ tai64utc($first_timestamp), |
164 |
|
|
+ tai64utc($last_timestamp), |
165 |
|
|
+ seconds_to_days($current_elapsed), |
166 |
|
|
+ $current_total, |
167 |
|
|
+ $current_total / ($current_elapsed / 3600), |
168 |
|
|
+ ; |
169 |
|
|
+ |
170 |
|
|
+# |
171 |
|
|
+# Output cumulative log stats |
172 |
|
|
+# |
173 |
|
|
+my $cumulative_elapsed = tai64diff($last_timestamp, $disp{'LOGFILE_EPOCH'}->{epoch}); |
174 |
|
|
+ |
175 |
|
|
+printf "# |
176 |
|
|
+# Cumulative Totals |
177 |
|
|
+# ----------------- |
178 |
|
|
+# |
179 |
|
|
+# Start : %s |
180 |
|
|
+# Finish : %s |
181 |
|
|
+# Elapsed: %s |
182 |
|
|
+# |
183 |
|
|
+# Total transactions : %12d |
184 |
|
|
+# Average tx per hour: %12d |
185 |
|
|
+", |
186 |
|
|
+ tai64utc($disp{'LOGFILE_EPOCH'}->{epoch}), |
187 |
|
|
+ tai64utc($last_timestamp), |
188 |
|
|
+ seconds_to_days($cumulative_elapsed), |
189 |
|
|
+ $cumulative_total, |
190 |
|
|
+ $cumulative_total / ($cumulative_elapsed / 3600), |
191 |
|
|
+ ; |
192 |
|
|
+ |
193 |
|
|
+ |
194 |
|
|
+# |
195 |
|
|
+# Output per-plugin stats |
196 |
|
|
+# |
197 |
|
|
+ |
198 |
|
|
+print "# |
199 |
|
|
+# Most Recent Logfile Cumulative Totals |
200 |
|
|
+# Disposition (plugin) Total Avg/Day Total Avg/Day |
201 |
|
|
+# ----------------------------------------------------------------------------\n"; |
202 |
|
|
+ |
203 |
|
|
+my $printf_format = "# %-30.30s %6d %3d%% %8d %10d %3d%% %8d\n"; |
204 |
|
|
+ |
205 |
|
|
+foreach my $c (sort { $disp{$b}->{curr} <=> $disp{$a}->{curr} } keys %disp) |
206 |
|
|
+{ |
207 |
|
|
+ next if ($c eq 'LOGFILE_EPOCH'); |
208 |
|
|
+ |
209 |
|
|
+ printf $printf_format, |
210 |
|
|
+ $c, |
211 |
|
|
+ $disp{$c}->{curr}, |
212 |
|
|
+ $disp{$c}->{curr} / $current_total * 100, |
213 |
|
|
+ $disp{$c}->{curr} / ($current_elapsed / 86400), |
214 |
|
|
+ $disp{$c}->{cum}, |
215 |
|
|
+ $disp{$c}->{cum} / $cumulative_total * 100, |
216 |
|
|
+ $disp{$c}->{cum} / (tai64diff($last_timestamp, $disp{$c}->{epoch}) / 86400), |
217 |
|
|
+ ; |
218 |
|
|
+} |
219 |
|
|
+ |
220 |
|
|
+print "# ----------------------------------------------------------------------------\n"; |
221 |
|
|
+printf $printf_format, |
222 |
|
|
+ 'TOTALS', |
223 |
|
|
+ $current_total, |
224 |
|
|
+ 100, |
225 |
|
|
+ $current_total / ($current_elapsed / 86400), |
226 |
|
|
+ $cumulative_total, |
227 |
|
|
+ 100, |
228 |
|
|
+ $cumulative_total / ($cumulative_elapsed / 86400), |
229 |
|
|
+ ; |
230 |
|
|
+ |
231 |
|
|
+exit 0; |
232 |
|
|
+ |
233 |
|
|
+ |
234 |
|
|
+sub tai64utc { |
235 |
|
|
+ my ($s) = @_; |
236 |
|
|
+ |
237 |
|
|
+ # @400000003f6c7bc5253bf98c |
238 |
|
|
+ # 0123456789012345678901234 |
239 |
|
|
+ # 0 1 2 |
240 |
|
|
+ # |-------------||------| |
241 |
|
|
+ if (substr($s, 0, 2) eq '@4') { |
242 |
|
|
+ my $ts = hex(substr($s, 2, 15)); |
243 |
|
|
+ $s = strftime('%Y-%m-%d %H:%M:%S', gmtime($ts)); |
244 |
|
|
+ } |
245 |
|
|
+ return $s; |
246 |
|
|
+} |
247 |
|
|
+ |
248 |
|
|
+# |
249 |
|
|
+# Return difference in seconds |
250 |
|
|
+# |
251 |
|
|
+sub tai64diff |
252 |
|
|
+{ |
253 |
|
|
+ my ($s1, $s2) = @_; |
254 |
|
|
+ |
255 |
|
|
+ # @400000003f6c7bc5253bf98c |
256 |
|
|
+ # 0123456789012345678901234 |
257 |
|
|
+ # 0 1 2 |
258 |
|
|
+ # |-------------||------| |
259 |
|
|
+ if (substr($s1, 0, 2) eq '@4' and substr($s2, 0, 2) eq '@4') |
260 |
|
|
+ { |
261 |
|
|
+ my $ts1 = hex(substr($s1, 2, 15)); |
262 |
|
|
+ my $ts2 = hex(substr($s2, 2, 15)); |
263 |
|
|
+ return $ts1 - $ts2; |
264 |
|
|
+ } |
265 |
|
|
+ else |
266 |
|
|
+ { |
267 |
|
|
+ return 0; |
268 |
|
|
+ } |
269 |
|
|
+} |
270 |
|
|
+ |
271 |
|
|
+ |
272 |
|
|
+# |
273 |
|
|
+# Return an english phrase representing a number of seconds |
274 |
|
|
+# |
275 |
|
|
+sub seconds_to_days |
276 |
|
|
+{ |
277 |
|
|
+ my ($secs) = @_; |
278 |
|
|
+ |
279 |
|
|
+ my $phrase = sprintf "%d days, ", ($secs / 86400); |
280 |
|
|
+ $secs %= 86400; |
281 |
|
|
+ $phrase .= sprintf "%d hours, ", ($secs / 3600); |
282 |
|
|
+ $secs %= 3600; |
283 |
|
|
+ $phrase .= sprintf "%d mins, %d secs", ($secs / 60), ($secs % 60); |
284 |
|
|
+} |
285 |
|
|
+ |