#
# http://www.fabiankeil.de/sourcecode/privoxy-log-parser/
#
-# $Id: privoxy-log-parser.pl,v 1.133 2012/07/27 17:37:00 fabiankeil Exp $
+# $Id: privoxy-log-parser.pl,v 1.148 2012/12/20 17:03:10 fabiankeil Exp $
#
# TODO:
# - LOG_LEVEL_CGI, LOG_LEVEL_ERROR, LOG_LEVEL_WRITE content highlighting
# hash key as input.
# - Add --compress and --decompress options.
#
-# Copyright (c) 2007-2010 Fabian Keil <fk@fabiankeil.de>
+# Copyright (c) 2007-2012 Fabian Keil <fk@fabiankeil.de>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
SHOW_FILTER_READIN_IN => 0,
SUPPRESS_EMPTY_LINES => 1,
SUPPRESS_SUCCESSFUL_CONNECTIONS => 1,
- SUPPRESS_ACCEPTED_CONNECTIONS => 1,
SUPPRESS_GIF_NOT_CHANGED => 1,
SUPPRESS_NEED_TO_DE_CHUNK_FIRST => 1,
Force => 'red',
Writing => 'light_green',
Received => 'yellow',
+ Actions => 'yellow',
# ----------------------
URL => 'yellow',
path => 'brown',
$c = highlight_matched_host($c, '(?<=to )[^\s]+');
- } elsif ($c =~ m/^accepted connection from .*/ or
+ } elsif ($c =~ m/^[Aa]ccepted connection from .*/ or
$c =~ m/^OK/) {
- # accepted connection from 10.0.0.1
+ # Privoxy 3.0.20:
+ # Accepted connection from 10.0.0.1 on socket 5
+ # Privoxy between 3.0.20 and 3.0.6:
+ # accepted connection from 10.0.0.1( on socket 5)?
# Privoxy 3.0.6 and earlier just say:
# OK
- return '' if SUPPRESS_ACCEPTED_CONNECTIONS;
- $c = highlight_matched_host($c, '(?<=connection from ).*');
+ $c = highlight_matched_host($c, '(?<=connection from )[^ ]*');
+ $c = highlight_matched_pattern($c, 'Number', '(?<=socket )\d+');
+
+ } elsif ($c =~ m/^Closing client socket/) {
+
+ # Closing client socket 5. Keep-alive: 0, Socket alive: 1. Data available: 0.
+ # Privoxy 3.0.20 and later
+ # Closing client socket 8. Keep-alive: 1. Socket alive: 0. Data available: 0. \
+ # Configuration file change detected: 0. Requests received: 11.
+
+ $c = highlight_matched_pattern($c, 'Number', '(?<=socket )\d+');
+ $c = highlight_matched_pattern($c, 'Number', '(?<=Keep-alive: )\d+');
+ $c = highlight_matched_pattern($c, 'Number', '(?<=Socket alive: )\d+');
+ $c = highlight_matched_pattern($c, 'Number', '(?<=available: )\d+');
+ $c = highlight_matched_pattern($c, 'Number', '(?<=detected: )\d+');
+ $c = highlight_matched_pattern($c, 'Number', '(?<=received: )\d+');
} elsif ($c =~ m/^write header to: .* failed:/) {
$c =~ s@(?<=received: )(\d+)@$h{'Number'}$1$h{'Standard'}@;
$c =~ s@(?<=read: )(\d+)@$h{'Number'}$1$h{'Standard'}@;
- } elsif ($c =~ m/^Continuing buffering headers/) {
+ } elsif ($c =~ m/^Continuing buffering (?:server )?headers/) {
# Continuing buffering headers. byte_count: 19. header_offset: 517. len: 536.
$c =~ s@(?<=byte_count: )(\d+)@$h{'Number'}$1$h{'Standard'}@;
$c =~ s@(?<=header_offset: )(\d+)@$h{'Number'}$1$h{'Standard'}@;
$c =~ s@(?<=len: )(\d+)@$h{'Number'}$1$h{'Standard'}@;
- # 3.0.15 and later:
- # Continuing buffering headers. Bytes most recently read: %d.
+ # 3.0.15 up to 3.0.19:
+ # Continuing buffering headers. Bytes most recently read: 498.
$c =~ s@(?<=read: )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+ # 3.0.20 and later:
+ # Continuing buffering server headers from socket 5. Bytes most recently read: 498.
+ $c =~ s@(?<=socket )(\d+)@$h{'Number'}$1$h{'Standard'}@;
} elsif ($c =~ m/^Received \d+ bytes while/) {
# Rejecting connection from 178.63.152.227. Maximum number of connections reached.
$c =~ s@(?<=onnection from )((?:\d+\.?){3}\d+)@$h{'Number'}$1$h{'Standard'}@;
- } elsif ($c =~ m/^(?:Reusing|Closing) server socket \d./ or
+ } elsif ($c =~ m/^(?:Reusing|Closing) server socket / or
$c =~ m/^No additional client request/) {
# Reusing server socket 4. Opened for 10.0.0.1.
# No additional client request received in time. \
# Closing server socket 4, initially opened for 10.0.0.1.
# No additional client request received in time on socket 29.
+ # Privoxy 3.0.20 and later
+ # Reusing server socket 7 connected to www.privoxy.org. Total requests: 2.
+ # Closing server socket 6 connected to d.asset.soup.io. Keep-alive: 0.\
+ # Tainted: 1. Socket alive: 1. Timeout: 60. Configuration file change detected: 0.
$c =~ s@(?<= socket )(\d+)@$h{'Number'}$1$h{'Standard'}@;
- $c = highlight_matched_host($c, '(?<=for )[^\s]+(?=\.$)');
+ $c = highlight_matched_host($c, '(?<=for )[^\s]+(?=\.)');
+ $c = highlight_matched_host($c, '(?<=connected to )[^\s]+(?=\.)');
+ for my $number_pattern ('requests', 'Keep-alive', 'Tainted', ' alive', 'Timeout', 'detected') {
+ $c = highlight_matched_pattern($c, 'Number', '(?<='. $number_pattern . ': )\d+');
+ }
} elsif ($c =~ m/^Connected to /) {
} elsif ($c =~ m/^Waiting for the next client request/ or
$c =~ m/^The connection on server socket/ or
- $c =~ m/^Client request arrived in time /) {
+ $c =~ m/^Client request (?:\d+ )?(?:arrived in time|has been pipelined) /) {
# Waiting for the next client request on socket 3. Keeping the server \
# socket 12 to a.fsdn.com open.
# The connection on server socket 6 to upload.wikimedia.org isn't reusable. Closing.
- # Used by Privoxy 3.0.18 and later:
+ # Privoxy 3.0.20 and later:
+ # Client request 4 arrived in time on socket 7.
+ # Used by Privoxy 3.0.18 and 3.0.19:
# Client request arrived in time on socket 21.
# Used by earlier version:
# Client request arrived in time or the client closed the connection on socket 12.
+ # Client request 8 has been pipelined on socket 7 and the socket is still alive.
+ $c =~ s@(?<=request )(\d+)@$h{'Number'}$1$h{'Standard'}@;
$c =~ s@(?<=on socket )(\d+)@$h{'Number'}$1$h{'Standard'}@;
$c =~ s@(?<=server socket )(\d+)@$h{'Number'}$1$h{'Standard'}@;
$c = highlight_matched_host($c, '(?<=to )[^\s]+');
# Waiting for up to 4999 bytes from the client.
$c =~ s@(?<=up to )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+ } elsif ($c =~ m/^Optimistically sending /) {
+
+ # Optimistically sending 318 bytes of client headers intended for www.privoxy.org
+ $c =~ s@(?<=sending )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+ $c = highlight_matched_host($c, '(?<=for )[^\s]+');
+
} elsif ($c =~ m/^Stopping to watch the client socket/) {
# Stopping to watch the client socket. There's already another request waiting.
# Stopping to watch the client socket 5. There's already another request waiting.
$c =~ s@(?<=client socket )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+ } elsif ($c =~ m/^Drained \d+ bytes before closing/) {
+
+ # Drained 180 bytes before closing socket 6
+ $c =~ s@(?<=Drained )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+ $c =~ s@(?<=socket )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+
+ } elsif ($c =~ m/^Tainting client socket/) {
+
+ # Tainting client socket 7 due to unread data.
+ $c =~ s@(?<=socket )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+
+ } elsif ($c =~ m/^Shifting \d+ pipelined bytes/) {
+
+ # Shifting 360 pipelined bytes by 360 bytes
+ $c =~ s@(?<=Shifting )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+ $c =~ s@(?<=by )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+
} elsif ($c =~ m/^Looks like we / or
$c =~ m/^Unsetting keep-alive flag/ or
$c =~ m/^No connections to wait/ or
$c =~ m/^The server still wants to talk, but the client hung up on us./ or
$c =~ m/^The server didn't specify how long the connection will stay open/ or
$c =~ m/^There might be a request body. The connection will not be kept alive/ or
+ $c =~ m/^There better be a request body./ or
$c =~ m/^Done reading from the client\.$/) {
# Looks like we reached the end of the last chunk. We better stop reading.
# The server still wants to talk, but the client hung up on us.
# The server didn't specify how long the connection will stay open. Assume it's only a second.
# There might be a request body. The connection will not be kept alive.
- # Done reading from the client\.
+ # Privoxy 3.0.20 and later
+ # There better be a request body.
+ # Done reading from the client.
} else {
'Fatal error' => \&handle_loglevel_ignore,
'Writing' => \&handle_loglevel_ignore,
'Received' => \&handle_loglevel_ignore,
+ 'Actions' => \&handle_loglevel_ignore,
'Unknown log level' => \&handle_loglevel_ignore,
);
'Fatal error' => \&handle_loglevel_ignore,
'Writing' => \&handle_loglevel_ignore,
'Received' => \&handle_loglevel_ignore,
+ 'Actions' => \&handle_loglevel_ignore,
'Unknown log level' => \&handle_loglevel_ignore
);