使用awstats 分析 Nginx 的访问日志

先安装awstats,安装过程在http://blog.chinaunix.net/u2/71666/showart.php?id=1988397

完成向导,接下来修改 www.test.cn 的统计配置

 

 

 

 

[root@test awstats]# pwd

/etc/awstats

[root@test awstats]# vi awstats.www.test.com.conf

找到统计的日志文件的路径

LogFile="/var/log/httpd/mylog.log"

改为

LogFile="/usr/local/nginx/logs/test.access_%YYYY-24%MM-24%DD-24.log"

LogFormat=1

改为

LogFormat = "%host %other %logname %time1 %methodurl %code %bytesd %refererquot %uaquot %otherquot"

 

 

 

 

 

 

[root@test awstats]# cp awstats.www.test.com.conf awstats.www.good.cn.conf

[root@test awstats]# vi awstats.www.good.cn.conf

需要注意一下几行

awstats.www.good.com.conf

LogFile="/usr/local/nginx/logs/good.access_%YYYY-24%MM-24%DD-24.log"

LogFormat = "%host %other %logname %time1 %methodurl %code %bytesd %refererquot %uaquot %otherquot"

SiteDomain="www.good.com"

HostAliases="good.com www.good.com 127.0.0.1 localhost"

 

 

默认编译安装的nginx对cgi的支持并不好(所以在编译的时候一般都没打开这个功能)

google了一把。大家都用fastcgi来支持。就照搬吧

[root@test html]# pwd

/usr/local/nginx/html

[root@test html]# mkdir cgi-bin

[root@test html]# cd cgi-bin/

[root@test cgi-bin]# vi fcgi_perl

 

 

 

#!/usr/bin/perl -w

use FCGI;

use Socket;

use FCGI::ProcManager;

sub shutdown { FCGI::CloseSocket($socket); exit; }

sub restart { FCGI::CloseSocket($socket); &main; }

use sigtrap 'handler', \&shutdown, 'normal-signals';

use sigtrap 'handler', \&restart, 'HUP';

require 'syscall.ph';

use POSIX qw(setsid);

 

#&daemonize; we don't daemonize when running under runsv

#this keeps the program alive or something after exec'ing perl scripts

END() { }

BEGIN() { }

{

no warnings;

*CORE::GLOBAL::exit = sub { die "fakeexit\nrc=" . shift() . "\n"; };

};

eval q{exit};

if ($@) {

exit unless $@ =~ /^fakeexit/;

}

&main;

 

sub daemonize() {

chdir '/' or die "Can't chdir to /: $!";

defined( my $pid = fork ) or die "Can't fork: $!";

exit if $pid;

setsid() or die "Can't start a new session: $!";

umask 0;

}

 

sub main {

#如果使用 IP sockets

#$socket = FCGI::OpenSocket( "127.0.0.1:8999", 10 );

#如果使用 UNIX sockets

#$socket = FCGI::OpenSocket( "/var/run/perl_cgi-dispatch.sock", 10 );

 

#foreach $item (keys %ENV) { delete $ENV{$item}; }

#设置fastcgi进程数,默认四个

my $n_processes = $ENV{FCGI_NPROCESSES} || 4;

$proc_manager = FCGI::ProcManager->new( {n_processes => $n_processes} );

#使用unix socket

$socket = FCGI::OpenSocket( "$ENV{FCGI_SOCKET_PATH}", 10 );

#设置Socket权限

chmod 0777, $ENV{FCGI_SOCKET_PATH};

 

; #use UNIX sockets - user running this script must have w access to the 'nginx' folder!!

$request =

FCGI::Request( \*STDIN, \*STDOUT, \*STDERR, \%req_params, $socket,

&FCGI::FAIL_ACCEPT_ON_INTR );

$proc_manager->pm_manage();

if ($request) { request_loop() }

FCGI::CloseSocket($socket);

}

 

