一种避免重复日志输出的处理方法及系统与流程

文档序号:12465555阅读:383来源:国知局
一种避免重复日志输出的处理方法及系统与流程

本发明涉及系统日志文件处理技术领域,尤其涉及一种避免重复日志输出的处理方法及系统。



背景技术:

程序发布到使用者的手上,可能还会存在一些bug,使用者不可能记得之前所做的操作或者很难描述问题,程序开发人员要修复这些bug通常很难,日志能够帮助开发者快速定位程序的bug。但是有时候会发现拿到日志文件非常大,有大量重复的的一条或者几条消息充斥着整个日志文件,例如如果不是一个不会导致需要关闭程序的致命的error重复产生的时候,可能就会有大量的重复日志。



技术实现要素:

本发明要解决的技术问题在于针对现有技术中日志文件有大量重复,重复处理耗费大量资源的缺陷,提供一种避免重复日志输出的处理方法及系统。

本发明解决其技术问题所采用的技术方案是:

本发明提供一种避免重复日志输出的处理方法,包括以下步骤:

S1、在日志记录系统中,调用日志写入接口函数传入当前日志信息,并为当前日志信息添加参数唯一标识;

S2、生成并打开新日志文件,获取日志记录系统中的日志列表,比较当前日志信息和日志列表中现有的日志信息的参数唯一标识,若不存在相同的参数唯一标识,则向新日志文件中写入当前日志信息;若存在相同的参数唯一标识,则表示当前日志信息已经存在于现有日志文件中,对当前日志信息进行过滤处理;

S3、关闭新日志文件,完成重复日志信息的处理。

进一步地,本发明的步骤S2中对当前日志信息进行过滤处理的方法具体为:

判断日志列表中存在的当前日志信息是否过期:

若过期,则向新日志文件中写入当前日志信息;

若未过期,通过当前日志信息更新现有日志文件,检测当前日志信息的长度,若当前日志信息长度大于日志长度设定值,则从末尾截断当前日志信息,使其长度满足日志长度设定值;若当前日志信息的长度小于日志长度设定值,则在当前日志信息末尾添加空格,使其满足日志长度设定值。

进一步地,本发明的步骤S1中日志写入接口函数为:

void log(int level,int code,const char*msg,...)

其中,level为日志等级,msg为日志信息,code为参数唯一标识,日志写入接口函数末尾能增加日志参数。

进一步地,本发明的方法中,当调用log函数记录日志信息msg的时候,需要保存或者更新该条msg日志的相关信息,为下次记录该条msg时提供操作依据;日志相关信息通过结构体stLogMsg和StLogFile进行记录;

stLogMsg结构体中包括:

日志标识id、该日志最后记录时间nSecLastRecord、该日志记录的位置nSeekPos、该日志行nRow、该日志长度nMesLen、该日志记录的次数nRecordCnt;

StLogFile结构体中包括:

日志文件的行数nRows、某一日志的最新记录与上条记录的最大时间间隔nSecExceed、某一日志的最新记录与上条记录的最大行数间隔nRowExceed。

进一步地,本发明的步骤S2中生成新日志文件时,按照日期生成日志文件的名称,并将新日志文件的名称添加到日志列表,其方法为:

通过当前的日期生成日志文件的名称,将其与stLogMsg结构体中的日志文件名称比较,如果相同,则不做处理;如果不同,表示是不同的日志文件,则清理stLogMsg结构体中的日志列表中保存的所有日志信息,并给stLogMsg结构体中的日志文件名称设置新的日志文件名。

进一步地,本发明的步骤S2中写入日志信息的方法具体为:调用fseek函数把文件指针的位置指向日志文件的末尾,使用fputs函数往日志文件中写入日志信息。

进一步地,本发明的方法中,判断日志列表中存在的当前日志信息是否过期的方法具体为:

