2012-03-05 128 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