sub request_loop {

while ( $request->Accept() >= 0 ) {

$proc_manager->pm_pre_dispatch();

 

#processing any STDIN input from WebServer (for CGI-POST actions)

$stdin_passthrough = '';

{ no warnings; $req_len = 0 + $req_params{'CONTENT_LENGTH'}; };

if ( ( $req_params{'REQUEST_METHOD'} eq 'POST' ) && ( $req_len != 0 ) )

{

my $bytes_read = 0;

while ( $bytes_read < $req_len ) {

my $data = '';

my $bytes = read( STDIN, $data, ( $req_len - $bytes_read ) );

last if ( $bytes == 0 || !defined($bytes) );

$stdin_passthrough .= $data;

$bytes_read += $bytes;

}

}

 

#running the cgi app

if (

( -x $req_params{SCRIPT_FILENAME} ) && #can I execute this?

( -s $req_params{SCRIPT_FILENAME} ) && #Is this file empty?

( -r $req_params{SCRIPT_FILENAME} ) #can I read this file?

)

{

pipe( CHILD_RD, PARENT_WR );

pipe( PARENT_ERR, CHILD_ERR );

my $pid = open( CHILD_O, "-|" );

unless ( defined($pid) ) {

print("Content-type: text/plain\r\n\r\n");

print

"Error: CGI app returned no output - Executing $req_params{SCRIPT_FILENAME} failed !\n";

next;

}

$oldfh = select(PARENT_ERR);

$| = 1;

select(CHILD_O);

$| = 1;

select($oldfh);

if ( $pid > 0 ) {

close(CHILD_RD);

close(CHILD_ERR);

print PARENT_WR $stdin_passthrough;

close(PARENT_WR);

$rin = $rout = $ein = $eout = '';

vec( $rin, fileno(CHILD_O), 1 ) = 1;

vec( $rin, fileno(PARENT_ERR), 1 ) = 1;

$ein = $rin;

$nfound = 0;

 

while ( $nfound =

select( $rout = $rin, undef, $ein = $eout, 10 ) )

{

die "$!" unless $nfound != -1;

$r1 = vec( $rout, fileno(PARENT_ERR), 1 ) == 1;

$r2 = vec( $rout, fileno(CHILD_O), 1 ) == 1;

$e1 = vec( $eout, fileno(PARENT_ERR), 1 ) == 1;

$e2 = vec( $eout, fileno(CHILD_O), 1 ) == 1;

 

if ($r1) {

while ( $bytes = read( PARENT_ERR, $errbytes, 4096 ) ) {

print STDERR $errbytes;

}

 

if ($!) {

$err = $!;

die $!;

vec( $rin, fileno(PARENT_ERR), 1 ) = 0

unless ( $err == EINTR or $err == EAGAIN );

}

}

if ($r2) {

while ( $bytes = read( CHILD_O, $s, 4096 ) ) {

print $s;

}

if ( !defined($bytes) ) {

$err = $!;

die $!;

vec( $rin, fileno(CHILD_O), 1 ) = 0

unless ( $err == EINTR or $err == EAGAIN );

}

}

last if ( $e1 || $e2 );

}

close CHILD_RD;

close PARENT_ERR;

waitpid( $pid, 0 );

} else {

foreach $key ( keys %req_params ) {

$ENV{$key} = $req_params{$key};

}

 

# cd to the script's local directory

if ( $req_params{SCRIPT_FILENAME} =~ /^(.*)\/[^\/]+$/ ) {

chdir $1;

}

close(PARENT_WR);

 

#close(PARENT_ERR);

close(STDIN);

close(STDERR);

 

#fcntl(CHILD_RD, F_DUPFD, 0);

syscall( &SYS_dup2, fileno(CHILD_RD), 0 );

syscall( &SYS_dup2, fileno(CHILD_ERR), 2 );

 

#open(STDIN, "<&CHILD_RD");

exec( $req_params{SCRIPT_FILENAME} );

die("exec failed");

}

} else {

print("Content-type: text/plain\r\n\r\n");

print

"Error: No such CGI app - $req_params{SCRIPT_FILENAME} may not exist or is not executable by this process.\n";

}

}

}

 

 

再设置启动的脚本

[root@test cgi-bin]# vi startfcgiperl

 

 

 

export FCGI_SOCKET_PATH="/tmp/perl_fcgi.socket"

export FCGI_NPROCESSES=4

./fcgi_perl &

 

然后加上执行权限

 

[root@test cgi-bin]# chmod +x fcgi_perl startfcgiperl

[root@test cgi-bin]# perl -MCPAN -e shell

cpan> install FCGI

cpan> install FCGI::ProcManager

[root@test cgi-bin]# ./startfcgiperl &

 

为nginx添加fastCGI的perl支持

[root@test conf]# pwd

/usr/local/nginx/conf

[root@test conf]# vi gzip.conf

 

 

 

 

#!nginx (-)

# gzip.conf

gzip on;

gzip_min_length 1100;

gzip_buffers 4 8k;

gzip_types text/plain;

output_buffers 1 32k;

postpone_output 1460;

 

 

[root@test conf]# vi proxy.conf

 

 

#!nginx (-)

# proxy.conf

proxy_redirect off;

proxy_set_header Host $http_host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

client_max_body_size 10m;

client_body_buffer_size 128k;

proxy_connect_timeout 90;

proxy_send_timeout 90;

proxy_read_timeout 90;

proxy_buffers 32 4k;

 

[root@test conf]# vi awstats.conf

 

 

 

fastcgi_pass unix:/tmp/perl_fcgi.socket;

fastcgi_index awstats.pl;

fastcgi_param SCRIPT_FILENAME /usr/local/awstats/wwwroot/cgi-bin/awstats.pl;

fastcgi_param QUERY_STRING $query_string;

