分析nginx大日志文件,python多线程必备! .

还在为分析nginx大日志犯愁吗?也许你会想到用shell处理,1G文件没有问题,上了10G文件,会消耗很久时间,用shell结合python多线程处理没有错。

什么都不用说了,直接上代码了

#!/usr/bin/python
#coding:utf8
import threading     #载入多线程模块
import time          #载入时间模块
import os            #载入os模块
import shutil        #载入shutil模块
import re            #载入re正则模块
fuhao=os.linesep     #换行符
start_time=int(time.strftime(‘%H%M%S‘))  #执行程序开始时间
print start_time
def count_cpu_heshu():                      #统计cpu核数函数
    file=open(‘/proc/cpuinfo‘)
    cpu_sum=[]
    for line in file.readlines():
        cpu_he=re.findall(‘^processor‘,line)
        if len(cpu_he)==1:
           cpu_sum.append(cpu_he)
        else:
           continue
    file.close()
    return len(cpu_sum)                    #返回cpu函数
def count_memory_size():                   #统计系统内存大小函数
    mem_sum=int(os.popen("free -m|awk  ‘{print $2}‘|sed -n ‘2p‘").readline().strip())  #统计内存的shell
    return mem_sum                                                                     #返回内存大小
def nginx_log_fenge():                    #因nginx日志太大,需要按500M分割,建立此函数进行分割日志
    if os.path.exists(‘/data/logs/nginx_tmp/‘)!=True:       #分割日志的临时目录
       os.makedirs(‘/data/logs/nginx_tmp/‘)
    if os.path.exists(‘/data/logs/nginx_tmp_binfa/‘)!=True: #并发目录
       os.makedirs(‘/data/logs/nginx_tmp_binfa/‘)
    if os.path.exists(‘/data/logs/nginx_tmp_txt01/‘)!=True:  #time记录txt目录 
       os.makedirs(‘/data/logs/nginx_tmp_txt01/‘)
    if os.path.exists(‘/data/logs/nginx_tmp_txt02/‘)!=True:  #url记录txt目录 
       os.makedirs(‘/data/logs/nginx_tmp_txt02/‘)
    if os.path.exists(‘/data/logs/nginx_tmp_chuli/‘)!=True:  #处理所有txt目录
       os.makedirs(‘/data/logs/nginx_tmp_chuli/‘)
    nginx_log_name=os.listdir(‘/data/logs/nginx_log‘)[0].strip()  #切割日志名
    nginx_file=‘/data/logs/nginx_log/%s‘ %nginx_log_name           #切割日志名及路径
    file=open(nginx_file)                   #nginx日志文件路径
    sizehint=int(count_memory_size() / count_cpu_heshu() * 0.5 * 1024 * 1024)              #此数字是按字节进行计算,这里大小为内存除以cpu核数剩以0.5得到的结果为500M
    position=0                               #当前位置为0
    file_num=1                               #分割文件名默认加1
    while True:                             #当条件为真执行,为假退出。
          lines = file.readlines(sizehint)   #读文件
          file_name=‘/data/logs/nginx_tmp/dd_access%d‘ %file_num  #分割成功的文件名
          file01=open(file_name,‘w‘)       #写文件
          file01.writelines(lines)         #把读取的单个1G文件写到文件名中
          if  file.tell() - position > 0: #如果分割的位置大于默认位置就继续执行,否则就退出。
              position = file.tell()      #替换位置
              file_num=file_num+1
              continue
          else:
              break
    file.close()
    file01.close()
    os.remove(file_name)
    time.sleep(300)
def nginx_log_time_count(file_name01):         #nginx分析日志函数
    file_name=‘/data/logs/nginx_tmp_binfa/%s‘ %file_name01    #并发日志名
    file_txt=‘/data/logs/nginx_tmp_txt01/%s.txt‘ %file_name01        #执行shell结果保存目录
    cmd="awk ‘{print $4}‘ %s|awk -F / ‘{print $NF}‘|awk -F : ‘{print $2$3$4$5}‘  2>/dev/null|sort 2>/dev/null|uniq -c 2>/dev/null|sort -nr 2>/dev/null|head -n 1 > %s" %(file_name,file_txt)  #分析脚本
    os.system(cmd)  #执行shell命令
    fuhao_cmd=‘%s‘ %fuhao
    f=open(file_txt)
    f1=open(‘/data/logs/nginx_tmp_chuli/time_sum.txt‘,‘a‘)
    for line in f.readlines():
         time_single_max= line.split()[0]   #单个文件连接数
         f1.writelines(time_single_max)
         f1.write(fuhao_cmd)
    f.close()
    f1.close()
