日志模块(一头文件就实现了日志记录)

开源日志库 [log4c] 使用 开源日志库[log4c]使用log4c简介要求平台软件需求log4c 下载、编译、安装下载编译、安装log4c 通用使用方式代码中使用配置文件代码库中进行链接使用将库和头文件放置到代码工程中修改对应的 CMAKE 配置文件代码添加参考链接及文献 log4c简介 Log4c是一个C库,用于灵活地记录文件、系统日志和其他目的地。它是根据Java库的日志建模的(http://jakarta.apache.org/log4j/),尽可能接近其API。这里是对Log4j的简短介绍,它描述了API和设计原理。 马克·孟 阅读详情

日志模块(一头文件就实现了日志记录)
温辉敏(wenhm@sina.com)  2009-8-2 晚

摘要:本文介绍了一个C/C++日志记录模块,它是对开源log4c进行的封装和修正的基础上[1][[2][3][4],将所有的代码都集成到一个.h头文件中。带来的革命性突破是日志模块的使用是那么的方便和简单:只要使用一个.h头文件即可无缝的将日志模块嵌入到你的工程中去,不需要再添加额外的的.c/.cpp或是链接lib/dll等,整个日志模块就是一个头文件。日志输出格式方面,提供了C语言传统的字符printf格式输出,同时也为C++提供了ostream方式的流式输出。

关键字: 日志 回滚 日志记录 log4c

下载源码:http://u.115.com/file/f5cb87b84a
日志记录模块.rar

或是csdn上搜索上述关键字即可找到。

1.   前言
一直想要找一个使用简单、功能能满足需求、空间占用小能同时能用于C和C++语言的日志记录模块,真是梦里寻她千百度,可依旧空山不语无一物。若像《林中路》述说的那样,有两条路供选择到还好,可问题是找不到路,只好在前人的基础上来进行一些封装(Wrapper)以达到目的了。

Log4Cxx/Log4Cpp等C++的库比较大,而且只能用于C++语言,C语言中无法使用。(其实可以使用C 函数来对C++代码进行封装,也可以达到在C语言中使用的目的的,只是自己懒没有去做这方面的工作。)

PWLIB、ACE等库中也有比较好的日志模块可因为和库关联性太大抽不出来,而且也是只能用于C++语言的。

于是发现log4c这个库还是不错的,C语言写的,整个编下来就几十K,可以支持C语言,至于C++语言只要外层进行下C++ 的ostream的流式封装就可以使用了。然后加入了PWLIB、ACE等库的一些比较简单适用的日志记录宏定义以方便适用,比如:

l  基本信息输出:带时间、文件名、行号、线程id、日志级别

l  以十六进制数字方式输出二进制数据块;

l  输出原始数据(不带时间、文件、行号、日志级别);

l  输出函数名;

l  条件日志输出(符合条件才会输出日志);

l  日志输出返回(日志输出后就return);

最后为了追求极限的使用方便,将所有的代码都放在一个头文件中,这样就不用在已有工程中添加日志模块的.c/.cpp,也不用链接日志模块的lib了。就一个头文件的包含就让日志模块无缝的嵌入到你的工程中。

2.   快速上手
2.1. C语言方式日志记录
下面是一个简单的使用日志模块的工程,工程中必须预定义了LOG4C_ENABLE 宏定义才能打开日志(通过该宏定义来控制是否打开日志),工程包含两个.c文件:main.c和test.c。采用Visual Stduio2005编译通过,代码可以去csdn上下载。

 main.c的代码:

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

 #include <stdio.h>

/**下面两条语句将日志模块的实现代码加入进来

#define IMPLEMENT_LOG4C语句一定要在#include "log4c_amalgamation.h"语句之前。

*/

 #define IMPLEMENT_LOG4C

 #include "log4c_amalgamation.h"

 

 extern void test();

 

 void main(int argc, char **argv)

 {

      ///日志模块缺省初始化

      LOG4C_INIT_DEFAULT();

      ///进行日志输出

      LOG4C((LOG_ERROR, "Hello world! My age is %d, and my name is %s!", 28, "Jess" ));

      test();

      ///关闭日志模块防止内存/资源泄漏

      LOG4C_FINI();

 }

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

 

 test.c的代码:

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

 #include <stdio.h>

 #include "log4c_amalgamation.h"

 

 void test()

 {

      ///进行日志输出

      LOG4C((LOG_ERROR, "Hello world! My age is %d, and my name is %s!", 28, "Jess" ));

 }

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

2.2. C++语言方式日志记录
下面是一个简单的使用日志模块的工程,工程中必须预定义了LOG_USELOG4CXX宏定义才能打开日志(通过该宏定义来控制是否打开日志),工程包含两个.cpp文件:main.cpp和test.cpp。采用Visual Stduio2005编译通过,代码可以去csdn上下载。

 main.cpp的代码:

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

 #include <stdio.h>

/**下面两条语句将日志模块的实现代码加入进来

#define IMPLEMENT_LOG4C语句一定要在#include "log4c_amalgamation.h"语句之前。

*/

 #define IMPLEMENT_LOG4C

 #include "log4c_amalgamation.h"

 

 extern void test();

 

 void main(int argc, char **argv)

 {

      ///日志模块缺省初始化

      LOG_INIT_DEFAULT();

      ///进行日志输出

      LOG(LOG_LEVEL_FATAL, "test_log_int" <<  "you are the best one!");   

      test();

      ///关闭日志模块防止内存/资源泄漏

      LOG_FINI();

 }

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

 

 test.cpp的代码:

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

 #include <stdio.h>

 #include "log4c_amalgamation.h"

 

 void test()

 {

      ///进行日志输出

      LOG(LOG_LEVEL_ERROR, "Hello world! My age is" << 28 << " and my name is " << "Jess!" );

 }

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

3.   功能介绍
日志输出模块支持C的sprintf类型的fromat格式输出,同时也支持C++的流式输出。日志输出的基本内容格式如下:

20090803 11:39:41.656 ThreadID:5552 ERROR - test_usinglog4c.c(27) Hello world!

由上可见,一条日志输出信息中包含了时间(精确到毫秒)、线程ID、日志级别、文件名、行号、用户输出日志信息。

个人觉得时间和线程ID还是非常有用的,特别是线程ID,对于查多线程程序的死锁是非常有帮助的。笔者在中兴时的做的好几个局端项目中服务器程序出现死锁,导致Web HTTP访问无法返回,都是只能立刻使用WatchDog来重启服务器程序,因为不能影响服务。然后拿了打出来的日志分析个天昏地暗,因为有线程ID,总能找到是那几个线程死锁,进而进一步分析问题发生的原因以解决问题。

4.   使用介绍
本日志系统比较简单就一个头文件即可实现日志模块以进行日志的记录,若是就简单的记录日志只要看2.快速上手一节就可以了,下面进行下详细介绍。

4.1. C语言方式使用
4.1.1.    代码中加上日志模块定义
工程中任意一个*.c 文件(记住只要一个c文件有下面的代码就OK,如main函数所在c文件)包含如下代码:

#define IMPLEMENT_LOG4C

#include "log4c_amalgamation.h"

有了上面两行代码就可以将日志模块的代码实现加到你的代码中了,六个字:简单、快捷、方便。这样该.c文件中就可以正常的使用日志模块的所有宏定义来进行日志记录。

4.1.2.    包含日志模块头文件
除了4.1.1中的.c文件外,其它的.c文件都必须包含日志模块头文件,其它要记录日志的*.c 文件包含如下代码:

#include "log4c_amalgamation.h"

这样就可以使用日志模块的所有宏定义来进行日志记录了。

4.1.3.    宏定义开关控制是否打开日志记录
工程中要定义预定义宏定义LOG4C_ENABLE,可以通过控制该宏定义开关来关闭日志模块,若关闭该宏定义则整个工程和没有加入日志模块是一样的,所有的日志宏定义都将失效。

 

4.1.4.    日志模块初始化
日志模块初始化代码,必须调用日志模块初始化代码后才能正确记录日志,只有正确执行了日志模块初始化代码后日志宏定义才能正确进行日志记录。所有在日志模块初始化代码之前执行的日志宏定义都将不能正确记录日志。

日志模块初始化有多个可使用的初始化宏定义,可以按照你程序的特性来选择一个合适的初始化宏定义就好了,下面分别进行介绍。

4.1.4.1.       缺省日志初始化宏定义
LOG4C_INIT_DEFAULT();

上面的代码会自动在可执行程序目录下生成log4crc日志模块配置文件(若存在则不生成),配置文件中可以指定日志级别等(见.3.3.日志配置文件log4crc文件内容)。

采用这种方式,用户比较省心,不用去设置配置文件名和具体的配置文件中各个参数,将自动生成一个缺省的log4crc配置文件,日志级别是notice,所以只能输出比notice级别更高的日志信息。

示例代码:

LOG4C_INIT_DEFAULT();

4.1.4.2.       带参数设置日志初始化宏定义
LOG4C_INIT_WITH_PARAM();

上面的日志初始化宏定义是可以设置日志级别、日志配置文件、生成日志文件名等各个参数的,若不进行这些设置则采用缺省的参数,此时功能就和LOG4C_INIT_DEFAULT一样。

参数设置有如下宏定义,这些宏定义都必须在LOG4C_INIT_WITH_PARAM宏定义执行之前调用:

4.1.4.2.1.     设置日志配置文件名
LOG4C_PARAM_CFG_FILE_NAME(strCfgFileName)

参数strCfgFileName即为配置文件的名称,类型为字符串,这个允许用户指定日志配置文件名,不一定非要用缺省的log4crc。可以不调用该宏定义,此时使用缺省的log4crc来作为日志配置文件名。

4.1.4.2.2.     设置日志级别
LOG4C_PARAM_LOG_LEVEL(strLogLevel)

strLogLevel即为日志级别,类型为字符串,级别有fatal/alert/crit/error/warn/notice/info/debug/trace/notset/unknown。各个日志级别越来越弱,fatal表示只有fatal的日志才输出,alert表示只有fatal/alert级别的日志才输出,其它一次类推,unknown表输出所有级别的日志信息。可以不调用该宏定义,此时使用缺省”notice”来作为缺省的日志输出级别。

4.1.4.2.3.     设置生成的日志输出文件的文件前缀的名称
LOG4C_PARAM_LOG_FILE_NAME(strLogFileName)

strLogFileName即为文件名,类型为字符串。可以不调用该宏定义,此时使用缺省的”log”来作为生成的日志文件名的前缀,此时生成的日志输出文件为log.0、log.1等。最新的日志文件总是log.0,当达到限定大小时,将log.0改为log.1,原来的log.1改为log.2,原来的log.2改为log.3依次类推,然后重新开启一个新的log.0文件来存放日志。

4.1.4.2.4.     设置日志输出文件的大小
LOG4C_PARAM_LOG_FILE_SIZE(iFileSize)

iFileSize即为文件大小,类型为整型,单位为字节。当输出的日志文件达到该大小时将重新开启一个新的日志文件来存放后续的日志。可以不调用该宏定义,此时使用缺省的1048576字节即1M。

4.1.4.2.5.     设置生成的日志文件个数
LOG4C_PARAM_LOG_FILE_NUM(iFileNum)

设置至多生成多少个日志文件,类型为整型。当生成的日志文件已经达到最大个数时,将把最旧的日志覆盖掉。

4.1.4.2.6.     设置是否重新读取配置文件
LOG4C_PARAM_REREAD_LOG_CFG_FILE(bReReadLogCfgFile)

设置是否输出每条日志信息时都重新读取配置文件,类型为整型。这个在不希望关闭程序动态改变输出日志级别时特别有用,0表示否,1表示是。

4.1.4.2.7.     示例代码
     ///设置日志配置文件名

     LOG4C_PARAM_CFG_FILE_NAME("MyLogCfgFile");

     ///设置生成日志文件名

     LOG4C_PARAM_LOG_FILE_NAME("MyLogFile");

     ///设置日志级别

     LOG4C_PARAM_LOG_LEVEL("unknown");

     ///设置日志文件大小

     LOG4C_PARAM_LOG_FILE_SIZE(1024);

     ///设置生成日志文件个数,达到最大个数将自动覆盖最旧的日志

     LOG4C_PARAM_LOG_FILE_NUM(5);

     ///设置每次记录日志都重新读取日志配置文件

     LOG4C_PARAM_REREAD_LOG_CFG_FILE(1);

     ///带参数日志模块初始化,以上所有设置了的参数都将生效,没有设置的采用缺省值

     LOG4C_INIT_WITH_PARAM();

4.1.4.3.       带参数设置日志初始化宏定义(多个进程实例)
LOG4C_INIT_WITH_PARAM_MULTI_PROCESS();

该宏定义作用和LOG4C_INIT_WITH_PARAM类似,只是用于多个进程实例时,设置参数也采用和LOG4C_INIT_WITH_PARAM一样的LOG4C_PARAM_CFG_FILE_NAME等宏定义来进行设置。

当有多个进程实例运行时,多个进程都会去访问日志配置文件,都会进行日志记录,此时生成的日志文件就是多个进程共同产生的了,容易导致混乱。此时可以采用LOG4C_INIT_WITH_PARAM_MULTI_PROCESS宏定义来进行初始化就好了。采用该宏定义,同一程序的多个进程实例间记录日志互相不影响。

假设LofCfgFile为设置的日志配置文件名,LogFile为设置的日志文件,则有多个进程实例时LofCfgFile1/LogFile1为第一个进程实例的日志配置文件名和生成的日志文件前缀;LofCfgFile2/LogFile2为第二个进程对应的,依次类推。

l  示例代码:

     ///设置日志配置文件名

     LOG4C_PARAM_CFG_FILE_NAME("MyLogCfgFile");

     ///设置生成日志文件名

     LOG4C_PARAM_LOG_FILE_NAME("MyLogFile");

     ///设置日志级别

     LOG4C_PARAM_LOG_LEVEL("unknown");

     ///设置日志文件大小

     LOG4C_PARAM_LOG_FILE_SIZE(1024);

     ///设置生成日志文件个数,达到最大个数将自动覆盖最旧的日志

     LOG4C_PARAM_LOG_FILE_NUM(5);

     ///设置每次记录日志都重新读取日志配置文件

     LOG4C_PARAM_REREAD_LOG_CFG_FILE(1);

     ///带参数日志模块初始化,以上所有设置了的参数都将生效,没有设置的采用缺省值

     LOG4C_INIT_WITH_PARAM_MULTI_PROCESS ();

4.1.5.    日志模块扫尾代码
LOG4C_FINI();

日志模块扫尾代码,程序退出时调用扫尾代码防止内存/资源泄漏。

4.1.6.    日志记录
4.1.6.1.       LOG4C宏定义记录日志
     LOG4C((LOG_ERROR, "Hello world! My age is %d, and my name is %s!", 28, "Jess" ));

所有日志宏定义输出都采用和sprintf函数参数一样的方式,要注意的是这里前后是两个“(”和两个 “)”,切记切记。

l  日志级别有如下几种可选:

LOG_FATAL/LOG_ALERT/LOG_CRIT/LOG_ERROR/LOG_WARN/LOG_NOTICE/LOG_INFO/LOG_DEBUG/LOG_TRACE/LOG_NOTSET/LOG_UNKNOWN。

本宏定义的日志记录代码将输出时间、线程ID、日志级别、文件名、行号、日志输出信息,输出日志的具体内容如下:

20090803 11:39:41.625 ThreadID:5552 ERROR root- test_usinglog4c.c(25) Hello world! My age is 28, and my name is Jess!

4.1.6.2.       LOG4C_FUN宏定义带函数名记录日志
     LOG4C_FUN(("LOG4C_FUN"));

本宏定义输出日志中带有当前函数名称,输出日志的具体内容如下:

20090808 03:26:24.890 ThreadID:444 TRACE root- test.c(262) FUN<test_log4c_fun>:LOG4C_FUN

4.1.6.3.       LOG4C_HEX_DUMP以十六进制方式输出缓冲区内容
     char strBuffer[128] = "You are the Best One!/0 Yes.";

     LOG4C_HEX_DUMP((LOG4C_TRACE, strBuffer, sizeof(strBuffer)));

本宏定义将缓冲区中数据以十六进制方式打印出来,要指定缓冲区首地址和缓冲区长度。

输出日志的具体内容如下:

20090808 03:26:24.937 ThreadID:444      TRACE    root- test.c(296)

0000  59 6f 75 20 61 72 65 20 - 74 68 65 20 42 65 73 74   You are the Best

0010  20 4f 6e 65 21 00 20 59 - 65 73 2e 00 00 00 00 00    One!. Yes......

0020  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00   ................

0030  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00   ................

0040  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00   ................

0050  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00   ................

0060  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00   ................

0070  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00   ................

 

l  示例代码:

///测试LOG4C_HEX_DUMP宏

void test_log4c_hex_dump()

{

     char strBuffer[128] = "You are the Best One!/0 Yes.";

     LOG4C_INIT_DEFAULT();

     LOG4C_HEX_DUMP((LOG4C_PRIORITY_TRACE, strBuffer, sizeof(strBuffer)));

     LOG4C_FINI();

}

 

4.1.6.4.       LOG4C_IF宏定义条件记录日志
     LOG4C_IF((4>3, LOG_ERROR, "LOG4C_IF:4>3"));

     LOG4C_IF((2>3, LOG_ERROR, "LOG4C_IF:2>3"));

本宏定义只有在满足第一参数为真时才会进行日志输出,否则不输出日志。上面的两条语句就只有第一条才会输出日志,第二条由于条件为假将不输出为日志。

输出日志的具体内容如下:

20090808 03:26:24.921 ThreadID:444 ERROR root- test.c(272) LOG4C_IF:4>3

4.1.6.5.       LOG4C_LINE宏定义输出当前行号
     LOG4C_LINE();

本宏定义输出当前行号,输出日志的具体内容如下:

20090808 03:26:24.937 ThreadID:444 TRACE root- test.c(283) line:283

4.1.6.6.       LOG4C_RETURN宏定义输出并return
     LOG4C_RETURN((LOG4C_PRIORITY_TRACE, "LOG4C_RETURN"));

本宏定义输出当前日志信息后就return退出当前函数,输出日志的具体内容如下:

20090808 03:26:24.953 ThreadID:444 TRACE root- test.c(306) LOG4C_RETURN

4.1.6.7.       LOG4C_RETURN_WITH_VALUE宏定义输出并带参数return
     LOG4C_RETURN((LOG4C_PRIORITY_TRACE, "LOG4C_RETURN 0"));

本宏定义输出当前日志信息后就带参数return退出当前函数,输出日志的具体内容如下:

20090808 03:26:24.953 ThreadID:444 TRACE root- test.c(306) LOG4C_RETURN 0

4.1.6.8.       LOG4C_ORIGIN宏定义输出用户原始信息日志
     LOG4C_ORIGIN ((LOG_ERROR,"LOG4C_ORIGIN"));

本宏定义输出的日志就只有用户要输出的原始信息,没有其它时间、线程ID、日志级别等等额外信息了。输出日志的具体内容如下:

LOG4C_ ORIGIN

4.1.6.9.       LOG4C_NO_FILENUM宏定义记录日志不带文件名和行号
     LOG4C_NO_FILENUM((LOG_ERROR,"LOG4C_NO_FILENUM"));

本宏定义输出的日志除了不带文件名和行号,其它和LOG4C宏定义输出的日志都相同,输出日志的具体内容如下:

20090804 17:34:07.578 ThreadID:1384     ERROR    root- LOG4C_NO_FILENUM

4.1.6.10.   LOG4C_NO_FILENUM_NO_LAYOUT宏定义记录日志
     LOG4C_NO_FILENUM_NO_LAYOUT((LOG_ERROR,"LOG4C_NO_FILENUM_NO_LAYOUT"));

本宏定义输出的日志就只有用户要输出的原始信息,没有其它时间、线程ID、日志级别等等额外信息了。本宏定义和LOG4C_ ORIGIN其实是一样的,输出日志的具体内容如下:

LOG4C_NO_FILENUM_NO_LAYOUT

4.1.6.11.   LOG4C_BLOCK_BEGIN和LOG4C_BLOCK_END宏定义跟踪调用层次
     LOG4C_BLOCK_BEGIN(("LOG4C_BLOCK_BEGIN0"));

     LOG4C_BLOCK_BEGIN(("LOG4C_BLOCK_BEGIN1"));

     LOG4C_BLOCK_BEGIN(("LOG4C_BLOCK_BEGIN2"));

     LOG4C_BLOCK_BEGIN(("LOG4C_BLOCK_BEGIN3"));

 

     LOG4C_BLOCK_END(("LOG4C_BLOCK_BEGIN3"));

     LOG4C_BLOCK_END(("LOG4C_BLOCK_BEGIN2"));

     LOG4C_BLOCK_END(("LOG4C_BLOCK_BEGIN1"));

     LOG4C_BLOCK_END(("LOG4C_BLOCK_BEGIN0"));

LOG4C_BLOCK_BEGIN宏定义表示进入一层,LOG4C_BLOCK_END宏定义表退出一层,上面宏定义的日志输出信息为:

20090808 03:26:24.875 ThreadID:444      TRACE    - test.c(244) B-Entry     ==> LOG4C_BLOCK_BEGIN0

20090808 03:26:24.875 ThreadID:444      TRACE    - test.c(245) B-Entry     ====> LOG4C_BLOCK_BEGIN1

20090808 03:26:24.875 ThreadID:444      TRACE    - test.c(246) B-Entry     ======> LOG4C_BLOCK_BEGIN2

20090808 03:26:24.875 ThreadID:444      TRACE    - test.c(247) B-Entry     ========> LOG4C_BLOCK_BEGIN3

20090808 03:26:24.875 ThreadID:444      TRACE    - test.c(249) B-Exit       <======== LOG4C_BLOCK_BEGIN3

20090808 03:26:24.890 ThreadID:444      TRACE    - test.c(250) B-Exit       <====== LOG4C_BLOCK_BEGIN2

20090808 03:26:24.890 ThreadID:444      TRACE    - test.c(251) B-Exit       <==== LOG4C_BLOCK_BEGIN1

20090808 03:26:24.890 ThreadID:444      TRACE    - test.c(252) B-Exit       <== LOG4C_BLOCK_BEGIN0

看到没,以上日志的输出是有层次的,表示进入LOG4C_BLOCK_BEGIN0 Block后,又进入LOG4C_BLOCK_BEGIN1 Block直到LOG4C_BLOCK_BEGIN3 Block,然后开始以相反顺序退出各Block。

4.2. C++语言方式使用
4.2.1.    代码中加上日志模块定义
工程中任意一个*.cpp 文件(记住只要一个cpp文件有下面的代码就OK,如main函数所在cpp文件)包含如下代码:

#define IMPLEMENT_LOG4C

#include "log4c_amalgamation.h"

有了上面两行代码就可以将日志模块的代码实现加到你的代码中了,六个字:简单、快捷、方便。这样该.cpp文件中就可以正常的使用日志模块的所有宏定义来进行日志记录。

4.2.2.    包含日志模块头文件
除了4.2.1中的.cpp文件外,其它的.cpp文件都必须包含日志模块头文件,其它要记录日志的*.c pp文件包含如下代码:

#include "log4c_amalgamation.h"

这样就可以使用日志模块的所有宏定义来进行日志记录了。

4.2.3.    宏定义开关控制是否打开日志记录
工程中要定义预定义宏定义LOG_USELOG4CXX,可以通过控制该宏定义开关来关闭日志模块,若关闭该宏定义则整个工程和没有加入日志模块是一样的,所有的日志宏定义都将失效。

4.2.4.    日志模块初始化
日志模块初始化代码,必须调用日志模块初始化代码后才能正确记录日志,只有正确执行了日志模块初始化代码后日志宏定义才能正确进行日志记录。所有在日志模块初始化代码之前执行的日志宏定义都将不能正确记录日志。

日志模块初始化有多个可使用的初始化宏定义,可以按照你程序的特性来选择一个合适的初始化宏定义就好了,下面分别进行介绍。

4.2.4.1.       缺省日志初始化宏定义
LOG_INIT_DEFAULT();

上面的代码会自动在可执行程序目录下生成log4crc日志模块配置文件(若存在则不生成),配置文件中可以指定日志级别等(见.3.3.日志配置文件log4crc文件内容)。

采用这种方式,用户比较省心,不用去设置配置文件名和具体的配置文件中各个参数,将自动生成一个缺省的log4crc配置文件,日志级别是notice,所以只能输出比notice级别更高的日志信息。

示例代码:

LOG_INIT_DEFAULT();

4.2.4.2.       带参数设置日志初始化宏定义
LOG_INIT_WITH_PARAM();

上面的日志初始化宏定义是可以设置日志级别、日志配置文件、生成日志文件名等各个参数的,若不进行这些设置则采用缺省的参数,此时功能就和LOG_INIT_DEFAULT一样。

参数设置有如下宏定义,这些宏定义都必须在LOG_INIT_WITH_PARAM宏定义执行之前调用:

4.2.4.2.1.     设置日志配置文件名
LOG_PARAM_CFG_FILE_NAME (strCfgFileName)

参数strCfgFileName即为配置文件的名称,类型为字符串,这个允许用户指定日志配置文件名,不一定非要用缺省的log4crc。可以不调用该宏定义,此时使用缺省的log4crc来作为日志配置文件名。

4.2.4.2.2.     设置日志级别
LOG_PARAM_LOG_LEVEL (strLogLevel)

strLogLevel即为日志级别,类型为字符串,级别有fatal/alert/crit/error/warn/notice/info/debug/trace/notset/unknown。各个日志级别越来越弱,fatal表示只有fatal的日志才输出,alert表示只有fatal/alert级别的日志才输出,其它一次类推,unknown表输出所有级别的日志信息。可以不调用该宏定义,此时使用缺省”notice”来作为缺省的日志输出级别。

4.2.4.2.3.     设置生成的日志输出文件的文件前缀的名称
LOG_PARAM_LOG_FILE_NAME (strLogFileName)

strLogFileName即为文件名,类型为字符串。可以不调用该宏定义,此时使用缺省的”log”来作为生成的日志文件名的前缀,此时生成的日志输出文件为log.0、log.1等。最新的日志文件总是log.0,当达到限定大小时,将log.0改为log.1,原来的log.1改为log.2,原来的log.2改为log.3依次类推,然后重新开启一个新的log.0文件来存放日志。

4.2.4.2.4.     设置日志输出文件的大小
LOG_PARAM_LOG_FILE_SIZE(iFileSize)

iFileSize即为文件大小,类型为整型,单位为字节。当输出的日志文件达到该大小时将重新开启一个新的日志文件来存放后续的日志。可以不调用该宏定义,此时使用缺省的1048576字节即1M。

4.2.4.2.5.     设置生成的日志文件个数
LOG_PARAM_LOG_FILE_NUM(iFileNum)

设置至多生成多少个日志文件,类型为整型。当生成的日志文件已经达到最大个数时,将把最旧的日志覆盖掉。

4.2.4.2.6.     设置是否重新读取配置文件
LOG_PARAM_REREAD_LOG_CFG_FILE(bReReadLogCfgFile)

设置是否输出每条日志信息时都重新读取配置文件,类型为整型。这个在不希望关闭程序动态改变输出日志级别时特别有用,0表示否,1表示是。

4.2.4.2.7.     示例代码
     ///设置日志配置文件名

     LOG_PARAM_CFG_FILE_NAME("test_log_with_param_macro");

     ///设置生成日志文件名

     LOG_PARAM_LOG_FILE_NAME("test_log_with_param_macro");

     ///设置日志级别

     LOG_PARAM_LOG_LEVEL("unknown");

     ///设置日志文件大小

     LOG_PARAM_LOG_FILE_SIZE(512);

     ///设置生成日志文件个数,达到最大个数将自动覆盖最旧的日志

     LOG_PARAM_LOG_FILE_NUM(5);

     ///设置每次记录日志都重新读取日志配置文件

     LOG_PARAM_REREAD_LOG_CFG_FILE(1);

     ///带参数日志模块初始化,以上所有设置了的参数都将生效,没有设置的采用缺省值

     LOG_INIT_WITH_PARAM();

 

4.2.4.3.       带参数设置日志初始化宏定义(多个进程实例)
LOG_INIT_WITH_PARAM_MULTI_PROCESS ();

该宏定义作用和LOG_INIT_WITH_PARAM类似,只是用于多个进程实例时,设置参数也采用和LOG_INIT_WITH_PARAM一样的LOG_PARAM_CFG_FILE_NAME等宏定义来进行设置。

当有多个进程实例运行时,多个进程都会去访问日志配置文件,都会进行日志记录,此时生成的日志文件就是多个进程共同产生的了,容易导致混乱。此时可以采用LOG_INIT_WITH_PARAM_MULTI_PROCESS宏定义来进行初始化就好了。采用该宏定义,同一程序的多个进程实例间记录日志互相不影响。

假设LofCfgFile为设置的日志配置文件名,LogFile为设置的日志文件,则有多个进程实例时LofCfgFile1/LogFile1为第一个进程实例的日志配置文件名和生成的日志文件前缀;LofCfgFile2/LogFile2为第二个进程对应的,依次类推。

l  示例代码:

     ///设置日志配置文件名

     LOG_PARAM_CFG_FILE_NAME("test_log_with_param_multi_process_macro");

     ///设置生成日志文件名

     LOG_PARAM_LOG_FILE_NAME("test_log_with_param_multi_process_macro");

     ///设置日志级别

     LOG_PARAM_LOG_LEVEL("unknown");

     ///设置日志文件大小

     LOG_PARAM_LOG_FILE_SIZE(512);

     ///设置生成日志文件个数,达到最大个数将自动覆盖最旧的日志

     LOG_PARAM_LOG_FILE_NUM(5);

     ///设置每次记录日志都重新读取日志配置文件

     LOG_PARAM_REREAD_LOG_CFG_FILE(1);

     ///带参数日志模块初始化,以上所有设置了的参数都将生效,没有设置的采用缺省值

     LOG_INIT_WITH_PARAM_MULTI_PROCESS();

4.2.5.    日志模块扫尾代码
LOG_FINI();

日志模块扫尾代码,程序退出时调用扫尾代码防止内存/资源泄漏。

4.2.6.    日志记录
C++方式目前的日志输出支持了基本元素的流输出,另支持std::string,std::wstring两个类型数据的输出。

4.2.6.1.       LOG宏定义记录日志
     LOG(LOG_LEVEL_FATAL, "Hello world! My age is " << 28 <<", and my name is " << "Jess!");

l  日志级别有如下几种可选:

LOG_LEVEL_FATAL/LOG_LEVEL_ALERT/LOG_LEVEL_CRIT/LOG_LEVEL_ERROR/LOG_LEVEL_WARN/LOG_LEVEL_NOTICE/LOG_LEVEL_INFO/LOG_LEVEL_DEBUG/LOG_LEVEL_TRACE/LOG_LEVEL_NOTSET/LOG_LEVEL_UNKNOWN。

本宏定义的日志记录代码将输出时间、线程ID、日志级别、文件名、行号、日志输出信息,输出日志的具体内容如下:

20090803 11:39:41.625 ThreadID:5552 ERROR root- test_usinglog4c.c(25) Hello world! My age is 28, and my name is Jess!

4.2.6.2.       LOG_PRINTF宏定义采用C语言方式printf参数格式记录日志
LOG_PRINTF((LOG_LEVEL_FATAL, " Hello world! My age is %d, and my name is %s!", 28, "Jess" ));

本宏定义输出都采用和sprintf函数参数一样的方式,要注意的是这里前后是两个“(”和两个 “)”,切记切记。输出的日志的具体内容如下:

20090803 11:39:41.625 ThreadID:5552 ERROR root- test_usinglog4c.c(25) Hello world! My age is 28, and my name is Jess!

4.2.6.3.       LOG_FUN宏定义带函数名记录日志
     LOG_FUN("LOG_FUN");

本宏定义输出日志中带有当前函数名称,输出日志的具体内容如下:

20090808 03:26:24.890 ThreadID:444 TRACE root- test.c(262) FUN<test_log4c_fun>:LOG_FUN

4.2.6.4.       LOG_HEX_DUMP以十六进制方式输出缓冲区内容
     char strBuffer[128] = "You are the Best One!/0 Yes.";

     LOG_HEX_DUMP((LOG4C_TRACE, strBuffer, sizeof(strBuffer)));

本宏定义将缓冲区中数据以十六进制方式打印出来,要指定缓冲区首地址和缓冲区长度。

输出日志的具体内容如下:

20090808 03:26:24.937 ThreadID:444      TRACE    root- test.c(296)

0000  59 6f 75 20 61 72 65 20 - 74 68 65 20 42 65 73 74   You are the Best

0010  20 4f 6e 65 21 00 20 59 - 65 73 2e 00 00 00 00 00    One!. Yes......

0020  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00   ................

0030  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00   ................

0040  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00   ................

0050  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00   ................

0060  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00   ................

0070  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00   ................

 

l  示例代码:

///测试LOG4C_HEX_DUMP宏

void test_log_hex_dump()

{

     char strBuffer[128] = "You are the Best One!/0 Yes.";

     LOG_INIT_DEFAULT();

     LOG_HEX_DUMP(LOG4C_PRIORITY_TRACE, strBuffer, sizeof(strBuffer));

     LOG_FINI();

}

 

4.2.6.5.       LOG_IF宏定义条件记录日志
     LOG_IF(4>3, LOG_LEVEL_ERROR, "LOG_IF:4>3");

     LOG_IF(2>3, LOG_LEVEL_ERROR, "LOG_IF:2>3");

本宏定义只有在满足第一参数为真时才会进行日志输出,否则不输出日志。上面的两条语句就只有第一条才会输出日志,第二条由于条件为假将不输出为日志。

输出日志的具体内容如下:

20090808 03:26:24.921 ThreadID:444 ERROR root- test.c(272) LOG_IF:4>3

4.2.6.6.       LOG_LINE宏定义输出当前行号
     LOG_LINE();

本宏定义输出当前行号,输出日志的具体内容如下:

20090808 03:26:24.937 ThreadID:444 TRACE root- test.c(283) line:283

4.2.6.7.       LOG_RETURN宏定义输出并return
     LOG_RETURN(LOG4C_LEVEL_TRACE, "LOG_RETURN");

本宏定义输出当前日志信息后就return退出当前函数,输出日志的具体内容如下:

20090808 03:26:24.953 ThreadID:444 TRACE root- test.c(306) LOG_RETURN

4.2.6.8.       LOG_RETURN_WITH_VALUE宏定义输出并带参数return
     LOG_RETURN(LOG4C_LEVEL_TRACE, "LOG_RETURN 0");

本宏定义输出当前日志信息后就带参数return退出当前函数,输出日志的具体内容如下:

20090808 03:26:24.953 ThreadID:444 TRACE root- test.c(306) LOG_RETURN 0

4.2.6.9.       LOG_ORIGIN宏定义输出用户原始信息日志
     LOG_ORIGIN (LOG_LEVEL_ERROR,"LOG_ORIGIN");

本宏定义输出的日志就只有用户要输出的原始信息,没有其它时间、线程ID、日志级别等等额外信息了。输出日志的具体内容如下:

LOG_ ORIGIN

4.2.6.10.   LOG_NO_FILENUM宏定义记录日志不带文件名和行号
     LOG_NO_FILENUM(LOG_LEVEL_ERROR,"LOG_NO_FILENUM");

本宏定义输出的日志除了不带文件名和行号,其它和LOG4C宏定义输出的日志都相同,输出日志的具体内容如下:

20090804 17:34:07.578 ThreadID:1384     ERROR    root- LOG_NO_FILENUM

4.2.6.11.   LOG_NO_FILENUM_NO_LAYOUT宏定义记录日志
     LOG_NO_FILENUM_NO_LAYOUT(LOG_LEVEL_ERROR,"LOG_NO_FILENUM_NO_LAYOUT");

本宏定义输出的日志就只有用户要输出的原始信息,没有其它时间、线程ID、日志级别等等额外信息了。本宏定义和LOG4C_ ORIGIN其实是一样的,输出日志的具体内容如下:

LOG_NO_FILENUM_NO_LAYOUT

4.2.6.12.   LOG_BLOCK宏定义跟踪调用层次
     LOG_BLOCK ("LOG_BLOCK0");

     LOG_BLOCK ("LOG_BLOCK1");

     LOG_BLOCK ("LOG_BLOCK2");

     LOG_BLOCK ("LOG_BLOCK3");

LOG_BLOCK宏定义将生成一个对象,利用对象的构造函数和析构函数来打印输出,构造函数调用时表示进入一层,析构函数调用时表退出一层,上面宏定义的日志输出信息为:

20090808 03:26:24.875 ThreadID:444      TRACE    - test.c(244) B-Entry     ==> LOG_BLOCK0

20090808 03:26:24.875 ThreadID:444      TRACE    - test.c(245) B-Entry     ====> LOG_BLOCK1

20090808 03:26:24.875 ThreadID:444      TRACE    - test.c(245) B-Entry     ======> LOG_BLOCK2

20090808 03:26:24.875 ThreadID:444      TRACE    - test.c(245) B-Entry     ========> LOG_BLOCK3

20090808 03:26:24.890 ThreadID:444      TRACE    - test.c(251) B-Exit       <======== LOG4C_BLOCK3

20090808 03:26:24.890 ThreadID:444      TRACE    - test.c(251) B-Exit       <==== ==LOG4C_BLOCK2

20090808 03:26:24.890 ThreadID:444      TRACE    - test.c(251) B-Exit       <==== LOG4C_BLOCK1

20090808 03:26:24.890 ThreadID:444      TRACE    - test.c(252) B-Exit       <== LOG4C_BLOCK0

看到没,以上日志的输出是有层次的,表示进入LOG4C_BLOCK0 Block后,又进入LOG4C_BLOCK1 Block直到LOG4C_BLOCK3 Block,然后开始以相反顺序退出各Block。

4.3. 日志配置文件log4crc文件内容
log4crc配置文件为log4c日志模块的缺省日志配置文件,文件内容见后面,采用XML格式。用户可以修改该配置文件来动态进行日志级别等的配置,详细的配置文件中各字段的格式可以去查看log4c的文档说明(http://log4c.sourceforge.net/),这里进行平时用的比较多的一些字段的简单介绍:

l  priority的值即为日志级别,可以设置的有: fatal/alert/crit/error/warn/notice/info/debug/trace/notset/unknown.各个日志级别越来越弱,fatal表示只有fatal的日志才输出,alert表示只有fatal/alert级别的日志才输出,其它一次类推,unknown表输出所有级别的日志信息。

l  maxsize的值为进行日志文件回滚时日志文件的大小,单位是字节。

l  maxnum的值表示至多记录多少个日志文件,然后重新回滚到第一个日志文件名。

l  prefix的值是生成日志文件的文件名前缀。

l  reread的值表示是否输出每条日志信息时都重新读取配置文件,这个在不希望关闭程序动态改变输出日志级别时特别有用,0表示否,1表示是。

l  log4crc配置文件内容:

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE log4c SYSTEM "">

 

<log4c version="1.2.1">

<config>

<bufsize>0</bufsize>

<debug level="2"/>

<nocleanup>0</nocleanup>

<reread>1</reread>

</config>

 

<category name="root" priority="notice"  appender="aname"/>

 

<rollingpolicy name="a_policy_name" type="sizewin" maxsize="1048576" maxnum="15" />

<appender name="aname" type="rollingfile"  logdir="." prefix="log" layout="dated_threadid" rollingpolicy="a_policy_name" />

 

<appender name="stdout" type="stream" layout="dated_threadid"/>

<appender name="stderr" type="stream" layout="dated"/>

<appender name="syslog" type="syslog" layout="basic"/>

</log4c>

5.   性能测试
5.1. C语言方式性能测试
1ms可以记录60条如下的语句:

20080215 11:22:27.859 ThreadID:888 ERROR - test_usinglog4c.c(31) Hello world! My age is 8, and my name is 黄道义!

统计性能:平均1S可记录3048条日记。

每条日记花费时间是:3.28e-4 (0.000328S)

5.2. C++语言方面性能测试
1ms输出了7个日志。

6.   空间占用
6.1. C语言空间占用
l  Debug版本

日志库本身带来生成可执行文件的大小增加140K,其它就是记录日志的宏定义的代码导致文件大小的增加了。

l  Release版本

日志库本身带来生成可执行文件的大小增加70K,其它就是记录日志的宏定义的代码导致文件大小的增加了。

6.2. C++语言空间占用
l  Debug版本

日志库本身带来生成可执行文件的大小增加212K,其它就是记录日志的宏定义的代码导致文件大小的增加了。

l  Release版本

日志库本身带来生成可执行文件的大小增加105K,其它就是记录日志的宏定义的代码导致文件大小的增加了。

7.   Linux平台编译注意事项
本日志头文件在linux平台下编译测试通过,Linux平台下要:

n  定义如下宏定义:

PTHREAD/HAVE_PTHREAD_H/HAVE_SHM

C语言方式日志宏定义开关: LOG4C_ENABLE

C++语言方式日志宏定义开关: LOG_USELOG4CXX

n  链接thread线程库

8.   参考资料及备注
【1】       Log4c开源源码和相应文档。

【2】       Log4c网上版本打印出来的时间值是格林尼治时间,不是本地时间,进行了修正。

【3】       Log4c的日志输出格式中没有线程ID,加上了线程ID。

【4】       Log4c的日志中没有输出文件名和行号,加上了文件名和行号。

 
 

本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/wenhm/archive/2009/08/14/4445955.aspx

Spring AOP 实现日志记录功能 最近项目中需要记录日志,跟大家想的一样 ,利用spring aop去实现,之前也参考了一些代码,自己实现了一套设计,供大家参考。之前看到网上很多是基于切面类Aspect去实现了,在切面类中定义before after around等逻辑以及要拦截等方法。本文利用注解实现了一套可以扩展等日志记录模块。1. 定义注解@Target(ElementType.METHOD) @Retention(Rete... 阅读详情

相关推荐

【Python】Flask日志记录:将日志输出到多个文件、显示行号、模块名称、日志级别等

参考文章:Flask使用日志记录到文件示例-博客园 flask的日志记录需要用到python标准库logging的支持。 示例 # -*- coding: utf-8 -*- from flask import Flask import logging app = Flask(__name__) @app.route('/') def root(): app.logger.info...

寒泉 3万+

rtthread ulog 日志组件

ulog

liuyuanbin9001 3190

Java基于注解实现日志记录模块,超详细注释!

在项目开发过程中,日志记录是一个至关重要的环节,它能够帮助开发人员追踪用户的重要操作,如新增、删除、修改等,从而有效监控系统的运行状态。通过日志记录,我们可以深入了解系统的运行情况,及时发现并解决问题,优化性能,提高用户体验。

m0_66216860的博客 2718

log4c 总结

mac上编译log4c-1.2.4 编译->配置->例子 一步一步学习log4c

爱无界的专栏 5532

【ray】【配置日志记录】

默认情况下,Ray 会删除跨多个进程冗余出现的日志的重复数据。这是代理的日志文件,包含创建或删除请求以及缓存命中和未命中的日志。有关实际安装的日志(例如,例如,如果您有大量工作角色 Actor,您可能希望轻松查看记录特定消息的 Actor 的索引。若要处理日志并将其导出到外部存储或管理系统,请查看 Kubernetes 上的日志持久性和 VM 上的日志持久性,了解更多详细信息。因此,每当您的集群或某些节点停止或终止时,日志文件都可能丢失。从广义上讲,存在两种类型的日志文件:系统日志文件和应用程序日志文件。

wq6qeg88的博客 4458

C++实现文件日志记录指南

本文还有配套的精品资源,点击获取 简介:在复杂系统开发和调试中,C++中的日志记录到文件是一项关键功能,它记录错误、异常和关键事件。本篇介绍如何从基础到高级实现C++文件日志记录功能,包括自定义日志级别、设计日志类、文件初始化和关闭、日志级别控制、多线程支持、日志旋转和格式化。同时,建议在实际项目中优先考虑使用成熟的日志库。 1. 日志系统概念介绍 日志系统...

weixin_28872035的博客 1824

嵌入式LOG记录

log先记录在内部flash,然后导出到u盘。

weixin_58595117的博客 622

CODESYS V3.5 SP17编程环境全攻略:从安装到多语言编程实战

本文全面解析CODESYS V3.5 SP17编程环境,从安装配置到多语言编程实战技巧。详细介绍了运行时环境设置、六种IEC 61131-3语言的特性对比与混合编程策略,以及高级功能开发如自定义算法模块和实时通信配置。适合工业自动化工程师快速掌握这一强大工具。

weixin_30632089的博客 489

ulog记录(RTTulog部分)

首先计算颜色信息的长度,然后根据颜色信息的长度确定新的日志起始地址和日志长度,去除颜色输出的标记后,再调用后端的输出函数),输出函数ulog_output_to_all_backend相关参数主要包括:日志级别,标签,是否为原始日志,缓冲区,长度。- `rt_err_t ulog_backend_set_filter(ulog_backend_t backend, ulog_backend_filter_t filter)` 函数用于设置日志后端的过滤器。参数 `tag` 是要设置的全局日志标签。

W546556的博客 1815

避坑指南:LISFLOOD-FP模型数据单位、参数文件与results文件夹结果解析全攻略

本文详细解析了LISFLOOD-FP洪水模拟模型的关键应用环节,包括数据单位校验、参数文件优化及结果文件解读与可视化。特别针对常见的单位混淆问题,提供了从DEM到边界条件的全面校验方法,并深入剖析了.par参数文件的配置技巧,帮助用户避免模型崩溃和结果失真。

weixin_42533622的博客 237

Selenium自动化测试遇到shadow-root元素?3种实用解决方案帮你搞定

本文针对Selenium自动化测试中遇到shadow-root元素难以定位的常见问题,提供了三种实用的解决方案。详细阐述了通过JavaScript直接穿透Shadow DOM、利用浏览器工具快速获取JS Path以及使用Python第三方库进行优雅封装的方法,并分享了提升脚本健壮性的实战策略与最佳实践,帮助测试人员有效应对现代Web组件化开发带来的挑战。

code8的博客 408

python日志记录_Python日志记录

python记录日志To start, logging is a way of tracking events in a program when it runs and is in execution. Python logging module defines functions and classes that provide a flexible event logging system ...

从零开始的教程世界 3644

NY8A053E 例程 之 PWM Ouput

更多关于NY8A053E的相关例程请留言!

倪彬笑阳的博客 2925

Flask实现高效日志记录模块

在Flask应用中,日志记录是重要的功能之一,它可以帮助开发人员跟踪请求的处理情况,快速定位错误,并且有助于应用的监控与调试。本文将介绍如何在Flask应用中实现请求日志记录,包括如何记录请求的各种信息(如请求数据、响应数据、错误信息等)并将其保存到数据库中。我们还会演示如何捕获不同级别的日志(信息级别、错误级别),并讨论如何处理复杂的响应数据(如流式响应)。

m0_56659620的博客 1740

在昇腾910B服务上部署搭建适配PDF解析工具Mineru2.5开源项目

本文介绍了在昇腾910B服务器上部署开源PDF解析工具Mineru2.5的过程。首先从昇腾社区下载mindie镜像并运行容器,安装系统依赖。针对部署过程中遇到的多个报错问题(如torchvision与torch版本不匹配、昇腾软件栈与NumPy 2.0不兼容等),提供了具体解决方案和兼容版本。通过设置环境变量、安装指定版本的Python依赖包,成功部署Mineru项目并下载模型。最后运行测试,验证了在NPU设备上运行pipeline的可行性。整个过程详细记录了版本适配和错误处理方法,为类似部署场景提供了参考

一起加油吧 2164

「极简」扣子(coze)教程 | 细节决定成败!这个小功能让用户满意度飙升,讲的太细了

这一期大师兄通过向扣子(coze)应用添加提示语的方法向用户显示系统运行的状态。

u014527622的博客 2113

在Flask中实现日志记录

你可以通过创建Formatter对象来自定义日志消息的格式。Formatter的构造器接受一个格式字符串,该字符串定义了日志消息的最终格式。在上述格式字符串中,%(name)s和是预定义的占位符,分别代表日志消息的时间戳、记录器名称、日志级别和日志消息本身。

sheji888的专栏 1934

【软件系统架构】系列六:MBSE(基于模型的系统工程)

基于模型的系统工程(MBSE)是一种以模型为核心的系统工程方法论,通过结构化、可视化的模型取代传统文档,实现从需求到验证的全生命周期管理。MBSE采用SysML建模语言,包含需求、功能、架构和验证四大要素,支持自动追踪、仿真分析和代码生成。相比文档式工程,MBSE具有变更影响自动分析、跨团队协作和高可视化等优势,广泛应用于航空航天、汽车电子等领域。典型开发流程包括需求建模、行为建模、架构建模等阶段,配合MagicDraw、Cameo等工具链实现。MBSE正与数字孪生、AI技术融合,推动自动化建模和智能验证的

moton2017的博客 2783
上一篇: 内存泄漏的检测、定位和解决经验总结
下一篇: C++中内存泄漏的检测
YearWang
博客等级 码龄20年 143粉丝 153原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值