分析邮件日志从每秒处理3个结果到每秒处理55个结果过程(grep提速)

由于业务需要,对EDM发出的邮件日志进行分析处理,我要做的是预处理,把posfix杂乱无章的日志中找到我需要的数据.

我用javamail发的邮件,发送邮件时获取到是一个messageId,形如:[email protected]

但是直接通过这个messageid是不能拿到发送邮件的status的,因为日志中是这么记录的:


May 16 17:34:53 c1202 postfix/cleanup[23641]: 00020127E4D: message-id=<2135546465.103503.1400232891548[email protected]>

May 16 17:34:53 c1202 postfix/error[23571]: 00020127E4D: to=<[email protected]163.com>, relay=none, delay=0.1, delays=0.08/0/0/0.01, dsn=4.4.2, status=deferred (delivery temporarily suspended: lost connection with 163mx01.mxmail.netease.com[220.181.14.139] while sending DATA command)

这个日志已经把没有用的行过滤掉了,只剩这两行是有用的.这两行的关联ID是00020127E4D,也就是说我要先通过


2135546465.103503.1400232891548[email protected]

获取到00020127E4D,然后再通过00020127E4D获取到第二行中的status.

Q:为什么不直接grep 邮件名?

A:因为发送邮件服务器是共用的,不能通过邮件名就确认这封邮件是由我的EDM服务发出,而messageid是EDM服务发出时的标志ID,所以需要通过messageid找到关联ID,再找到发送结果那么折腾.


    #假设同一条mailid的记录在最近10行内
mailTmp=`grep -A 10 "${line}" "${logFile2}"`
#获取mailid,例如582664BDA66
mailid=`echo "${mailTmp}"| fgrep -m 1 "${line}" | awk ‘{print $6}‘|sed ‘s/://g‘`
#获取发送结果,可能会有重试多条,只读第一条.
sendStatus=`echo "${mailTmp}" | fgrep "${mailid}"| fgrep "postfix/smtp" | fgrep -m 1 "to=" | sed ‘s/.*status=//g‘`

获取到status的核心代码就是这三行.再加个外层while循环从文件中读取messageid输入line的样子.

版本一:

   需求能实现,但速度很慢,每秒最高得出3条status结果.

版本二:

  maillog的日志是并发写入的,虽然对同一封邮件发出写入的日志顺序是固定的,但同一个mailid可能要读1000行才能找到这关键的两行数据.

  改进:

    1. 为了减少第一条语句的搜索,过滤掉无用的行,例如postfix/qmgr,postfix/smtpd等行,我不关注的信息.

    2. 根据mailid预先排序,把关联的mailid放在一起,这样更加能够减轻第一条grep的搜索.

  结果:

    每秒3条速度提升到每秒5条,还不错,但还是太慢了,因为第一天的日志有19W条...这样算下去要10个小时才能弄完.

版本三:

  每秒5条,没想到什么好办法提升了,就想着能不能并发呢?开N个线程,那每秒不就可以处理N*5条了吗?

  改进:

    尝试使用shell下面的并发,找了一下资料,参考一位疑似TX员工分享的代码:
http://my.oschina.net/sanpeterguo/blog/133304

    我使用的服务器是8核CPU,为了尽量不影响原有的服务,我把线程开了5个.

  结果:

    果然很有效,开了5个线程,能把速度提升到每秒处理12~17个.

版本四:

  grep有多个用法,其中有grep/fgrep/egrep,后面两个只不过是第一个带参数的alias,但网上说用fgrep会更快,fgrep是fix
string grep,不解析pattern,搜索会更快.

  还有的说法在grep前加LANC=C,即用的时候为LANC=C grep XXXX,我试了,几乎没影响.

  改进:

    使用fgrep

  结果:

    略微有效,现在每秒稳定在15~18个了.

版本五:

  其实我这里非常需要用到一个数据结构,map,字典结构,要是我可以预先把日志里所有的messageId->status处理好,然后我直接查就可以了,但是没找到shell下面map结构的工具...据说bash
4.2有,但用起来也很复杂,如果用python/java来写就实在太简单了,但我想挑战shell,用shell实现这个需求,而且用grep来匹配字符串效率是最高的,尝试用map失败.

版本六:

  由于用了多线程对同一个文件进行grep,那文件的写性能肯定很影响效率啊!

  尝试一: 把mail.log文件读到内存里,即logFile3=`cat ${logFile2}`,然后再用echo "${logFile3}"
|grep XXX这样去筛选.

  结果: 一运行就报错了...不给这样用..也不知道为啥,报的是参数过长...mail.log文件有88MB,不行.

  于是我想能不能搞个linux下的ramdisk,这样肯定能大大提升mail.log的读性能啊!

  google了一下资料发现,linux下ramdisk原生就是支持的,就在ls -al
/dev/ram*,预设了一些,但是用的时候,ramdisk大小是固定的,一旦分配了,重启前就不能改变了.这样不好,这台机器上的主要服务不是我现在用的日志分析小程序,不能独占那么多内存,而且日志大小每天都不一样,不能直接分配一个较大的内存来这样用.

  然后我再找到了/dev/shm,这是默认是内存的一半大小,用于共享内存使用的.用的是tmpfs,更重要的是动态的,如果你不放东西进去
