2 # postfix_grep greps postfix logs and returns all lines matching pattern and queueid from matching lines
3 # and is released under the terms of the GNU GPL version 3, or any
4 # later version, at your option. See the file README and COPYING for
6 # Copyright 2013 by Don Armstrong <don@donarmstrong.com>.
17 postfix_grep - greps postfix logs and returns all lines matching pattern and queueid from matching lines
21 postfix_grep [options] [regex] [mailfile]
24 --regex, -e regular expression to match
25 --debug, -d debugging level (Default 0)
26 --help, -h display this help
27 --man, -m display manual
35 Regular expression to match. May be specified multiple times, in which
36 case a message must match all of them.
38 If given, all remaining options are considered to be mail files.
42 Debug verbosity. (Default 0)
46 Display brief usage information.
63 my %options = (debug => 0,
70 'debug|d+','help|h|?','man|m');
72 pod2usage() if $options{help};
73 pod2usage({verbose=>2}) if $options{man};
75 use IO::Uncompress::Gunzip;
77 $DEBUG = $options{debug};
79 if (not exists $options{regex}) {
80 $options{regex} = shift @ARGV if @ARGV;
82 $options{regex} = ref($options{regex})?$options{regex}:[$options{regex}];
85 if (not $options{regex}) {
86 push @USAGE_ERRORS,"You must supply a regex using -e or the command line";
89 pod2usage(join("\n",@USAGE_ERRORS)) if @USAGE_ERRORS;
92 for my $regex (@{$options{regex}}) {
93 $regexes{$regex} = qr/\Q$regex\E/;
98 my $buffer_size=10000;
101 # use undef as a special stdin holder
106 for my $file (@ARGV) {
107 my $fh = IO::Uncompress::Gunzip->new(defined $file ? $file:\*STDIN,
110 or die "IO::Uncompress::Gunzip failed: $IO::Uncompress::Gunzip::GunzipError";
115 for my $regex (keys %regexes) {
116 if ($line !~ $regexes{$regex}) {
121 my $queue_id = parse_queue_id($line);
122 $postfix_ids{$queue_id} = 1 if defined $queue_id;
124 output_and_update_buffer(\%regexes,\%postfix_ids,\@line_buffer,$buffer_size,$line);
126 while (@line_buffer) {
127 output_if_match(\%regexes,\%postfix_ids,\@line_buffer);
130 print Dumper(\%postfix_ids);
137 # /^(?<date>.+?) # date
138 # \s(?<hostname>\S+)# hostname
139 # \spostfix\/(?<process_name>[^[]+) #process
140 # \[(?<pid>[^\]]+)\]:\s #pid
141 # (?<queue_id>[A-F0-9]+)\:\s
144 # return $+{queue_id}
149 \spostfix\/([^[]+) #process
151 ([A-F0-9]+)\:\s # queue_id
157 # Apr 28 07:18:43 golf postfix/cleanup[27095]: 94E4F27038:
160 sub output_and_update_buffer{
161 my ($regexes,$postfix_ids,$lb,$lb_max_size,$line) = @_;
162 if (@{$lb} > $lb_max_size) {
163 output_if_match($regexes,$postfix_ids,$lb);
168 sub output_if_match {
169 my ($regexes,$postfix_ids,$lb) = @_;
171 my $line = shift @{$lb};
172 return unless defined $line;
173 my $queue_id = parse_queue_id($line);
174 if (defined $queue_id and $postfix_ids->{$queue_id}) {
176 for my $regex (keys %{$regexes}) {
177 if ($line !~ $regexes->{$regex}) {