CN112612760A - 一种日志消息输出方法及装置 - Google Patents

一种日志消息输出方法及装置 Download PDF

Info

Publication number
CN112612760A
CN112612760A CN202011621666.0A CN202011621666A CN112612760A CN 112612760 A CN112612760 A CN 112612760A CN 202011621666 A CN202011621666 A CN 202011621666A CN 112612760 A CN112612760 A CN 112612760A
Authority
CN
China
Prior art keywords
log
log message
message buffer
messages
buffer queue
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Pending
Application number
CN202011621666.0A
Other languages
English (en)
Inventor
臧虎
谢钊
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Agricultural Bank of China
Original Assignee
Agricultural Bank of China
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Agricultural Bank of China filed Critical Agricultural Bank of China
Priority to CN202011621666.0A priority Critical patent/CN112612760A/zh
Publication of CN112612760A publication Critical patent/CN112612760A/zh
Pending legal-status Critical Current

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F16/00Information retrieval; Database structures therefor; File system structures therefor
    • G06F16/10File systems; File servers
    • G06F16/17Details of further file system functions
    • G06F16/1734Details of monitoring file system events, e.g. by the use of hooks, filter drivers, logs
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F16/00Information retrieval; Database structures therefor; File system structures therefor
    • G06F16/10File systems; File servers
    • G06F16/17Details of further file system functions
    • G06F16/172Caching, prefetching or hoarding of files

Landscapes

  • Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • Data Mining & Analysis (AREA)
  • Databases & Information Systems (AREA)
  • Physics & Mathematics (AREA)
  • General Engineering & Computer Science (AREA)
  • General Physics & Mathematics (AREA)
  • Debugging And Monitoring (AREA)

Abstract

本申请实施例公开了一种日志消息输出方法及装置,预先设定固定内存容量的日志消息缓冲区,日志消息缓冲区包括预设数目个日志消息缓冲队列,方法包括:记录函数调用链上发生函数调用异常的当前日志消息;调用日志插入函数,根据日志消息队列的插入索引将当前日志消息存储至日志消息缓冲队列,调用日志输出函数,将日志消息缓冲队列中的多条日志消息输出至外部缓冲区。由此可见,本申请实施例避免了使用动态分配函数分配的内存存储日志消息,而是利用预先设定好的日志消息缓冲区,在进行日志存储和输出时采用控制字节长度提高可靠性,能够保证日志模块在系统异常发生时,日志消息的记录和输出具有可靠性。

Description

