2012-03-05 119 views
0

我有一个PHP 5.3.4项目,我需要解析日志文件并向用户显示摘要。日志文件格式(这是我无法控制的)看起来大致是这样的:解析日志文件的模式

BEGIN GROUP: my group 
<TESTCASE ID=1> 
*** Test Name: Some Test 
</TESTCASE RESULT="PASSED"> 
END GROUP: my group 
BEGIN GROUP: another group 
<TESTCASE ID=1> 
*** Test Name: Some other Test 
</TESTCASE RESULT="PASSED"> 
BEGIN GROUP: sub group 
<TESTCASE ID=2> 
*** Test Name: Foo 
</TESTCASE RESULT="FAILED"> 
END GROUP: sub group 
<TESTCASE ID=3> 
*** Test Name: Bar 
</TESTCASE RESULT="PASSED"> 
END GROUP: another group 

我想,我想先分析日志文件中这样的一组对象:

abstract class ResultBase 
{ 
    // name of this result element 
    private $name_ = null; 
    // line number in the result log corresponding ot this element 
    private $line_ = null; 

    // ... 
} 

// defines a Group element from the logfile 
class Group extends ResultBase 
{ 
    // array of ResultBase-derived child elements belonging to this group. 
    private $children_ = null; 

    // ... 
} 

// defines a TestCase element from the logfile 
class TestCase extends ResultBase 
{ 
    // test case id 
    private $id_ = null; 
    // "passed" or "failed" result 
    private $result_ = null; 

    // ... 
} 

class LogFile 
{ 
    // array of ResultBase-derived elements that constitute the log 
    private $elements_ = null; 
} 

而且然后打印的对象:

function Print($log_file) 
{ 
    // some recursive print algorithm... 
} 

我是新来的PHP,所以如果上述错误的方向借此,请让我知道。

我正在寻找一些模式来应用和一些伪代码建议如何实现它。

function Parse($log_file_name) 
{ 
    $logfile = new LogFile(); 
    // what goes here??? 
    return $logfile; 
} 

Print(Parse('C:\mylogfile.log')); 
+2

你开始挑选墙纸的颜色前,请确保您有墙壁开始。获取首先解析/提取日志文件数据的逻辑,然后决定你的对象应该是什么样的。 – 2012-03-05 17:53:02

+0

这是问题的底部,“什么在这里???”线。我应该把它放在最前面。我欢迎您对解析算法提出建议。解析器应该是某种状态机器吗? (在TestCase状态或Group状态下)该算法看起来像什么? – PaulH 2012-03-05 18:00:21

+1

正是。你已经忍受了一吨无用的绒毛。我们不打算为你写日志解析器。 – 2012-03-05 18:00:49

回答

0

你可以做这样的事情:

$log = new LogFile('C:\mylogfile.log'); 
$log->parse(); 
printf("Log has %d groups.\n", $log->getGroups()); # Log has 3 groups. 

LogFile距离SplFileObject延伸:

class LogFile extends SplFileObject { 
    private $groups; 
    public function rewind() { 
     $this->groups = 0; 
     parent::rewind(); 
    } 
    public function current() { 
     $line = parent::current(); 
     if (substr($line, 0, 13) === 'BEGIN GROUP: ') $this->groups++; 
     return $line; 
    } 
    public function parse() { 
     foreach($this as $line); 
    } 
    public function getGroups() { 
     return $this->groups; 
    } 
} 

这也许给你一些指点。一个更好的方法将是可以接受任何迭代器,以便它会使事情更加灵活,一个装饰:

$log = new SplFileObject($logFileName); 
$parser = new LogFileParser($log); 
$parser->parse(); 
printf("Log has %d groups.\n", $parser->getGroups()); 

class LogFileParser extends IteratorIterator 
{ 
    private $groups; 
    public function rewind() { 
     $this->groups = 0; 
     parent::rewind(); 
    } 
    public function current() { 
     $line = parent::current(); 
     if (substr($line, 0, 13) === 'BEGIN GROUP: ') $this->groups++; 
     return $line; 
    } 
    public function parse() { 
     foreach($this as $line); 
    } 
    public function getGroups() { 
     return $this->groups; 
    } 
} 
+0

谢谢,我喜欢这个方向。 – PaulH 2012-03-06 14:29:03