3

我有一个代理应用程序在文本文件中生成日志文件,该文件从一行到下一行不一致。根据行报告的内容,某些数据将存在或丢失。这是一个例子:

2012-08-05 10:48:59 Login.Failure   [ip address]    12312191391921
2012-08-05 10:49:05 Login.Success   [ip address]    19919292912912  IQi8CaVGiXoPXGy
2012-08-05 12:50:57 Logout      19919292912912  IQi8CaVGiXoPXGy Expired

有七个可能的值,但如您所见,它们并非一直都存在。

我想在数据库中输入这些值,以便创建统计信息。到目前为止,我猜我需要查看位置 2 (0,1,2) 的数组,如果它匹配某个字符串,只期望这些项目在那里,如果它匹配另一个字符串,只期望这些项目, ETC。

到目前为止,我的想法已经到了中断数组并根据它找到的值添加新条件的地步。我知道,这行不通,但就我的想法而言,这是:

$output = explode("\n", $output);
foreach($output as $var) {
$tmp = explode(" ", $var);
$dateentered = $tmp[0];
$timeentered = $tmp[1];
$event = $tmp[3];

if  $tmp[3]="Login.Failure" then

$IP = $tmp[4];
$username = $tmp[5];

$connection = mysql_connect("localhost", "user", "pass") or die('unable to connect');

mysql_select_db('dbname') or die('unable to select database');

$sql = "INSERT INTO table SET dateentered='$dateentered', timeentered='$timeentered', event='$event', IP ='$IP ', username='$username'";

$result=mysql_query($sql,$connection) or die('Error in query: $query. ' .mysql_error());


else if $tmp[3]="Login.Success" then

$IP = $tmp[4];
$username = $tmp[5];
$session = $tmp[6];

...等等...

我希望能够提取所有成功并总结它们,然后对失败做同样的事情,依此类推。

你会如何处理这个问题?如果有人甚至对合理的工作流程有一个想法,我可以从那里构建。我显然只是一个初学者,尽管我确实有好几页。

感谢您的所有回复。

4

3 回答 3

1

为什么你的数据库结构不是这样的:

2012-08-05 10:48:59 Login.Failure   [ip address]    12312191391921  NULL            NULL
2012-08-05 10:49:05 Login.Success   [ip address]    19919292912912  IQi8CaVGiXoPXGy NULL
2012-08-05 12:50:57 Logout          NULL            19919292912912  IQi8CaVGiXoPXGy Expired

或者像这样:

2012-08-05 10:48:59 Login.Failure   [ip address]    12312191391921  ""              ""
2012-08-05 10:49:05 Login.Success   [ip address]    19919292912912  IQi8CaVGiXoPXGy ""
2012-08-05 12:50:57 Logout          ""              19919292912912  IQi8CaVGiXoPXGy Expired

应该优先考虑在正确的列中维护正确的数据,或者更确切地说,在同一列中维护关联数据。

为了解决你的代码,我相信这个解决方案会起作用:

$output;                            // data gotten from file
$connection = mysql_connect("localhost", "user", "pass") 
  or die('unable to connect');      // connect to DB
mysql_select_db('dbname')           // select DB
  or die('unable to select database');
$output = explode("\n", $output);   // tokenize input by lines
for($i=0; $i<count($output); $i++) {// for each line
  $tmp = explode(" ", $output[i]);  // tokenize lines by spaces
  $dateentered = $tmp[0];           // set required data
  $timeentered = $tmp[1];           // set required data
  $event    = $tmp[3];              //i think this should be [2]
  $IP       = "";                   // set default value of possible data
  $username = "";                   // set default value of possible data
  $session  = "";                   // set default value of possible data
  $expired  = "";                   // set default value of possible data

       if ($event=="Login.Failure") { 
    $IP       = $tmp[4];            //i think this should be [3]
    $username = $tmp[5];            //i think this should be [4]
  } 
  else if ($event=="Login.Success") {
    $IP       = $tmp[4];            //i think this should be [3]
    $username = $tmp[5];            //i think this should be [4]
    $session  = $tmp[6];            //i think this should be [5]
  }
  else if ($event=="Logout") {
    $username = $tmp[5];            //i think this should be [4]
    $session  = $tmp[6];            //i think this should be [5]
    $expired  = $tmp[7];            //i think this should be [6]
  }
/*
 * Update DB:
 */
  $sql = "INSERT INTO table SET "
        ."dateentered='$dateentered', "
        ."timeentered='$timeentered', "
        ."event='$event', "
        ."IP ='$IP', " 
        ."username='$username', "
        ."session='$session', "
        ."expired='$expired'";
  $result=mysql_query($sql,$connection) 
    or die('Error in query: $query. ' .mysql_error() 
          .'\n\nWhile Processing line $i');
}                                   // closing brace of for loop
mysql_close($connection);           // close connection to DB

关于您的代码的问题:

  • 在哪里/是什么$tmp[2];我认为您的索引可能会偏离 1

还请务必查看我的代码,以确保它的行为符合您的要求,以便将其插入您的数据库。我想我正确地解释了你的问题并提出了一个可行的解决方案,但只有你可以确定。

于 2012-08-07T22:53:24.227 回答
0

您确实需要验证插入到数据库中的每一行。我可能会使用一个简单的函数来执行此操作,它返回一个适当的分隔字符串或一个可以附加到插入语句的数组。

从您的示例文本的外观来看,文本是制表符分隔的,所以这是一个开始。在该功能中,您至少可以对其进行爆炸以获取单个项目。随之而来的是,它们似乎一个接一个地不同,这也很好,这意味着您的逻辑应该很容易理解哪些丢失了。

这个非常简单的代码应该让你开始......

function findMyFields($inputString)
{
    $tArray=explode('\t', $string);
    if(str_len($tArray[0])==19) 
    // the dateTime looks to be 19 characters and will stay fixed length
    {
        $returnString=$tArray[0].',';
    }
    else
    {
        $returnString=null.',';
    }
    // and so on for each field.

    return $returnString;
}
于 2012-08-07T22:39:08.673 回答
0

您可以创建一个关联数组,其中键是日志条目类型(Login.SuccessLogin.Failure等),值是条目数组。

然后按第一个键循环遍历数组。因为您知道每种日志类型需要哪些字段;它是创建模板 SQL 查询的简单案例(当然有适当的转义)。

于 2012-08-07T22:48:45.453 回答