一种日志消息输出方法及装置
技术领域
本申请涉及计算机领域,尤其涉及一种日志消息输出方法及装置。
背景技术
当前每个系统都需要部署日志模块,记录系统的日常运行情况。日志模块最重要的一部分是记录系统在运行时出现异常的情况,以便之后技术人员根据日志模块记录的信息,分析系统异常发生的原因,解决系统的异常问题。系统在运行的时候,涉及在系统中的不同模块间的接口或函数的互相调用,如图1所示,为函数调用的示意图。在进行函数调用的时候,可能会出现调用异常的情况,因此就需要日志模块记录下尽可能详细的调用链情况。
现有的系统异常发生时刻记录完整函数调用链的日志模块的方案中,使用了依赖动态内存分配函数分配的内存作为日志消息缓冲区,若系统的内存空间不足,日志模块在记录日志消息时就可能因为调用动态内存分配函数申请内存失败而导致日志消息记录失败,这对于日志模块记录系统发生异常的日志消息是非常不利的,因为日志模块作为技术人员定位系统异常的关键一环必须保证能够在这种高度不稳定甚至是接近崩溃的环境下正确执行日志的记录功能,因此日志模块应该具有远高于一般程序的可靠性。
并且,在将记录系统异常情况的日志消息输出到磁盘时,需要维护一个保持磁盘文件打开状态的文件句柄,在输出完毕之后,还要将文件句柄进行关闭,保证日志资源不会发生泄露风险。但是当系统发生异常时,文件句柄可能也发生异常,导致记录的日志消息无法从内存中顺利输出,进而导致日志模块崩溃,技术人员依然无法得知系统发生异常时的具体情况。
也就是说,当前的日志模块由于利用依赖动态内存分配函数分配的内存作为日志消息缓冲区,不能保证日志消息在记录时的可靠性。当前的日志模块将日志消息输出到磁盘时,由于需要维护文件句柄降低了日志消息输出的可靠性。
综上,当前的日志模块无法保证在系统异常发生时,日志消息的记录和输出的可靠性。
发明内容
为了解决现有技术中日志模块无法保证在系统异常发生时,日志消息的记录和输出的可靠性的问题,本申请提供了一种日志消息输出方法,能够保证日志模块在系统异常发生时,日志消息的记录和输出具有可靠性。
本申请实施例还提供一种日志消息输出方法,预先设定固定内存容量的日志消息缓冲区,所述日志消息缓冲区包括预设数目个日志消息缓冲队列;
所述方法包括:
记录函数调用链上发生函数调用异常的当前日志消息;
判断所述当前日志消息的字节长度是否超过预先设定的日志消息的最大字节长度,若否,则直接调用日志插入函数,根据所述日志消息队列的插入索引将所述当前日志消息存储至所述日志消息缓冲队列,若是,则将所述当前日志消息中超过最大字节长度的部分进行删除,得到截断日志消息,调用所述日志插入函数,根据所述插入索引将所述截断日志消息存储至所述日志消息缓冲队列;
判断所述日志消息缓冲队列中的多条日志消息的总字节长度是否超过外部缓冲区的可用字节长度,若否,则调用所述日志输出函数,将所述日志消息缓冲队列中的多条日志消息输出至所述外部缓冲区,若是,则将所述日志消息缓冲队列中超过所述外部缓冲区的可用字节长度的部分进行删除,得到截断日志消息缓冲队列的多条日志消息,调用日志输出函数,将所述截断日志消息缓冲队列的多条日志消息输出至外部缓冲区,其中,所述外部缓冲区用于用户直接对所述多条日志消息进行处理。
可选的,所述日志消息缓冲区包括多个预先设定的日志消息缓冲队列,预先设定多个所述日志插入函数,所述日志消息缓冲队列的数目与日志插入函数的数目相同,所述日志插入函数与所述日志消息缓冲队列一一对应;
所述调用日志插入函数,根据所述日志消息队列的插入索引将所述当前日志消息存储至所述日志消息缓冲队列包括:
根据所述当前日志消息确定对应的日志插入函数,根据所述日志插入函数确定对应的日志消息缓冲队列;
调用所述对应的日志插入函数,根据所述插入索引将所述当前日志消息存储至对应的日志消息缓冲队列。
可选的,预先设定所述日志消息缓冲队列的日志消息的最大数目,所述最大数目根据所述固定内存容量的日志消息缓冲区确定;
在判断所述当前日志消息的字节长度是否超过所述预先设定的日志消息的最大字节长度之前,所述方法还包括:
判断所述日志消息缓冲队列的日志消息的当前数目是否超过所述预先设定的日志消息的最大数目,若是,返回错误值,若否,则继续判断所述当前日志消息的字节长度是否超过所述预先设定的日志消息的最大字节长度。
可选的,所述方法还包括:
在将所述日志消息缓冲队列中的多条日志消息输出至所述外部缓冲区之后,清空所述日志消息缓冲队列中的多条日志消息。
可选的,所述清空所述日志消息缓冲队列中的多条日志消息包括:
调用所述日志输出函数清空所述日志消息缓冲队列中的多条日志消息。
可选的,所述清空所述日志消息缓冲队列中的多条日志消息包括:
调用日志清空函数将所述日志消息队列的多条日志消息进行清空。
可选的,预先设定所述插入索引的初始值为0;
所述调用日志插入函数,根据所述日志消息队列的插入索引将所述当前日志消息存储至所述日志消息缓冲队列包括:
调用日志插入函数,根据插入索引的初始值将第一日志消息存储至所述日志消息缓冲队列,将所述插入索引的初始值加一作为插入索引的待插入索引值;
调用日志插入函数,根据当前插入索引的待插入索引值将后续日志消息存储至所述日志消息缓冲队列,将所述当前插入索引的待插入索引值加一作为插入索引的待插入索引值。
本申请实施例还提供一种日志消息输出装置,所述装置包括:
预先设定单元,用于预先设定固定内存容量的日志消息缓冲区,所述日志消息缓冲区包括预设数目个日志消息缓冲队列;
记录单元,用于记录函数调用链上发生函数调用异常的当前日志消息;
存储单元,用于判断所述当前日志消息的字节长度是否超过预先设定的日志消息的最大字节长度,若否,则直接调用日志插入函数,根据所述日志消息队列的插入索引将所述当前日志消息存储至所述日志消息缓冲队列,若是,则将所述当前日志消息中超过最大字节长度的部分进行删除,得到截断日志消息,调用所述日志插入函数,根据所述插入索引将所述截断日志消息存储至所述日志消息缓冲队列;
输出单元,用于判断所述日志消息缓冲队列中的多条日志消息的总字节长度是否超过外部缓冲区的可用字节长度,若否,则调用所述日志输出函数,将所述日志消息缓冲队列中的多条日志消息输出至所述外部缓冲区,若是,则将所述日志消息缓冲队列中超过所述外部缓冲区的可用字节长度的部分进行删除,得到截断日志消息缓冲队列的多条日志消息,调用日志输出函数,将所述截断日志消息缓冲队列的多条日志消息输出至外部缓冲区,其中,所述外部缓冲区用于用户直接对所述多条日志消息进行处理。
可选的,所述日志消息缓冲区包括多个预先设定的日志消息缓冲队列,预先设定多个所述日志插入函数,所述日志消息缓冲队列的数目与日志插入函数的数目相同,所述日志插入函数与所述日志消息缓冲队列一一对应;
所述存储单元调用日志插入函数,根据所述日志消息队列的插入索引将所述当前日志消息存储至所述日志消息缓冲队列包括:
所述存储单元根据所述当前日志消息确定对应的日志插入函数,根据所述日志插入函数确定对应的日志消息缓冲队列;
所述存储单元调用所述对应的日志插入函数,根据所述插入索引将所述当前日志消息存储至对应的日志消息缓冲队列。
可选的,预先设定所述日志消息缓冲队列的日志消息的最大数目,所述最大数目根据所述固定内存容量的日志消息缓冲区确定;
在存储单元判断所述当前日志消息的字节长度是否超过所述预先设定的日志消息的最大字节长度之前,所述装置还包括:
判断单元,用于判断所述日志消息缓冲队列的日志消息的当前数目是否超过所述预先设定的日志消息的最大数目,若是,返回错误值,若否,则继续判断所述当前日志消息的字节长度是否超过所述预先设定的日志消息的最大字节长度。
与现有技术相比,本申请至少具有以下优点:
本申请实施例提供了一种日志消息输出方法,预先设定固定内存容量的日志消息缓冲区,所述日志消息缓冲区包括预设数目个日志消息缓冲队列,方法包括:记录函数调用链上发生函数调用异常的当前日志消息;判断所述当前日志消息的字节长度是否超过预先设定的日志消息的最大字节长度,若否,则直接调用日志插入函数,根据所述日志消息队列的插入索引将所述当前日志消息存储至所述日志消息缓冲队列,若是,则将所述当前日志消息中超过最大字节长度的部分进行删除,得到截断日志消息,调用所述日志插入函数,根据所述插入索引将所述截断日志消息存储至所述日志消息缓冲队列;判断所述日志消息缓冲队列中的多条日志消息的总字节长度是否超过外部缓冲区的可用字节长度,若否,则调用所述日志输出函数,将所述日志消息缓冲队列中的多条日志消息输出至所述外部缓冲区,若是,则将所述日志消息缓冲队列中超过所述外部缓冲区的可用字节长度的部分进行删除,得到截断日志消息缓冲队列的多条日志消息,调用日志输出函数,将所述截断日志消息缓冲队列的多条日志消息输出至外部缓冲区,其中,所述外部缓冲区用于用户直接对所述多条日志消息进行处理。由此可见,本申请实施例通过预先设定固定内存容量的日志消息缓冲区,日志消息缓冲区中包括日志消息缓冲队列,通过控制每条日志消息的字节长度,控制日志消息记录的可靠性,通过控制日志消息输出到外部缓冲区的字节长度,控制日志消息输出的可靠性。本申请实施例避免了使用动态分配函数分配的内存存储日志消息,而是利用预先设定好的日志消息缓冲区,在进行日志存储和输出时采用控制字节长度提高可靠性,能够保证日志模块在系统异常发生时,日志消息的记录和输出具有可靠性。
附图说明
为了更清楚地说明本申请实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本申请中记载的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其它的附图。
图1为本申请提供的一种函数调用链示意图;
图2为本申请提供的一种日志消息输出方法实施例的流程图;
图3为本申请提供的一种日志消息缓冲区的示意图;
图4为本申请提供的一种日志消息输出装置实施例的结构框图。
具体实施方式
为了使本技术领域的人员更好地理解本申请方案,下面将结合本申请实施例中的附图,对本申请实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本申请保护的范围。
如背景技术所述,日志模块对于运行在生产环境的系统来说必不可少。日志模块可以用于记录系统的运行状态变化、操作执行历史、错误信息等等,既是技术人员日常检查系统运行状态的重要手段,又是系统出现可疑情况或发生故障时分析问题必不可少的工具。对于运行在生产环境的系统而言,在系统发生异常时及时准确的记录系统运行状态信息无疑是日志模块最为重要的作用,为此日志模块必须具备以下两个方面的特性:(1)具备高可靠性。系统发生异常的可能原因从硬件故障、系统资源不足、软件兼容性问题、程序BUG到人工操作失误等等不一而足。发生异常后的系统往往处于一种高度不稳定的状态,日志模块作为技术人员定位异常的关键一环必须保证能够在这种高度不稳定甚至是接近崩溃的环境下正确执行并完成自身所提供的日志记录功能,因此其必须具有远高于一般程序的可靠性,这就要求日志模块在设计上必须采用某些特殊措施,例如尽可能使用不会发生异常的函数。举例来说,如果一个日志模块在缓存日志数据时采用了动态内存分配函数,例如malloc函数,那么如果使用该日志模块的系统由于内存空间不足发生异常,日志模块在记录日志时就可能因为调用malloc函数申请内存失败而发生异常,进而导致日志记录失败。(2)记录系统异常内容的完整性和准确性。生产环境情况复杂,一旦系统出现故障,往往会引发一些不可预料的情况,导致远程监控等功能连锁失效,在这种情况下,技术人员手中最为稳定可靠的异常分析工具就是系统的日志。在系统故障诊断时,技术人员的首要任务是分析和定位问题发生原因,其中最为重要的就是定位引发系统异常的指令在系统程序源码中的位置(是哪一行代码)并找到异常发生时程序正在处理的数据内容,这就需要日志模块能够尽可能完整的将程序发生异常时刻正在调用的函数链及链上每一环其所处理的数据准确记录下来。
长期以来,C语言开发领域一直缺少像JAVA、C#等语言那样的权威、通用的日志模块,通常C语言系统的日志模块在系统发生异常时,都只会记录开发者预先定义好的某个错误码,如果技术人员希望获取异常发生时更详细的信息,通行的做法是去分析操作系统内核日志和程序异常退出留下的核心(Core)文件。考虑到Core文件分析的时间代价和复杂性,这种方式对于异常问题的快速分析和定位显然是非常不利的。
现有技术中有专利(专利申请号为201910413980.0)公开了可供C语言程序使用的、能够记录C语言程序异常发生时刻完整函数调用链的日志模块的设计方案,但是该专利方案存在以下缺点:(1)依赖于动态分配的堆内存、锁资源等多种需要主动申请和释放的资源。从实现方案的架构上看,现有技术中的专利要实现存储和输出日志消息记录的函数调用链信息必须采用由“字典容器+链表容器”的日志缓冲区,在C语言中要实现随着数据量动态增长的、不限制大小的数据结构就必然会需要使用malloc等动态内存分配函数分配堆内存作为存储空间。此外,现有技术中的专利为了确保多线程环境下的线程安全还大量使用了锁,同时为了随时向磁盘输出日志消息还需要维护一个保持打开状态文件描述符(该文件描述符是日志模块将当前日志消息输出到目标磁盘文件的文件句柄)。这些需要主动控制申请和释放的资源会降低日志模块的异常稳定性,这对于常常需要在系统发生异常后的不稳定状态下完成异常日志信息记录的日志模块而言是非常不利的。(2)现有技术中的专利日志模块中除了进行记录日志消息和输出日志消息的应用程序接口(ApplicationProgrammingInterface,API),还包括初始化日志模块和关闭日志模块的API。日志模块的调用者需要在使用日志的其他API之前,首先主动调用初始化API(openLogger)进行日志模块初始化,即进行日志模块的资源分配,包括堆内存、锁、文件句柄等,并在不再需要使用日志模块时主动调用关闭API(close Logger)。这种日志模块一方面增加了使用日志模块进行开发的技术人员的工作量,同时也增加了日志模块由于使用不当导致发生异常的概率。例如:技术人员如果忘记调用close Logger函数就会导致日志模块占用的资源无法释放,如果在调用open Logger之前就调用日志记录或输出的API,可能会出现调用失败,甚至导致日志模块的进程崩溃,而由于日志模块发生故障时一般是无法记录自身故障原因,这就导致此类问题往往难以定位分析。(3)多线程环境下同时处理大量日志的记录和输出时API调用时,容易产生系统性能瓶颈。由于现有技术中的专利在字典容器中为每个线程单独建立了一个“线程标识-日志缓冲队列”的键值对,并采用锁机制来保证同一时刻只有一个线程能够读/写字典容器,因此这就导致多线程环境下日志的并发读写过程实质上是以同步方式顺序进行而非并行的,这将大大降低多线程系统的日志写入效率,并且随着线程数和日志读写API调用频率的增加而持续恶化。
基于此,本申请实施例提供了一种日志消息输出方法,通过预先设定固定内存容量的日志消息缓冲区,日志消息缓冲区中包括日志消息缓冲队列,通过控制每条日志消息的字节长度,控制日志消息记录的可靠性,通过控制日志消息输出到外部缓冲区的字节长度,控制日志消息输出的可靠性。本申请实施例避免了使用动态分配函数分配的内存存储日志消息,而是利用预先设定好的日志消息缓冲区,在进行日志存储和输出时采用控制字节长度提高可靠性,能够保证日志模块在系统异常发生时,日志消息的记录和输出具有可靠性。
参见图2,该图为本申请实施例提供的一种日志消息输出方法的流程图。
在本申请的实施例中,预先设定固定内存容量的日志消息缓冲区,日志消息缓冲区包括预设数目个日志消息缓冲队列,预先设定日志消息缓冲队列每条日志消息的最大字节长度,预先设定所述日志消息缓冲队列的日志消息的最大数目,所述最大数目根据所述固定内存容量的日志消息缓冲区确定,预先设定外部缓冲区的可用字节长度,外部缓冲区用于用户直接对多条日志消息进行处理。
在实际应用中,利用C语言标准的第三版,C11标准中的用于定义线程内全局变量的关键字thread_local,来定义一个固定内存容量的日志消息缓冲区,如图3所示。定义日志消息缓冲区的程序代码如下所示:
Figure BDA0002872447520000091
从程序代码中可以看出,日志消息缓冲区包括两个属性:日志消息缓冲队列(msg_queue)和插入索引(top)。日志消息缓冲队列中每个队列最大可以容纳MAX_QUEUE_LEN条消息,每条消息的最大长度是MAX_MSG_LEN字节,其中,MAX_QUEUE_LEN和MAX_MSG_LEN都是根据日志消息缓冲区预先设定的。插入索引(top)指向日志消息缓冲队列(msg_queue)的尾部最后一个位置的下一个位置,为指示日志消息存储到该位置的索引,初始值为0。
本实施例提供的日志消息输出方法包括如下步骤:
步骤S201:记录函数调用链上发生函数调用异常的当前日志消息。
在本申请的实施例中,若系统中的函数调用发生异常,则记录函数调用链上的当前发生异常的日志消息。
在实际应用中,预先在函数调用位置进行“埋点”,“埋点”就是将预先定义好的、需要记录的信息,之后在异常发生后,从异常发生的位置沿着异常发生时刻的函数调用链的反方向逐层返回过程中通过埋点逐层记录异常。
步骤S202:判断所述当前日志消息的字节长度是否超过预先设定的日志消息的最大字节长度,若否,则直接调用日志插入函数,根据所述日志消息队列的插入索引将所述当前日志消息存储至所述日志消息缓冲队列,若是,则将所述当前日志消息中超过最大字节长度的部分进行删除,得到截断日志消息,调用所述日志插入函数,根据所述插入索引将所述截断日志消息存储至所述日志消息缓冲队列。
在本申请的实施例中,在调用日志插入函数将当前日志消息存储至消息缓冲队列时,需要判断当前日志消息的字节长度是否超过预先设定的日志消息的最大字节长度(MAX_MSG_LEN),若没有超过最大字节长度,则直接调用日志插入函数将当前日志消息存储至日志消息缓冲队列,并向日志模块返回插入成功的返回值,例如返回数值0。若当前日志消息的字节长度超过预先设定的日志消息的最大字节长度,在调用日志插入函数时,就会只存储不超过最大字节长度部分的日志消息,即将当前日志消息中超过最大字节长度的部分删除,得到截断日志消息,调用日志插入函数,将截断日志消息存储至日志消息缓冲队列,并向日志模块返回插入截断日志消息的返回值。具体的,返回插入截断日志消息的返回值为非0数值。若当前日志消息存储失败,也向日志模块返回存储失败的返回值。具体的,返回存储失败的返回值为非0数值。具体的,可以利用strlen库函数来计算当前日志消息的字节长度。
作为一种示例,日志插入函数可以是int addLoggerMsg(const char*msg)。
需要说明的是,调用日志插入函数将当前日志消息存储至消息缓冲队列,是根据消息缓冲队列的插入索引进行存储的,如图3所示。具体利用插入索引(top)进行存储当前日志消息的可以是如下步骤:调用日志插入函数,根据插入索引的初始值将第一日志消息存储至日志消息缓冲队列的队首,将插入索引的初始值加一作为插入索引的待插入索引值。插入索引的待插入索引值即代表下一次的插入位置的索引。调用日志插入函数,根据当前插入索引的待插入索引值将后续日志消息存储至日志消息缓冲队列的相应位置,将当前插入索引的待插入索引值加一作为插入索引的待插入索引值。也就是说,每次将当前日志消息存储至日志消息缓冲队列之后,插入索引的待插入索引都加1,作为下一次日志消息进行存储的位置索引。
需要说明的是,日志消息缓冲区还预先设定日志消息缓冲队列的日志消息的最大数目,最大数目是根据固定内存容量的日志消息缓冲区确定的。在判断当前日志消息的字节长度是否超过预先设定的日志消息的最大字节长度之前,还可以判断日志消息缓冲队列的日志消息的当前数目是否超过预先设定的日志消息的最大数目,若是,向日志模块返回非0错误值,若否,则继续判断当前日志消息的字节长度是否超过预先设定的日志消息的最大字节长度。这样也可以控制日志消息的记录上限,避免内存空间不足。
值得注意的是,日志消息缓冲区包括多个预先设定的日志消息缓冲队列,以便存储日志消息。不同的日志消息缓冲队列可以存储不同类型的日志消息,例如错误日志消息缓冲队列可以存储错误(error)日志消息,警告日志消息缓冲队列可以存储警告(warn)日志消息,info日志消息缓冲队列可以存储info日志消息。还可以预先设定多个日志插入函数,日志消息缓冲队列的数目与日志插入函数的数目相同,日志插入函数与日志消息缓冲队列一一对应。例如错误日志消息缓冲队列的日志插入函数可以是intaddLogger errorMsg(const char*msg),警告日志消息缓冲队列的日志插入函数可以是addLogger warnMsg(const char*msg)。具体利用日志插入函数进行存储当前日志消息的可以是如下步骤:根据当前日志消息确定对应的日志插入函数,根据日志插入函数确定对应的日志消息缓冲队列,调用对应的日志插入函数,根据插入索引将当前日志消息存储至对应的日志消息缓冲队列。
作为一种示例,当前日志消息是错误日志消息,确定存储时的日志插入函数为addLogger error Msg(const char*msg),并确定存储的日志消息缓冲队列为错误日志消息缓冲队列。调用addLogger error Msg(const char*msg)将错误日志消息存储至错误日志消息缓冲队列。
需要说明的是,日志消息缓冲区包括多个日志消息缓冲队列,例如包括了错误日志消息缓冲队列、警告日志消息缓冲队列和info日志消息缓冲队列,其中错误日志消息缓冲队列和警告日志消息缓冲队列都可以采用二维数组队列,info日志消息缓冲队列可以是一维数组,可以不是队列。这是由于对于一般运行信息而言,通常只是在需要时记录,将当前单条日志消息存储并立刻输出,并不存在需要同时缓存多条日志消息的需求。
在实际应用中,相同类型的日志缓冲队列的最大消息数目和每条消息的最大字节长度是固定的,但是不同类型的日志缓冲队列的最大消息数目和每条消息的最大字节长度可以不同,可以根据实际需求进行确定。
步骤S203:判断所述日志消息缓冲队列中的多条日志消息的总字节长度是否超过外部缓冲区的可用字节长度,若否,则调用所述日志输出函数,将所述日志消息缓冲队列中的多条日志消息输出至所述外部缓冲区,若是,则将所述日志消息缓冲队列中超过所述外部缓冲区的可用字节长度的部分进行删除,得到截断日志消息缓冲队列的多条日志消息,调用日志输出函数,将所述截断日志消息缓冲队列的多条日志消息输出至外部缓冲区,其中,所述外部缓冲区用于用户直接对所述多条日志消息进行处理。
在本申请的实施例中,当日志消息缓冲队列存储多条日志消息之后,可以将多条日志消息进行输出,输出到外部缓冲区(user_buf),不直接输出到磁盘中,外部缓冲区用于用户直接对多条日志消息进行处理。预先设定外部缓冲区的可用字节长度(len_nuf)。在调用日志输出函数输出多条日志消息的时候,判断日志消息缓冲队列中的多条日志消息的总字节长度是否超过外部缓冲区的可用字节长度,若没有超过外部缓冲区的可用字节长度,则调用日志输出函数,将日志消息缓冲队列中的多条日志消息输出至外部缓冲区,并向日志模块返回输出成功的返回值,例如返回数值0。若超过外部缓冲区的可用字节长度,则将日志消息缓冲队列中超过外部缓冲区的可用字节长度的部分进行删除,得到截断日志消息缓冲队列的多条日志消息,调用日志输出函数,将截断日志消息缓冲队列的多条日志消息输出至外部缓冲区,并向日志模块返回输出截断日志消息的返回值。具体的,返回输出截断日志消息的返回值为非0数值。具体的,将日志消息缓冲队列中超过外部缓冲区的可用字节长度的部分进行删除时,可以只留下可用字节长度减1后的字节长度的日志消息进行输出。
作为一种示例,日志输出函数可以是int getLoggerMsg(char*user_buf,intlen_buf)。日志输出函数还可以是int popLoggerMsg(char*user_buf,intlen_buf)。其中,intpopLoggerMsg(char*user_buf,int len_buf)具有当日志消息输出完毕后自动清空日志消息缓冲队列的功能。
需要说明的是,在将日志消息缓冲队列中的多条日志消息输出至外部缓冲区之后,清空日志消息缓冲队列中的多条日志消息。具体的,可以调用日志输出函数清空日志消息缓冲队列中的多条日志消息,例如intpopLoggerMsg(char*user_buf,int len_buf)。还可以调用日志清空函数将日志消息队列的多条日志消息进行清空。具体的,日志清空函数可以是voidclearLoggerMsg()。在实际应用中,调用日志清空函数进行清空日志消息缓冲队列时,可以将插入索引的待插入索引值直接设置为0,就能够实现清空日志消息缓冲队列。
在实际应用中,调用日志插入函数和日志输出函数可以根据系统的实际需求侧重点进行变化。例如:如果系统更强调日志性能(写入/读取的速度),则可以使用snprintf或类似库函数进行日志消息的插入和输出,这样就可以在不进行额外字节长度检查的情况下,做到不会因为写入长度超过缓冲区可用长度而发生内存越界。如果系统对稳定性的要求更高,则可以采用strlen+strncpy的方式进行日志消息的插入和输出,这是因为这两个函数都不会抛出异常因此稳定性更高。本申请实施例中并不包含能够直接输出到类似磁盘等外部文件的API,但是实际上却大大提升了日志模块使用的灵活性。本申请实施例中列举的返回值可以定义为int类型,也可以定义为char、short等类型,采用同样的返回值类型有利于简化和统一调用者处理函数返回值的方式。
由此可见,本申请实施例通过预先设定固定内存容量的日志消息缓冲区,日志消息缓冲区中包括日志消息缓冲队列,通过控制每条日志消息的字节长度,控制日志消息记录的可靠性,通过控制日志消息输出到外部缓冲区的字节长度,控制日志消息输出的可靠性。本申请实施例避免了使用动态分配函数分配的内存存储日志消息,而是利用预先设定好的日志消息缓冲区,在进行日志存储和输出时采用控制字节长度提高可靠性,能够保证日志模块在系统异常发生时,日志消息的记录和输出具有可靠性。
本申请实施例定义了一个日志消息缓冲区,本申请的日志消息缓冲区是在程序启动前初始化,因此避免了对动态内存的使用,同时由于不管是多线程还是单线程,线程内的程序都是顺序执行的,因此对线程内的操作无需加锁,避免了死锁的风险。此外,本申请实施例的方法由于没有使用任何直接将日志信息输出到外部文件的接口,因此避免了使用文件句柄管理打开的文件,这也就意味着日志模块无需负责文件句柄的关闭。
本申请实施例还具有以下优点:(1)具备极高的异常安全性和异常可靠性。由于本申请实施例的日志模块未使用任何动态内存、锁、文件句柄等资源,因此完全没有发生资源泄露的风险,同时极大地降低了异常发生后由于资源冲突(例如死锁)或资源不足(内存耗尽)等原因导致日志模块无法正常工作的可能性。(2)调用者无需负责确定程序内初始化和关闭日志模块的时机,也无需调用任何专门的API来初始化和关闭日志模块。
基于以上实施例提供的一种日志消息输出方法,本申请实施例还提供了一种日志消息输出装置,下面结合附图来详细说明其工作原理。
参见图4,该图为本申请实施例提供的一种日志消息输出装置400的结构框图。
本实施例提供的日志消息输出装置400包括:
预先设定单元410,用于预先设定固定内存容量的日志消息缓冲区,所述日志消息缓冲区包括预设数目个日志消息缓冲队列;
记录单元420,用于记录函数调用链上发生函数调用异常的当前日志消息;
存储单元430,用于判断所述当前日志消息的字节长度是否超过预先设定的日志消息的最大字节长度,若否,则直接调用日志插入函数,根据所述日志消息队列的插入索引将所述当前日志消息存储至所述日志消息缓冲队列,若是,则将所述当前日志消息中超过最大字节长度的部分进行删除,得到截断日志消息,调用所述日志插入函数,根据所述插入索引将所述截断日志消息存储至所述日志消息缓冲队列;
输出单元440,用于判断所述日志消息缓冲队列中的多条日志消息的总字节长度是否超过外部缓冲区的可用字节长度,若否,则调用所述日志输出函数,将所述日志消息缓冲队列中的多条日志消息输出至所述外部缓冲区,若是,则将所述日志消息缓冲队列中超过所述外部缓冲区的可用字节长度的部分进行删除,得到截断日志消息缓冲队列的多条日志消息,调用日志输出函数,将所述截断日志消息缓冲队列的多条日志消息输出至外部缓冲区,其中,所述外部缓冲区用于用户直接对所述多条日志消息进行处理。
可选的,所述日志消息缓冲区包括多个预先设定的日志消息缓冲队列,预先设定多个所述日志插入函数,所述日志消息缓冲队列的数目与日志插入函数的数目相同,所述日志插入函数与所述日志消息缓冲队列一一对应;
所述存储单元430调用日志插入函数,根据所述日志消息队列的插入索引将所述当前日志消息存储至所述日志消息缓冲队列包括:
所述存储单元430根据所述当前日志消息确定对应的日志插入函数,根据所述日志插入函数确定对应的日志消息缓冲队列;
所述存储单元430调用所述对应的日志插入函数,根据所述插入索引将所述当前日志消息存储至对应的日志消息缓冲队列。
可选的,预先设定所述日志消息缓冲队列的日志消息的最大数目,所述最大数目根据所述固定内存容量的日志消息缓冲区确定;
在存储单元430判断所述当前日志消息的字节长度是否超过所述预先设定的日志消息的最大字节长度之前,所述装置400还包括:
判断单元,用于判断所述日志消息缓冲队列的日志消息的当前数目是否超过所述预先设定的日志消息的最大数目,若是,返回错误值,若否,则继续判断所述当前日志消息的字节长度是否超过所述预先设定的日志消息的最大字节长度。
当介绍本申请的各种实施例的元件时,冠词“一”、“一个”、“这个”和“所述”都意图表示有一个或多个元件。词语“包括”、“包含”和“具有”都是包括性的并意味着除了列出的元件之外,还可以有其它元件。
需要说明的是,本领域普通技术人员可以理解实现上述方法实施例中的全部或部分流程,是可以通过计算机程序来指令相关的硬件来完成,所述的程序可存储于一计算机可读取存储介质中,该程序在执行时,可包括如上述各方法实施例的流程。其中,所述存储介质可为磁碟、光盘、只读存储记忆体(Read-Only Memory,ROM)或随机存储记忆体(RandomAccessMemory,RAM)等。
本说明书中的各个实施例均采用递进的方式描述,各个实施例之间相同相似的部分互相参见即可,每个实施例重点说明的都是与其他实施例的不同之处。尤其,对于装置实施例而言,由于其基本相似于方法实施例,所以描述得比较简单,相关之处参见方法实施例的部分说明即可。以上所描述的装置实施例仅仅是示意性的,其中所述作为分离部件说明的单元及模块可以是或者也可以不是物理上分开的。另外,还可以根据实际的需要选择其中的部分或者全部单元和模块来实现本实施例方案的目的。本领域普通技术人员在不付出创造性劳动的情况下,即可以理解并实施。
以上所述仅是本申请的具体实施方式,应当指出,对于本技术领域的普通技术人员来说,在不脱离本申请原理的前提下,还可以做出若干改进和润饰,这些改进和润饰也应视为本申请的保护范围。

