<?php$fn = '/var/log/haproxy.log.2';
$fp = fopen($fn, 'r') or die("file open $fn false");
while($s = fgets($fp)) {
  preg_match('/\[[\d.:]+\].+\[([\d.:]+)\]/', $s, $r);
  if(empty($r[1])) continue;
  @$res[$r[1]]++;
}fclose($fp);
asort($res);
 
print_r($res);
?>

解决方案 »

  1.   

    你的需求这样是解决不了的要分开处理。。比如,可将ip按第一位,写到255个文件里面,,,也可以将ip转换成数字,这样处理后续可以少用点内存分别在255个文件里面,找出前1000名因为每组至多包含2^24个不同的数【暂时不考虑ipv6】,这个内存可接受的
    这样用一个数组遍历,复杂度O(n),即可找出前1000最后维护一个1000的有序数组,往里面插入数据即可,超过1000,弹出最小的那个
      

  2.   

    $i= 0;
    $fp = fopen($fn, 'r') or die("file open $fn false");
    while($s = fgets($fp) && $i++<1000) {
      preg_match('/\[[\d.:]+\].+\[([\d.:]+)\]/', $s, $r);
      if(empty($r[1])) continue;
      @$res[$r[1]]++;
    }
      

  3.   

    呵呵,搞错了!#3是只取前1000条记录应该是
    $res = array_slice($res, 0, 1000);
      

  4.   

    是啊,这样完成了,但是很慢啊
    <?php$fn = '/var/log/haproxy.log.2';
    $fp = fopen($fn, 'r') or die("file open $fn false");
    while($s = fgets($fp)) {
      preg_match('/\[[\d.:]+\].+\[([\d.:]+)\]/', $s, $r);
      if(empty($r[1])) continue;
      @$res[$r[1]]++;
    }fclose($fp);
    rsort($res);
     
    print_r(array_slice($res,0,1000));
    ?>
      

  5.   

    amani11说的很对,但放到255个文件,不如先分割数组吧
      

  6.   

    看样子真是linux,不能用awk么,一定要php?
      

  7.   

    我们公司要求用PHP啊,再说awk我也不了解
      

  8.   

    你的文件有多大?
    awk + 管道 + sort和head 一行命令应该可以满足你的需求,效率相应也高些.
      

  9.   

    就是说你们有多个日志文件,每日递增,你现在要对所有日志文件做个统计,对吧?
    你们单个日志文件最大能有多大?
    我上次网上看到篇博文,博主说用awk处理一个1G多的文件做统计,花费的时间是1分半左右。
    不知道你用php #6的代码处理花费了多长时间,文件多大?
      

  10.   

    因为我是新人,目前是练手
    需求如下
    (1)、目标IP统计,统计出访问最多的前1000个目标IP,相关报表结构如下:
    IP地址 总访问次数 访问主域名1/访问次数 访问主域名2/访问次数 访问主域名3/访问次数 ......
    10.10.255.31 1000 Efly.cc/230 Abc.cn/240 Cdf.com/280 .......
    (2)、域名统计,统计出访问最多的前1000个域名,相关报表信息如下:
    域名 总访问次数 响应IP1/访问次数 响应IP2/访问次数 ......
    efly.cc 1000 202.96.128.86/100 202.96.128.166/200 .......
    (3)、URL统计,统计出访问最多的前1000个URL,相关报表信息如下:
    URL 总访问次数 响应IP1/访问次数 响应IP2/访问次数 .....
    Efly.cc/index.php 1000 202.96.128.86/100 202.96.128.166/200 ......
    是要处理后的1000个结果。
      

  11.   

    早说练手嘛,早说我就不在这瞎掺和了。
    在你#6代码的基础上,开多两个数组,分别统计域名和URL的,不要多次读文件哈。
      

  12.   

    域名和URL我还都没有取出来,#6那个代码在服务器上可以运行,但是速度比较慢
    带我那个人的意思是,以后我要处理的文件会更大,这样写不行
    要学会分段处理
    他说的好像是要我写一个函数每次取出1万的数据量,用完再清空
    然后另外写一个函数把处理结果和这次读取的数据合起来
      

  13.   

    Mar  8 12:51:27 10.10.255.5 haproxy[4840]: 124.240.66.100:42408[10.10.255.5:36236]->112.90.32.240:80[112.90.32.240:80] [08/Mar/2012:12:51:26.939] http_check http_image/<NOSRV> 12/0/24/30/91 200 18990 - - ---- 541/541/9/0/0 0/0 {img.alim
    ama.cn|http://www.taobao.com/go/act/sale/250x250men.php?pid=mm_17936709_2306571_8939881&refpos=,a,null&pid=mm_17936709_2306571_8939881&pvid=2_1331182226_146363p2_163744779} "GET /cms/images/1323674511466.jpg HTTP/1.1"
    用正则这样取域名报错
    preg_match('([A-Za-z0-9]+\.)+[A-Za-z0-9]+/', $s, $r);
    Warning: arsort() expects parameter 1 to be array, null given in D:\软件\php-5.2
    .1-Win32\newfile10.php on line 12Warning: array_slice(): The first argument should be an array in D:\软件\php-5.2
    .1-Win32\newfile10.php on line 13