若stLogFile::nRows-tLogMsg::nRow>=stLogFile::nRowsExceed,或stLogMsg::nRow-nSecLastRecord>=stLogFile::nRowsExceed,则表示当前日志信息对应的上一次日志信息过期。

进一步地,本发明的参数唯一标识为日志错误代码。

本发明提供一种避免重复日志输出的处理系统,包括:

日志写入接口函数调用单元,用于在日志记录系统中,调用日志写入接口函数传入当前日志信息,并为当前日志信息添加参数唯一标识;

日志信息过滤单元,用于生成并打开新日志文件,获取日志记录系统中的日志列表,比较当前日志信息和日志列表中现有的日志信息的参数唯一标识,若不存在相同的参数唯一标识,则向新日志文件中写入当前日志信息;若存在相同的参数唯一标识,则表示当前日志信息已经存在于现有日志文件中,对当前日志信息进行过滤处理;

日志输出单元,用于关闭新日志文件,完成重复日志信息的处理。

本发明产生的有益效果是:本发明的避免重复日志输出的处理方法,通过对日志信息添加参数唯一标识,达到对日志信息进行标识的目的,能够有效的检测并过滤掉重复的日志信息;该方法能够避免大量重复的一条或者几条消息充斥着整个日志文件,也避免了因为此原因而导致日志文件过于臃肿,这为开发人员快速定位问题起到了一定的作用,大大提高了工作效率。

附图说明

下面将结合附图及实施例对本发明作进一步说明,附图中:

图1是本发明实施例的流程图;

图2是本发明实施例的日志相关结构图。

具体实施方式

为了使本发明的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本发明进行进一步详细说明。应当理解,此处所描述的具体实施例仅用以解释本发明,并不用于限定本发明。

如图1所示,本发明实施例的避免重复日志输出的处理方法,包括以下步骤:

S1、在日志记录系统中,调用日志写入接口函数传入当前日志信息,并为当前日志信息添加参数唯一标识;本实施例的参数唯一标识为日志错误代码。

日志写入接口函数为:

void log(int level,int code,const char*msg,...)

其中,level为日志等级,msg为日志信息,code为参数唯一标识,日志写入接口函数末尾能增加日志参数。

当调用log函数记录日志信息msg的时候,需要保存或者更新该条msg日志的相关信息,为下次记录该条msg时提供操作依据;日志相关信息通过结构体stLogMsg和StLogFile进行记录;

stLogMsg结构体中包括:

日志标识id、该日志最后记录时间nSecLastRecord、该日志记录的位置nSeekPos、该日志行nRow、该日志长度nMesLen、该日志记录的次数nRecordCnt;

StLogFile结构体中包括:

日志文件的行数nRows、某一日志的最新记录与上条记录的最大时间间隔nSecExceed、某一日志的最新记录与上条记录的最大行数间隔nRowExceed。

S2、生成并打开新日志文件,获取日志记录系统中的日志列表,比较当前日志信息和日志列表中现有的日志信息的参数唯一标识,若不存在相同的参数唯一标识,则向新日志文件中写入当前日志信息;若存在相同的参数唯一标识,则表示当前日志信息已经存在于现有日志文件中,对当前日志信息进行过滤处理;对当前日志信息进行过滤处理的方法具体为:

判断日志列表中存在的当前日志信息是否过期:

若过期,则向新日志文件中写入当前日志信息;

若未过期,通过当前日志信息更新现有日志文件,检测当前日志信息的长度,若当前日志信息长度大于日志长度设定值,则从末尾截断当前日志信息,使其长度满足日志长度设定值;若当前日志信息的长度小于日志长度设定值,则在当前日志信息末尾添加空格,使其满足日志长度设定值。

S3、关闭新日志文件,完成重复日志信息的处理。

本发明实施例的避免重复日志输出的处理系统,包括:

日志写入接口函数调用单元,用于在日志记录系统中,调用日志写入接口函数传入当前日志信息,并为当前日志信息添加参数唯一标识;

