日志分析工具Awstats实战之Nginx篇:分析结果动态化

运维 系统运维
继上一篇文章“分析工具Awstats实战之Nginx篇-分析结果静态化”后,作者推出了这个系列的第二篇:日志分析工具Awstats实战之Nginx篇:分析结果动态化,介绍了如何将awstats的日志分析信息用静态页面来进行显示,不过显示效果肯定没有动态的好,本篇文章将带大家一起来部署动态的分析结果查阅。

继上一篇文章“分析工具Awstats实战之Nginx篇-分析结果静态化”后,作者推出了这个系列的第二篇:日志分析工具Awstats实战之Nginx篇:分析结果动态化,介绍了如何将awstats的日志分析信息用静态页面来进行显示,不过显示效果肯定没有动态的好,本篇文章将带大家一起来部署动态的分析结果查阅。

环境:

  1. CentOS 6.4 
  2. ip:192.168.1.113 
  3. 域名:www.sunsky.com(server和client都通过hosts文件解析) 
  4. nginx-1.2.9 编译安装,路径/usr/local/nginx,服务开启状态 
  5. 日志记录格式为nginx默认的,切勿更改,否则会造成awstats无法分析日志。 
  6. log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 
  7. '$status $body_bytes_sent "$http_referer" ' 
  8. '"$http_user_agent" "$http_x_forwarded_for"'; 
  9. awstats-7.2.tar.gz CPAN-2.00.tar.gz FCGI-0.74.tar.gz FCGI-ProcManager-0.24.tar.gz 
  10. 必须有perl-devel,不然无法编译FCGI。 

一、日志自动切割

对于nginx的日志切割,由于没有像apache一样去用cronolog工具,这里我们就写一个脚本,让它可以在每天00:01自动执行,切割昨天的日志(交由awstats分析),压缩前天的日志(压缩日志可减小存储空间,为防止awstats没有分析完就被压缩,所以只压缩前天的日志)。

  1. vim /server/scripts/cut_nginx_log.sh 

输入以下内容:

  1. #!/bin/sh 
  2. yesterday=`date -d "yesterday" +"%Y%m%d"` 
  3. before_yesterday=`date -d "-2 day" +"%Y%m%d"` 
  4. Nginx_Dir="/usr/local/nginx" 
  5. Nginx_logs="/app/logs" 
  6. Log_Name="www_access" 
  7. cd /tmp 
  8. [ -d $Nginx_Logs ] && cd $Nginx_logs || exit 1 
  9. [ -f $Log_Name.log ] && /bin/mv $Log_Name.log ${Log_Name}_${yesterday}.log || exit 1 
  10. if [ $? -eq 0 -a -f $Nginx_Dir/logs/nginx.pid ] 
  11. then 
  12. kill -USR1 `cat $Nginx_Dir/logs/nginx.pid` 
  13. fi 
  14. [ -f  ${Log_Name}_${before_yesterday}.log ] && /usr/bin/gzip ${Log_Name}_${before_yesterday}.log|| exit 1 

执行crontab -e将该脚本加入定时任务中

  1. 1 0 * * * /bin/sh /server/scripts/cut_nginx_log.sh >/dev/null 2>&1 

这样每天凌晨00:01就能自动实现日志的切割,压缩等功能了。

因为本次实验下的nginx此时已经有日志了,另外为了后文awstats能对切割过的日志进行分析,所以这里我们要运行一下此脚本,来将现有日志进行切割生成昨天的日志方便后文操作。

  1. /bin/sh /server/scripts/cut_nginx_log.sh >/dev/null 2>&1 

#p#

二、配置FCGI

1、安装CPAN

  1. wget http://search.cpan.org/CPAN/authors/id/A/AN/ANDK/CPAN-2.00.tar.gz 
  2. tar zxf CPAN-2.00.tar.gz 
  3. cd CPAN-2.00 
  4. perl Makefile.PL 
  5. make && make install 