def nginx_log_url_count(file_name01):         #nginx分析日志函数
    file_name=‘/data/logs/nginx_tmp_binfa/%s‘ %file_name01  #并发日志名
    file_txt=‘/data/logs/nginx_tmp_txt02/%s.txt‘ %file_name01   #执行shell结果保存目录
    cmd="awk ‘{print $7}‘ %s  2>/dev/null|sort 2>/dev/null|uniq -c 2>/dev/null|sort -rn 2>/dev/null|head -n 200 > %s " %(file_name,file_txt)  #分析脚本
    os.system(cmd)  #执行shell命令
    fuhao_cmd=‘%s‘ %fuhao
    f=open(file_txt)
    f1=open(‘/data/logs/nginx_tmp_chuli/url_sum.txt‘,‘a‘)
    for line in f.readlines():          #把url_status里面每一行值以列表方法增加到url_count列表里面
        f1.writelines(line.strip())
        f1.write(fuhao_cmd)
    f.close()
    f1.close()
def dxc_call_time_count():                       #多线程调用分析日志函数
    file_name_read=[]                        #文件名读取列表
    f=os.listdir(‘/data/logs/nginx_tmp_binfa/‘)   #显示data/logs/nginx_tmp/目录下所有文件
    for read_filename in f:
        filename_chuancan=read_filename.strip()  #单个文件名
        filename=threading.Thread(target=nginx_log_time_count,args=(filename_chuancan,))  #建立多线程
        file_name_read.append(filename)         #添加线程到file_name_read列表
    filename_sum=range(len(file_name_read))     #统计文件名数量
    for line in filename_sum:
        file_name_read[line].start()            #启动线程
    for line in filename_sum:
        file_name_read[line].join()             #等待多线程结束后,就结束进程。
def dxc_call_url_count():                       #多线程调用分析日志函数
    file_name_read=[]                        #文件名读取列表
    f=os.listdir(‘/data/logs/nginx_tmp_binfa/‘)   #显示data/logs/nginx_tmp/目录下所有文件
    for read_filename in f:
        filename_chuancan=read_filename.strip()  #单个文件名
        filename=threading.Thread(target=nginx_log_url_count,args=(filename_chuancan,))  #建立多线程
        file_name_read.append(filename)         #添加线程到file_name_read列表
    filename_sum=range(len(file_name_read))     #统计文件名数量
    for line in filename_sum:
        file_name_read[line].start()            #启动线程
    for line in filename_sum:
        file_name_read[line].join()             #等待多线程结束后,就结束进程。
def time_count_chuli():                         #time处理函数
    f=open(‘/data/logs/nginx_tmp_chuli/time_sum.txt‘)
    time_max=[]
    for count in f:
       time_max.append(int(count.strip()))
    f.close()
    return max(time_max)
def url_count_chuli():                          #url处理函数
    f=open(‘/data/logs/nginx_tmp_chuli/url_sum.txt‘)
    url_max=[]
    for count in f:
        url_max.append(count.split())
    f.close()
    return url_max