日志名称更新单元,用于生成新日志文件,若新日志文件的名称与日志列表中现有的日志文件名称均不相同,则将新日志文件名称添加到日志列表中;

日志信息过滤单元,用于生成并打开新日志文件,获取日志记录系统中的日志列表,比较当前日志信息和日志列表中现有的日志信息的参数唯一标识,若不存在相同的参数唯一标识,则向新日志文件中写入当前日志信息;若存在相同的参数唯一标识,则表示当前日志信息已经存在于现有日志文件中,对当前日志信息进行过滤处理;

日志输出单元,用于关闭新日志文件,完成重复日志信息的处理。

在本发明的另一个具体实施例中,对出现的名词进行如下解释:

●FILE

FILE它实际上是由系统定义的一个C语言结构,该结构中含有文件名、文件状态和文件当前位置等信息。在编写源程序时不必关心FILE结构的细节。例如:FILE*fp;表示fp是指向FILE结构的指针变量,通过fp即可找存放某个文件信息的结构变量,然后按结构变量提供的信息找到该文件,实施对文件的操作。习惯上也笼统地把fp称为指向一个文件的指针,文件指针在C语言中用一个指针变量指向一个文件。

在C语言中,文件操作都是由库函数来完成的,本发明中涉及到的文件操作函数主要有fread、fwrite、fseek和ftell,fopen函数用来打开一个文件,

fclose函数关闭一个文件,fseek移动文件流的读写位置,ftell用来取得文件目前读写的位置。

●日志

日志是记录系统中硬件、软件和系统问题的信息,同时还可以监视系统中发生的事件。用户可以通过它来检查错误发生的原因,或者寻找受到攻击时攻击者留下的痕迹。

相关接口和函数介绍:

●fopen

c语言库函数该,用于打开文件。

函数原型:FILE*fopen(const char*path,const char*mode);

参数:“path”是被打开文件的文件名;“mode”是指文件的类型和操作要求。

返回值:文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回NULL,并把错误代码存在errno中。

●fclose

c语言库函数该,功能是关闭一个文件流。注意:使用fclose()函数就可以把缓冲区内最后剩余的数据输出到内核缓冲区,并释放文件指针和有关的缓冲区。

函数原型:int fclose(FILE*fp);

返回值:如果流成功关闭,fclose返回0,否则返回EOF(-1)。(如果流为NULL,而且程序可以继续执行,fclose设定error number给EINVAL,并返回EOF。)

●fputs

c语言库函数该,具有的功能是向指定的文件写入一个字符串(不自动写入字符串结束标记符‘\0’)。

函数原型:int fputs(char*string,FILE*fp);

参数:string为将要写入的字符串;fp为文件流指针。

返回值:成功写入一个字符串后,文件的位置指针会自动后移,函数返回值为非负整数;否则返回EOF(符号常量,其值为-1)。

●fseek

c语言库函数该,函数的功能是设置文件指针的位置。

函数原型:int fseek(FILE*fp,long offset,int fromwhere);

参数:参数fp为已打开的文件指针;参数offset为根据参数fromwhere来移动读写位置的位移数。参数fromwhere为下列其中一种:SEEK_SET、SEEK_CUR、SEEK_END。SEEK_SET表示从距文件开头offset位移量为新的读写位置.SEEK_CUR以目前的读写位置往后增加offset个位移量.SEEK_END将读写位置指向文件尾后再增加offset个位移量.

返回值:当调用成功时则返回0,若有错误则返回-1,errno会存放错误代码.

●ftell

c语言库函数该,该函数用来取得文件流目前的读写位置.

函数原型:long ftell(FILE*fd);

返回值:当调用成功时则返回目前的读写位置,若有错误则返回-1,errno会存放错误代码。

