发明内容
本申请所要解决的技术问题是提供一种嵌入式系统的日志管理方法,具有系统开销小、简洁高效、日志记录完备的特点,有利于开发者快速定位和解决问题。为此,本申请还要提供一种相应的嵌入式系统。
为解决上述技术问题,本申请提供了一种嵌入式系统的日志管理方法,包括如下步骤。步骤S110:在嵌入式系统的源代码编译时,利用脚本对源代码进行预处理编码;所述预处理编码包括文件编码、消息编码和文本编码。所述文件编码是指对源代码中的文件进行编号,每个编号对应于一个文件。所述消息编码是指对源代码的每个文件中的消息ID进行编号。所述文本编码是指对源代码的每个文件中的日志输出标识进行编号。步骤S120:对嵌入式系统的源代码的每个文件中的每个消息ID,将该消息ID所在文件的文件编码、该消息ID的消息编码、以及日志类型为消息类型这三部分构成一条跟踪代码,对应一条消息类型的日志。对嵌入式系统的源代码的每个文件中的每个日志输出标识,将该日志输出标识所在文件的文件编码、该日志输出标识的文本编码、以及日志类型为文本类型这三部分构成一条跟踪代码,对应一条文本类型的日志。将所有的跟踪代码都存储在第一文件中,第一文件中还记录了每条消息类型的日志的消息结构,还记录了每条文本类型的日志的文本格式,均与相应的跟踪代码相对应。每一条消息类型的日志的文本格式记录了该条消息类型的日志中各个参数的名称及顺序。每一条文本类型的日志的文本格式记录了该条文本类型的日志的描述、各个参数的名称、顺序及占用空间。步骤S130:在嵌入式系统运行时,将输出的实时日志记录在第二文件中。每一条日志都包括两部分:日志头部和动态参数。日志头部包括跟踪代码、时间戳和日志长度。动态参数就是嵌入式系统运行时需要记录的参数。消息类型的日志的动态参数就是传递的消息的内容,与消息结构相对应。文本类型的日志的动态参数就是需要记录的变量的实时值,与文本格式相对应。步骤S140:将第二文件所记录的每一条日志根据跟踪代码在第一文件中找到相应的消息结构或文本格式,恢复出易于理解的可读日志内容。
上述嵌入式系统的日志管理方法在第一文件中记录日志的消息结构或文本格式。嵌入式系统在运行时在第二文件中输出日志时可以不再需要输出消息结构或文本格式中的固定不变的内容,而仅需输出发生变化的内容。最终再将第二文件中的日志记录通过跟踪代码与第一文件中记录的消息结构或文本格式进行关联,从而恢复出可读的日志内容。这样便减少了日志输出时的系统开销,又能保持完备的日志记录。
进一步地,所述步骤S110中,在嵌入式系统的源代码的至少部分文件中包含有一个或多个消息定义;每个消息定义包括消息ID和消息结构。这表明消息ID与消息结构具有关联关系。
进一步地,所述步骤S110中,在嵌入式系统的源代码的至少部分文件中包含有一处或多处日志输出标识,当源代码运行到日志输出标识时就会输出文本类型的日志。这里介绍了日志输出标识的功能。
进一步地,所述步骤S120中,将嵌入式系统输出的日志分为消息类型和文本类型;消息类型的日志用来记录嵌入式系统的不同模块之间的消息交互,文本类型的日志用来记录嵌入式系统运行时的参数输出。这里介绍了本申请的日志类型的分类。
进一步地,所述步骤S130中,消息类型的日志的日志头部比文本类型的日志的日志头部更长,用来存储发出消息的源模块以及接收消息的目的模块。这是一种优选的实现方式。
进一步地,所述步骤S130中,将文本类型的日志分为多个优先级;嵌入式系统在运行阶段输出文本类型的日志时,首先检查该条日志是否满足大于或等于当前优先级阈值,满足时才会输出。这是一种优选的实现方式。
进一步地,所述步骤S130中,在嵌入式系统的调试阶段输出所有优先级的文本类型的日志;这是一种优选的实现方式,有利于系统调试。
进一步地,所述步骤S130中,将消息类型的日志分为多个优先级;嵌入式系统在输出消息类型的日志时,首先检查该条日志是否满足大于或等于当前优先级阈值,满足时才会输出。这是一种优选的实现方式。
进一步地,所述步骤S140中,如果第二文件所记录的某一条日志的跟踪代码表明这是消息类型的日志,则根据跟踪代码在第一文件中找到相应的消息结构,根据消息结构所记录的各个参数的顺序找到相应的参数数值,从而解码出可读的日志内容。由于第二文件中不再需要记录消息结构中的固定不变的内容,例如各个参数的名称及顺序,因此嵌入式系统在第二文件中输出日志记录时可以减少系统开销。
进一步地,所述步骤S140中,如果第二文件所记录的某一条日志的跟踪代码表明这是文本类型的日志,则根据跟踪代码在第一文件中找到了相应的文本格式,根据文本格式中的各个参数的顺序及占用空间找到相应长度的参数的数值,从而解码出可读的日志内容。由于第二文件中不再需要记录文本格式中的固定不变的内容,例如日志描述、各个参数的名称、顺序及占用空间,因此嵌入式系统在第二文件中输出日志记录时可以减少系统开销。
本申请还提供了一种嵌入式系统,包括预处理编码单元、存储单元、日志实时输出单元和日志解读单元。所述预处理编码单元用来在编译嵌入式系统的源代码时,利用脚本对源代码进行预处理编码;所述预处理编码单元进一步包括文件编码单元、消息编码单元和文本编码单元。所述文件编码单元用来对源代码中的文件进行编号,每个编号对应于一个文件,文件编码各不相同。所述消息编码单元用来对源代码的每个文件中的消息ID进行编号;在同一个文件中,每个编号对应于一个消息ID,消息编码各不相同。所述文本编码单元用来对源代码的每个文件中的日志输出标识进行编号;在同一个文件中,每个编号对应于一个日志输出标识,文本编码各不相同。所述存储单元用来在第一文件中存储每条消息类型的日志的跟踪代码及其对应的消息结构,还存储每条文本类型的日志的跟踪代码及其文本格式。所述消息类型的日志的跟踪代码包括文件编码、消息编码、消息类型三部分,嵌入式系统的源代码的每个文件中的每个消息ID都有一条跟踪代码,对应一条消息类型的日志。所述文本类型的日志的跟踪代码包括文件编码、文本编码、消息类型三部分,嵌入式系统的源代码的每个文件中的每个日志输出表示都有一条跟踪代码,对应一条文本类型的日志。所述日志实时输出单元用来在嵌入式系统运行时,将输出的实时日志记录在第二文件中;每一条日志都包括日志头部和动态参数两部分。所述日志解读单元用来将第二文件中记录的每一条日志根据跟踪代码在第一文件中找到相应的消息结构或文本格式,恢复出易于理解的可读日志内容。
上述嵌入式系统由存储单元在第一文件中记录日志的消息结构或文本格式。嵌入式系统在运行时,由日志实时输出单元在第二文件中输出日志时可以不再需要输出消息结构或文本格式中的固定不变的内容,而仅需输出发生变化的内容。最终再由日志解读单元将第二文件中的日志记录通过跟踪代码与第一文件中记录的消息结构或文本格式进行关联,从而恢复出可读的日志内容。这样便减少了日志输出时的系统开销,又能保持完备的日志记录。
本申请还提供了一种嵌入式系统的日志管理方法,包括如下步骤。步骤S310:在嵌入式系统的源代码编译时,利用脚本对源代码进行预处理编码;所述预处理编码包括文件编码和混合编码。所述文件编码是指对源代码中的文件进行编号,每个编号对应于一个文件。所述混合编码是指对源代码的每个文件中的消息ID和日志输出标识进行编号。步骤S320:对嵌入式系统的源代码的每个文件中的每个消息ID,将该消息ID所在文件的文件编码、该消息ID的混合编码、以及日志类型为消息类型这三部分构成一条跟踪代码,对应一条消息类型的日志。对嵌入式系统的源代码的每个文件中的每个日志输出标识,将该日志输出标识所在文件的文件编码、该日志输出标识的混合编码、以及日志类型为文本类型这三部分构成一条跟踪代码,对应一条文本类型的日志。将所有的跟踪代码都存储在第一文件中,第一文件中还记录了每条消息类型的日志的消息结构,还记录了每条文本类型的日志的文本格式,均与相应的跟踪代码相对应;每一条消息类型的日志的文本格式记录了该条消息类型的日志中各个参数的名称及顺序;每一条文本类型的日志的文本格式记录了该条文本类型的日志的描述、各个参数的名称、顺序及占用空间。步骤S330:在嵌入式系统运行时,将输出的实时日志记录在第二文件中;每一条日志都包括日志头部和动态参数两部分。步骤S340:将第二文件所记录的每一条日志根据跟踪代码在第一文件中找到相应的消息结构或文本格式,恢复出易于理解的可读日志内容。
上述嵌入式系统的日志管理方法是本申请的实施例二,与实施例一的区别仅在于用混合编码取代了实施例一中的消息编码和文本编码。
本申请还提供了一种嵌入式系统,包括预处理编码单元、存储单元、日志实时输出单元和日志解读单元。所述预处理编码单元用来在编译嵌入式系统的源代码时,利用脚本对源代码进行预处理编码;所述预处理编码单元进一步包括文件编码单元和混合编码单元。所述文件编码单元用来对源代码中的文件进行编号,每个编号对应于一个文件,文件编码各不相同。所述消息编码单元用来对源代码的每个文件中的消息ID和日志输出标识进行编号;在同一个文件中,每个编号对应于一个消息ID或日志输出标识,混合编码各不相同。所述存储单元用来在第一文件中存储每条消息类型的日志的跟踪代码及其对应的消息结构,还存储每条文本类型的日志的跟踪代码及其文本格式。所述消息类型的日志的跟踪代码包括文件编码、混合编码、消息类型三部分,嵌入式系统的源代码的每个文件中的每个消息ID都有一条跟踪代码,对应一条消息类型的日志。所述文本类型的日志的跟踪代码包括文件编码、混合编码、消息类型三部分,嵌入式系统的源代码的每个文件中的每个日志输出表示都有一条跟踪代码,对应一条文本类型的日志。所述日志实时输出单元用来在嵌入式系统运行时,将输出的实时日志记录在第二文件中;每一条日志都包括日志头部和动态参数两部分。所述日志解读单元用来将第二文件中记录的每一条日志根据跟踪代码在第一文件中找到相应的消息结构或文本格式,恢复出易于理解的可读日志内容。
上述嵌入式系统是本申请的实施例二,与实施例一的区别仅在于用混合编码单元取代了实施例一中的消息编码单元和文本编码单元。
本申请取得的技术效果是在第一文件中记录日志的消息结构或文本格式,在第二文件中输出日志时可以不再需要输出消息结构或文本格式中的固定不变的内容,而仅需输出发生变化的内容;最终再将第二文件中的日志记录通过跟踪代码与第一文件中记录的消息结构或文本格式进行关联,从而恢复出可读的日志内容。这样便减少了日志输出时的系统开销,又能保持完备的日志记录。
具体实施方式
请参阅图1,这是本申请提供的嵌入式系统的日志管理方法的实施例一,包括如下步骤。
步骤S110:在嵌入式系统的源代码编译时,利用脚本对源代码进行预处理编码。所述预处理编码包括文件编码(FILE_CODE)、消息编码(SIG_CODE)和文本编码(TXT_CODE)。
所述文件编码是指对源代码中的文件进行编号,每个编号对应于一个文件。例如采用逐一增加的方式,第一个文件编号为0,后面的文件编号逐个加1。
所述消息编码是指对源代码的每个文件中的消息ID进行编号。在同一个文件中,例如采用逐一增加的方式,第一个消息ID编号为0,后面的消息ID的编号逐个加1。在不同文件中,消息ID可以采用相同的编号。在嵌入式系统的源代码的至少部分文件中包含有一个或多个消息定义。每个消息定义包括消息ID和消息结构,收到消息的模块只有知道消息ID才能正确解析出消息内容。嵌入式系统一般使用C语言,通常在C语言文件的头部记载有该文件的消息定义。
所述文本编码是指对源代码的每个文件中的日志输出标识进行编号。在同一个文件中,例如采用逐一增加的方式,第一个日志输出标识编号为0,后面的日志输出标识的编号逐个加1。在不同文件中,日志输出标识可以采用相同的编号。在嵌入式系统的源代码的至少部分文件中包含有一处或多处日志输出标识,当源代码运行到日志输出标识时就会输出文本类型的日志。
步骤S120:对嵌入式系统的源代码的每个文件中的每个消息ID,将该消息ID所在文件的文件编码、该消息ID的消息编码、以及日志类型为消息类型这三部分构成一条跟踪代码(TRACE_CODE),对应一条消息类型的日志。
对嵌入式系统的源代码的每个文件中的每个日志输出标识,将该日志输出标识所在文件的文件编码、该日志输出标识的文本编码、以及日志类型为文本类型这三部分构成一条跟踪代码,对应一条文本类型的日志。
本申请中,把嵌入式系统输出的日志分为两种类型(PRINT_TYPE):消息类型(SIG)、文本类型(TXT)。消息类型的日志用来记录嵌入式系统的不同模块之间的消息交互,文本类型的日志用来记录嵌入式系统运行时的参数输出。
将所有的跟踪代码都存储在第一文件中,例如称为trace.db。第一文件中还记录了每条消息类型的日志的消息结构,还记录了每条文本类型的日志的文本格式,均与相应的跟踪代码相对应。每一条消息类型的日志的文本格式记录了该条消息类型的日志中各个参数的名称及顺序,以使消息类型的日志在输出时不必具有这些内容,从而降低了嵌入式系统输出消息类型的日志的资源占用。每一条文本类型的日志的文本格式记录了该条文本类型的日志的描述、各个参数的名称、顺序及占用空间,以使文本类型的日志在输出时不必具有这些内容,从而降低了嵌入式系统输出文本类型的日志的资源占用。
优选地,第一文件中采用32比特(bits)来存储每个跟踪代码。例如,高位的16比特用来存储文件编码,低位的13比特用来存储消息编码或文本编码之一,中间的3比特用来存储日志类型。
步骤S130:在嵌入式系统运行时,将输出的实时日志记录在第二文件中,例如称为trace.bin。每一条日志都包括两部分:日志头部和动态参数。
日志头部是每条日志最开始的部分,包括跟踪代码、时间戳和日志长度。日志长度就是该条日志占用的字节数。优选地,消息类型的日志比文本类型的日志多4个字节,其中2个字节用来表示源(Source)模块,另2个字节用来表示目的(Destination)模块。
动态参数就是嵌入式系统运行时需要记录的参数。消息类型的日志的动态参数就是传递的消息的内容,与消息结构相对应。文本类型的日志的动态参数就是需要记录的变量的实时值,与文本格式相对应。
优选地,这一步中将文本类型的日志分为多个优先级。嵌入式系统在输出文本类型的日志时,首先检查该条日志是否满足大于或等于当前优先级阈值,满足时才会输出。
例如将文本类型的日志按照由高到低的优先级顺序分为紧急(CRITICAL)、错误(ERROR)、警告(WARNING)、消息(INFORMATION)和自定义。
优选地,在嵌入式系统的调试阶段输出所有优先级的文本类型的日志。
优选地,在嵌入式系统的运行阶段只输出紧急的文本类型的日志,这是指将当前优先级阈值设为紧急级别。
优选地,这一步中将消息类型的日志也分为多个优先级。嵌入式系统在输出消息类型的日志时,首先检查该条日志是否满足大于或等于当前优先级阈值,满足时才会输出。
步骤S140:将第二文件所记录的每一条日志根据跟踪代码在第一文件中找到相应的消息结构或文本格式,恢复出易于理解的可读日志内容。
如果第二文件所记录的某一条日志的跟踪代码表明这是消息类型的日志,则根据跟踪代码在第一文件中找到相应的消息结构,根据消息结构所记录的各个参数的顺序找到相应的参数数值,从而解码出可读的日志内容。
如果第二文件所记录的某一条日志的跟踪代码表明这是文本类型的日志,则根据跟踪代码在第一文件中找到了相应的文本格式,根据文本格式中的各个参数的顺序及占用空间找到相应长度的参数的数值,从而解码出可读的日志内容。
请参阅图2,这是本申请提供的嵌入式系统的实施例一,与图1所示的嵌入式系统的日志管理方法的实施例一相对应。所述嵌入式系统200包括预处理编码单元210、存储单元220、日志实时输出单元230和日志解读单元240。
所述预处理编码单元210用来在编译嵌入式系统的源代码时,利用脚本对源代码进行预处理编码。所述预处理编码单元210进一步包括文件编码单元212、消息编码单元214和文本编码单元216。
所述文件编码单元212用来对源代码中的文件进行编号,每个编号对应于一个文件,文件编码各不相同。
所述消息编码单元214用来对源代码的每个文件中的消息ID进行编号。在同一个文件中,每个编号对应于一个消息ID,消息编码各不相同。在不同文件中,消息ID可以采用相同的消息编码。
所述文本编码单元216用来对源代码的每个文件中的日志输出标识进行编号。在同一个文件中,每个编号对应于一个日志输出标识,文本编码各不相同。在不同文件中,日志输出标识可以采用相同的文本编码。
所述存储单元220用来在第一文件中存储每条消息类型的日志的跟踪代码及其对应的消息结构,还存储每条文本类型的日志的跟踪代码及其文本格式。
所述消息类型的日志的跟踪代码包括文件编码、消息编码、消息类型三部分,嵌入式系统的源代码的每个文件中的每个消息ID都有一条跟踪代码,对应一条消息类型的日志。
所述文本类型的日志的跟踪代码包括文件编码、文本编码、消息类型三部分,嵌入式系统的源代码的每个文件中的每个日志输出表示都有一条跟踪代码,对应一条文本类型的日志。
所述日志实时输出单元230用来在嵌入式系统运行时,将输出的实时日志记录在第二文件中。每一条日志都包括日志头部和动态参数两部分。
所述日志解读单元240用来将第二文件中记录的每一条日志根据跟踪代码在第一文件中找到相应的消息结构或文本格式,恢复出易于理解的可读日志内容。
下面将以消息类型的日志为例,对本申请提供的嵌入式系统的日志管理方法的实施例一进行示例性说明。假设在嵌入式系统的源代码的某个文件中具有消息定义如下所示,//后的内容为注释说明。
#define TASK1 0x0001 // 定义了TASK1模块的地址
#define TASK2 0x0002 // 定义了TASK2模块的地址
#define SIG1 0x0F01 // 定义了SIG1的消息ID
#define SIG2 0x0F02 // 定义了SIG2的消息ID
struct
{
int sig1_a;
int sig1_b;
}sig1; // 定义了sig1的消息结构,需要注意各个参数的顺序
struct
{
char sig2_a;
int sig2_b;
}sig2; // 定义了sig2的消息结构,需要注意各个参数的顺序
BIND(SIG1, sig1); // 将SIG1的消息ID和sig1的消息结构相关联
BIND(SIG2, sig2); // 将SIG2的消息ID和sig2的消息结构相关联
从上述消息定义可以发现,每个消息ID均与一种消息结构相对应。
在嵌入式系统的源代码的至少部分文件中包含有一处或多处消息输出标识,当源代码运行到消息输出标识时就会输出消息类型的日志。假设在嵌入式系统的源代码的某个文件中具有消息输出标识如下所示,//后的内容为注释说明。
SendSig(SIG1, TASK1, TASK2); // 将消息ID为SIG1的消息类型的日志从TASK1模块发送到TASK2模块
SendSig(SIG2, TASK2, TASK1); // 将消息ID为SIG2的消息类型的日志从TASK2模块发送到TASK1模块
在步骤S110中对源代码进行预处理编码时,文件编码占用2个字节、消息编码占用1.5个字节。在步骤S120中在第一文件存储跟踪代码时,日志类型占用0.5个字节,那么完整的跟踪代码占用4个字节。
在步骤S130中由第二文件记录输出的实时日志时,消息ID为SIG1的消息类型的日志在第二文件中如下所示,0x表示十六进制数,//后的内容为注释说明。
0x00 0x00 // 文件编码
0x01 0x2F // 前4比特表示日志类型,后12比特表示消息编码
0x11 0x11 0x11 0x11 // 时间戳
0x01 0x00 // 源模块为TASK1模块
0x02 0x00 // 目的模块为TASK2模块
0x04 0x00 // 日志长度为4个字节
0x11 0x00 // 参数sig1_a的内容,占用2个字节
0x22 0x00 // 参数sig1_b的内容,占用2个字节
其中,跟踪代码占用4个字节,时间戳占用4个字节,源模块占用2个字节,目的模块占用2个字节,日志长度占用2个字节,动态参数占用4个字节,消息ID为SIG1的消息类型的日志一共占用18个字节。
在步骤S140中由第二文件记录输出的实时日志时,消息ID为SIG2的消息类型的日志在第二文件中如下所示,0x表示十六进制数,//后的内容为注释说明。
0x00 0x00 // 文件编码
0x02 0x2F // 前4比特表示日志类型,后12比特表示消息编码
0x11 0x11 0x11 0x11 // 时间戳
0x02 0x00 // 源模块为TASK2模块
0x01 0x00 // 目的模块为TASK1模块
0x03 0x00 // 日志长度为3个字节
0x63 // 参数sig2_a的内容,占用1个字节
0x22 0x00 // 参数sig2_b的内容,占用2个字节
其中,跟踪代码占用4个字节,时间戳占用4个字节,源模块占用2个字节,目的模块占用2个字节,日志长度占用2个字节,动态参数占用3个字节,消息ID为SIG2的消息类型的日志一共占用17个字节。
在步骤S140中将第二文件所记录的消息类型的日志根据跟踪代码在第一文件中找到相应的消息结构,就能根据消息结构所记录的各个参数的顺序找到相应的参数数值,从而解码出可读的日志内容以便于理解和分析。
下面再以文本类型的日志为例,对本申请提供的嵌入式系统的日志管理方法的实施例一进行示例性说明。假设在嵌入式系统的源代码的某个文件中具有日志输出标识如下所示。
print("a_print: x1=%d, x2=%d", x1, x2);
其中a_print是日志描述,x1和x2是参数,需要注意参数之间的顺序关系;%d是参数内容的占用空间,这些的整体构成了文本格式。
假设在嵌入式系统的源代码的另一个文件中具有日志输出标识如下所示。
print("b_print: y1=%c, y2=%d", y1, y2);
其中b_print是日志描述,y1和y2是参数,需要注意参数之间的顺序关系;%c和%d是参数内容的占用空间,这些的整体构成了文本格式。
在步骤S110中对源代码进行预处理编码时,文件编码占用2个字节、文本编码占用1.5个字节。在步骤S120中在第一文件存储跟踪代码时,日志类型占用0.5个字节,那么完整的跟踪代码占用4个字节。第一文件中存储的跟踪代码及对应的文本格式如下所示,//后的内容为注释说明。
TXT: // 日志类型为文本类型
0 -> "\a.c" // 文件编码及其指向的文件名称
0->"a_print: x1=%d, x2=%d", // 文本编码及其对应的文本格式
1 -> "\b.c" // 文件编码及其指向的文件名称
0->"b_print: y1=%c, y2=%d", // 文本编码及其对应的文本格式
在步骤S130中由第二文件记录输出的实时日志时,文件编码为0的文件中文本编码为0的文本类型的日志在第二文件中如下所示,0x表示十六进制数,//后的内容为注释说明。
0x00 0x00 // 文件编码
0x00 0x00 // 日志类型及文本编码
0x11 0x11 0x11 0x11 // 时间戳
0x04 0x00 // 日志长度为4个字节
0x11 0x00 // 参数x1的内容,占用2个字节
0x22 0x00 // 参数x2的内容,占用2个字节
其中,跟踪代码占用4个字节,时间戳占用4个字节,日志长度占用2个字节,动态参数占用4个字节,文件编码为0的文件中文本编码为0的文本类型的日志一共占用14个字节。由于省略了日志描述、参数之间的顺序关系及各参数的占用空间,因此第二文件中记录的该条文本类型的日志可以减小占用10个字节的空间。
在步骤S130中由第二文件记录输出的实时日志时,文件编码为1的文件中文本编码为0的文本类型的日志在第二文件中如下所示,0x表示十六进制数,//后的内容为注释说明。
0x01 0x00 // 文件编码
0x00 0x00 // 日志类型及文本编码
0x11 0x11 0x11 0x11 / 时间戳
0x03 0x00 // 日志长度为4个字节
0x63 // 参数y1的内容,占用1个字节
0x22 0x00 // 参数y2的内容,占用2个字节
其中,跟踪代码占用4个字节,时间戳占用4个字节,日志长度占用2个字节,动态参数占用3个字节,文件编码为1的文件中文本编码为0的文本类型的日志一共占用13个字节。由于省略了日志描述、参数之间的顺序关系及各参数的占用空间,因此第二文件中记录的该条文本类型的日志可以减小占用10个字节的空间。
请参阅图3,这是本申请提供的嵌入式系统的日志管理方法的实施例二,包括如下步骤。
步骤S310:在嵌入式系统的源代码编译时,利用脚本对源代码进行预处理编码。所述预处理编码包括文件编码和混合编码。
所述文件编码是指对源代码中的文件进行编号,每个编号对应于一个文件。例如采用逐一增加的方式,第一个文件编号为0,后面的文件编号逐个加1。
所述混合编码是指对源代码的每个文件中的消息ID和日志输出标识进行编号。在同一个文件中,例如采用逐一增加的方式,第一个消息ID或日志输出标识编号为0,后面的消息ID或日志输出标识的编号逐个加1。在不同文件中,消息ID和日志输出标识可以采用相同的编号。
步骤S320:对嵌入式系统的源代码的每个文件中的每个消息ID,将该消息ID所在文件的文件编码、该消息ID的混合编码、以及日志类型为消息类型这三部分构成一条跟踪代码,对应一条消息类型的日志。
对嵌入式系统的源代码的每个文件中的每个日志输出标识,将该日志输出标识所在文件的文件编码、该日志输出标识的混合编码、以及日志类型为文本类型这三部分构成一条跟踪代码,对应一条文本类型的日志。
本申请中,把嵌入式系统输出的日志分为两种类型:消息类型、文本类型。将所有的跟踪代码都存储在第一文件中,例如称为trace.db。第一文件中还记录了每条消息类型的日志的消息结构,还记录了每条文本类型的日志的文本格式,均与相应的跟踪代码相对应。每一条消息类型的日志的文本格式记录了该条消息类型的日志中各个参数的名称及顺序。每一条文本类型的日志的文本格式记录了该条文本类型的日志的描述、各个参数的名称、各个参数的顺序及占用空间。
步骤S330:在嵌入式系统运行时,将输出的实时日志记录在第二文件中,例如称为trace.bin。每一条日志都包括日志头部和动态参数两部分。
步骤S340:将第二文件所记录的每一条日志根据跟踪代码在第一文件中找到相应的消息结构或文本格式,恢复出易于理解的可读日志内容。
请参阅图4,这是本申请提供的嵌入式系统的实施例二,与图3所示的嵌入式系统的日志管理方法的实施例二相对应。所述嵌入式系统400包括预处理编码单元410、存储单元420、日志实时输出单元430和日志解读单元440。
所述预处理编码单元410用来在编译嵌入式系统的源代码时,利用脚本对源代码进行预处理编码。所述预处理编码单元410进一步包括文件编码单元412和混合编码单元414。
所述文件编码单元412用来对源代码中的文件进行编号,每个编号对应于一个文件,文件编码各不相同。
所述消息编码单元414用来对源代码的每个文件中的消息ID和日志输出标识进行编号。在同一个文件中,每个编号对应于一个消息ID或日志输出标识,混合编码各不相同。在不同文件中,消息ID或日志输出标识可以采用相同的混合编码。
所述存储单元420用来在第一文件中存储每条消息类型的日志的跟踪代码及其对应的消息结构,还存储每条文本类型的日志的跟踪代码及其文本格式。
所述消息类型的日志的跟踪代码包括文件编码、混合编码、消息类型三部分,嵌入式系统的源代码的每个文件中的每个消息ID都有一条跟踪代码,对应一条消息类型的日志。
所述文本类型的日志的跟踪代码包括文件编码、混合编码、消息类型三部分,嵌入式系统的源代码的每个文件中的每个日志输出表示都有一条跟踪代码,对应一条文本类型的日志。
所述日志实时输出单元430用来在嵌入式系统运行时,将输出的实时日志记录在第二文件中。每一条日志都包括日志头部和动态参数两部分。
所述日志解读单元440用来将第二文件中记录的每一条日志根据跟踪代码在第一文件中找到相应的消息结构或文本格式,恢复出易于理解的可读日志内容。
本申请提供的嵌入式系统及其日志管理方法具有如下的有益效果。
第一,对嵌入式系统中的文件、消息ID、日志输出标识进行编码,可以覆盖绝大部分嵌入式系统的日志输出需求,输出的日志记录完整多样。
第二,嵌入式系统在运行时,输出消息类型的日志可以省略参数名称及顺序,输出文本类型的日志可以省略日志描述、参数名称、参数顺序和参数占用空间,有效降低了系统开销,提高了系统的运行效率。
第三,可快速地从实时输出的日志中根据跟踪代码找到消息结构或文本格式,恢复成可读日志,帮助开发人员快速定位并解决问题。
以上仅为本申请的优选实施例,并不用于限定本申请。对于本领域的技术人员来说,本申请可以有各种更改和变化。凡在本申请的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本申请的保护范围之内。