Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Need help with parse efficiency 1

Status
Not open for further replies.

mlibeson

Programmer
Mar 6, 2002
311
US
Can anyone help to increase the speed of my code snippet. I use the code to parse a web log that is formatted in any variation of the Common Log Format (CLF). It breaks every record into fields that I will use for analysis later.

Code:
               $main::tlp = $main::readline;
               $main::currentField = 0;
               @main::line = ();
               $main::spaceTest   = 0;
               $main::quoteTest   = 0;
               $main::squoteTest  = 0;
               $main::bracketTest = 0;
               $main::parenTest   = 0;

               while (length($main::tlp) > 0) {
                    $main::c = substr($main::tlp,0,1);
                    $main::tlp = substr($main::tlp,1);
                    if ($main::spaceTest > 0) {
                         if ($main::c =~ /^\s/) {
                              ### End of field.
                              $main::spaceTest = 0;
                              $main::tlp =~ s/^\s+//;
                              $main::currentField++;
                         } elsif ($main::c eq "\\") {
                              ### Next character does not terminate field if ' '.
                              if ($main::tlp =~ /^\s/) {
                                   $main::line[$main::currentField] .= $main::c . ' ';
                              } else {
                                   $main::line[$main::currentField] .= $main::c;
                              }
                         } else {
                              ### Still in current field.
                              $main::line[$main::currentField] .= $main::c;
                         }
                    } elsif ($main::quoteTest > 0) {
                         if (($main::c eq '"') && ($main::tlp =~ /^(\s+|$)/)) {
                              ### End of field.
                              $main::line[$main::currentField] .= '"';
                              $main::quoteTest = 0;
                              $main::tlp =~ s/^\s+//;
                              $main::currentField++;
                         } elsif ($main::c eq "\\") {
                              ### Next character does not terminate field if '"'.
                              if ($main::tlp =~ /^\"/) {
                                   $main::line[$main::currentField] .= $main::c . '"';
                                   $main::tlp =~ s/^\"//;
                              } else {
                                   $main::line[$main::currentField] .= $main::c;
                              }
                         } else {
                              ### Still in current field.
                              $main::line[$main::currentField] .= $main::c;
                         }
                    } elsif ($main::squoteTest > 0) {
                         if (($main::c eq '\'') && ($main::tlp =~ /^(\s+|$)/)) {
                              ### End of field.
                              $main::line[$main::currentField] .= '\'';
                              $main::squoteTest = 0;
                              $main::tlp =~ s/^\s+//;
                              $main::currentField++;
                         } elsif ($main::c eq "\\") {
                              ### Next character does not terminate field if '\''.
                              if ($main::tlp =~ /^\'/) {
                                   $main::line[$main::currentField] .= $main::c . '\'';
                                   $main::tlp =~ s/^\'//;
                              } else {
                                   $main::line[$main::currentField] .= $main::c;
                              }
                         } else {
                              ### Still in current field.
                              $main::line[$main::currentField] .= $main::c;
                         }
                    } elsif ($main::bracketTest > 0 ) {
                         if ($main::c eq ']') {
                              ### End of field.
                              $main::line[$main::currentField] .= ']';
                              $main::bracketTest = 0;
                              $main::tlp =~ s/^\s+//;
                              $main::currentField++;
                         } elsif ($main::c eq "\\") {
                              ### Next character does not terminate field if ']'.
                              if ($main::tlp =~ /^\]/) {
                                   $main::line[$main::currentField] .= $main::c . ']';
                                   $main::tlp =~ s/^\]//;
                              } else {
                                   $main::line[$main::currentField] .= $main::c;
                              }
                         } else {
                              ### Still in current field.
                              $main::line[$main::currentField] .= $main::c;
                         }
                    } elsif ($main::parenTest > 0 ) {
                         if ($main::c eq '(') {
                              ### Next ')' character does not terminate field if '('.
                              $main::line[$main::currentField] .= '(';
                              $main::parenTest++;
                         } elsif ($main::c eq ')') {
                              ### Check End of field.
                              if ($main::parenTest > 1) {
                                   $main::line[$main::currentField] .= ')';
                                   $main::parenTest--;
                              } else {
                                   $main::line[$main::currentField] .= ')';
                                   $main::parenTest = 0;
                                   $main::tlp =~ s/^\s+//;
                                   $main::currentField++;
                              }
                         } elsif ($main::c eq "\\") {
                              ### Next character does not terminate field if ')'.
                              if ($main::tlp =~ /^\)/) {
                                   $main::line[$main::currentField] .= $main::c . ')';
                                   $main::tlp =~ s/^\)//;
                              } else {
                                   $main::line[$main::currentField] .= $main::c;
                              }
                         } else {
                              ### Still in current field.
                              $main::line[$main::currentField] .= $main::c;
                         }
                    } else {
                         if ($main::c =~ /^\s$/) {
                              if ($main::tlp !~ /^\s*[\"\'\[\(]/) { $main::spaceTest++; }
                              $main::tlp =~ s/^\s+//;
                              $main::currentField++;
                         } elsif (($main::c eq '"') && ($main::spaceTest == 0)) {
                              $main::quoteTest++;
                              $main::line[$main::currentField] = '"';
                              $main::tlp =~ s/^\s+//;
                         } elsif (($main::c eq '\'') && ($main::spaceTest == 0)) {
                              $main::squoteTest++;
                              $main::line[$main::currentField] = '\'';
                              $main::tlp =~ s/^\s+//;
                         } elsif (($main::c eq '[') && ($main::spaceTest == 0)) {
                              $main::bracketTest++;
                              $main::line[$main::currentField] = '[';
                              $main::tlp =~ s/^\s+//;
                         } elsif (($main::c eq '(') && ($main::spaceTest == 0)) {
                              $main::parenTest++;
                              $main::line[$main::currentField] = '(';
                              $main::tlp =~ s/^\s+//;
                         } else {
                              $main::spaceTest++;
                              $main::line[$main::currentField] .= $main::c;
                         }
                    }
               }

Your help is appreciated.

Thank you.


Michael Libeson
 
Michael, hi.

Now this isn't pretty - but it has the advantage of being very short. How does it compare for speed?

I'd never heard of the CLF so I got a definition from which I hope matches the file format you're using.
Code:
my ($remotehost, $rfc, $user, $time, $request, $status, $bytes);

while(<DATA>){
	
	chomp;	

	/\s+/; $remotehost = $`; $_ = $';
	/\s+/; $rfc = $`;        $_ = $';
	/\s+/; $authuser = $`;   $_ = $';
	/\[/;                    $_ = $';
	/\]/; $time = $`;        $_ = $';
	/"/;                     $_ = $';
	/"/; $request = $`;      $_ = $';

	s/^\s+//g;
	/\s+/; $status = $`;     $_ = $';
	$bytes = $_;
	

	print "remotehost=$remotehost\n";
	print "rfc=$rfc\n";
	print "authuser=$authuser\n";
	print "time=$time\n";
	print "request=$request\n";
	print "status=$status\n";
	print "bytes=$bytes\n";
	last;

}


__END__
bacuslab.pr.mcs.net - - [01/Jan/1997:12:57:45 -0600] "GET /~bacuslab/ HTTP/1.0" 304 0
bacuslab.pr.mcs.net - - [01/Jan/1997:12:57:49 -0600] "GET /~bacuslab/BLI_Logo.jpg HTTP/1.0" 200 8210
bacuslab.pr.mcs.net - - [01/Jan/1997:12:57:49 -0600] "GET /~bacuslab/BulletA.gif HTTP/1.0" 304 0
bacuslab.pr.mcs.net - - [01/Jan/1997:12:57:50 -0600] "GET /~bacuslab/Email4.gif HTTP/1.0" 304 0
bacuslab.pr.mcs.net - - [01/Jan/1997:12:57:50 -0600] "GET /~bacuslab/HomeCount.xbm HTTP/1.0" 200 890
151.99.190.27 - - [01/Jan/1997:13:06:51 -0600] "GET /~bacuslab HTTP/1.0" 301 -4
151.99.190.27 - - [01/Jan/1997:13:06:52 -0600] "GET /~bacuslab/ HTTP/1.0" 200 1779
151.99.190.27 - - [01/Jan/1997:13:06:54 -0600] "GET /~bacuslab/BLI_Logo.jpg HTTP/1.0" 200 8210
151.99.190.27 - - [01/Jan/1997:13:06:54 -0600] "GET /~bacuslab/BulletA.gif HTTP/1.0" 200 1151
151.99.190.27 - - [01/Jan/1997:13:06:54 -0600] "GET /~bacuslab/Email4.gif HTTP/1.0" 200 3218
151.99.190.27 - - [01/Jan/1997:13:06:54 -0600] "GET /~bacuslab/HomeCount.xbm HTTP/1.0" 200 890
151.99.190.27 - - [01/Jan/1997:13:07:21 -0600] "GET /~bacuslab/celsheet.html HTTP/1.0" 200 13276
151.99.190.27 - - [01/Jan/1997:13:07:25 -0600] "GET /~bacuslab/CellSheet.xbm HTTP/1.0" 200 356
151.99.190.27 - - [01/Jan/1997:13:07:38 -0600] "GET /~bacuslab/celsort1.gif HTTP/1.0" 200 24576
151.99.190.27 - - [01/Jan/1997:13:07:38 -0600] "GET /~bacuslab/cvscreen.gif HTTP/1.0" 200 24576
151.99.190.27 - - [01/Jan/1997:13:07:38 -0600] "GET /~bacuslab/celsort2.gif HTTP/1.0" 200 32768
151.99.190.27 - - [01/Jan/1997:13:07:38 -0600] "GET /~bacuslab/csfull20.gif HTTP/1.0" 200 40960

Mike

To err is human,
but to really foul things up -
you require a man Mike.

Want to get great answers to your Tek-Tips questions? Have a look at faq219-2884
 
Or with a single regex. I added some comments for (hopefully) clarity.

This uses the same data that Mike found.

Code:
while (<DATA>) {
    /^([\w\.]+)\s+      # Remote Host
        (.+?)\s+        # RFC931 - Remote User
        (.+?)\s+        # authuser
        (\[[^\]]+\])\s+ # date
        (\"[^\"]+\")\s+ # request
        (\d+)\s+        # status
        (\d+)\s+        # bytes
        /x;             # allows for comments & ws in regex

     my ($rmt_host, $rfc931, $authuser, $date, $request, $status, $bytes) = ($1,$2,$3,$4,$5,$6,$7);
}

If you want to get rid of the []'s and the ""'s around the date and request, respectively, the appropriate sections of the regexs can be easily modified.
 
It's more important that the code be maintainable, than fast
IMHO

Is speed such a real issue in log parsing? mebbee I missed a decade ...

--Paul

--Mike too harsh man, M-i-k-e- , lighten up


Nancy Griffith - songstress extraordinaire,
and composer of the snipers anthem "From a distance ...
 
Harsh? eh?

What did I do? Seriously.

Mike

To err is human,
but to really foul things up -
you require a man Mike.

Want to get great answers to your Tek-Tips questions? Have a look at faq219-2884

 
Thank you all for your replies. I have tried shortened versions like the ones proposed. Here is the dilema:

1) Sometimes fields that contain strings do not have the double quotes to delimit the field and sometimes they do.

2) Sometimes there are quotes within the field.

The above 2 items are the reason why my code looks char by char. I look for each fields delimiter on an individual basis. If the field is not surrounded by [], (), "", or '', then I use whitespace to delimit the field. If it is one of the sets mentioned, then I must make sure not to use a matching char within the field. I check to make sure the char is not escaped first next I check to see if there is a whitespace after the char. If this is true I consider it to be the end delimiter.

I hope this helps clear things up a little as to the reason why there is so much code.

Thanks again.


Michael Libeson
 
Ok - Post some of the variant records Michael.

Mike

To err is human,
but to really foul things up -
you require a man Mike.

Want to get great answers to your Tek-Tips questions? Have a look at faq219-2884

 
There is one thing I left out. The request field actualy has 4 parts to it. The method, uri, query, and the protocol.

Here are some samples taken from MikeLacey's earlier in the post:

Code:
bacuslab.pr.mcs.net - - [01/Jan/1997:12:57:45 -0600] "GET /~bacuslab/cgi-bin/script.pl?get="hello" HTTP/1.0" 304 0 refer="[URL unfurl="true"]www.google.com"[/URL] agent=(mozilla)
bacuslab.pr.mcs.net - - [01/Jan/1997:12:57:49 -0600] "GET /~bacuslab/BLI_Logo.jpg HTTP/1.0" 200 8210 "[URL unfurl="true"]http://www.google.com/index.cgi?"[/URL] "Mozilla/1.0(spider "version 1.0")"
bacuslab.pr.mcs.net - - [01/Jan/1997:12:57:49 -0600] "GET /~bacuslab/BulletA.gif HTTP/1.0" 304 0 - Mozilla
bacuslab.pr.mcs.net - - [01/Jan/1997:12:57:50 -0600] "GET /~bacuslab/Email4.gif HTTP/1.0" 304 0 [URL unfurl="true"]www.google.com[/URL] -
bacuslab.pr.mcs.net - - [01/Jan/1997:12:57:50 -0600] "GET /~bacuslab/HomeCount.xbm HTTP/1.0" 200 890 "" 'mc'speedy'
151.99.190.27 - - [01/Jan/1997:13:06:51 -0600] "GET /~bacuslab HTTP/1.0" 301 4 - -
151.99.190.27 - - [01/Jan/1997:13:06:52 -0600] "GET /~bacuslab/ HTTP/1.0" 200 1779 - "mozilla"


Michael Libeson
 
New to Perl, loving it. My approach to this problem was to use split() a couple of times, tidy up the pieces.

Code:
while(<LOG>) {
  ($vIP,$rfc931,$username,$timestamp,$tz,
   $request,$uri,$protocol,$sc,$size) = split;
  ($x,$x,$x,$referrer,$x,$uaString)   = split(/"/);

vIP is visitor IP addy, tz is timezone, sc is status code, uaString is user agent.

Followed by --
Code:
  $timestamp        =~ s/\[//go;
  ($logDate,$hms)   = split(/:/,$timestamp,2);
  $tz               =~ s/\]//go;
  ($hh,$mm,$ss)     = split(/:/,$hms);
  ($dd,$txtMon,$yy) = split(/\//,$logDate);

to pick out date stuff.

Finally, pass referrer, uri, and uaString through logic to escape single quotes and commas and the record is ready for CSV output.

Efficient? Legible? Seems to be holding up so far.
 
Ok, so that's Extended Common Log Format then - from what that web site says.

From your example, the request string with the embedded quotes:

"GET /~bacuslab/cgi-bin/script.pl?get="hello" HTTP/1.0"

My problem with parsing that is that the second " character ("hello) could be seen as ending the field. On possible way around it is that it is not followed by white-space - so the terminating " char *could* be the even-numbered-quote-which-is-followed-by-whitespace...

If that rule works you could /"/ and $_=$' your way through the string looking for an even numbered " which is followed by white-space to terminate the field.

Mike

To err is human,
but to really foul things up -
you require a man Mike.

Want to get great answers to your Tek-Tips questions? Have a look at faq219-2884

 
MikeLacey

Counting quotes is an interesting view, but leads to possible issues depending on the number of quotes from query strings in the request and refer fields, as well as the user-agent field. Cookies complicates this even further. I need to be able to process varying logs formats at once, so some may be extended format, some may not. Some may have additional data where not every record has the same number of fields. I think AWK may handle this already, but is not available to me. If someone new the algorithm that AWK uses to parse a line, it might help.

Thanks for the option.


Michael Libeson
 
MikeLacey thanks again for another attempt. I have tried third party tools in order to analyze web traffic, but there were always problems with records being dropped because they were not parsed correctly. There are also features I need that are not in other software packages or one has some, but not all features. I need to cutomize the tool often, so PERL has been my choice of processing with a database back-end. The parse code is a small fragment of a large application I have written and I am just trying to increase the application throughput. The segment is one of the pieces that although works 99.99% of the time, it takes longer to process the records than to do a regex to find the fields. The reason I am not able to use the regex is because I woul need to know which regex to use for each line being processed. The code I have has been the most accurate solution, I just need to improve its speed.


Michael Libeson
 
Hmm *wry smile* not very "Common" is it? This CLF...

I'll look again at your code.

Mike

To err is human,
but to really foul things up -
you require a man Mike.

Want to get great answers to your Tek-Tips questions? Have a look at faq219-2884

 
Thanks MikeLacey. Yes CLF is not very CLF these days as it has become more configurable. The log format depends on how the administrator wants to see the log data. The same goes for IIS.


Michael Libeson
 
Michael, hi.

I might have something that could make it run a little faster.

I've been doing some, mostly unproductive, fiddling to do with " and ' processing.

I got to the point of realising (again) that you need to check the character *after* a " to see whether it's the start of an embedded quoted string or the end of the current quoted string. Ok.

So I went and looked at how you're setting $c; now you're calling substr() to work your way through the current $tlp and it occurs to me that it may be more efficient to convert $tlp to an array @tlp where every element is a single character from $tlp and work your way through that instead.

Working your way through an array would almost certainly be faster than two calls to substr() per $tlp particularly as the second call involves the copying of $tlp itself.

Holding the current $tlp in an array would also let you deal with embedded quoted strings by allowing you to easily examinine the next character.

Mike

To err is human,
but to really foul things up -
you require a man Mike.

Want to get great answers to your Tek-Tips questions? Have a look at faq219-2884

 
MikeLacey,

Good point. I have looked at it so many ways that I seem to have over looked the obvious.

I am going to try and create an array using the following and see if it will increase the speed:

@tlp = split(//,$main::readline);

I can also use the array to skip iterations when characters are escaped.

I was also thinking if I stayed with the original plan, but allowed to bypass iterations when I had a non-space delimiter by pushing all characters into the same field up until the "\" or matching delimter. Then I would not be processing the string by every character.

I'll try both ways and see what runs better.


Michael Libeson
 
allowed to bypass iterations when I had a non-space delimiter"

Yes, I was thinking that as well - I'd change to an array but still do it char by char at first though :) Whenever I change too much at once my head begins to hurt.

Mike

To err is human,
but to really foul things up -
you require a man Mike.

Want to get great answers to your Tek-Tips questions? Have a look at faq219-2884

 
> I think AWK may handle this already, but is not available to me.

Awk or nawk or mawk or gawk must be available for every system that's not a toy. See if you have nawk.

[tt]
BEGIN { SP = "[ \t\n]+"; NQ = "[^\"]*" }

{
remotehost = word(SP)
rfc = word(SP)
authuser = word(SP)
word("[[]")
time = word("[]]")
word("\"")

# Assumes the embedded quote starts with `="'.
r = "^(" NQ "=\"" NQ "\")*" NQ
# Assumes opening embedded quote
# not followed by whitespace.
r = "^(" NQ "\"([^ \t\n]" NQ ")?\")*" NQ

request = Match( $0, r )
$0 = substr( RRIGHT, 2 )
word( "^" SP )
status = word(SP)
bytes = word( SP "|$" )

print remotehost " | " rfc " | " authuser " | " time
print request " <<<"
print status " | " bytes
}

function word(re)
{ $0 = Match( $0, re, 3 )
return RLEFT
}

function Match( s, r, which )
{ match( s, r )
return _match( s, which )
}
function _match( s, which )
{ if ( RSTART )
{ RMATCH = substr(s, RSTART, RLENGTH )
RLEFT = substr(s, 1, RSTART - 1)
RRIGHT = substr(s, RSTART + RLENGTH )
}
else
{ RLEFT = s
RMATCH = RRIGHT = ""
}
if (!which) return RMATCH
if (1==which) return RLEFT
if (2==which) return RMATCH
return RRIGHT
}
[/tt]
When fed this:

bacuslab.pr.mcs.net - - [01/Jan/1997:12:57:45 -0600] "GET /~bacuslab/cgi-bin/script.pl?get="hello" HTTP/1.0" 304 0 refer=" agent=(mozilla)
bacuslab.pr.mcs.net - - [01/Jan/1997:12:57:49 -0600] "GET /~bacuslab/BLI_Logo.jpg HTTP/1.0" 200 8210 " "Mozilla/1.0(spider "version 1.0")"
bacuslab.pr.mcs.net - - [01/Jan/1997:12:57:49 -0600] "GET /~bacuslab/BulletA.gif HTTP/1.0" 304 0 - Mozilla
bacuslab.pr.mcs.net - - [01/Jan/1997:12:57:50 -0600] "GET /~bacuslab/Email4.gif HTTP/1.0" 304 0 -
bacuslab.pr.mcs.net - - [01/Jan/1997:12:57:50 -0600] "GET /~bacuslab/HomeCount.xbm HTTP/1.0" 200 890 "" 'mc'speedy'
151.99.190.27 - - [01/Jan/1997:13:06:51 -0600] "GET /~bacuslab HTTP/1.0?get="hello"?put="bye" HTTP/1.0" 301 4 - -
151.99.190.27 - - [01/Jan/1997:13:06:52 -0600] "GET /~bacuslab/ HTTP/1.0" 200 1779 - "mozilla"

the output is
[tt]
bacuslab.pr.mcs.net | - | - | 01/Jan/1997:12:57:45 -0600
GET /~bacuslab/cgi-bin/script.pl?get="hello" HTTP/1.0 <<<
304 | 0
bacuslab.pr.mcs.net | - | - | 01/Jan/1997:12:57:49 -0600
GET /~bacuslab/BLI_Logo.jpg HTTP/1.0 <<<
200 | 8210
bacuslab.pr.mcs.net | - | - | 01/Jan/1997:12:57:49 -0600
GET /~bacuslab/BulletA.gif HTTP/1.0 <<<
304 | 0
bacuslab.pr.mcs.net | - | - | 01/Jan/1997:12:57:50 -0600
GET /~bacuslab/Email4.gif HTTP/1.0 <<<
304 | 0
bacuslab.pr.mcs.net | - | - | 01/Jan/1997:12:57:50 -0600
GET /~bacuslab/HomeCount.xbm HTTP/1.0 <<<
200 | 890
151.99.190.27 | - | - | 01/Jan/1997:13:06:51 -0600
GET /~bacuslab HTTP/1.0?get="hello"?put="bye" HTTP/1.0 <<<
301 | 4
151.99.190.27 | - | - | 01/Jan/1997:13:06:52 -0600
GET /~bacuslab/ HTTP/1.0 <<<
200 | 1779
[/tt]
 
Since the opening quotation mark of the embedded quoted string in the request field is preceded by =, a regular expression can handle it.

In Awk:
[tt]
{
remotehost = $1
rfc = $2
authuser = $3
split( $0, a, / \[|\] +/ )
time = a[2]
$0 = a[3]
match( $0, /^"([^"]*(="[^"]*")*)*"/ )
request = substr($0,RSTART+1,RLENGTH-2)
$0 = substr($0,RSTART+RLENGTH)
status = $1
bytes = $2
print remotehost, rfc, authuser, time, request,
status, bytes
}
BEGIN { OFS = "|" }
[/tt]

