Nginx日志分析脚本 | Nginx Log Analyzer
日志格式使用标准的即可
log_format main '$remote_addr - [$time_local] "$host" "$request" '
'$status ($bytes_sent) "$http_referer" '
'"$uri $args" [$request_time]';
access_log /var/log/nginx/access.log main;
使用方法
./nginx-log-analyzer /var/log/nginx/access.log 1000
脚本代码
PHP写的
#!/usr/bin/php5
< ?
$log = $argv[1];
if ( !is_file($log) ) die("Could not find log file\n");
if ( !$skip_factor = $argv[2] ) $skip_factor = 1;
$r = fopen($log, 'r');
$count = array();
$time = array();
echo 'Processing';
$summary = array();
while ( $line = fgets($r) )
{
if ( $c % 50000 == 0 ) echo '.';
if ( ++$c % $skip_factor != 0 ) continue;
preg_match('/[^ ]+ \- \[(.+?)\] "(.+?)" "([^ ]+) ([^ ]+) .*?" ([0-9]+) \(([0-9]+)\) "(.*?)" "([^ ]+) (.*?)" \[([0-9.]+)\]/', $line, $m);
$type = $m[3];
$time = $m[10];
$url = $m[1];
$status = $m[5];
$length = $m[6];
$uri = $m[4];
$url = $m[2] . '/' . $m[8] . '?' . $m[9];
$summary['calls']['Overall']++;
$summary['calls'][$type]++;
$summary['time']['Overall'] += $time;
$summary['time'][$type] += $time;
$summary['status'][$status]++;
$url = preg_replace('/[0-9]+/', '[x]', $url);
$summary['urls']['calls'][$url] += 1;
$summary['urls']['time'][$url] += $time;
}
echo "\n\n";
echo "= Summary ===========================================================================\n";
foreach ( $summary['calls'] as $type => $count ) $summary_types .= "{$type}: {$count} ";
printf('| %-25s: %s' . "\n", 'Request types', $summary_types );
foreach ( $summary['time'] as $type => $timing ) $summary_timing .= "{$type}: {$timing} ";
printf('| %-25s: %s' . "\n", 'Request timing', $summary_timing );
foreach ( $summary['status'] as $status => $count ) $summary_statuses .= "{$status}: {$count} ";
printf('| %-25s: %s' . "\n", 'Request statuses', $summary_statuses );
echo "\n";
arsort($summary['urls']['time']);
echo "= Details ===========================================================================\n";
printf('| %15s | %20s | %25s | %-15s ' . "\n", 'Calls', 'Total time (sec)', 'Reponse rate (sec/call)', 'URL pattern');
foreach ( $summary['urls']['time'] as $url => $time )
{
if ( ++$ri >= 35 ) break;
$calls = $summary['urls']['calls'][$url];
printf('| %15d | %20.3f | %25.3f | %-15s ' . "\n", $calls, $time, $time/$calls, $url );
}