,他占用内存就是0,如果你较大的东西进去再删掉,内存能释放掉让给其它程序使用.

  而且/dev/shm是可以安全使用的,很多服务器会用这个目录来当一些临时文件的存储,更有甚者把/tmp挂载到/dev/shm下面!非常满足我的需求!

  改进:

    把mail.log放到/dev/shm

  结果:

    分析日志提升到每秒55条了~!YES!大喜~

以上就是我分析日志从每秒处理3个结果到每秒处理55个结果过程,
性能足足提升了16倍啊!现在仅需一个小时就可以把19W条messageid分析完了,不错的结果.或许还有改进的空间,继续折腾吧.

分析邮件日志从每秒处理3个结果到每秒处理55个结果过程(grep提速)

时间: 2024-10-16 17:20:06

分析邮件日志从每秒处理3个结果到每秒处理55个结果过程(grep提速)的相关文章

sarg分析squid日志

1.SARG介绍 SARG的全称是:Squid Analysis Report GeneratorSARG非常好用的Squid日志分析工具,它输出html格式,可以详细列出了每一位用户访问internet的站点信息,时间占用信息,排名,连接次数,访问量,访问量等.软件的主页:http://sarg.sourceforge.net/sarg.php 目前最新的版本是sarg-2.3.1 ####要使用SARG必须有网页页面,所以先安装apache.yum -y install httpd* ,安装

awk 分析web日志(页面执行时间)

shell脚本分析 nginx日志访问次数最多及最耗时的页面(慢查询) 当服务器压力比较大,跑起来很费力时候.我们经常做站点页面优化,会去查找那些页面访问次数比较多,而且比较费时. 找到那些访问次数高,并且比较耗时的地址,就行相关优化,会取得立竿见影的效果的. 下面是我在做优化时候,经常用到的一段shell 脚本. 这个也可以算是,统计web页面的slowpage 慢访问页面,象mysql slowquery . 以下是我的:nginx 配制 log_format main '$remote_a

分析ngnix日志文件的开发程序记录

package com.school.statistics; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; impor

在Linux上使用logwatch分析监控日志文件

原文:http://seanlook.com/2014/08/23/linux-logwatch-usage/ 1. 介绍 在维护Linux服务器时,经常需要查看系统中各种服务的日志,以检查服务器的运行状态. 如登陆历史.邮件.软件安装等日志.系统管理员一个个去检查会十分不方便:且大多时候,这会是一种被动的检查,即只有在发现系统运行异常时才会想到去查看 日志以获取异常的信息.那么如何主动.集中的分析这些日志,并产生报告,定时发送给管理员就会显得十分重要. logwatch 是一款用 Perl 语

awk分析nginx日志里面的接口响应时间

最近,有客户反应客户端卡,老板集合技术人员开会讨论,找出慢的原因,由此产生了分析nginx响应时间,由于线上环境nginx日志格式带上了引号,处理起来有点麻烦,以下是处理过程 一.nginx日志格式 log_format main '$remote_addr – $remote_user [$time_iso8601] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user

shell脚本分析nginx日志

第一版,比较粗糙,仅限于能用 正在写入的文件不能用tar进行压缩 --------压缩日志---------------------- 94 access.log 95 tar: access.log: file changed as we read it 96 #### 压缩日志失败 #### #!/bin/sh #分析nginx日志 DATE=`date '+%Y%m%d-%H%M'` ARCHIVE=/usr/log_bak/nginx_$DATE.tar.gz MESSAGE=/usr/

利用LogParser分析IIS日志

LogParser是微软官方出品的用于读取分析IIS日志的工具,使用类SQL语句过滤文本日志内容,并可将内容导出到csv.sqlserver作进一步分析 下载地址:http://www.microsoft.com/en-us/download/details.aspx?id=24659 目前最新版本为2.2,下载后一直下一步,默认安装目录为:C:\Program Files (x86)\Log Parser 2.2\     一.获取IIS日志 记日志时间默认是UTC,如要使用本地时间记录,可勾

vsftpd开启日志记录上传、下载、删除,分析xferlog日志

在web服务器上搭建了vsftpd用来上传代码程序,开启日志记录客户端的上传.下载删除等操作: #修改/etc/vsftpd/vsftpd.conf [[email protected] ~]# vim /etc/vsftpd/vsftpd.conf anonymous_enable=NO anon_root=/ftpanon local_enable=YES write_enable=YES local_umask=022 dirmessage_enable=YES dual_log_enab

awstats分析nginx日志文件

awstats分析nginx日志文件,将生成的结果(为txt文件)保存在/var/www/awstats目录下,通过apche来 显示生成的结果. nginx的域名为:www.a.com:80 LogFile="/usr/local/mybin/nginx/logs/access.log"  #nginx的日志文件路径 DirData="/var/www/awstats/" #awstats生成结果的保存路径 SiteDomain="www.a.com&q