Claims (10)

1.一种日志消息输出方法,其特征在于,预先设定固定内存容量的日志消息缓冲区,所述日志消息缓冲区包括预设数目个日志消息缓冲队列;
所述方法包括:
记录函数调用链上发生函数调用异常的当前日志消息;
判断所述当前日志消息的字节长度是否超过预先设定的日志消息的最大字节长度,若否,则直接调用日志插入函数,根据所述日志消息队列的插入索引将所述当前日志消息存储至所述日志消息缓冲队列,若是,则将所述当前日志消息中超过最大字节长度的部分进行删除,得到截断日志消息,调用所述日志插入函数,根据所述插入索引将所述截断日志消息存储至所述日志消息缓冲队列;
判断所述日志消息缓冲队列中的多条日志消息的总字节长度是否超过外部缓冲区的可用字节长度,若否,则调用所述日志输出函数,将所述日志消息缓冲队列中的多条日志消息输出至所述外部缓冲区,若是,则将所述日志消息缓冲队列中超过所述外部缓冲区的可用字节长度的部分进行删除,得到截断日志消息缓冲队列的多条日志消息,调用日志输出函数,将所述截断日志消息缓冲队列的多条日志消息输出至外部缓冲区,其中,所述外部缓冲区用于用户直接对所述多条日志消息进行处理。
2.根据权利要求1所述的方法,其特征在于,所述日志消息缓冲区包括多个预先设定的日志消息缓冲队列,预先设定多个所述日志插入函数,所述日志消息缓冲队列的数目与日志插入函数的数目相同,所述日志插入函数与所述日志消息缓冲队列一一对应;
所述调用日志插入函数,根据所述日志消息队列的插入索引将所述当前日志消息存储至所述日志消息缓冲队列包括:
根据所述当前日志消息确定对应的日志插入函数,根据所述日志插入函数确定对应的日志消息缓冲队列;
调用所述对应的日志插入函数,根据所述插入索引将所述当前日志消息存储至对应的日志消息缓冲队列。
3.根据权利要求1或2所述的方法,其特征在于,预先设定所述日志消息缓冲队列的日志消息的最大数目,所述最大数目根据所述固定内存容量的日志消息缓冲区确定;
在判断所述当前日志消息的字节长度是否超过所述预先设定的日志消息的最大字节长度之前,所述方法还包括:
判断所述日志消息缓冲队列的日志消息的当前数目是否超过所述预先设定的日志消息的最大数目,若是,返回错误值,若否,则继续判断所述当前日志消息的字节长度是否超过所述预先设定的日志消息的最大字节长度。
4.根据权利要求1所述的方法,其特征在于,所述方法还包括:
在将所述日志消息缓冲队列中的多条日志消息输出至所述外部缓冲区之后,清空所述日志消息缓冲队列中的多条日志消息。
5.根据权利要求4所述的方法,其特征在于,所述清空所述日志消息缓冲队列中的多条日志消息包括:
调用所述日志输出函数清空所述日志消息缓冲队列中的多条日志消息。
6.根据权利要求4所述的方法,其特征在于,所述清空所述日志消息缓冲队列中的多条日志消息包括:
调用日志清空函数将所述日志消息队列的多条日志消息进行清空。
7.根据权利要求1所述的方法,其特征在于,预先设定所述插入索引的初始值为0;
所述调用日志插入函数,根据所述日志消息队列的插入索引将所述当前日志消息存储至所述日志消息缓冲队列包括:
调用日志插入函数,根据插入索引的初始值将第一日志消息存储至所述日志消息缓冲队列,将所述插入索引的初始值加一作为插入索引的待插入索引值;
调用日志插入函数,根据当前插入索引的待插入索引值将后续日志消息存储至所述日志消息缓冲队列,将所述当前插入索引的待插入索引值加一作为插入索引的待插入索引值。
8.一种日志消息输出装置,其特征在于,所述装置包括:
预先设定单元,用于预先设定固定内存容量的日志消息缓冲区,所述日志消息缓冲区包括预设数目个日志消息缓冲队列;
记录单元,用于记录函数调用链上发生函数调用异常的当前日志消息;
存储单元,用于判断所述当前日志消息的字节长度是否超过预先设定的日志消息的最大字节长度,若否,则直接调用日志插入函数,根据所述日志消息队列的插入索引将所述当前日志消息存储至所述日志消息缓冲队列,若是,则将所述当前日志消息中超过最大字节长度的部分进行删除,得到截断日志消息,调用所述日志插入函数,根据所述插入索引将所述截断日志消息存储至所述日志消息缓冲队列;
输出单元,用于判断所述日志消息缓冲队列中的多条日志消息的总字节长度是否超过外部缓冲区的可用字节长度,若否,则调用所述日志输出函数,将所述日志消息缓冲队列中的多条日志消息输出至所述外部缓冲区,若是,则将所述日志消息缓冲队列中超过所述外部缓冲区的可用字节长度的部分进行删除,得到截断日志消息缓冲队列的多条日志消息,调用日志输出函数,将所述截断日志消息缓冲队列的多条日志消息输出至外部缓冲区,其中,所述外部缓冲区用于用户直接对所述多条日志消息进行处理。
9.根据权利要求8所述的装置,其特征在于,所述日志消息缓冲区包括多个预先设定的日志消息缓冲队列,预先设定多个所述日志插入函数,所述日志消息缓冲队列的数目与日志插入函数的数目相同,所述日志插入函数与所述日志消息缓冲队列一一对应;
所述存储单元调用日志插入函数,根据所述日志消息队列的插入索引将所述当前日志消息存储至所述日志消息缓冲队列包括:
所述存储单元根据所述当前日志消息确定对应的日志插入函数,根据所述日志插入函数确定对应的日志消息缓冲队列;
所述存储单元调用所述对应的日志插入函数,根据所述插入索引将所述当前日志消息存储至对应的日志消息缓冲队列。
10.根据权利要求8或9所述的装置,其特征在于,预先设定所述日志消息缓冲队列的日志消息的最大数目,所述最大数目根据所述固定内存容量的日志消息缓冲区确定;
在存储单元判断所述当前日志消息的字节长度是否超过所述预先设定的日志消息的最大字节长度之前,所述装置还包括:
判断单元,用于判断所述日志消息缓冲队列的日志消息的当前数目是否超过所述预先设定的日志消息的最大数目,若是,返回错误值,若否,则继续判断所述当前日志消息的字节长度是否超过所述预先设定的日志消息的最大字节长度。
CN202011621666.0A 2020-12-30 2020-12-30 一种日志消息输出方法及装置 Pending CN112612760A (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN202011621666.0A CN112612760A (zh) 2020-12-30 2020-12-30 一种日志消息输出方法及装置

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN202011621666.0A CN112612760A (zh) 2020-12-30 2020-12-30 一种日志消息输出方法及装置

Publications (1)

Publication Number Publication Date
CN112612760A true CN112612760A (zh) 2021-04-06

Family

ID=75249518

Family Applications (1)

Application Number Title Priority Date Filing Date
CN202011621666.0A Pending CN112612760A (zh) 2020-12-30 2020-12-30 一种日志消息输出方法及装置

Country Status (1)

Country Link
CN (1) CN112612760A (zh)

Cited By (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN113687971A (zh) * 2021-08-24 2021-11-23 杭州迪普科技股份有限公司 内存映象文件的生成方法及装置
CN117149837A (zh) * 2023-10-27 2023-12-01 建信金融科技有限责任公司 消息发送方法、装置、电子设备和计算机可读介质

Citations (11)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US4159517A (en) * 1976-07-07 1979-06-26 International Business Machines Corporation Journal back-up storage control for a data processing system
EP0096199A2 (en) * 1982-06-21 1983-12-21 International Business Machines Corporation Method and apparatus for logging journal data in a computing apparatus
US20120030172A1 (en) * 2010-07-27 2012-02-02 Oracle International Corporation Mysql database heterogeneous log based replication
CN102447633A (zh) * 2011-12-29 2012-05-09 北京亿赞普网络技术有限公司 一种日志传输的方法和系统
CN106681651A (zh) * 2016-05-05 2017-05-17 安徽南瑞继远电网技术有限公司 一种两级缓冲机制的日志管理系统设计方法
CN107688624A (zh) * 2017-08-18 2018-02-13 杭州迪普科技股份有限公司 一种日志索引构建方法及装置
US20180144015A1 (en) * 2016-11-18 2018-05-24 Microsoft Technology Licensing, Llc Redoing transaction log records in parallel
CN110134385A (zh) * 2019-05-17 2019-08-16 中国农业银行股份有限公司 记录c语言函数调用链的方法及c语言通用日志框架
US20200201721A1 (en) * 2018-12-19 2020-06-25 Vmware, Inc. In-place garbage collection of a sharded, replicated distributed state machine based on supersedable operations
US10700711B1 (en) * 2017-11-03 2020-06-30 Caringo Inc. Multi-part upload and editing of erasure-coded objects
CN111427859A (zh) * 2020-03-25 2020-07-17 京东数字科技控股有限公司 一种消息处理方法、装置、电子设备及存储介质

Patent Citations (11)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US4159517A (en) * 1976-07-07 1979-06-26 International Business Machines Corporation Journal back-up storage control for a data processing system
EP0096199A2 (en) * 1982-06-21 1983-12-21 International Business Machines Corporation Method and apparatus for logging journal data in a computing apparatus
US20120030172A1 (en) * 2010-07-27 2012-02-02 Oracle International Corporation Mysql database heterogeneous log based replication
CN102447633A (zh) * 2011-12-29 2012-05-09 北京亿赞普网络技术有限公司 一种日志传输的方法和系统
CN106681651A (zh) * 2016-05-05 2017-05-17 安徽南瑞继远电网技术有限公司 一种两级缓冲机制的日志管理系统设计方法
US20180144015A1 (en) * 2016-11-18 2018-05-24 Microsoft Technology Licensing, Llc Redoing transaction log records in parallel
CN107688624A (zh) * 2017-08-18 2018-02-13 杭州迪普科技股份有限公司 一种日志索引构建方法及装置
US10700711B1 (en) * 2017-11-03 2020-06-30 Caringo Inc. Multi-part upload and editing of erasure-coded objects
US20200201721A1 (en) * 2018-12-19 2020-06-25 Vmware, Inc. In-place garbage collection of a sharded, replicated distributed state machine based on supersedable operations
CN110134385A (zh) * 2019-05-17 2019-08-16 中国农业银行股份有限公司 记录c语言函数调用链的方法及c语言通用日志框架
CN111427859A (zh) * 2020-03-25 2020-07-17 京东数字科技控股有限公司 一种消息处理方法、装置、电子设备及存储介质

Non-Patent Citations (1)

* Cited by examiner, † Cited by third party
Title
白彦峰等: "Unix消息队列的应用", 现代计算机, no. 04, pages 85 - 87 *

Cited By (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN113687971A (zh) * 2021-08-24 2021-11-23 杭州迪普科技股份有限公司 内存映象文件的生成方法及装置
CN113687971B (zh) * 2021-08-24 2023-06-27 杭州迪普科技股份有限公司 内存映象文件的生成方法及装置
CN117149837A (zh) * 2023-10-27 2023-12-01 建信金融科技有限责任公司 消息发送方法、装置、电子设备和计算机可读介质

Similar Documents

Publication Publication Date Title
TWI397814B (zh) 用於稽核記憶體之系統與方法
US7302613B2 (en) System and method for capturing kernel-resident information
CN110134385B (zh) 记录c语言函数调用链的方法及c语言通用日志框架
KR100786932B1 (ko) 크래시 덤프 파일 및 그 요약을 생성하기 위한 시스템, 방법 및 컴퓨터 판독가능 매체
US20140208083A1 (en) Multi-threaded logging
EP2756400B1 (en) Memory dump with expanded data and user privacy protection
US7124251B2 (en) Stack allocation system and method
CN112612760A (zh) 一种日志消息输出方法及装置
US20080320336A1 (en) System and Method of Client Side Analysis for Identifying Failing RAM After a User Mode or Kernel Mode Exception
US20040153635A1 (en) Privileged-based qualification of branch trace store data
CN107133144B (zh) 一种动态监测堆内存使用错误的内存监测装置及方法
US20170068587A1 (en) Data dump for a memory in a data processing system
CN100392606C (zh) 一种定位虚拟操作系统内存泄漏的方法
US7159223B1 (en) Methods and systems for applications to interact with hardware
CN107168773A (zh) 一种jvm崩溃后问题定位及应用恢复的处理方法及装置
CN105045641B (zh) 一种启动组件的界面的方法及装置
US6367036B1 (en) Fast trace log
CN113076233B (zh) 一种io性能检测方法、装置、设备及存储介质
US20150378799A1 (en) Automatic memory leak detection
CN116795576A (zh) 基于日志打印的设备驱动调试方法、装置和电子设备
CN113220495B (zh) 一种进程异常事件处理方法、装置、电子设备及存储介质
EP3336626A1 (en) Memory analysis for industrial controllers
CN113760701A (zh) 测试处理方法及装置
CN113574513A (zh) 检测用于保护存储器的存储密钥的更改
CN109308256A (zh) 一种java程序动态分析方法、设备和存储介质

Legal Events

Date Code Title Description
PB01 Publication
PB01 Publication
SE01 Entry into force of request for substantive examination
SE01 Entry into force of request for substantive examination