Reputation: 51
I am trying to parse a .log file with PHP. My program keeps ending with the "killed" message. I tried running my PHP program on two different servers with the same input .log file.
Ultimately I need to count the instances of a pattern in the .log file. This .log file is a text file with each line having various text. Each line will have a hyphen that will act as a field separator. Any text to the right of a dash "-" on a given line can be discounted and not considered.
I have a recursive function named "caller." I have tried re-writing the code to not use recursion. I had different problems with that approach.
I have tried saving my output to a variable or to a new file. Neither approach gave me a clear advantage. I do not think the output (saving up patterns according to my logic) is causing the memory issue.
I have a nested loop in the code. For each line of the .log file, I am examining each character left-to-right to find the dash "-".
The dmesg
command shows a line like this for each time I run the PHP program:
Out of memory in UB 999: OOM killed process 950 (php) score 0 ...
How can I re-write this to not end with a "killed" message?
(My code does not count the patterns yet. I am not ready to complete it. I just want to get to this half-way step where it does not end with the word "killed".)
Here is my code:
<?php
$filea = "good.log";
$newf = fopen("new.txt", "w");
$file = fopen($filea, "r");
$charnum = 0;
$numlines = 0;
$temp = fopen($filea, "r");
while(!feof($temp)){
$line = fgets($temp);
$numlines++;
}
fclose($temp);
function caller($newf, $fileline, $charnum){
if ($fileline[$charnum] == '-') {
$x = $charnum;
$stringx = "";
for ($h = 0; $h < $x; $h++){
$stringx = $stringx.$fileline[$h];
}
fwrite($newf, $stringx);
fwrite($newf, "\n");
echo $stringx;
}
else {
$charnum = $charnum + 1;
caller($newf, $fileline, $charnum);
}
}
for ($k = 0; $k < $numlines; $k = $k++) {
$fileline = fgets($file);
$charnum = 0;
caller($newf, $fileline, $charnum);
}
fclose($newf);
fclose($file);
?>
Upvotes: 1
Views: 1084
Reputation: 53563
If you're just trying to get the part of each line to the left of the dash, you can do it all in one line:
preg_match_all('/^([^-\n])\-/m', file_get_contents('good.log'), $matches);
After this, $matches[0]
will contain a list of the terms that match (including the dash) and $matches[1]
will contain the same list without the dash. For example, given:
one two - three - four
no dash on this line
five - six
seven - eight
Then, $matches[1]
will be an array containing: one two
, five
, seven
Upvotes: 0
Reputation: 11832
So what your code actually does is go through the log file and count the number of lines in the while loop. (Needlessly overwriting $line
every time.)
Then in your for loop, you pass in one line at a time to the function caller
and indicate charnum
0.
In your function you check whether the char at charnum
is a -
and if so you go on to do stuff. But if it's not a -
, you continue to the next char.
... Your problem is that you do this by calling caller
recursively! So for each char in the line, you place a new function call on the call stack. Don't do this. Rather put a for loop in the caller
function to increment charnum
every time, and use break
to break out of the for loop, when you finally find a -
. That should fix your problem.
Upvotes: 1
Reputation: 36399
Presumably one of your log lines doesn't contain "-"
so your function recurses infinitely.
Removing the recursion and fixing the bug gives:
function caller($newf, $fileline, $charnum){
$len = strlen($fileline);
for ( $i = $charnum; $i < $len; $i++ )
{
if ($fileline[$i] == '-') {
$x = $i;
$stringx = "";
for ($h = 0; $h < $x; $h++){
$stringx = $stringx.$fileline[$h];
}
fwrite($newf, $stringx);
fwrite($newf, "\n");
echo $stringx;
return;
}
}
}
A simpler way would be to use the built in PHP functions strpos
and substr
:
function caller($newf, $fileline){
$pos = strpos($fileline, "-");
if ( $pos !== FALSE )
{
$stringx = substr( $fileline, 0, $pos );
fwrite($newf, $stringx);
fwrite($newf, "\n");
echo $stringx;
}
}
On a side note the initial loop to count the lines seems unnecessary? You could just do:
while(!feof($file)){
$fileline = fgets($file);
$charnum = 0;
caller($newf, $fileline, $charnum);
}
Upvotes: 1