一般的日志记录系统,都会有一个日志写入接口函数,该函数的参数一定得有日志内容,日志等级等其他参数可选,例如void log(int level,const char*msg,...)该函数参数包含日志等级level与日志内容。本发明需要避免同一条日志短时间内重复输出到文件,那么就需要能够唯一确认该条日志消息,可以通过给该日志函数新填一个参数唯一标记日志,也可以通过在log函数内部计算该msg参数的哈希值以确定其为一。由于本人开发的系统使用的log函数需要传入日志错误代码,所以这里以该参数作为日志的唯一标示。日志函数为void log(int level,int code,const char*msg,...)。

当调用log函数记录msg的时候,需要保存或者更新该条msg日志的相关信息,为下次记录该条msg时如何操作做判断。日志相关结构如图2所示:

stLogMsg结构体记录某一类日志的信息,日志通过错误代码唯一标识,所以这里stLogMsg::id即错误代码,该结构更多成员的介绍可以看其注释。

StLogFile为日志文件结构体,StLogFile::nSecExceed与StLogFile::nRowsExceed是日志信息过期的判断条件,如果该日志上一次的记录信息过期,需要把当前日志当成新日志来处理,新日志需要记录到文件当前的末尾位置。当某类型日志本次记录与上次记录时间隔的太久或者该日志与日志文件的最新日志的行数隔的太远,称之为日志过期。stLogMsg::strFileName为日志文件名称,当日志文件发生改变,代表该文件的stLogMsg结构对象的stLogMsg::lstLog的所有日志信息需要清理。

下面详细介绍本实施例中日志记录实现流程(调用log函数记录日志前,需要设置StLogFile::nSecExceed与StLogFile::nRowsExceed等日志信息过期条件,本系统设置的StLogFile::nSecExceed为3,StLogFile::nRowsExceed为50):

a)调用log函数,传入日志等级,错误代码,msg内容等参数。

b)通过当前的日期生成日志文件的名字(本系统要求每天一个日志,如果该系统运行跨天,会使用新的日志文件,日志文件根据日期来命名),与stLogMsg::strFileName比较,如果不同(相同则不做处理),表示是不同的日志文件了,则清理stLogMsg::lstLog保存的所有日志信息,并给stLogMsg::strFileName设置新的日志文件名。

c)fopen函数打开日志文件,通过log函数参数code,在stLogMsg::lstLog中查找是否存在该条日志记录信息。如果不存在,执行步骤d,否则执行步骤e。

d)调用fseek(fd,0L,SEEK_END)把文件指针的位置指向文件的末尾,使用fputs函数往文件写入该msg内容,并把文件的行数stLogFile::nRows增加1(注意每条日志在文件中都写成一行)。

由于该条msg第一次写入日志文件记录,所以需要在stLogMsg::lstLog添加stLogMsg结构的日志信息。

stLogMsg::id赋值为code,

stLogMsg::nSecLastRecord通过获取系统时间获取,

stLogMsg::nSeekPos为当前日志的文件写入位置,新日志需要记录到文件当前的末尾位置,获取当前日志写入的位置需要调用fseek(fd,0L,SEEK_END),让文件指针的位置指向文件的末尾,然后通过ftell获取文件的当前位置。

tLogMsg::nRow为该日志所处的文件的行,赋值为stLogFile::nRows;

tLogMsg::nRecordCnt该日志记录的次数,由于第一次记录,设置为1;

tLogMsg::nMsgLen该日志内容的长度(注意这里需要加上日志记录的次数的信息,这是本日志系统在日志信息后强制加的信息,虽然重复日志信息不记录,但是可以通过日志记录的次数的信息了解到该条日志的执行的次数)。

e)由于该msg在stLogMsg::lstLog中已经存在日志信息,所以要通过该stLogMsg结构日志信息来决定如何对该条信息处理了。首先要判断该条日志信息是否过期。如果stLogFile::nRows-tLogMsg::nRow>=stLogFile::nRowsExceed或系统时间stLogMsg::nRow-nSecLastRecord>=stLogFile::nRowsExceed,则表示当前msg上一次日志记录信息过期(反之则没过期),需要把该msg作为新的日志要记录到文件尾,操作和步骤d一样。

