按日期切割nginx访问日志--及性能优化
先谈下我们需求,一个比较大的nginx访问日志,根据访问日期切割日志,保存在/tmp目录下。
测试机器为腾讯云机子,单核1G内存。测试日志大小80M。
不使用多线程版:
#!/usr/bin/env python
# coding=utf-8 import re
import datetime if __name__ == '__main__':
date_pattern = re.compile(r'\[(\d+)\/(\w+)\/(\d+):')
with open('./access_all.log-20161227') as f:
for line in f:
day, mon, year = re.search(date_pattern, line).groups()
mon = datetime.datetime.strptime(mon, '%b').month
log_file = '/tmp/%s-%s-%s' % (year, mon, day)
with open(log_file, 'a+') as f:
f.write(line)
耗时:
[root@VM_255_164_centos data_parse]# time python3 log_cut.py
real 0m41.152s
user 0m32.578s
sys 0m6.046s
多线程版:
#!/usr/bin/env python
# coding=utf-8 import re
import datetime
import threading date_pattern = re.compile(r'\[(\d+)\/(\w+)\/(\d+):') def log_cut(line):
day, mon, year = re.search(date_pattern, line).groups()
mon = datetime.datetime.strptime(mon, '%b').month
log_file = '/tmp/%s-%s-%s' % (year, mon, day)
with open(log_file, 'a+') as f:
f.write(line) if __name__ == '__main__':
with open('./access_all.log-20161227') as f:
for line in f:
t = threading.Thread(target=log_cut, args=(line,))
t.setDaemon(True)
t.start()
耗时:
# time python3 log_cut.py real 1m35.905s
user 1m10.292s
sys 0m19.666s
使用多线程版竟然比不使用多进程版要慢的多。。cpu密集型任务使用上下文切换果然很耗时。
线程池版:
线程池类
#!/usr/bin/env python
# coding=utf-8 import queue
import threading
import contextlib
import time StopEvent = object() class ThreadPool(object): def __init__(self, max_num, max_task_num = None):
if max_task_num:
self.q = queue.Queue(max_task_num)
else:
self.q = queue.Queue()
self.max_num = max_num
self.cancel = False
self.terminal = False
self.generate_list = []
self.free_list = [] def run(self, func, args, callback=None):
if self.cancel:
return
if len(self.free_list) == 0 and len(self.generate_list) < self.max_num:
self.generate_thread()
w = (func, args, callback,)
self.q.put(w) def generate_thread(self):
t = threading.Thread(target=self.call)
t.start() def call(self):
current_thread = threading.currentThread()
self.generate_list.append(current_thread) event = self.q.get()
while event != StopEvent: func, arguments, callback = event
try:
result = func(*arguments)
success = True
except Exception as e:
success = False
result = None if callback is not None:
try:
callback(success, result)
except Exception as e:
pass with self.worker_state(self.free_list, current_thread):
if self.terminal:
event = StopEvent
else:
event = self.q.get()
else:
self.generate_list.remove(current_thread) def close(self):
self.cancel = True
full_size = len(self.generate_list)
while full_size:
self.q.put(StopEvent) #
full_size -= 1 def terminate(self):
self.terminal = True while self.generate_list:
self.q.put(StopEvent) self.q.queue.clear() @contextlib.contextmanager
def worker_state(self, state_list, worker_thread):
state_list.append(worker_thread)
try:
yield
finally:
state_list.remove(worker_thread)
threadingPool.py
代码
#!/usr/bin/env python
# coding=utf-8 import re
import datetime
from threadingPool import ThreadPool date_pattern = re.compile(r'\[(\d+)\/(\w+)\/(\d+)\:') def log_cut(line):
day, mon, year = date_pattern.search(line).groups()
mon = datetime.datetime.strptime(mon, '%b').month
log_file = '/tmp/%s-%s-%s' % (year, mon, day)
with open(log_file, 'a+') as f:
f.write(line) def callback(status, result):
pass pool = ThreadPool(1) with open('./access_all.log-20161227') as f:
for line in f:
pool.run(log_cut, (line,), callback) pool.close()
耗时:
# time python3 log_cut2.py real 0m53.371s
user 0m44.761s
sys 0m5.600s
线程池版比多线程版要快,看来写的线程池类还是有用的。减少了上下文切换时间。
进程池版:
#!/usr/bin/env python
# coding=utf-8 import re
import datetime
from multiprocessing import Pool date_pattern = re.compile(r'\[(\d+)\/(\w+)\/(\d+):') def log_cut(line):
day, mon, year = re.search(date_pattern, line).groups()
mon = datetime.datetime.strptime(mon, '%b').month
log_file = '/tmp/%s-%s-%s' % (year, mon, day)
with open(log_file, 'a+') as f:
f.write(line) if __name__ == '__main__':
pool = Pool(1)
with open('./access_all.log-20161227') as f:
for line in f:
pool.apply_async(func=log_cut, args=(line,))
pool.close()
单个进程耗时:
# time python3 log_cut.py real 0m28.392s
user 0m23.451s
sys 0m1.888s
2个进程耗时:
# time python3 log_cut.py real 0m40.920s
user 0m33.690s
sys 0m3.206s
看来使用多进程时,如果是单核cpu只开一个进程,多核cpu的话开多个速度更快,单核cpu开多个进程速度很慢。
shell版
#!/bin/bash
Usage(){
echo "Usage: $0 Logfile"
}
if [ $# -eq ] ;then
Usage
exit
else
Log=$
fi
date_log=$(mktemp)
cat $Log |awk -F'[ :]' '{print $5}'|awk -F'[' '{print $2}'|uniq > date_log
for i in `cat date_log`
do
grep $i $Log > /tmp/log/${i::}-${i::}-${i::}.access
done
耗时:
# time sh log_cut.sh access_all.log- real 0m2.435s
user 0m2.042s
sys 0m0.304s
shell的效果非常棒啊,只用2s多久完成了。
按日期切割nginx访问日志--及性能优化的更多相关文章
- 性能调优之访问日志IO性能优化
性能调优之访问日志IO性能优化 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:908821 ...
- 访问日志IO性能优化
在高并发量的场景下磁盘IO往往是性能的瓶颈所在,访问日志涉及到频繁的写操作,所以这部分要尽可能地优化,不然将拖累系统的整体性能.针对文件记录及数据库记录两种方式可以有以下措施提高写性能, l 避免频繁 ...
- 采集并分析Nginx访问日志
日志服务支持通过数据接入向导配置采集Nginx日志,并自动创建索引和Nginx日志仪表盘,帮助您快速采集并分析Nginx日志. 许多个人站长选取了Nginx作为服务器搭建网站,在对网站访问情况进行分析 ...
- Nginx访问日志.Nginx日志切割
11月27日任务 12.10 Nginx访问日志12.11 Nginx日志切割12.12 静态文件不记录日志和过期时间 1.Nginx访问日志 示例一: 日志格式 vim /usr/local/ngi ...
- Nginx 访问日志轮询切割
Nginx 访问日志轮询切割脚本 #!/bin/sh Dateformat=`date +%Y%m%d` Basedir="/application/nginx" Nginxlog ...
- Nginx访问日志、 Nginx日志切割、静态文件不记录日志和过期时间
1.Nginx访问日志 配制访问日志:默认定义格式: log_format combined_realip '$remote_addr $http_x_forwarded_for [$time_loc ...
- Nginx访问日志、日志切割、静态文件不记录日志和过期时间
6月8日任务 12.10 Nginx访问日志12.11 Nginx日志切割12.12 静态文件不记录日志和过期时间 12.10 Nginx访问日志 除了在主配置文件nginx.conf里定义日志格式外 ...
- Linux centosVMware Nginx访问日志、Nginx日志切割、静态文件不记录日志和过期时间
一.Nginx访问日志 vim /usr/local/nginx/conf/nginx.conf //搜索log_format 日至格式 改为davery格式 $remote_addr 客户端IP ...
- nginx访问日志(access_log)
一.nginx访问日志介绍 nginx软件会把每个用户访问网站的日志信息记录到指定的日志文件里,供网站提供者分析用户的浏览行为等,此功能由ngx_http_log_module模块负责,对应的官方地址 ...
随机推荐
- kindle型号
这篇文章为 Kindle 新手解决三个问题:怎么辨别Kindle 型号?通过 Kindle 外观判断准确吗?Kindle序列号在那里? 贴吧吧友提问的原话"在咸鱼看到一台,那哥们说也不知道K ...
- 机器学习实战笔记(Python实现)-07-分类性能度量指标
1.混淆矩阵 下图是一个二类问题的混淆矩阵,其中的输出采用了不同的类别标签 常用的衡量分类性能的指标有: 正确率(Precision),它等于 TP/(TP+FP) ,给出的是预测为正例的样本中的真正 ...
- zabbix完整安装
一.nginx安装 1.必要软件准备: 为了支持rewrite功能,我们需要安装pcre: yum install pcre-* 需要ssl的支持,如果不需要ssl支持,请跳过这一步: yum ins ...
- Python常用方法
Python strip()方法 描述: Python strip()方法用于移除字符串头尾指定的字符(默认为空格). 语法: str.strip([chars]) 参数: chars -- 移除字符 ...
- 【Pyrosim案例】01:空气流动
1 案例说明 Pyrosim是一款FDS前后处理软件.以一个非常简单的案例来描述Pyrosim的工作流程.本案例计算域中包含一个空气入口,一个环境出口. 案例主要演示以下内容: 创建Vents 增加切 ...
- Spring 框架的架包分析、功能作用、优点,及jar架包简介
Spring 框架的架包详解 Spring的作用 Spring的优势 由于刚搭建完一个MVC框架,决定分享一下我搭建过程中学习到的一些东西.我觉得不管你是个初级程序员还是高级程序员抑或 ...
- 子DIV设置margin-top影响父DIV位置的解决办法
父div如果没有任何东西,子div设置margin-top,父div会下落 <!DOCTYPE html> <html lang="en"> <hea ...
- Introduction to graph theory 图论/脑网络基础
Source: Connected Brain Figure above: Bullmore E, Sporns O. Complex brain networks: graph theoretica ...
- EEG preprocessing - A Trick Before Doing ICA
EEGLab maillist My ICs don't have high power in low frequency is b/c I do a small trick here. before ...
- VS 生成事件
转载自: http://hi.baidu.com/gisince/item/7f0439ee610c94255a2d64b4 今天写了生成事件的处理,如下: 从网上Down了一个例子,运行时提示错误 ...