In Ruby:

$_ =~
/(\S+) (\S+) (\S+) \[(.*?)\] "((?:[^"]*?(?:="[^"]*")*)*)"\s+(\S+) (\S+)/
remotehost,rfc,authuser,time,request,status,bytes = $~[1..7]
printf "%s|%s|%s|%s|%s|%s|%s\n",
remotehost,rfc,authuser,time,request,status,bytes



bacuslab.pr.mcs.net - - [01/Jan/1997:12:57:45 -0600] "GET /~bacuslab/cgi-bin/script.pl?get="hello" HTTP/1.0" 304 0 refer=" agent=(mozilla)
151.99.190.27 - - [01/Jan/1997:13:06:51 -0600] "GET /~bacuslab HTTP/1.0?get="hello"?foo="bye" HTTP/1.0" 301 4 - -
bacuslab.pr.mcs.net - - [01/Jan/1997:12:57:49 -0600] "GET /~bacuslab/BLI_Logo.jpg HTTP/1.0" 200 8210 " "Mozilla/1.0(spider "version 1.0")"
bacuslab.pr.mcs.net - - [01/Jan/1997:12:57:49 -0600] "GET /~bacuslab/BulletA.gif HTTP/1.0" 304 0 - Mozilla
bacuslab.pr.mcs.net - - [01/Jan/1997:12:57:50 -0600] "GET /~bacuslab/Email4.gif HTTP/1.0" 304 0 -
bacuslab.pr.mcs.net - - [01/Jan/1997:12:57:50 -0600] "GET /~bacuslab/HomeCount.xbm HTTP/1.0" 200 890 "" 'mc'speedy'
151.99.190.27 - - [01/Jan/1997:13:06:52 -0600] "GET /~bacuslab/ HTTP/1.0" 200 1779 - "mozilla"

becomes

bacuslab.pr.mcs.net|-|-|01/Jan/1997:12:57:45 -0600|GET /~bacuslab/cgi-bin/script.pl?get="hello" HTTP/1.0|304|0
151.99.190.27|-|-|01/Jan/1997:13:06:51 -0600|GET /~bacuslab HTTP/1.0?get="hello"?foo="bye" HTTP/1.0|301|4
bacuslab.pr.mcs.net|-|-|01/Jan/1997:12:57:49 -0600|GET /~bacuslab/BLI_Logo.jpg HTTP/1.0|200|8210
bacuslab.pr.mcs.net|-|-|01/Jan/1997:12:57:49 -0600|GET /~bacuslab/BulletA.gif HTTP/1.0|304|0
bacuslab.pr.mcs.net|-|-|01/Jan/1997:12:57:50 -0600|GET /~bacuslab/Email4.gif HTTP/1.0|304|0
bacuslab.pr.mcs.net|-|-|01/Jan/1997:12:57:50 -0600|GET /~bacuslab/HomeCount.xbm HTTP/1.0|200|890
151.99.190.27|-|-|01/Jan/1997:13:06:52 -0600|GET /~bacuslab/ HTTP/1.0|200|1779
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top