fastcgi_param REQUEST_METHOD $request_method;

fastcgi_param CONTENT_TYPE $content_type;

fastcgi_param CONTENT_LENGTH $content_length;

fastcgi_param GATEWAY_INTERFACE CGI/1.1;

fastcgi_param SERVER_SOFTWARE nginx;

fastcgi_param SCRIPT_NAME $fastcgi_script_name;

fastcgi_param REQUEST_URI $request_uri;

fastcgi_param DOCUMENT_URI $document_uri;

fastcgi_param DOCUMENT_ROOT $document_root;

fastcgi_param SERVER_PROTOCOL $server_protocol;

fastcgi_param REMOTE_ADDR $remote_addr;

fastcgi_param REMOTE_PORT $remote_port;

fastcgi_param SERVER_ADDR $server_addr;

fastcgi_param SERVER_PORT $server_port;

fastcgi_param SERVER_NAME $server_name;

fastcgi_read_timeout 60;

 

 

[root@test conf]# vi nginx.conf

 

 

user nobody;

worker_processes 2;

events {

use epoll;

worker_connections 2048;

}

http {

include mime.types;

default_type application/octet-stream;

access_log logs/access.log;

sendfile on;

tcp_nodelay on;

keepalive_timeout 65;

include gzip.conf;

log_format test '$remote_addr - $remote_user [$time_local] "$request" '

'$status $body_bytes_sent "$http_referer" '

'"$http_user_agent" "$http_x_forwarded_for"';

log_format good '$remote_addr - $remote_user [$time_local] "$request" '

'$status $body_bytes_sent "$http_referer" '

'"$http_user_agent" "$http_x_forwarded_for"';

server

{

listen 80;

server_name www.test.com test.com;

access_log logs/test.access.log test;

location ~ ^/NginxStatus/ {

stub_status on;

access_log off;

}

location ~ ^/(WEB-INF)/ {

deny all;

}

location ~ \.(htm|html|gif|jpg|jpeg|png|bmp|ico|rar|css|js|zip|java|jar|txt|flv|swf|mid|doc|ppt|xls|pdf|txt|mp3|wma)$ {

root /projects/test;

expires 24h;

}

location ~* .*\.pl$

{

include awstats.conf;

}

location /awstatsicon/

{

alias /usr/local/awstats/wwwroot/icon/;

}

location /{

proxy_pass http://localhost:8080;

include proxy.conf;

}

error_page 404 /html/404.html;

error_page 502 503 /html/502.html;

error_page 500 504 /50x.html;

location = /50x.html {

root html;

}

}

server

{

listen 80;

server_name www.good.cn good,cn www.good.net good.net;

access_log logs/good.access.log good;

location ~ ^/(WEB-INF)/ {

deny all;

}

location ~ \.(htm|html|gif|jpg|jpeg|png|bmp|ico|rar|css|js|zip|java|jar|txt|flv|swf|mid|doc|ppt|xls|pdf|txt|mp3|wma)$ {

root /projects/good;

expires 24h;

}

location ~* .*\.pl$

{

include awstats.conf;

}

location /awstatsicon/

{

alias /usr/local/awstats/wwwroot/icon/;

}

location /{

proxy_pass http://localhost:8080;

include proxy.conf;

}

error_page 404 /html/404.html;

error_page 502 503 /html/502.html;

error_page 500 504 /50x.html;

location = /50x.html {

root html;

}

}

}

 

 

配置Nginx自动切割日志

跟 Apache HTTP Server(以下称 Apache)不同的是,Apache 可以将日志输出通过管道的方式进行重新定向,依此来进行自动的日志切割。Nginx 在现今版本上还没能跟 Apache 一样,通过%YY等参数按日期分批创建日志,但是通过给 nginx 进程发送一个特定的信号,可以使 nginx 重新生成日志文件。我们可以定期执行一个 Shell 脚本来切换日志,重新命名或转移,具体的脚本如下:

 

 

 

 

[root@test sbin]# pwd

/usr/local/nginx/sbin

[root@test sbin]# more logcron.sh

mv /usr/local/nginx/logs/test.access.log /usr/local/nginx/logs/test.access_`date +%Y%m%d`.log

mv /usr/local/nginx/logs/good.access.log /usr/local/nginx/logs/good.access_`date +%Y%m%d`.log

killall --s USR1 nginx

 

 

[root@test sbin]# crontab -e

 

 

 

59 23 * * * /usr/local/nginx/sbin/logcron.sh

20 2 * * * /usr/local/awstats/tools/awstats_updateall.pl now -awstatsprog=/usr/local/awstats/wwwroot/cgi-bin/awstats.pl

 

然后可以通过http://www.test.com/awstats.pl

 

http://www.good.com/awstats.pl来查看那些人访问了你的网站。。。。

你可能感兴趣的:(nginx,分析,awstats,访问日志)