如果日志信息没有过期,只需要通过该条msg更新上一次日志即可,这也是本发明的特别的地方。日志更新步骤如下:

检查当前msg的长度(一般相同的code标识的log长度是相同的,但是有可能因为某些原因而导致log长度不一样,可以见下面举例。另外因为文件的写入是覆盖写,如果当前msg的长度大于上次的长度,有可能会覆盖其他的日志),

i.如果当前msg的的长度>stLogMsg::nMsgLen(注意日志的长度都

是在强制添加固定的长度信息后的长度,所以msg的长度也需要加上这个长度),从末尾截断该msg使该msg的长度还是stLogMsg::nMsgLen(也可以把该日志当做过期来处理),

ii.如果当前msg长度<stLogMsg::nMsgLen,则在msg后面添加空

格填充自至msg长度为stLogMsg::nMsgLen。

例如:有一条第一次已经写入文件的打开摄像头失败的log,该日志可能因为摄像头的名称不一样而导致该日志长度会不一样(注意该日志‘}’后面的字符串是强制添加的日志记录次数的信息,该信息长度为固定的18,times字符串冒号后面有8个空格为stLogMsg::nRecordCnt预留,即使用9个字符的长度存放该日志记录的次数stLogMsg::nRecordCnt)

[2016-XX-XX 18:48:06.288][ERROR][0xFFFF0001]{open camera CAMERA10failed.}-times:1

该条日志写入文件后更新日志信息stLogMsg::nMsgLen为94(msg的长度为76+18);

如果现在马上又有一条打开摄像头失败的类型的msg(该msg为[2016-XX-XX 18:48:06.688][ERROR][0xFFFF0001]{open camera CAMERA100failed.})要写日志,因为这条msg长度77加上日志记录次数的信息长度18的长度肯定大于stLogMsg::nMsgLen,截断该msg后,该msg为

[2016-XX-XX 18:48:06.688][ERROR][0xFFFF0001]{open camera CAMERA100failed.

写入文件的日志内容为:

[2016-XX-XX 18:48:06.688][ERROR][0xFFFF0001]{open camera CAMERA100failed.-times:2

接着又有一条打开摄像头失败的类型的msg(该msg为[2016-XX-XX18:48:06.688][ERROR][0xFFFF0001]{open camera CAMERA1failed.})要写日志,可以看到该msg长度为75,补充空格后,该msg为(msg后面有一空格):

[2016-XX-XX 18:48:06.888][ERROR][0xFFFF0001]{open camera CAMERA1failed.}

写入文件的日志内容为:

[2016-XX-XX 18:48:06.888][ERROR][0xFFFF0001]{open camera CAMERA1failed.}-times:3

把日志记录次数stLogMsg::nRecordCnt增加1,并更新到日志的信息中。这样通过更新日志的次数,而不重复记录日志的方式,不仅没有损失日志的条数等信息,而且还避免了重复。

调用fseek函数,使让文件指针的移到stLogMsg::nSeekPos的位置,调用fputs函数把日志字符串写入文件,至此更新结束。

f)使用fclose函数关闭日志文件。

可以看到,使用该方案,在有大量重复的同一日志输出时,只会在之前已经记录过的日志的基础上更新日志记录的次数信息,不会有大量重复的日志信息出现在日志文件中。并且由于有StLogFile::nSecExceed和StLogFile::nRowsExceed等设置日志信息过期的条件,不会导致最新写入的重复日志在日志文件的末尾位置太远。该方案避免大量重复的一条或者几条消息充斥着整个日志文件,也避免了因为此原因而导致日志文件过于臃肿,这为开发人员快速定位问题起到了一定的作用。

应当理解的是,对本领域普通技术人员来说,可以根据上述说明加以改进或变换,而所有这些改进和变换都应属于本发明所附权利要求的保护范围。

当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1