/**
*作者:ahuaxuan
*日期:2008-10-21
**/ [size=medium]
日志监控这个功能应该有很多程序员都遇到过这种需求,一般来说它在关键型应用(尤其涉及到收入问题,该功能也是来自于系统问题发生后我们的反省)上显得尤其重要.下面我们来看看我们之所以需要这丫得前因后果.
我们将其分为两个部分
一开发,开发以人为主导因素,一般得流程是:开发->单元测试->集成测试->黑盒测试.理论上来讲,这个流程是没有问题的,不过有一个前提或者说是基础,那就是我们的程序员和测试人员是不能同时失误的,如果同时失误,那么有问题的代码可能会被部署到服务器运行.
二部署,部署之后程序是否正常很大程度上和服务器软硬件环境有关,如果需要保证我们的程序可以无差错运行,那么就需要保证我们的软硬件环境的正常运行.
有了这两点上的保证,那么我们晚上就可以安心的睡觉了,不过事实上这两个环节都有可能发生问题.
第一点,测试人员和程序员同时粗心的”巧合”确实是会发生,发生的频率和团队的项目管理水平有及其紧密的联系,两者成明显反比,项目管理水平越低,那么发生这种情况的几率就越高,反之亦然.同时,世界上没有不犯错误的人,据我所知,windows2000在开发的时候有900个人员,而测试人员达到了1800个,由此可见,微软非常明白这个道理.
第二点,服务器软硬件问题的发生有时候会非常的蹊跷,比如说网线出了点小问题都能把人折磨半天.或者原本理论上没有问题的网络时不时的会出现点小问题,让人丈二和尚摸不着头脑,尤其是我们可能会半天都没有察觉到它对我们程序的影响.
那么基于以上论断,有规范的流程,有貌似正常的软硬件环境对我们来说还是不够的,我们还需要保证我们的应用运行良好(尤其是核心应用,其他应用看情况).那么一旦我们的应用出现问题,我们怎么才能及时的得到通知呢,日志是个好东西,我们可以从日志下手
对于java程序员来说,最熟悉的莫过于的是log4j,对于c’er来说最熟悉的可能是log4c, 还有log4c++,log4p等等等等,log4````还是比较多的.不过本文并不准备介绍他们的使用步骤或者其他什么方面.
纵观日志监控的类型,基本可以分为2个大类,耦合和解耦.耦合类基本把日志监控的功能整合到应用程序中,比如说扩展log4j(自己写一个myappender之类的,这对于java程序员来说最熟悉),还有扩展log4c(不熟,无发言权)等等.拿扩展log4j来说,在myappender中记录下错误的信息,然后发给一个日志搜集程序也是可以的,如果你不想扩展log4j,那么没有问题,有exceptioninterceptor吗?不管怎样,你一定有一个总的异常拦截的方案,在把这些异常显示到页面之前你总得做点什么吧,ok,就在这里,把这个异常发到日志搜集程序里去吧.
还有一种就是解耦了,也就是说你的应用程序无需关心日志监控方面的问题.交给别人来做吧,这样似乎比较安心一点.那么这样做的一个关键就是在分析日志文件上,分析完之后发送给一个统一的日志搜集程序就行了(这个日志搜集程序收到请求后可以发邮件给当事人).
这样问题就变成了如何解析日志文件了.我把它分为以下几个步骤:
1定义日志格式,要解析日志,那么这个日志数据需要遵循某种规范,比如说我们规定我们的日志必须以”日期 时间 级别:”这样的形式开头
Eg: 2008-10-17 10:00:43 INFO:xxxxxxxxxxxxxxxxxxxxxxxxxxx
2 合理设置日志的输出级别.比如把warn和error的信息输出到单独的文件中去,而不是把它们和info或者debug放在一起.这样做的目的是减轻日志分析器的压力.
3 需要开发一个日志搜集中心,所有项目的日志分析器在分析到错误信息后都可以发到这个统一的日志搜集中心.
下面的代码是我用python写的一个日志分析器的雏形时的代码,仅供理解使用.代码中有一些解释,主要用到了python几个模块:
正则表达式模块,该模块用来判断日志是否符合要求
time模块,常用模块
urllib和urllib2模块,发送http请求模块,日志信息会被发送到统一的日志中心.
cPickle模块,记录最新的日志日期和时间
socket模块,得到机器的ip和机器名
hashlib模块,过滤重复的日志信息
以下是代码部分:
#!python
import re, time
import urllib2, urllib
import cPickle as pp
import zlib, socket, hashlib
#------------------------ setting begin ------------------------
fileAddress = 'E:/workspace/logs/aaa.log'
logLevel = 'ERROR:'
datePattern = '\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2}'
msgReceiveUrl = 'http://localhost:8083/test/logcollect'
fileDataPath = 'D:/a.txt'
sepMinutes = 5
#------------------------ setting end ------------------------
logf = open(fileAddress, 'r')
p = re.compile(datePattern)
class LogParser(object):
def __init__(self, t):
self.lastTime = t
self.msgList = []
self.tmpTime = None
def isNewMsg(self, msg):
currentTimeStr = msg[:19]
currentTime = time.strptime(currentTimeStr, '%Y-%m-%d %H:%M:%S')
if self.lastTime == None:
self.lastTime = time.localtime()
if currentTime > self.lastTime:
self.tmpTime = currentTime
return True
else:
return False
'''
如果是新的日志信息则保存到需要发送的列表中
'''
def collectMsg(self, msg):
if self.isNewMsg(msg):
self.msgList.append(msg)
else:
pass
'''
过滤重复的日志信息
将日志列表中的新日志信息发出去,
'''
def sendMsg(self):
#record the last time
if self.tmpTime != None:
picklef = open(fileDataPath, 'w')
pp.dump(self.tmpTime, picklef)
print 'middle time ------------ ' + str(self.tmpTime)
picklef.close()
finalList = []
existMsgList = []
for tmpmsg in self.msgList:
hash = hashlib.md5(tmpmsg[19:-1]).hexdigest()
if not existMsgList.__contains__(hash):
existMsgList.append(hash)
finalList.append(tmpmsg)
#data = zlib.compress(str(finalList[:1000]))
#print data
print finalList
body = {}
for a in finalList[:10000]:
body['msg'] = a
body['ip'] = socket.gethostbyname(socket.gethostname())
body['hostname'] = socket.gethostname()
#print self.msgList
#cj = cookielib.CookieJar()
# opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
opener = urllib2.build_opener()
urllib2.install_opener(opener)
req = urllib2.Request(msgReceiveUrl, urllib.urlencode(body))
u = urllib2.urlopen(req)
print u.read()
'''
解析日志文件中的每行日志
'''
def parseLog(self):
tmpLogStr = ''
for a in logf:
#print ' pattern result ' + str(p.match(a))
if p.match(a) != None:
if tmpLogStr != '':
self.collectMsg(tmpLogStr)
if a.find(logLevel) > 0:
tmpLogStr = a
else:
tmpLogStr = tmpLogStr + a
if __name__ == '__main__':
picklef = open(fileDataPath)
t = None
try:
t = pp.load(picklef);
except EOFError:
pass
#t = time.strptime('2008-10-17 10:00:43', '%Y-%m-%d %H:%M:%S')
picklef.close()
begin = time.time()
print 'begin --- last log time : ' + str(t)
parser = LogParser(t)
parser.parseLog()
parser.sendMsg()
logf.close()
print 'end ------- total time is ' + str(time.time() - begin)
有了这个脚本,那么我们任何的应用无需作逻辑上的改动,不需要改动java代码,只需要修改一下log4j的配置文件即可.可以说和application是完全解耦的.
ahuaxuan的机器是cpu e4400,频率2g,内存2g,硬盘7200转,型号不知,分析8m的日志文件用时1.2s.该脚本可以使用操作系统的cron功能使其定时运行. 比如说10分钟运行一次.
这样,一旦系统出现问题,相关人员可以立刻收到邮件,及时处理,把损失降到最小.
由于ahuaxuan水平所限,文章或者代码中不免有不妥之处,望不吝赐教[/size]
分享到:
- 2008-10-21 17:16
- 浏览 2446
- 评论(0)
- 论坛回复 / 浏览 (0 / 4407)
- 查看更多
相关推荐
java反编译器,支持jdk5.0 博文链接:https://ahuaxuan.iteye.com/blog/139493
内容概要:本文档介绍了航空公司的业务分析案例研究,涵盖两个主要部分:a) 使用SSIS进行数据转换,b) 利用RapidMiner进行预测分析。这两个任务旨在通过改善客户满意度来优化业务运营。数据来源包括多个CSV文件,如flight_1.csv、flight_2.csv、type.csv、customer.csv 和 address.csv。第一部分要求学生创建事实表、客户维度表和时间维度表,并描述整个数据转换流程。第二部分则需要利用RapidMiner开发两种不同的模型(如决策树和逻辑回归)来预测客户满意度,并完成详细的报告,其中包括执行摘要、预测分析过程、重要变量解释、分类结果、改进建议和伦理问题讨论。 适合人群:适用于对数据科学和商业分析有一定基础的学生或专业人士。 使用场景及目标:本案例研究用于教学和评估,帮助学员掌握数据转换和预测建模的技术方法,提高客户满意度和业务绩效。目标是通过实际操作加深对相关工具和技术的理解,并能够将其应用于实际业务中。 其他说明:此作业占总评的40%,截止时间为2024年10月25日16:00。
一、课题介绍 现在我国尤其是北方城市,工业发达,废弃排放严重,这使得雾霾越来越厉害,让能见度极低。这严重影响了我们的交通系统,导航系统,卫星定位系统等,给人民出行,工作带来极大的不便利。目前市场上高清拍摄设备虽然可以让成像清晰点,但是造价高昂。如果有一套软件处理系统,可以实时地处理含雾的图像,让成像去雾化,让图像变得清晰,将会很受欢迎。 该课题是基于MATLAB平台的图像去雾处理,配备一个人机交互GUI界面,可以选择全局直方图均衡化,Retinex算法,同态滤波,通过对比处理前后的图像的直方图,而直方图是一副图像各灰度值在0-256的分布个数的表,信息论已经整明,具有均匀分布直方图的图像,其信息量是最大的。 二、算法介绍 ①全局直方图均衡化:通俗地理解就是,不管三七二十一,直接强行对彩色图像的R,G,B三通道颜色进行histeq均衡处理,然后进行三通道重组; ②Retinex算法:通俗地讲就是,分离R,G,B三通道,对每个通道进行卷积滤波。
微信支付V2版本的支付接口,java的SDK
一款IDEA好用的插件,适用于旗舰版,可以延长试用期限,你懂的!
内容概要:本文详细介绍了发电机组保护整定方法,讨论了发电机可能遇到的故障状态及相应的保护措施,包括定子绕组故障、转子绕组故障、过电流、过电压等情况,并提供了具体的保护配置。接着,对变压器常见故障进行了分类说明,并给出变压器的主保护和后备保护配置方案。文章进一步计算了不同短路点的短路电流,阐述了互感器的选择标准,并举例解释了纵联保护的应用和后备保护的作用。 适合人群:电力系统工程师、继电保护技术人员及相关研究领域的学者。 使用场景及目标:适用于发电厂和变电站的设计、维护和运行人员,旨在提高电力系统的安全性和稳定性。目标是确保电力系统关键设备的安全运行,防止故障的发生,减少事故造成的损失。 其他说明:本文不仅提供了详细的理论分析,还包括了大量的数据计算和实例说明,有助于读者更好地理解和掌握继电保护的相关知识和技术。
基于C++开发的微商系统项目源码 使用技术:C++/Qt、Mysql、TCP/IP 软件架构 三个大端:服务端、客户端(买家端)、业务端(卖家端) PS:需要连Mysql数据库才能正常使用,连接mysql时记得把用户、密码啥的改为自己的数据库信息
1503ANDH1503002016_20241116222825
数理逻辑近世代数复习资料,思维导图部分
京东中台业务架构敏捷性方法 MotriDSP 落地实践.pdf
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过严格测试运行成功才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
CCF会员复习资料(1).zip
ASP.NET养老院老人信息管理系统源码 这是一款非常优秀的养老院老人信息管理系统。程序功能齐全,可选择性强。 管理员后台: 1、人员信息管理:老人信息管理、管理员信息管理、员工信息管理 2、公寓信息管理:添加公寓楼信息、管理公寓楼信息、添加公寓信息、管理公寓信息 3、公寓安排管理:添加公寓安排、公寓安排管理、缴费管理 4、健康管理信息管理:添加健康管理信息、管理健康管理信息 5、紧急联络人管理 6、意见信息管理 7、公告信息管理:添加公告信息、管理公告信息 8、出入信息管理:请假信息管理、访客记录管理、退住情况 员工后台: 1、人员信息管理:老人信息管理 2、健康管理信息管理:管理健康管理信息 3、紧急联络人管理 4、意见信息管理 5、公告信息管理:管理公告信息 6、出入信息管理:请假信息管理、访客记录管理、退住情况 老人后台: 1、修改个人信息 2、修改登陆密码 3、意见信息管理:发布意见信息、意见信息管理 4、查看公告信息
走向现代化数据分析架构:趋势与挑战.pdf
PHP通用权限管理系统源码 安装说明: 1.把管理系统.sql 导入到MYSQL数据库中,把App/Common/Conf/db.php中的数据库名称,账号密码改成自己的。 2.把程序放在二级目录下,如:http://localhost/xcrm/ 账号 admin 密码admin123 3.请使用IE8以上,或是谷歌浏览器。 4.支持环境php+apache,php版本要大于5.3 注意:删除App下面 Runtime 文件夹;如果Linux服务器,需要分配777权限; 修改config.php数据库连接地址:绝对路径 大家在安装的时候遇到问题 1.页面顶部出现空白一行 解决办法:db.php 要以uft8无BOM格式编码 保存 notepad++ 编辑器里 格式 下 2.乱码问题 解决办法:数据库建表的时候选 uft8-general-ci 编码格式 然后点开 SQL 把1,SQL复制进去,执行就可以了 3、如果程序执行时报错? 解决办法:保存PHP>5.3版本 删除App下面 Runtime 文件夹 使用须知:注释:权限管理,修改完用户所属组之后,
详细介绍及样例数据:https://blog.csdn.net/m0_65541699/article/details/143823092
席卡制作模版会议较多的单位,经常要打印席卡,本模版可以解决燃眉之急
从 0 到 1 构建集群服务质量运营体系降低云成本.pdf
永辉超市的混合云建设与运维.pdf
Java超市订单管理系统源码 运行环境:jdk8(jdk7)+mysql+Eclipse+maven+tomcat7 项目技术:springboot+spring mvc+mybatis+jquery+jsp 注意事项:1.所有模块没有实现查看,编辑,删除,添加功能 2.压缩包中的建库smbms.sql是mysql5.7的语句,其中datetime比较特殊,在低版本mysql下会报错