def write_report_email():                       #写文件用来发email
    fuhao_cmd=‘%s‘ %fuhao
    time_max=time_count_chuli()                 #接受time处理函数返回的结果
    url_max=url_count_chuli()                   #接受url处理函数返回的结果
    file=open(‘/data/logs/nginx_log_email_tmp.txt‘,‘w‘)
    file.write("nginx单秒的最大请求数为:%d" %time_max)
    file.write(fuhao_cmd)
    file.write(‘nginx连接数TOP100排序‘)
    file.write(fuhao_cmd)
    new_dict={}                       #定义一字典用来统计连接重复数,得到字典结果为连接地址:连接重复数
    for i in url_max:                 #遍历url_max列表
         new_dict[i[1]] = new_dict.get(i[1],0) + int(i[0])    #i[1]表示连接地址,i[0]表示连接重复数,new_dict[i[1]]表示把列表中的地址重复数与地址连接交换,如果连接相同,就累加连接重复数.
    n_dict = {}                       #定义一字典用来恢复原来的连接重复数:连接地址
    for k in new_dict:                #遍历new_dict字典
         n_dict[new_dict[k]] = k      #k表示连接地址,new_dict[k]表示连接重复数,最后n_dict结果为连接重复数:连接地址
    url_count=sorted(n_dict.iteritems(),key=lambda dict1:dict1[0],reverse=True) #对字典进行排序
    for line in url_count:
        file.write(‘连接重复数:‘)
        file.write(str(line[0]))              #把连接重复数写到日志临时文件
        file.write(‘   ‘)
        file.write(‘http://d.m1905.com‘)      #写连接头文件
        file.write(str(line[1]))              #把连接地址写到日志临时文件
        file.write(fuhao_cmd)
    file.close()
    file=open(‘/data/logs/nginx_log_email_tmp.txt‘,‘r‘)   #读取日志临时文件
    row=0
    file01=open(‘/data/logs/nginx_log_email.txt‘,‘w‘)     #写文件
    for line in file.readlines():
        row=row+1                                         #row表示行数
        if row <= 102:                                    #读取文件到102行,大于102行就退出
           file01.write(line)
        else:
           break
    file.close()
    file01.close()
    os.remove(‘/data/logs/nginx_log_email_tmp.txt‘)       #删除日志临时文件  
    os.remove(‘/data/logs/nginx_tmp_chuli/time_sum.txt‘)       #删除time_sum文件 
    os.remove(‘/data/logs/nginx_tmp_chuli/url_sum.txt‘)       #删url_sum文件  
def rmdir_nginx_log_mulu():       #清空日志目录函数
    shutil.rmtree(‘/data/logs/nginx_tmp/‘)  #清空日志临时目录,供新日志存放
    os.mkdir(‘/data/logs/nginx_tmp/‘)
    shutil.rmtree(‘/data/logs/nginx_log/‘)  #清空日志目录,供新日志存放
    os.mkdir(‘/data/logs/nginx_log‘)
def main():
   shutil.rmtree(‘/data/logs/nginx_tmp_chuli‘)  #清空日志临时目录,供新日志存放
   os.mkdir(‘/data/logs/nginx_tmp_chuli‘)
   cpu_he=count_cpu_heshu()                                       #cpu核数
   while len(os.listdir(‘/data/logs/nginx_tmp/‘))>0:   #动态统计分割日志文件个数
 f=os.listdir(‘/data/logs/nginx_tmp/‘)          #动态统计分割日志文件
 key=0                                                       #默认key为0
 while (key<=cpu_he-1 and key<len(f)):      #对cpu核数进行对比
         name = ‘/data/logs/nginx_tmp/%s‘ %f[key]    #日志文件名
         shutil.move(name,‘/data/logs/nginx_tmp_binfa/‘)  #移动日志文件,为了减少负载太高
         key=key+1
 dxc_call_time_count()
        dxc_call_url_count() 
 shutil.rmtree(‘/data/logs/nginx_tmp_binfa/‘)
 os.mkdir(‘/data/logs/nginx_tmp_binfa/‘)
        shutil.rmtree(‘/data/logs/nginx_tmp_txt01/‘)
        os.mkdir(‘/data/logs/nginx_tmp_txt01/‘)
        shutil.rmtree(‘/data/logs/nginx_tmp_txt02/‘)
        os.mkdir(‘/data/logs/nginx_tmp_txt02/‘)
   write_report_email()
   rmdir_nginx_log_mulu() 
nginx_log_fenge()
main()
stop_time=int(time.strftime(‘%H%M%S‘))
print stop_time
#os.system(‘/usr/bin/python /root/liu_shell/nginx_log/send_email.py‘)   #send_email.py把结果发邮件到开发人员

注:只需要你把需要分析的nginx日志放在/data/logs/nginx_log/这个目录就OK了。

查看结果,只需要看/data/logs/nginx_log_email.txt这个文件就OK了。

可以通过send_email.py把/data/logs/nginx_log_email.txt这个文件内容发送给开发人员

时间: 2024-08-04 12:44:52

分析nginx大日志文件,python多线程必备! .的相关文章

(整理二)读取大日志文件

一般读取文件有三种方式: 1.读取到内存中: 2.分块读取: 3.采用内存映射技术. 一.读取到内存中 此种方式比较适合小文件,可以通过文件流的方式直接读取到内存中进行处理. 二.分块读取 当文件很大时(特别是文件大小大于内存大小),读取到内存中就很不合理.这种时候,我们可以将文件进行分块,然后进行分块读取. 1 /// <summary> 2 /// 读取大文件方法 3 /// </summary> 4 /// <param name="initialPath&q

采集并分析Nginx访问日志

日志服务支持通过数据接入向导配置采集Nginx日志,并自动创建索引和Nginx日志仪表盘,帮助您快速采集并分析Nginx日志. 许多个人站长选取了Nginx作为服务器搭建网站,在对网站访问情况进行分析时,需要对Nginx访问日志统计分析,从中获取网站的访问量.访问时段等访问情况.传统模式下利用CNZZ等方式,在前端页面插入js,用户访问的时候触发js,但仅能记录访问请求.或者利用流计算.离线统计分析Nginx访问日志,但需要搭建一套环境,并且在实时性以及分析灵活性上难以平衡. 日志服务在支持查询

logstash grok 分析 nginx access 日志

为了便于量化分析nginx access日志,使用logstash 进行筛选匹配 1.确定nginx 日志格式     log_format access '$remote_addr - $remote_user [$time_local] '               '$http_host $request_method $uri '               '$status $body_bytes_sent '               '$upstream_status $ups

清理ms sql server 大日志文件数据

1.手动分离数据库: 2.手动删除日志文件: 3.重新生成日志文件: CREATE DATABASE FMIS0 ON (FILENAME = 'E:\FMIS0_DATA\FMIS0-Date') FOR ATTACH_REBUILD_LOG ;GO 清理ms sql server 大日志文件数据

删除大日志文件中的某段数据

using System; using System.IO; using System.Linq; using System.Text; namespace TestMultyConsole2 { public class LocalFileHelper { /// <summary> /// 删除大日志文件中的某些数据 /// </summary> /// <param name="filePath">源文件路径</param> ///

SQL Server日志文件过大 大日志文件清理方法 不分离数据库

SQL Server日志文件过大    大日志文件清理方法 ,网上提供了很多分离数据库--〉删除日志文件-〉附加数据库 的方法,此方法风险太大,过程也比较久,有时候也会出现分离不成功的现象.下面的方式是不需要做数据库分离和附加操作的. SQL 2008收缩清空日志方法: 1.在SQL2008中清除日志就必须在简单模式下进行,等清除动作完毕再调回到完整模式,一定必务要再改回完整模式,不然数据库就不支持时间点备份了.1).选择数据库–属性-选项-恢复模式–选择简单.2).收缩数据库后,再调回完整.2

请大神指导从大日志文件中统计关键字次数的办法

awk 'NR==FNR{a[$0]=1;next}{if($0 in a)b[$0]++}END{for (i in b)print i,b[i]}' filea fileb | sort 文件A中有若干行数据,每行为一个关键字文件B为大日志文件,大小为10G以下 想着能够统计出文件A中每个关键字在B中的出现次数,例如行1,3行2,10行3,100..... 最笨的办法是逐行读入后用grep,但是太费时间,有没有只打开一次B文件,就能把A中所有行都统计出来的办法呢? aaa 3 bbb 3 c

命令分析nginx访问日志的用法

awk分析日志常用高级使用命令方法 分析访问日志(Nginx为例) 日志格式: '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"' 统计访问IP次数: # awk '{a[$1]++}END{for(i

python 按照日期切分大日志文件(重点)和按照指定大小切分日志文件

#! /usr/bin/env python # -*- coding:utf8 -*- # 切分nginx 按照日期切分日志文件 from __future__ import division import os,sys big_file='/data/logs/media.net.error.log' # 按照文件大小拆分 def split_by_filesize(fromfile,todir,chunksize=0): """ chunksize: 字节建议每100M