Python统计web应用的每个连接使用情况
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python统计web应用的每个连接使用情况相关的知识,希望对你有一定的参考价值。
背景:前段时间接到一个需求,领导说他想要知道我们在生产环境中某系统的每个应用使用情况。
需求:
统计每个按钮的点击量;
不能影响生产环境;
数据要不断递增,而不是看某个时间段的;
数据要永久存放,不丢;
思路:我想这可以通过nginx的日志来进行分析,每个action和后台的nginx接到请求肯定是一对一的,那么我们通过nginx的日志,那这个需求就解决了;
方案:
分析nginx的请求日志;
凌晨进行日志分析,且数据不妨到生产环境;
做定时任务;
存放到mongodb;
总结:在每天凌晨进行日志分析,把处理结果存放那个到线下mongodb数据库中
代码实现:
连接mongo代码↓
#coding=utf-8 # auth: xinsir # date: 2017/10/02 # version:3.0 from pymongo import MongoClient import pickle #建立MongoDB数据库连接 client = MongoClient(‘192.168.1.197‘,27017) #连接所需数据库,test为数据库名 db=client.nginxlog #连接所用集合,也就是我们通常所说的表,test为表名 collection=db.recording # 写一个方法,用于反序列化数据 def Deserialization(name): Data = pickle.load(name) return Data # 写一个方法,向mongo中存放数据 def InsterData(data): collection.insert(data) # 写一个方法,用来查询mongo中的数据 def SechMongo(link): for u in collection.find( {‘Link‘: link} ): return True else: return False # 写一个方法,用来更新mongo中的数据 def Update(wherelink): data = collection.find_one({‘Link‘:wherelink}) collection.update({‘Link‘:wherelink},{‘$set‘:{‘cunt‘:int(data[‘cunt‘])+1}})
插入模版代码↓
#coding=utf-8 # auth: xinsir # date: 2017/10/02 # version:3.0 #_*_ coding:utf-8 _*_ # 写一个方法,用来导入请求连接的模版,在进行日志分析之前,首先要对mongo集合中插入模版 import systemmongo ActionLog = ‘../nginxlog/result.txt‘ def Sech(File): SechDic = {} with open(File,‘r‘,encoding=‘UTF-8‘) as ActionLogFile: for line in ActionLogFile.readlines(): a = line.split(‘\t‘) b = a[-1].split(‘\n‘) del a[-1] a.append(b[0]) SechDic[a[0]] = { ‘ModuleName‘: a[0], ‘ButtonName‘: a[1], ‘Link‘: a[2], ‘cunt‘: a[3], } systemmongo.InsterData(SechDic[a[0]]) ActionLogFile.close() if __name__ == ‘__main__‘: Sech(ActionLog)
看一下action模版的格式
看一下插入后的集合样子
分析nginx日志代码↓
#_*_ coding:utf-8 _*_ # auth: xinsir # date: 2017/10/02 # version:3.0 import systemmongo,os # 写一个方法,判断文件是否存在.返回布尔值 def judgment_file(FileName): if os.path.exists( FileName ): return True else: return False # 写一个方法,把字符串切割成列表,return list def SplitStr(StrName, Format,): return StrName.split(Format) # 读取日志文件,获取文件中的所有包含action的记录,并写入到新的log文件中 def read_file(file, new_file,): ReadPosition = 0 LastLine = 0 FileSize = 0 FileDic = {} # 打开两个文件,一个是日志文件,一个是临时文件,把日志文件进行更改后,以字典的格式序列化到日志文件中 with open(file, ‘r‘) as log_file, open(new_file, ‘w‘) as new_log_file: # 查看文件总长多少,写入临时文件 FileSizeNew = os.path.getsize(file) log_file.seek(ReadPosition) if FileSize < FileSizeNew: for (num, line) in enumerate(log_file): if ‘.action‘ in line.strip(): new_line = line.strip().split(sep=‘\" \"‘) ListFirstValue = SplitStr(new_line[0], ‘\"‘) ListMostValue = SplitStr(new_line[-1], ‘\"‘) del new_line[0] del new_line[-1] new_line.insert(0, ListFirstValue[1]) new_line.append(ListMostValue[0]) Method = str(new_line[3]).split()[0] request = str(new_line[3]).split()[1] HttpVersion = str(new_line[3]).split()[2] if ‘?‘ in request: Uri = request.split(sep=‘?‘)[0] Query_string = request.split(sep=‘?‘)[1] else: Uri = request.split( sep=‘?‘ )[0] Query_string = ‘‘ if ‘.action‘ in Uri: # if LogFileStatus : FileDic[num + 1 + LastLine] = { ‘remote_addr‘: new_line[0], ‘host‘: new_line[1], ‘time_local‘: new_line[2], ‘request‘: request, ‘uri‘:Uri, ‘query_string‘:Query_string, ‘eethod‘: Method, ‘HttpVersion‘: HttpVersion, ‘body_bytes_sent‘: new_line[4], ‘http_referer‘: new_line[5], ‘http_user_agent‘: new_line[6], ‘http_x_forwarded_for‘: new_line[7], ‘server_addr‘: new_line[8], ‘status‘: new_line[9], ‘request_time‘: new_line[10], } else: print(‘静态请求不做记录!‘) continue IsNot = systemmongo.SechMongo( ‘http://‘ + FileDic[num + 1 + LastLine][‘host‘] + FileDic[num + 1 + LastLine][‘uri‘]) if IsNot: systemmongo.Update( ‘http://‘ + FileDic[num + 1 + LastLine][‘host‘] + FileDic[num + 1 + LastLine][‘uri‘]) print(‘更新记录成功:‘‘http://‘ + FileDic[num + 1 + LastLine][‘host‘] + FileDic[num + 1 + LastLine][‘uri‘]) else: print(‘action请求不存在!不做记录!‘) else: print(‘静态请求不做处理!‘) else: print(‘日志文件没有发生改变!‘) new_log_file.write(str(FileDic)) log_file.close() new_log_file.close() if __name__ == ‘__main__‘: LOGPATH_new = ‘../nginxlog/b.txt‘ for fpathe, dirs, fs in os.walk(‘E:\python工程\jlj-nginx-log-web\jlj-nginx-log-web\\nginxlog\log‘): #循环目录下的所有日志文件 for f in fs: LOGPATH = os.path.join(fpathe, f) read_file(LOGPATH, LOGPATH_new)
配合linux的crontab任务,每天凌晨把生产环境的nginx日志scp到线下,这里特别要说明,因为我们的nginx访问量很大,大的时候在线连接数能达到3000+,可想而知一天的nginx日志也要有八九百兆,之前小编写的代码是一次性打开文件分别循环日志的每一行,但是这样会把机器的内存撑爆,所以现在是按照年月日的格式把nginx的日志进行了切割。
看一下nginx的日志切割
[[email protected] ~]# cat /etc/nginx/sbin/cut_log_hour.sh #!/bin/bash #nginx 日志路径 log_dir="/Disk/log/nginx" #当前时间 2017/09/28/15 date_dir=`date +%Y/%m/%d/%H` #创建时间目录 /bin/mkdir -p ${log_dir}/${date_dir} > /dev/null 2>&1 # 把当前日志移动到对应的目录下,并且重命名 /bin/mv ${log_dir}/access.log ${log_dir}/${date_dir}/access.log # 重新生成一个日志文件 kill -USR1 `cat /var/run/nginx.pid`
在看以下nginx的日志记录格式,每一个关键词都用双引号进行了分割,这样有助于我们后台进行日志分析
log_format main ‘"$remote_addr" "$host" "$time_local" "$request" "$body_bytes_sent" "$http_referer" "$http_user_agent" "$http_x_forwarded_for" "$server_addr" "$status" "$request_time"‘;
小编也是初次写代码,如果有不对和思路凌乱的地方,还请大家指导,环境大家在评论区进行评论,也欢迎大家加我QQ同学习。
QQ:894747821
本文出自 “学习改变命运” 博客,请务必保留此出处http://xinsir.blog.51cto.com/5038915/1970198
以上是关于Python统计web应用的每个连接使用情况的主要内容,如果未能解决你的问题,请参考以下文章