今年一年都没有怎么静下心写点东西,事情很多,变故也很多。上半年在老东家,邮件系统的架构做完了,Exchange2010也有了点了解。上个月,又杀回了北京。北京有很多朋友,也有很多51CTO的朋友,以后线下活动,也可以更多的参与了。。
    最近一直很忙,家里的,工作的。工作上的事情,也是很凌乱,或者叫多线程,一会干个这,一会干戈那。现在有了点时间,也该写点东西了。前几天做了件事情,觉得还是有点收获的,应该记录下来,为自己沉淀点东西。也可以分享给好多一直还在用站短问候我的朋友们。

    前段时间碰到这么样一个事情,有封从外部组织发送到公司某客服账户的邮件,按预期,应该根据传输规则,将此邮件复制一份并密抄给另一个邮箱账户,作为备份数据。但客服系统的管理员发现,出现了邮件丢失的情况。就是说,按照预期会生成的邮件,没有收到,导致客服系统,和备份账户中的邮件不一致。这个时候需要查看这封邮件的跟踪日志,来确定邮件到底是在哪个过程中,丢失的。。邮件系统的管理员接到这件事情以后就开始检查,Exchange里面已经做了邮件跟踪日志,但结果发现不全,一个星期以前的,都没有了。因为之前有个习惯,就是定期将跟踪日志拷贝出来保存在另外一个地方,进行存档。目的有两个,一个是避免占用空间过多导致服务器资源紧张以及性能问题。第二个原因就是一旦对邮件系统进行备份,日志将会自动清除,也就意味着使用exchange的管理工具,只能看到上次备份以来的邮件跟踪信息。
 
    关于这件事情,就不多说了,反正最后的结果是,我们通过找到之前备份的邮件跟踪日志,查出了问题所在。但问题解决之后,我有了一个想法。Exchange的跟踪查询工具,是可以满足我们最基本的跟踪查询需求。但是限制因素很多,比如日志的路径,文件类型的数据等。当然,不排除像 尘封メ心 或者 cashcat 那样的Exchange高手,可以通过很多手段,甚至PowerShell等专业工具来实现邮件的跟踪查询。。但是我想,如果能将跟踪日志做成一个数据库,是不是更好呢?比如放到SQL里面,大家都知道光是SQL的查询,就可以做到非常丰富。还有报表服务,可以做出一个非常友好的查询界面,供一些非IT专业人员来进行查询。如果需要更专业的分析,SQL还有一个强大BI功能,绝对满足任何要求的查询。甚至可以变态的分析出每天公司里面哪个男同事跟哪个女同事沟通最密切,他们的邮件都说了什么。。

    所以,我的想法就是,利用SQL强大的查询、分析功能,实现对邮件的跟踪。

    根本的需求有了,下面就得对需求,进行分析了。首先,把握住需求的核心对象,就是跟踪日志,更准确的说,是某一条用于描述邮件传递过程的日志信息。。其次,要理清思路,想清楚整个信息传递的过程。这个过程,简单来说的话,就是,最初的数据是生成于Exchange跟踪日志目录,然后需要被导入到SQL数据库中,最后通过SQL查询被检索出来。。
 
    对象搞清楚了,需要进行处理的过程搞清楚了,下面就是搞清楚应该怎么办。第一,日志数据的生成,没有问题,Exchange本身就会生成.log的日志文件,或者配置Exchange启用跟踪日志功能。第二,将.log文件的内容导入到SQL数据库当中,这一步是关键。第三,进行信息检索,这个也不是问题,SQL很容易被查询。所以,整件事情的唯一需要做的,就是把.log的文件内容导入到SQL中。

    这里我就不Step-by-Step的讲怎么一步一步操作的了,因为整个过程相对来说,步骤还是很多的。我这里就简单介绍一下如何实现的,只要大家对SQL有基本实际经验,应该都不是问题。

    先来用一句话概括:通过SQL的BCP语句,实现数据的批量导入。。当然,前提是要先建表,.log文件中的每个列,作为表的列,就可以了。
    BCP语句的语法,可以查SQL的联机丛书,或者微软的TechNet网站进行查询,语法还是很简单的。我就不多介绍了,这里我只把我用到的贴上来。。
 
    bcp ExchangeLogs.dbo.[MessageTracking] in "D:\Exchange Logs\Unicode\MSGTRK20100703-1.txt " -T -Slocalhost -t, -r\n -w -e"D:\Exchange Logs\Bulkinsert\error_MSGTRK20100703-1.txt"

    看起来很简单吧?但是我还是碰了很多钉子。。所以,我觉得比写Step-by-Step的步骤更重要的事情,是把我遇到的这些钉子拔出来给大家看看。

    钉子一:文件格式
        有心的朋友可能已经看到上面的BCP命令当中,是“MSGTRK20100703-1.txt”而不是“.log”的。更有心的,可能发现路径里面有个Unicode的文件夹。这都不是意外啊,这就是最大的一颗钉子。
        其实SQL DB本身就支持从某个文本中批量的导入数据,可以直接用Studio的图形界面,也可以用“bulk insert”,或者是我用到的BCP命令。但是我碰到了一个头疼的问题就是,死活数据导入不成功,各种方式都用过了。后来发现,Exchange自动生成的.log文件,文字编码是使用的UTF-8标准,而SQL报错说不支持。。怎么办?答案是,转!
        先转格式。。一个很土的办法就是,用记事本打开log文件,然后什么别改,直接另存为.txt,注意这时有个“编码”选项,记得要选成“Unicode”。。但是这个土办法,转一个两个还行,一个Exchange环境运行个几年下来。。那得有多少.log文件啊?所以说土嘛。。那怎么样能够批量的进行编码转换呢?

    钉子二:批量进行格式转换
        附件里有个工具,是网上下载的,怕有毒的,就自个去找Google它老人家要吧。。批量转格式的方法,我相信不止一种,我也相信这个工具绝对不是最好的,如果哪个以后找到更好的,记得回来通报一下。。
        因为这个工具,确实是个小工具,经不起大的工作量。我第一次的时候,一次性选了一个文件夹,大概4G左右的日志,有好几百个.log文件吧。。结果小工具直接罢工了,试了好几次,终于摸出门路来了。。一次选的,不能太多,1G左右的量最好,要不然就把它撑爆了。。呵呵。。

    钉子三:生成.bat脚本
        经过几个回合,我的所有的UTF-8编码的.log文件,都被转成了Unicode编码的.txt文件。剩下的,就是往SQL里面导入了。土人的做法是,一次一次的在CMD里面运行BCP的这个命令(题外话:记住,那个叫CMD,命令提示符,不要再说是DOS了,很土的),每次都把另外一个文件名复制到上一次运行的命令参数里面,修改掉之前的。
        那么多的文件,一次一次运行,会死人的啊。。于是出现了一个神人,他主张用.bat脚本,把这条命令在一个TXT文本里面复制个万八千行的,一次执行完所有命令。这时又面临一个问题,就是脚本里面,每一行当中的那个文件名,都是不一样的,这时他想到一行一行修改文件名。。但是,如果面对成千上万个文件,就意味着要Copy上万次文件名。。所以说,能干出这事的,都是神人啊。
        那我们不是神,是人,是人就会使用工具,这时我们想到了Excel。利用Excel的文本函数,可以很方便的将一排文字,切割成几列,然后修改其中一列,最后再组合成一个完整的文本内容。。
        如果非要知道怎么做,可以参考这里《巧用Excel函数,简化批量导入AD用户及密码修改》 http://bisheng.blog.51cto.com/409831/182286 ,虽然内容不一样,但异曲同工,灵活运用嘛。

    好,三颗钉子拔完,此事基本搞定。其实,其间也走过一些弯路,一些回头路,还有好多小的钉子。反正最终,成功的将.log文件的内容,导入到了SQL数据库当中。后面的事情就好说了,我试过select语句,还是很好用的,而且把几个常用查询语句保存了下来。
    其实,关键是,只要数据进入到SQL,后面就都好办了。无论是查询语句,报表,甚至是BI,能够将邮件跟踪的分析做到什么样一种高度,就看你对SQL的研究深度了。

    再说说遗憾。。遗憾的事情就是,这所有的过程,除了Exchange或者SQL本身可以完成的工作以外,其他的操作,必须由人手动完成。。只不过我们是用了一些自动化的方式,进行了一些批量的处理,简化了一些工作量而已。。真正的全自动化的过程,还需要进一步完善。当然,再想进一步,光靠SQL已经是不够了。。

    最后,我再展望一下,如果希望做到全自动化,至少有几个方面的问题需要解决。
    第一,需要对Exchange生成日志的那个目录做监控,一旦发现有日志生成,自动将其进行转化。当然具体的过程,可能还需要考虑是否先判断文件已写完,或者考虑先复制到另一文件夹,再做处理。
    第二,文件格式的转换,就不能用我们那个小工具了,必须通过标准的文字编码转换方式进行。
    第三,需要自动的出发SQL的数据导入进程,并校验整个过程中的完整性和正确性。
    如果能做到这三个方面的自动化处理,基本上,就完美了。

    可能有人此时听得有点犯晕,也可能有人已经有所感悟。。这不就是数据交换么?这不就是中间件么?这不就是Biztalk么??

    人云:查询个日志,把Biztalk都请出来了??杀鸡焉用牛刀呼??我曰:闲来之时,可以一试。。

    全文完。。。^_^....