当前位置: 首页 > news >正文

网站建设推广熊掌号王野天个人资料

网站建设推广熊掌号,王野天个人资料,软件开发入门,南宁网站建设嵌入式日志信息保存调试#xff08;ulog#xff09; 获取 项目地址#xff1a;https://github.com/rdpoor/ulog uLog 为嵌入式微控制器或任何资源有限的系统提供结构化的日志记录机制。它继承了流行的 Log4c 和 Log4j 平台背后的一些概念#xff0c;但开销更低。 使用方…嵌入式日志信息保存调试ulog 获取 项目地址https://github.com/rdpoor/ulog uLog 为嵌入式微控制器或任何资源有限的系统提供结构化的日志记录机制。它继承了流行的 Log4c 和 Log4j 平台背后的一些概念但开销更低。 使用方法 将ulog中的ulog.c和ulog.h文件移植进入自己的工程。 打开使能ulog函数使能在ulog.h中 #define ULOG_ENABLED日志输出等级 typedef enum {ULOG_TRACE_LEVEL100,ULOG_DEBUG_LEVEL,ULOG_INFO_LEVEL,ULOG_WARNING_LEVEL,ULOG_ERROR_LEVEL,ULOG_CRITICAL_LEVEL,ULOG_ALWAYS_LEVEL } ulog_level_t;main函数分析 记住一个点自定义里面的等级A只有我们使用的ULOG_XXX函数中XXX的等级 A 的时候该函数才会被真正的执行 #include stdio.h #include string.h #include ulog.h #include sys/types.h #include sys/stat.h #include fcntl.h// 用户自定义用于调试的函数函数 void my_console_logger(ulog_level_t severity, char *msg) {printf(console: %s [%s]: %s\n,time, // user defined functionulog_level_name(severity),msg); } // 用户自定义用于将日志存储进文件的函数 void my_file_logger(ulog_level_t severity, char *msg) {int fd open(file.txt,O_RWRD|O_CRATE,0655);printf(,file: %s [%s]: %s\n,time, // user defined functionulog_level_name(severity),msg)close(fd); }int main() {int arg 42;// ulog的初始化ULOG_INIT();// 订阅my_console_logger函数给予相应的等级为 ULOG_WARNING_LEVELULOG_SUBSCRIBE(my_console_logger, ULOG_WARNING_LEVEL);// 订阅my_file_logger函数给予相应的等级为 ULOG_DEBUG_LEVELULOG_SUBSCRIBE(my_file_logger, ULOG_DEBUG_LEVEL);// 只会执行 my_file_logger的函数理由是 ULOG_WARNING_LEVEL ULOG_INFO_LEVEL 的等级// 但是 ULOG_DEBUG_LEVEL ULOG_INFO_LEVEL 的等级// 自定义函数相应等级只有小于等于的时候才会执行相应的操作函数ULOG_INFO(Info, arg%d, arg); // logs to file but not console// ULOG_WARNING_LEVEL ULOG_DEBUG_LEVELULOG_CRITICAL(Critical, arg%d, arg); // logs to file and console// 改变my_console_logger函数的操作等级为 ULOG_INFO_LEVELULOG_SUBSCRIBE(my_console_logger, ULOG_INFO_LEVEL);// 改变后两个自定义函数的操作等级都小于等于 ULOG_INFO_LEVEL所以两个函数都会执行ULOG_INFO(Info, arg%d, arg); // logs to file and console// 取消 my_file_logger 函数的订阅操作ULOG_UNSUBSCRIBE(my_file_logger);// 其中my_file_logger取消了又 ULOG_INFO_LEVEL ULOG_INFO_LEVEL, 所以打印调试信息ULOG_INFO(Info, arg%d, arg); }自定义日志函数编写 windows char* get_timestamp() {time_t ti_t;struct tm s_tm;time(ti_t);localtime_s(s_tm, ti_t);char* time_chr (char*)malloc(sizeof(char)*20);memset(time_chr,0,20);sprintf(time_chr, %d-%d-%d %d:%d:%d,s_tm.tm_year 1900, s_tm.tm_mon 1, s_tm.tm_mday, s_tm.tm_hour, s_tm.tm_min, s_tm.tm_sec);return time_chr; }void my_console_logger(ulog_level_t severity, const char* msg) {char *get_time get_timestamp();printf(%s [%s]: %s\n,get_time, // user defined functionulog_level_name(severity),msg);free(get_time); }linux char *get_timestamp() {time_t tt;struct tm *t;time(tt);char *time_chr (char *)malloc(sizeof(char) * 20);memset(time_chr, 0, 20);t localtime(tt);sprintf(time_chr, %d-%d-%d %d:%d:%d, t-tm_year1900,t-tm_mon 1,t-tm_mday,(t-tm_hour 15)%24,t-tm_min,t-tm_sec);return time_chr; }void my_console_logger(ulog_level_t severity, const char *msg) {char *get_time get_timestamp();printf(%s [%s]: %s\n,get_time, // user defined functionulog_level_name(severity),msg);free(get_time); }void my_file_logger(ulog_level_t severity, const char *msg) {char *get_time get_timestamp();FILE* fp fopen(my_test.txt, a); // 打开文件my_test.txt 这里文件可以跟改为时间fprintf(fp, %s [%s]: %s\n,get_time, // user defined functionulog_level_name(severity),msg);free(get_time); }执行后文件中的内容类似以下这个格式是按照自己喜好在日志函数中自己编写。 2023-4-18 20:23:14 [INFO]: Info, arg42 2023-4-18 20:23:14 [CRITICAL]: main.c:67 arg42 2023-4-18 20:23:14 [INFO]: main.c:66 arg42源码分析 ulog_message #define ULOG_DEBUG(...) ulog_message(ULOG_DEBUG_LEVEL, __VA_ARGS__) // 这里的...表示的是可变参数 __VA_ARGS__ 这个也是对应的表示可变参数 这里也可以改为 // #define ULOG_DEBUG(...) ulog_message(ULOG_DEBUG_LEVEL, const char* fmt, ...)void ulog_message(ulog_level_t severity, const char* fmt, ...) {// va_list 是一个字符指针可以理解为指向当前参数的一个指针取参必须通过这个指针进行va_list ap;int i;// 然后应该对ap 进行初始化让它指向可变参数表里面的第一个参数,也就是const char* fmtva_start(ap, fmt);// 依次获取ap的类型并进行sprintf函数类型功能组合成字符串// 最大长度 ULOG_MAX_MESSAGE_LENGTH超过会被截断vsnprintf(s_message, ULOG_MAX_MESSAGE_LENGTH, fmt, ap);// 将这个 ap 指针关掉以免发生危险va_end(ap);for (i 0; i ULOG_MAX_SUBSCRIBERS; i) {// 函数是依次执行的那个函数先注册那个先运行if (s_subscribers[i].fn ! NULL) {// 只有使用的输出等级大于自定义函数等级的时候就会执行if (severity s_subscribers[i].threshold) {s_subscribers[i].fn(severity, s_message);}}} }ulog_err_t // 错误标志枚举 typedef enum {ULOG_ERR_NONE 0,ULOG_ERR_SUBSCRIBERS_EXCEEDED,ULOG_ERR_NOT_SUBSCRIBED, } ulog_err_t;ulog_subscribe、ulog_unsubscribe // 执行函数指针 typedef void (*ulog_function_t)(ulog_level_t severity, char* msg); // 执行结构体 typedef struct {ulog_function_t fn;ulog_level_t threshold; } subscriber_t; // 执行结构体数组 #define ULOG_MAX_SUBSCRIBERS 6 static subscriber_t s_subscribers[ULOG_MAX_SUBSCRIBERS];// search the s_subscribers table to install or update fn // 订阅函数也就是将函数放入执行结构体数组中并赋予相应的输出等级 ulog_err_t ulog_subscribe(ulog_function_t fn, ulog_level_t threshold) {int available_slot -1;int i;for (i 0; i ULOG_MAX_SUBSCRIBERS; i) {if (s_subscribers[i].fn fn) {// 执行结构体数组已经含有该执行函数进行更新即可// already subscribed: update threshold and return immediately.s_subscribers[i].threshold threshold;return ULOG_ERR_NONE;}else if (s_subscribers[i].fn NULL) {// found a free slot// 找到数组中最近的一个未使用的执行结构体赋予标志信息available_slot i;}}// fn is not yet a subscriber. assign if possible.if (available_slot -1) {// 执行结构体数组中已经存储满return ULOG_ERR_SUBSCRIBERS_EXCEEDED;}// 将执行函数信息放入执行结构体数组s_subscribers[available_slot].fn fn;s_subscribers[available_slot].threshold threshold;return ULOG_ERR_NONE; }// search the s_subscribers table to remove // 取消订阅就是将该函数从执行结构体数组中删除 ulog_err_t ulog_unsubscribe(ulog_function_t fn) {int i;for (i 0; i ULOG_MAX_SUBSCRIBERS; i) {if (s_subscribers[i].fn fn) {s_subscribers[i].fn NULL; // mark as emptyreturn ULOG_ERR_NONE;}}return ULOG_ERR_NOT_SUBSCRIBED; }ulog_level_name // 获取相应的输出等级字符串 const char* ulog_level_name(ulog_level_t severity) {switch (severity) {case ULOG_TRACE_LEVEL: return TRACE;case ULOG_DEBUG_LEVEL: return DEBUG;case ULOG_INFO_LEVEL: return INFO;case ULOG_WARNING_LEVEL: return WARNING;case ULOG_ERROR_LEVEL: return ERROR;case ULOG_CRITICAL_LEVEL: return CRITICAL;case ULOG_ALWAYS_LEVEL: return ALWAYS;default: return UNKNOWN;} }
http://www.hkea.cn/news/14339351/

