Thread Perl Speicherprobleme mit großen Dateien (W32 Version) (31 answers)
Opened by Mapache at 2009-05-05 14:38

Gast Mapache
 2009-05-05 21:24
#121258 #121258
Geniale Idee!

Ich und will nun herausbekommen, wie die mysteriöse/überlange Zeile zumindest anfängt.
Habe es dazu folgendermaßen angepasst:

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#!/usr/bin/perl
use strict;
use warnings;
use FileHandle;

my $infile=shift;

my $ftp_file        = "ifwprod-ftp.log";
my $dns_file        = "ifwprod-dns.log";
my $web_file        = "ifwprod-web.log";
my $mail_file       = "ifwprod-mail.log";
my $other_file      = "ifwprod-other.log";

my $ftp = new FileHandle "> $ftp_file";
my $dns = new FileHandle "> $dns_file";
my $web = new FileHandle "> $web_file";
my $mail = new FileHandle "> $mail_file";
my $other = new FileHandle "> $other_file";

my $fh = new FileHandle($infile,'r');
die "ERROR Open $infile ($!)\n" unless(defined($fh));
my $data="";
my $line;
my $buff;
my $count; 
while(!$fh->eof())
{
  $line='';
  # Daten einlesen solange kein "\n" oder "\r" kommt
  # overflow couter
  my $oc = 0;
  while(index($data,"\x0A") < 0  && index($data,"\x0D") < 0 )
  {
    $fh->read($buff,1024); # anpassen wenn es zu langsam ist...
    $data.=$buff;
    $oc++;
    if ( $oc gt 1000 ) {
      print "Overflow detected at line $count:\n";
      print $data."\n";
      print $buff."\n";
      exit(1);
    }
  }
  # erste Zeile Heraussplitten ("\n" und "\r") gehen verloren
  # das läuft solange wie $data noch Newlines enthalten
  # das "split" ist recht langsam, mit "index" und "substr" währe es schneller
  ($line,$data)=split(/[\x0A\x0D]+/,$data,2);
  #print $line."\n\n";
  working($line);
  $count++;
  if ( ! ( $count % 10000 ) ) { print "$count lines done\n"; }

}
# jetzt noch den Rest verarbeiten...
working($_) for(split(/[\x0A\x0D]+/,$data));

close($fh);

close $ftp;
close $dns;
close $web;
close $mail;
close $other;

exit(0);

#########################################
# Verarbeiten ###########################
#########################################
sub working
{
  $_ = shift;
  # arbeite damit ...
  
    # FTP
    if ( /dstport: 21 / || /dstport: 20 / || /srcport: 21 / || /srcport: 20 / ||
         /dstport=21,/ || /dstport=20,/ || /srcport=21,/ || /srcport=20,/           
       )    
    {
        print $ftp $_ or die $!;
    }
    # DNS
    elsif ( /dstport: 53 / || /srcport: 53 / || /dstport=53,/ || /srcport=53,/ ) {
        print $dns $_ or die $!;
    }
    # WEB
    elsif (
        (/srcip: 10\.1\.1\.1[0-9]?/ && ( /dstport: 80 / || /dstport: 53 / || /dstport: 443 / ))
        ||
        (/srcip=10\.1\.1\.1[0-9]?,/ && ( /dstport=80,/ || /dstport=53,/ || /dstport=443,/ ))
    ) {
        print $web $_ or die $!;
    }
    # MAIL
    elsif ( /dstport: 25 / || /srcport: 25 / || /dstport=25,/ || /srcport=25,/ ) {
        print $mail $_ or die $!;
    }
    else {
      print $other $_ or die $!;
    }
  
}


Er spuckt mir aber nur genau 252 Zeichen aus.

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
1600000 lines done
1610000 lines done
1620000 lines done
1630000 lines done
1640000 lines done
1650000 lines done
1660000 lines done
1670000 lines done
1680000 lines done
1690000 lines done
Overflow detected at line 1695136:
Apr 27 09:08:32 abc12_ab0.net.intra.abc-firm.com auditd: Apr 27 07:08:32 2009 UTC f_http_proxy a_libproxycommon t_nettraffic p_major pid: 3060 ruid: 0 euid: 0 pgid: 3060 logid: 0 cmd: 'httpp' domain: htpp edomain: htpp hostname: abcd.net.abcde.abc-b


Ist das überhaupt eine Möglichkeit die "böse" Zeile zu checken? Oder mach ich was falsch?

View full thread Perl Speicherprobleme mit großen Dateien (W32 Version)