2、安装FCGI和FCGI::ProcManager

  1. wget http://search.cpan.org/CPAN/authors/id/F/FL/FLORA/FCGI-0.74.tar.gz 
  2. tar zxf FCGI-0.74.tar.gz 
  3. cd FCGI-0.74 
  4. 第一种安装方法:perl -MCPAN -e 'install FCGI' 
  5. 第二种安装方法:perl Makefile.PL 
  6.               make&&make install 
  7. wget http://search.cpan.org/CPAN/authors/id/B/BO/BOBTFISH/FCGI-ProcManager-0.24.tar.gz 
  8. tar zxf FCGI-ProcManager-0.24.tar.gz 
  9. cd FCGI-ProcManager-0.24 
  10. 第一种安装方法:perl -MCPAN -e 'install FCGI::ProcManager' 
  11. 第二种安装方法:perl Makefile.PL 
  12.               make&&make install 

在执行第一种安装方法的时候,一定是全程自动滚动下来提示OK的。如果出现提示你输入yes之类的,你需要按提示操作完之后,再运行第二次直到全程自动滚动下来提示OK才为完成安装。或者你就用第二种方法来执行安装。

3、创建FCGI启动文件

  1. vi /usr/local/nginx/sbin/fcgi       #此处按个人习惯命名 
  2. #!/usr/bin/perl 
  3. use FCGI; 
  4. #perl -MCPAN -e 'install FCGI' 
  5. use Socket; 
  6. use POSIX qw(setsid); 
  7. #use Fcntl; 
  8. require 'syscall.ph'; 
  9. &daemonize; 
  10. #this keeps the program alive or something after exec'ing perl scripts 
  11. END() { } BEGIN() { } 
  12. *CORE::GLOBAL::exit = sub { die "fakeexit\nrc=".shift()."\n"; }; 
  13. eval q{exit}; 
  14. if ($@) { 
  15.         exit unless $@ =~ /^fakeexit/; 
  16. }; 
  17. &main; 
  18. sub daemonize() { 
  19.     chdir '/'                 or die "Can't chdir to /: $!"; 
  20.     defined(my $pid = fork)   or die "Can't fork: $!"; 
  21.     exit if $pid; 
  22.     setsid                    or die "Can't start a new session: $!"; 
  23.     umask 0; 
  24. sub main { 
  25. #$socket = FCGI::OpenSocket( "127.0.0.1:8999", 10 ); 
  26. $socket = FCGI::OpenSocket( "/usr/local/nginx/fastcgi_temp/perl_cgi-dispatch.sock", 10 ); 
  27. #use UNIX sockets - user running this script must have w access to the 'nginx' folder!! 
  28. $request = FCGI::Request( \*STDIN, \*STDOUT, \*STDERR, \%req_params, $socket ); 
  29. if ($request) { request_loop()}; 
  30. FCGI::CloseSocket( $socket ); 
  31. sub request_loop { 
  32. while( $request->Accept() >= 0 ) {                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
  33. #processing any STDIN input from WebServer (for CGI-POST actions) 
  34. $stdin_passthrough =''
  35. $req_len = 0 + $req_params{'CONTENT_LENGTH'}; 
  36. if (($req_params{'REQUEST_METHOD'} eq 'POST') && ($req_len != 0) ){ 
  37. my $bytes_read = 0
  38. while ($bytes_read < $req_len) { 
  39. my $data = ''
  40. my $bytes = read(STDIN, $data, ($req_len - $bytes_read)); 
  41. last if ($bytes == 0 || !defined($bytes)); 
  42. $stdin_passthrough .= $data; 
  43. $bytes_read += $bytes; 
  44.  } 
  45. #running the cgi app 
  46. if ( (-x $req_params{SCRIPT_FILENAME}) && #can I execute this? 
  47. (-s $req_params{SCRIPT_FILENAME}) && #Is this file empty? 
  48. (-r $req_params{SCRIPT_FILENAME})     #can I read this file? 
  49. ){ 
  50. pipe(CHILD_RD, PARENT_WR); 
  51. my $pid = open(KID_TO_READ, "-|"); 
  52. unless(defined($pid)) { 
  53. print("Content-type: text/plain\r\n\r\n"); 
  54. print "Error: CGI app returned no output - Executing $req_params 
  55. {SCRIPT_FILENAME} failed !\n"; 
  56. next; 
  57. if ($pid > 0) { 
  58. close(CHILD_RD); 
  59. print PARENT_WR $stdin_passthrough; 
  60. close(PARENT_WR); 
  61. while(my $s = <KID_TO_READ>) { print $s; } 
  62. close KID_TO_READ; 
  63. waitpid($pid, 0); 
  64. } else { 
  65. foreach $key ( keys %req_params){ 
  66. $ENV{$key} = $req_params{$key}; 
  67. # cd to the script's local directory 
  68. if ($req_params{SCRIPT_FILENAME} =~ /^(.*)\/[^\/]+$/) { 
  69. chdir $1; 
  70. close(PARENT_WR); 
  71. close(STDIN); 
  72. #fcntl(CHILD_RD, F_DUPFD, 0); 
  73. syscall(&SYS_dup2, fileno(CHILD_RD), 0); 
  74. #open(STDIN, "<&CHILD_RD"); 
  75. exec($req_params{SCRIPT_FILENAME}); 
  76. die("exec failed"); 
  77.           } 
  78.        } 
  79. else { 
  80. print("Content-type: text/plain\r\n\r\n"); 
  81. print "Error: No such CGI app - $req_params{SCRIPT_FILENAME} may not exist or is 
  82. not executable by this process.\n"; 
  83.        } 
  84.    } 

创建完成后,需要赋予fcgi执行权限:

  1. chmod 755 /usr/local/nginx/sbin/fcgi 

启动FPM(FastCGI 进程管理器)

  1. perl /usr/local/nginx/sbin/fcgi >/dev/null 2>$1 

在这里,Nginx需要对fcgi生成的/usr/local/nginx/fastcgi_temp/perl_cgi-dispatch.sock有读写权限,否则会报502错误。

#p#

三、Awstats的安装与配置

1、部署awstats

首先我们要下载awstats软件包,并将其放在常规目录(/usr/local)下:

  1. wget http://awstats.sourceforge.net/files/awstats-7.2.tar.gz 
  2. tar zxf awstats-7.2.tar.gz 
  3. mv awstats-7.2 /usr/local/awstats 

由于wget下载下来的包中权限是非root的,所以这里要修改权限,否则稍后*.pl将无法运行:

  1. chown -R root.root /usr/local/awstats 
  2. chmod +x /usr/local/awstats/tools/*.pl 
  3. chmod +x /usr/local/awstats/wwwroot/cgi-bin/*.pl 

接下来我们要执行awstats/tools下的awstats_configure.pl配置向导,用来生成awstats的配置文件,awstats配置文件的命名规则是awstats.website.conf

  1. cd /usr/local/awstats/tools/ 
  2. ./awstats_configure.pl 

此时会出现如下提示:

  1. ----- AWStats awstats_configure 1.0 (build 1.9) (c) Laurent Destailleur ----- 
  2. This tool will help you to configure AWStats to analyze statistics for 
  3. one web server. You can try to use it to let it do all that is possible 
  4. in AWStats setup, however following the step by step manual setup 
  5. documentation (docs/index.html) is often a better idea. Above all if: 
  6. - You are not an administrator user, 
  7. - You want to analyze downloaded log files without web server, 
  8. - You want to analyze mail or ftp log files instead of web log files, 
  9. - You need to analyze load balanced servers log files, 
  10. - You want to 'understand' all possible ways to use AWStats... 
  11. Read the AWStats documentation (docs/index.html). 
  12. -----> Running OS detected: Linux, BSD or Unix 
  13. -----> Check for web server install 
  14. Enter full config file path of your Web server. 
  15. Example: /etc/httpd/httpd.conf 
  16. Example: /usr/local/apache2/conf/httpd.conf 
  17. Example: c:\Program files\apache group\apache\conf\httpd.conf 
  18. Config file path ('none' to skip web server setup): 
  19. > none      #这里让填写网页服务器的配置文件路径,因为我们用的不是apache,所以这里要填none 
  20. Your web server config file(s) could not be found. 
  21. You will need to setup your web server manually to declare AWStats 
  22. script as a CGI, if you want to build reports dynamically. 
  23. See AWStats setup documentation (file docs/index.html) 
  24. -----> Update model config file '/usr/local/awstats/wwwroot/cgi-bin/awstats.model.conf' 
  25.   File awstats.model.conf updated. 
  26. -----> Need to create a new config file ? 
  27. Do you want me to build a new AWStats config/profile 
  28. file (required if first install) [y/N] ? y         #询问是否创建一个新的配置文件,这里填y 
  29. -----> Define config file name to create 
  30. What is the name of your web site or profile analysis ? 
  31. Example: www.mysite.com 
  32. Example: demo 
  33. Your web site, virtual server or profile name: 
  34. > www.sunsky.com      #这里让填写你的网站域名,虚拟主机名或者随便一个配置名 
  35. -----> Define config file path 
  36. In which directory do you plan to store your config file(s) ? 
  37. Default: /etc/awstats 
  38. Directory path to store config file(s) (Enter for default): 
  39. >              #这里要填写你配置文件存放路径,我们使用它默认的路径/etc/awstats,所以直接回车即可 
  40. -----> Create config file '/etc/awstats/awstats.www.sunsky.com.conf' 
  41.  Config file /etc/awstats/awstats.www.sunsky.com.conf created. 
  42. -----> Add update process inside a scheduler 
  43. Sorry, configure.pl does not support automatic add to cron yet. 
  44. You can do it manually by adding the following command to your cron: 
  45. /usr/local/awstats/wwwroot/cgi-bin/awstats.pl -update -config=www.sunsky.com 
  46. Or if you have several config files and prefer having only one command: 
  47. /usr/local/awstats/tools/awstats_updateall.pl now 
  48. Press ENTER to continue...   #提示不能自动加入crontab定时任务,需要稍后自己添加,我们按回车继续即可 
  49. A SIMPLE config file has been created: /etc/awstats/awstats.www.sunsky.com.conf 
  50. You should have a look inside to check and change manually main parameters. 
  51. You can then manually update your statistics for 'www.sunsky.com' with command: 
  52. > perl awstats.pl -update -config=www.sunsky.com 
  53. You can also build static report pages for 'www.sunsky.com' with command: 
  54. > perl awstats.pl -output=pagetype -config=www.sunsky.com 
  55. Press ENTER to finish... #提示配置文件创建完成和如何更新配置及建立静态报告页,这里我们回车即可结束这个配置向导 

2、修改awstats配置文件

完成配置文件的创建之后,我们还需要对/etc/awstats/awstats.www.sunsky.com.conf里的一些参数进行修改。

  1. sed -i 's#LogFile="/var/log/httpd/mylog.log"#LogFile="/app/logs/www_access_%YYYY-24%MM-24%DD-24.log"#g' /etc/awstats/awstats.www.sunsky.com.conf 

这里更改的目的是指定awstats需要分析的nginx的日志文件路径。这里的路径大家要按自己的日志路径来填。

  1. sed -i 's#DirData="/var/lib/awstats"#DirData="/usr/local/awstats/data"#g'/etc/awstats/awstats.www.sunsky.com.conf 

这里更改的目的是指定awstats的数据库配置文件(即awstats的数据库(纯文本))。

由于,此处没有/usr/local/awstats/data目录,所以我们要创建出来:

  1. mkdir /usr/local/awstats/data 

以上的两个替换操作进行完之后一定要用命令查看替换是否成功,以便及早发现纰漏。

  1. grep "LogFile=" /etc/awstats/awstats.www.sunsky.com.conf 
  2. grep "DirData=" /etc/awstats/awstats.www.sunsky.com.conf 

查询替换结果正确之后,即可进行下面的步骤。

3、生成awstats统计信息数据库

现在我们需要用awstats来生成对日志的统计分析信息出来了。由于我们用的是支持perl的FCGI动态化访问页面,所以此处我们只需要直接更新数据库即可。FCGI程序会自动将数据库以动态页面的形式展现出来,无须再手动生成静态页面了。本处我们用脚本来完成。

  1. vim /server/scripts/awstats_up.sh 
  2. #!/bin/sh 
  3. /usr/local/awstats/wwwroot/cgi-bin/awstats.pl -update -config=www.sunsky.com >/dev/null 2>&1 

该脚本里面用下面的命令也是可以的。

  1. /usr/local/awstats/tools/awstats_updateall.pl now 

运行该脚本生成分析结果

  1. /bin/sh /server/scripts/awstats_up.sh 

#p#

四、配置日志分析页面的来访ip的地址位置显示

这里我们用国内最准确的ip数据库——QQ纯真库我在博客附件里面放了这个工具,大家下载之后通过CRT用lrzsz工具传上去,具体步骤这里不写了。

附件里面有三个文件qqhostinfo.pm,qqwry.pl和QQWry.Dat,我们将这三个文件统统都放到/usr/local/awstats/wwwroot/cgi-bin/plugins中。

接下来,我们修改qqwry.pl文件,将./QQWry.Dat修改为${DIR}/plugins/QQWry

  1. vim /usr/local/awstats/wwwroot/cgi-bin/plugins/qqwry.pl 
  2. #my $ipfile="./QQWry.Dat"

修改为:

  1. my $ipfile="${DIR}/plugins/QQWry.Dat "

然后编辑awstats的配置文件/etc/awstats/awstats.www.sunsky.com.conf(根据你前面配置的站点信息生成的文件),将LoadPlugin="hostinfo"替换为LoadPlugin="qqhostinfo"即可。

  1. sed -i 's#\#LoadPlugin="hostinfo"#LoadPlugin="qqhostinfo"#g'/etc/awstats/awstats.www.sunsky.com.conf 

切记,在这些替换完之后一定要查看替换是否成功,以便及早发生纰漏。

  1. grep "LoadPlugin=\"qqhostinfo\"" /etc/awstats/awstats.www.sunsky.com.conf 

如果检查无误,那么我们的ip地址位置显示就配置好了,在后面的日志分析中,我们就可以清楚的看到来访ip的地理位置信息了。

五、配置nginx

接下来我们要配置nginx使其能安全的访问到分析的数据

  1. vim /usr/local/nginx/conf/nginx.conf 

在server{}内添加如下内容:

  1. server { 
  2.            listen 80; 
  3.            server_name www.sunsky.com; 
  4.             location / { 
  5.             root   /www/sunsky; 
  6.             index  index.html index.htm; 
  7.             access_log  /app/logs/www_access.log  main; 
  8.     } 
  9.             location ~* ^/cgi-bin/.*\.pl$ { 
  10.             root /usr/local/awstats/wwwroot; 
  11.                fastcgi_pass unix:/usr/local/nginx/fastcgi_temp/perl_cgi-dispatch.sock; 
  12.                fastcgi_index index.pl; 
  13.                include  fastcgi_params; 
  14.                charset gb2312; 
  15.                auth_basic "Restricted";       #有些网站不愿意公开网站流量信息,所以加个认证 
  16.                auth_basic_user_file /usr/local/nginx/htpasswd.pass;  #该文件由apache的加密认证工具htpasswd创建 
  17.            } 
  18.       location ~ ^/icon/ { 
  19.          root   /usr/local/awstats/wwwroot/; 
  20.          index index.html; 
  21.          access_log off; 
  22.          error_log off; 
  23.          charset gb2312; 
  24.       } 

为了保持nginx.conf主配置文件更加整洁干净,所以我们将fastcgi_param的一系列参数添加到/usr/local/nginx/conf/fastcgi_params文件的最顶部,然后在nginx.conf里面调用这个文件即可。

  1. vi /usr/local/nginx/conf/fastcgi_params 
  2. fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 
  3. fastcgi_param QUERY_STRING     $query_string; 
  4. fastcgi_param REQUEST_METHOD   $request_method; 
  5. fastcgi_param CONTENT_TYPE     $content_type; 
  6. fastcgi_param CONTENT_LENGTH   $content_length; 
  7. fastcgi_param GATEWAY_INTERFACE CGI/1.1; 
  8. fastcgi_param SERVER_SOFTWARE    nginx; 
  9. fastcgi_param SCRIPT_NAME        $fastcgi_script_name; 
  10. fastcgi_param REQUEST_URI        $request_uri; 
  11. fastcgi_param DOCUMENT_URI       $document_uri; 
  12. fastcgi_param DOCUMENT_ROOT      $document_root; 
  13. fastcgi_param SERVER_PROTOCOL    $server_protocol; 
  14. fastcgi_param REMOTE_ADDR        $remote_addr; 
  15. fastcgi_param REMOTE_PORT        $remote_port; 
  16. fastcgi_param SERVER_ADDR        $server_addr; 
  17. fastcgi_param SERVER_PORT        $server_port; 
  18. fastcgi_param SERVER_NAME        $server_name; 
  19. fastcgi_read_timeout 60; 

针对上面的加密,由于nginx没有好的加密认证工具,需要借助apache的htpasswd来实现加密认证功能:

  1. htpasswd -c -m /usr/local/nginx/htpasswd.pass sunskyadmin      #用户名为sunskyadmin 

配置完毕之后,检查nginx语法,然后优雅重启之后,用游览器访问http://www.sunsky.com/cgi-bin/awstats.pl?config=www.sunsky.com,输入账号密码之后即可查看统计信息了。

至此,awstats已经可以实现对Nginx的日志统计,动态化安全访问及来访ip的地址位置显示等功能了。

五、配置awstats自动运行

为了让整个日志的统计过程可以实现自动化,将awstats.sh脚本加入crontab定时任务中去,此时结合上面的定时切割任务,我们的crontab里面会有多出来两条定时任务。

  1. 1 0 * * * /bin/sh /server/scripts/cut_nginx_log.sh >/dev/null 2>&1 
  2. 0 1 * * * /bin/sh /server/scripts/awstats_up.sh >/dev/null 2>&1 

到此,我们整个日志访问工具awstats在nginx上对日志分析之后的静态化和动态化访问都已经实现了。后面的话,我会再写一篇awstats对apache服务器的日志分析部署文档。大家如果有什么问题的话,可以联系我进行交流探讨,咱们共同学习,共同进步!

本文作者:sunsky,博客地址:http://sunsky.blog.51cto.com/

责任编辑:黄丹 来源: 博客
相关推荐

2013-10-31 11:08:15

2013-11-01 10:43:35

日志分析Awstats实战Apache

2015-07-31 10:57:01

安全日志windows安全日志安全日志分析

2023-10-24 07:22:22

Nginx运维管理

2017-09-14 10:45:47

PostgreSQL日志分析pgBadger

2012-09-20 10:07:29

Nginx源码分析Web服务器

2019-03-20 13:44:30

Web 开发代码

2014-02-12 10:28:50

Hadoop

2009-06-10 18:12:38

Equinox动态化OSGi动态化

2021-04-27 08:57:58

开发技能代码

2024-08-06 09:40:21

2023-10-30 09:01:08

Nginx日志分析

2022-03-21 15:02:05

Harmonyhiperf鸿蒙

2024-03-19 08:02:28

集群GaussDB指标

2022-03-25 00:00:00

Splunk搜索SPL

2018-01-16 10:11:11

Nginx访问日志

2023-07-07 06:53:56

远程软件日志向日葵

2022-06-29 09:19:09

静态代码C语言c代码

2013-09-11 09:36:02

VMwareLog Insight

2021-01-25 20:20:35

数据分析SparkHadoop
点赞
收藏

51CTO技术栈公众号