首页 > 其他 > 详细

记录我的第一个awk脚本-日志统计

时间:2015-03-10 02:05:28      阅读:277      评论:0      收藏:0      [点我收藏+]

项目中需要一个统计接口量的脚本,于是尝试着写了第一个awk脚本。

过程不轻松,但是写完了觉得很爽。哈哈

-----------------------------------------------------------------------------------------------------------------------------------

?

#########################################
####思路:
####1 按行读取,需要判断每条记录的归属线程,并缓存起来,
####2 每个线程的记录打印都是有顺序的,输入报文>异常>输出报文
####3 将输入报文覆盖缓存,当第一次读取到Exception时,认为异常开始,将最近一次的输入报文打印,
####4 异常全部打印完毕后,打印输入报文
####注意:
####所有的缓存都是按照线程名称做得,类似于线程变量,互不影响,通过数组实现
####
####使用:
####1 THREAD_KEY需要替换,不同的日志不一样
####2 INPUT_KEY和OUTPUT_KEY如不同也替换
####3 isExclude函数,如有需要可以修改不同的排除条件
#########################################
BEGIN{
#	变量是不带双引号的,变量值需要带着双引号
	THREAD_KEY = "@HttpThreadPool";
	INPUT_KEY = "输入报文";
	OUTPUT_KEY = "输出报文";
	ROW_CACHE = "ROW_CACHE";
	THREAD_NAME = "THREAD_NAME";
	FILE_NAME = "XXXXX";
}

#获取线程名
function getThreadName(str){
#       线程名称开始索引
        THREAD_KEY_END_INDEX = index($0, THREAD_KEY);
        if(THREAD_KEY_END_INDEX > 0){
#               获取线程名称
                THREAD_NAME_T = substr($0, THREAD_KEY_END_INDEX - 9, 9 );
                if(THREAD_NAME_T != "") {
                        THREAD_NAME= THREAD_NAME_T;
                }
        }
	return THREAD_NAME;	
}

#判断此行是否需要排除,后续可增加条件
function isExclude(str){
	return index(str, "通过HTTP方式获取缓存失败");
}

#判断不需打印输入输出报文的异常
function needRequestMsg(str){
	return index(str, "未找到相应文件")  + index(str, "没有生成密钥");
}


{
	if(FILE_NAME != FILENAME){
		if(FILE_NAME != "XXXXX" ){
			printf("+++++++++++++++++文件处理完成[%s]+++++++++++++++++++\n", FILE_NAME);
		}
		printf("+++++++++++++++++开始处理文件[%s]+++++++++++++++++++\n", FILENAME);
		FILE_NAME = FILENAME;
	}

#	获取线程名	
	THREAD_NAME = getThreadName($0);	

#	处理不需要打印输入输出报文的部分
	if(needRequestMsg($0) > 0){
                printf("---------Begin Exception-%s-[%d]------------\n", THREAD_NAME, ++THREAD_EXCEPTION_NUM[THREAD_NAME]);		
		printf("%s\n", ROW_CACHE);
		printf("%s\n", $0);
		getline ;
		while (index($0, "at ") > 0 && index($0, "(") > 0 ){
			printf("%s\n", $0);
			getline;
		}
                printf("---------End Exception-%s-[%d]------------\n", THREAD_NAME, THREAD_EXCEPTION_NUM[THREAD_NAME]);
	}


#	当此行中有关键字Exception	
	if(index($0, "Exception") > 0 && isExclude($0) == 0) {
#		BEGIN_EXCEPTION_FLAG是一个key为线程名称的数组缓存,记录当前线程是否开始一个Exception
                if((BEGIN_EXCEPTION_FLAG[THREAD_NAME] == "" || BEGIN_EXCEPTION_FLAG[THREAD_NAME] == "0")){
#			当没有开始时,将缓存的输入报文打印,同时记录状态为已开始
			BEGIN_EXCEPTION_FLAG[THREAD_NAME] = "1";
		}
#		当此行没有线程名称,且不存在Caused by关键字时,说明为异常被换行,打印上一行
		if(index($0, THREAD_NAME) == 0 && index($0, "Caused") == 0 && index($0, "at ") == 0){
		 	BODY_EXCEPTION[THREAD_NAME] = sprintf("%s\n%s", BODY_EXCEPTION[THREAD_NAME], ROW_CACHE);
		}
#		所有Exception的行都打印
		BODY_EXCEPTION[THREAD_NAME] = sprintf("%s\n%s", BODY_EXCEPTION[THREAD_NAME], $0);
	}
#	存在关键字"at "的行打印
	if(index($0, "at ") > 0 && index($0, "(") > 0){
		BODY_EXCEPTION[THREAD_NAME] = sprintf("%s\n%s", BODY_EXCEPTION[THREAD_NAME], $0);
	}
#	当此行中存在输出报文关键字,且已经开始一个Exception,打印输入报文,Exception体,输出报文
	if(index($0, OUTPUT_KEY) > 0 && BEGIN_EXCEPTION_FLAG[THREAD_NAME] == "1"){
                printf("---------Begin Exception-%s-[%d]------------\n", THREAD_NAME, ++THREAD_EXCEPTION_NUM[THREAD_NAME]);
		printf("%s\n", INPUT_MSG[THREAD_NAME]);
		printf("%s\n", BODY_EXCEPTION[THREAD_NAME]);
		
#		有可能输出报文有换行,目前处理换行一次的情况,判断行尾是"?>"时,读取下一行并打印
		printf("%s", $0);
		if(substr($0, length($0)-1) == "?>"){
                        getline t;
                	printf("%s\n", t);
		} else {
			print "\n";	
		}
		
		printf("---------End Exception-%s-[%d]------------\n", THREAD_NAME, THREAD_EXCEPTION_NUM[THREAD_NAME]);
#		输出报文已打印,Exception结束
		BEGIN_EXCEPTION_FLAG[THREAD_NAME] = "0";
		BODY_EXCEPTION[THREAD_NAME] = "";
		INPUT_MSG[THREAD_NAME] = "";
	}
#	当此行中存在输入报文关键字时
	if(index($0, INPUT_KEY) > 0){
#		缓存此行,并判断是否存在报文换行的情况
		INPUT_MSG[THREAD_NAME] = $0;
		if(substr($0, length($0)-1) == "?>"){
			getline t;
			INPUT_MSG[THREAD_NAME] = sprintf("%s%s", INPUT_MSG[THREAD_NAME], t);
		}
	}
#	缓存当前行
	ROW_CACHE = $0;
}

END{
	printf("+++++++++++++++++文件处理完成[%s]+++++++++++++++++++\n", FILENAME);
}

?

记录我的第一个awk脚本-日志统计

原文:http://z1041950008.iteye.com/blog/2190857

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!