日志分析工具(二分法分段查找处理)

Author: selfimpr

Blog: http://blog.csdn.net/lgg201

Mail: lgg860911@yahoo.com.cn


需求:日志文件按照时间顺序记录,每次只需要按照时间分析其中某段的日志内容。当此条件下,使用sed,awk等工具是需要扫描全文件的,因此,有了这个小东西,按照文件内容二分查找。

该程序未经测试,有不合理,不正确,性能不佳需要改进的地方,请直言。。。

二分查找库程序:

#! /usr/bin/php <?php function binary_find_analysis($filename, $process_func, $compare_func) { if( !is_readable($filename) || !function_exists($process_func) || !function_exists($compare_func) ) return false; if( !($fp = fopen($filename, 'r')) ) return false; $file_size = filesize($filename); $args = func_get_args(); $extra_args = array_slice($args, 3); #将文件指针移动到符合条件的首行 if( !goto_correct_line($fp, $file_size, 0, $file_size, $compare_func, $extra_args) ) return false; #读取其后所有匹配条件的行,调用处理函数 while( ($line = fgets($fp)) && !call_user_func_array($compare_func, build_arguments($extra_args, $line)) ) $process_func($line); fclose($fp); return true; } function build_arguments($extra_args) { $args = func_get_args(); $other_args = array_slice($args, 1); return array_merge($other_args, $extra_args); } function goto_correct_line($fp, $file_size, $begin, $end, $compare_func, $extra_args) { #未查找到匹配条件记录 if($begin >= $end) return false; $middle = floor( ($begin + $end) / 2 ); fseek($fp, $middle); goto_line_head($fp, $file_size); $original_pos = ftell($fp); $line = fgets($fp); $current_pos = ftell($fp); $cmp_ret = call_user_func_array($compare_func, build_arguments($extra_args, $line)); if( $cmp_ret > 0 ) return goto_correct_line($fp, $file_size, $begin, $original_pos - 1, $compare_func, $extra_args); else if( $cmp_ret < 0 ) return goto_correct_line($fp, $file_size, $current_pos, $end, $compare_func, $extra_args); else return goto_correct_head($fp, $file_size, $compare_func, $extra_args); } function goto_correct_head($fp, $file_size, $compare_func, $extra_args) { while( ($tmp_pos = ftell($fp)) && !call_user_func_array($compare_func, build_arguments($extra_args, $line = fgets($fp))) ) { fseek($fp, $tmp_pos); goto_prev_line_head($fp, $file_size); } return true; } function goto_prev_line_head($fp, $file_size) { goto_line_head($fp, $file_size); goto_nchar($fp, $file_size, -1); goto_line_head($fp, $file_size); } function goto_line_head($fp, $file_size) { goto_nchar($fp, $file_size, -1); while( ftell($fp) && PHP_EOL != fgetc($fp) ) goto_nchar($fp, $file_size, -2); } function goto_nchar($fp, $file_size, $n) { $offset = ftell($fp) + $n; $offset = min($file_size, max($offset, 0)); fseek($fp, $offset); }

我们的日志格式为:

时间(Y-m-d H:i:s) 日志级别 日志编号 日志内容

下面是根据自己的业务写的一个简单的调用处理

function log_process($data) { echo $data; } function timecmp($a, $b) { preg_match(LOG_PARSE_PATTERN, $a, $matches); return floor(strtotime($matches['time']) / 300) - floor($b / 300); } define('LOG_PARSE_PATTERN', '/^(?P<time>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})(?>\s+)(?P<level>(?>\w+))(?>\s+)(?P<number>(?>\d+))(?>\s+)(?P<content>(?>.*))$/'); #为strtotime设置时区 date_default_timezone_set('Asia/Shanghai'); $time = strtotime('2011-07-28 00:10:00'); binary_find_analysis('log_2011-07-28-00', 'log_process', 'timecmp', $time);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值