相关文章:

  • 网站开发备案费用销售类网站模板
  • 广西高端网站建设国外工作招聘网站
  • 服装 网站模板 wordpress深圳市建设注册中心网站
  • 高端网站开发找苏州觉世品牌怎么定义自豪地采用WordPress
  • 网站一年的费用网站建设开发案例教程视频教程
  • 获取网站漏洞后下一步怎么做军事网站模板下载
  • php网站作业模版wordpress主题seo
  • 给公司做网站 优帮云it外包前景
  • 国内vps做网站要备案吗wordpress 访问不了
  • 手机网站建设请示让自己的电脑做网站的服务器
  • 重庆seo网站管理去黄山旅游攻略和费用
  • 做网站托管的好处白酒网站源码
  • 做网站设计素材网站模块添加
  • 网站源代码分列怎么做做网站网站要找谁
  • 给人做网站昆山网站建设工作室
  • 怎样做企业网站宣传环保主题的网站模板
  • 那里可以建网站成品短视频代码推荐大全
  • 网站域名邮箱.net网站
  • 网站是谁做的宁波网站开发制作
  • 王建设个人网站如何申请电商网站
  • 佳作哪个公司做网站比较好平面网页设计学校
  • 建站模板源码做网站都需要哪些知识
  • 经典网站欣赏、app定制哪里找
  • 建筑网站登陆页面鸣蝉建站平台
  • 广州网站优化效果什么是网络营销?网络营销的特点有哪些?
  • 哪些网站可以做微信wordpress多本小说站出售
  • 如何快速备案网站厦门医院网站建设
  • 网站推广seo做单挣钱的网站
  • 专门做喷涂设备的网站哪些网站可以做百科参考资料
  • 蚌埠网站制作公司价格招聘网站制作公司