用 awk 和 goaccess 分析nginx accesslog

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_28018283/article/details/82983673

awk 方式

本文主要用这种方式实现 统计 access.log 超过 1s 的记录。
思路:先用 awk 将每天切割的 nginx 日志生成自定义的分析结果文件 ,由 python 脚本处理,导入mysql :记录日期慢Url 路径慢Url 最短时间最差时间访问次数 ,是否修复修复日期等,最后由前端进行展示。

按天切割 Nginx 日志

这里为了每天夜里只分析当天生成的nginx日志,我们可以把nginx按天切割备份。日常环境中,我们也可以使用这种方法,按天、按月、按年lai 备份和切割日志,方便后期进行数据过滤或删除。

#/bin/bash
nginxLog="/usr/local/nginx/logs/access.log"
logBakFile="/usr/local/nginx/logs/"$(date "+%F")/"access.log"

if [ ! -d ${logBakFile%/*} ]
then
    mkdir -p ${logBakFile%/*}
fi
mv $nginxLog $logBakFile 2>&1 >/dev/null
kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`
#切割nginx日志
59 23 * * * bash /root/auto-sh/nginxErrLog_logrotate.sh
59 22 * * * bash /root/auto-sh/nginxAccLog_logrotate.sh

这样,我们就得到了,这样的Nginx切割的日志
在这里插入图片描述

[root@macco-web 2018-10-08]# ls
access.log  error.log

这里我们对 access.log 进行处理

附上 nginx.conf 日志格式部分的配置:

log_format main "$remote_addr  $http_x_readtime [$time_local] \
"$request_method http://$host$request_uri\" $status $body_bytes_sent \"$http_referer\" \"$upstream_addr\" \
"$http_user_agent\" \"$upstream_response_time\" \"$request_time\" ";

Awk 脚本

#分析nginx日志 需要去除 每天备份的log“” 存储到1.txt
cat access.log| awk '{print $(NF)}' | awk -F "\"" '{print $2}'>1.txt
#将 1.txt的结果拼接到 access.log   存放到log.txt
paste -d " "  access.log  1.txt > log.txt
# 从 log.txt 选取想要分析的参数存放到最终的文件中,限制选取 $request_time >1 的
cat log.txt |awk '($NF>1 ){print $3 " " $5 " "  $6 " " $11 " " $NF}'>/public/nginxStatic.txt

访问 nginxStatic.txt 的结果:可以看到有我们选取的 http_x_readtime$request_method$request_uri$http_user_agent, $request_time
在这里插入图片描述

最后用 python,将数据处理分析之后存储到mysql。
附上思路代码:

import MySQLdb as mdb
from tqdm import tqdm

# 统计 access.log 超过 1S 的记录
# AWK 将每天的nginx日志 产生log ,由本脚本 导入sql,记录
# 日期,慢Url 路径,慢Url 最短时间,最差时间,访问次数 ,是否修复 ,修复日期
# 前端进行展示
# 定义日志文件路径
log_file_path = "/statics/nginxStatic.txt"
# 按行读取日志,过滤分析 存入mysql
f = open(log_file_path)
lines = f.readlines()
for line in tqdm(lines):
    # 用 " " 切分单行数据
    tmp_list =  line.split(" ")
    api_time = tmp_list[0].replace("[","")
    api_method = tmp_list[1].replace("\"","")
    api_url = tmp_list[2].replace("\"","")
    api_ua = tmp_list[3].replace("\"","")
    api_request_time = tmp_list[4].replace("\n","")
    # print(api_request_time)
    # sys.exit(0)
    is_fix = get_nginx_log(api_url)
    if is_fix:
        # 更新log的频率 ,更新sl_time
        id = is_fix[0][0]
        s_time = is_fix[0][1]
        l_time = is_fix[0][2]
        if api_request_time > s_time and api_request_time < l_time:
            update_nginx_log(id,1,api_request_time)
        elif api_request_time < s_time:
            update_nginx_log(id,2,api_request_time)
        elif api_request_time > l_time:
            update_nginx_log(id, 3, api_request_time)
    else:
        insert_nginx_log(api_time, api_url, api_ua, api_request_time,api_method)

数据表的表结构:

CREATE TABLE `nginxlog` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'log自增ID',
  `url` varchar(256) NOT NULL DEFAULT '',
  `method` varchar(20) DEFAULT NULL COMMENT '调用方法',
  `ua` varchar(128) DEFAULT NULL COMMENT 'user_agent',
  `short_time` decimal(5,2) DEFAULT '0.00' COMMENT '最短时间',
  `long_time` decimal(5,2) DEFAULT '0.00' COMMENT '最长时间',
  `is_fix` tinyint(1) unsigned DEFAULT '0' COMMENT '0未修复',
  `number` int(11) DEFAULT '1' COMMENT '访问次数',
  `create_time` varchar(128) DEFAULT '',
  `fix_time` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=37 DEFAULT CHARSET=utf8mb4;

跑完之后的数据,可以很方便的给前端进行数据调用和展现了
在这里插入图片描述

goaccess

#安装(或源码安装)
apt-get install goaccess

$ goaccess -h
# 常用参数
-a --agent-list 启用由主机用户代理的列表。为了更快的解析,不启用该项
-d --with-output-resolver 在HTML/JSON输出中开启IP解析,会使用GeoIP来进行IP解析
-f --log-file 需要分析的日志文件路径
-p --config-file 配置文件路径
-o --output 输出格式,支持html、json、csv
-m --with-mouse 控制面板支持鼠标点击
-q --no-query-string 忽略请求的参数部分
--real-time-html 实时生成HTML报告
--daemonize 守护进程模式,--real-time-html时使用

# 生成可视化html报告
goaccess -f /usr/local/nginx/logs/access.log -a > /public/report.html

生成的报告页面预览如下:能看到各种状态码的访问次数,日PV,UV等等详细信息。
在这里插入图片描述

这种方案还是比较简单省事的,一步就解决了上面所有的步骤 ,不过我还是选择上面的方案 ,虽然麻烦,但是有操作感,也能细节到每一步的自定义。

猜你喜欢

转载自blog.csdn.net/qq_28018283/article/details/82983673