先谈下我们需求,一个比较大的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访问日志--及性能优化的更多相关文章

  1. 性能调优之访问日志IO性能优化

    性能调优之访问日志IO性能优化   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:908821 ...

  2. 访问日志IO性能优化

    在高并发量的场景下磁盘IO往往是性能的瓶颈所在,访问日志涉及到频繁的写操作,所以这部分要尽可能地优化,不然将拖累系统的整体性能.针对文件记录及数据库记录两种方式可以有以下措施提高写性能, l 避免频繁 ...

  3. 采集并分析Nginx访问日志

    日志服务支持通过数据接入向导配置采集Nginx日志,并自动创建索引和Nginx日志仪表盘,帮助您快速采集并分析Nginx日志. 许多个人站长选取了Nginx作为服务器搭建网站,在对网站访问情况进行分析 ...

  4. Nginx访问日志.Nginx日志切割

    11月27日任务 12.10 Nginx访问日志12.11 Nginx日志切割12.12 静态文件不记录日志和过期时间 1.Nginx访问日志 示例一: 日志格式 vim /usr/local/ngi ...

  5. Nginx 访问日志轮询切割

    Nginx 访问日志轮询切割脚本 #!/bin/sh Dateformat=`date +%Y%m%d` Basedir="/application/nginx" Nginxlog ...

  6. Nginx访问日志、 Nginx日志切割、静态文件不记录日志和过期时间

    1.Nginx访问日志 配制访问日志:默认定义格式: log_format combined_realip '$remote_addr $http_x_forwarded_for [$time_loc ...

  7. Nginx访问日志、日志切割、静态文件不记录日志和过期时间

    6月8日任务 12.10 Nginx访问日志12.11 Nginx日志切割12.12 静态文件不记录日志和过期时间 12.10 Nginx访问日志 除了在主配置文件nginx.conf里定义日志格式外 ...

  8. Linux centosVMware Nginx访问日志、Nginx日志切割、静态文件不记录日志和过期时间

    一.Nginx访问日志 vim /usr/local/nginx/conf/nginx.conf //搜索log_format  日至格式 改为davery格式 $remote_addr  客户端IP ...

  9. nginx访问日志(access_log)

    一.nginx访问日志介绍 nginx软件会把每个用户访问网站的日志信息记录到指定的日志文件里,供网站提供者分析用户的浏览行为等,此功能由ngx_http_log_module模块负责,对应的官方地址 ...

随机推荐

  1. GCD的相关函数使用

    GCD 是iOS多线程实现方案之一,非常常用 英文翻译过来就是伟大的中枢调度器,也有人戏称为是牛逼的中枢调度器 是苹果公司为多核的并行运算提出的解决方案 1.一次性函数 dispatch_once 顾 ...

  2. Lambda表达式的诞生过程

    这是一篇很经典的文章,解决了工作中一些使用过但是又不太明白的知识点,今天终于弄明白了.花了一晚上重新整的,坚决要分享出来!!! 那得从很久很久以前说起了,记得那个时候... 懵懂的记得从前有个叫委托的 ...

  3. Spring bean依赖注入、bean的装配及相关注解

    依赖注入 Spring主要提供以下两种方法用于依赖注入 基于属性Setter方法注入 基于构造方法注入 Setter方法注入 例子: public class Communication { priv ...

  4. 轻量级ORM框架——第一篇:Dapper快速学习

    我们都知道ORM全称叫做Object Relationship Mapper,也就是可以用object来map我们的db,而且市面上的orm框架有很多,其中有一个框架 叫做dapper,而且被称为th ...

  5. mssqlserver数据导出到另外一个数据库

    mssqlserver数据导出到另外一个数据库 准备源数据库,找到想要导出的数据库,右键选择"任务"再选择"导出数据" 设置源数据库信息 3.设置目标数据库,导 ...

  6. RemodelanyWhere11.0.2673版本下载

    百度云盘链接:http://pan.baidu.com/s/1geL5lez 密码:hisq 原文转载至:http://blog.sun0816.com/13623.html

  7. [转][iOS]NSHash​Table & NSMap​Table

    NSSet and NSDictionary, along with NSArray are the workhorse collection classes of Foundation. Unlik ...

  8. Usual tiny skills & solutions

    Ubuntu and Win10 - double OS 2016-02-21 Yesterday I helped my friend install Ubuntu (14.04 LTS) on h ...

  9. SNMP与MIB

    简单网络管理协议(SNMP:Simple Network Management Protocol)是一套网络管理协议,注意,SNMP是一个强大的网络管理协议,而不是"简单"的.利用 ...

  10. AngularJS(1)

    AngularJS(1) 在讲正题之前,先说一下有关angular简介方面的信息: 1. angularJS  诞生于2009年,由Misko Hevery 等人创建,后为Google所收购.是一款优 ...