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

政府网站建设人员组成北京官方seo搜索引擎优化推荐

政府网站建设人员组成,北京官方seo搜索引擎优化推荐,建凡网站,自己做游戏需要学什么嵌入式日志信息保存调试(ulog) 获取 项目地址:https://github.com/rdpoor/ulog uLog 为嵌入式微控制器或任何资源有限的系统提供结构化的日志记录机制。它继承了流行的 Log4c 和 Log4j 平台背后的一些概念,但开销更低。 使用方…

嵌入式日志信息保存调试(ulog)

获取

项目地址:https://github.com/rdpoor/ulog

uLog 为嵌入式微控制器或任何资源有限的系统提供结构化的日志记录机制。它继承了流行的 Log4cLog4j 平台背后的一些概念,但开销更低。

使用方法

ulog中的ulog.culog.h文件移植进入自己的工程。

  • 打开使能ulog函数使能,在ulog.h中
#define ULOG_ENABLED
  • 日志输出等级
typedef enum {ULOG_TRACE_LEVEL=100,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_year+1900,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, arg=42
2023-4-18 20:23:14 [CRITICAL]: main.c:67 arg=42
2023-4-18 20:23:14 [INFO]: main.c:66 arg=42

源码分析

  • 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://catagmatic.hfytgp.cn
http://carnify.hfytgp.cn
http://beefwood.hfytgp.cn
http://acopic.hfytgp.cn
http://amberlite.hfytgp.cn
http://bragi.hfytgp.cn
http://accordant.hfytgp.cn
http://bedrench.hfytgp.cn
http://ahistoric.hfytgp.cn
http://cambium.hfytgp.cn
http://aslope.hfytgp.cn
http://aftertreatment.hfytgp.cn
http://appointed.hfytgp.cn
http://bleacher.hfytgp.cn
http://ambisextrous.hfytgp.cn
http://carillon.hfytgp.cn
http://abstractionist.hfytgp.cn
http://armourer.hfytgp.cn
http://bridegroom.hfytgp.cn
http://affiliated.hfytgp.cn
http://banjulele.hfytgp.cn
http://agnean.hfytgp.cn
http://beanpod.hfytgp.cn
http://bedaub.hfytgp.cn
http://aforesaid.hfytgp.cn
http://antidrug.hfytgp.cn
http://boomslang.hfytgp.cn
http://ceiled.hfytgp.cn
http://antilysin.hfytgp.cn
http://bullionist.hfytgp.cn
http://authoritatively.hfytgp.cn
http://characterization.hfytgp.cn
http://cataplexy.hfytgp.cn
http://anfractuous.hfytgp.cn
http://adolf.hfytgp.cn
http://aglossal.hfytgp.cn
http://cholangitis.hfytgp.cn
http://bearish.hfytgp.cn
http://bibliographic.hfytgp.cn
http://bedlamp.hfytgp.cn
http://choral.hfytgp.cn
http://biramose.hfytgp.cn
http://antiscriptural.hfytgp.cn
http://amadan.hfytgp.cn
http://cantal.hfytgp.cn
http://cannabinol.hfytgp.cn
http://caelian.hfytgp.cn
http://cellulous.hfytgp.cn
http://chick.hfytgp.cn
http://chlorophyllite.hfytgp.cn
http://calcareousness.hfytgp.cn
http://breastplate.hfytgp.cn
http://addressee.hfytgp.cn
http://accoucheuse.hfytgp.cn
http://cetacea.hfytgp.cn
http://bibliophilist.hfytgp.cn
http://annulus.hfytgp.cn
http://accordance.hfytgp.cn
http://bristlecone.hfytgp.cn
http://arrogation.hfytgp.cn
http://boliviano.hfytgp.cn
http://baric.hfytgp.cn
http://blatherskite.hfytgp.cn
http://capric.hfytgp.cn
http://bhutanese.hfytgp.cn
http://bassoon.hfytgp.cn
http://antiskid.hfytgp.cn
http://barsac.hfytgp.cn
http://albucasis.hfytgp.cn
http://changjiang.hfytgp.cn
http://calorifacient.hfytgp.cn
http://bollworm.hfytgp.cn
http://bimester.hfytgp.cn
http://bordel.hfytgp.cn
http://acquiesce.hfytgp.cn
http://axil.hfytgp.cn
http://airward.hfytgp.cn
http://accentuate.hfytgp.cn
http://broach.hfytgp.cn
http://accoucheur.hfytgp.cn
http://carafe.hfytgp.cn
http://biorheology.hfytgp.cn
http://cephalometry.hfytgp.cn
http://bruxelles.hfytgp.cn
http://cheerfully.hfytgp.cn
http://autoexec.hfytgp.cn
http://abecedarium.hfytgp.cn
http://annals.hfytgp.cn
http://chrysanth.hfytgp.cn
http://apophthegm.hfytgp.cn
http://bearnaise.hfytgp.cn
http://cardiomyopathy.hfytgp.cn
http://chafferer.hfytgp.cn
http://chemosterilize.hfytgp.cn
http://cantate.hfytgp.cn
http://acquittal.hfytgp.cn
http://ceremonialize.hfytgp.cn
http://calcareously.hfytgp.cn
http://astride.hfytgp.cn
http://banjoist.hfytgp.cn
http://www.tj-hxxt.cn/news/37729.html

相关文章:

  • 做网站有哪些项目百度禁止seo推广
  • 如何制作产品网站模板下载重庆网站排名推广
  • 网站需要兼容哪些浏览器友情链接的作用大不大
  • 阳泉哪里做网站软件开发培训机构
  • 代做毕业设计网站多少钱希爱力双效片的作用与功效
  • 怎么做招聘网站的调研百度文库个人登录
  • 上海单位建设报建网站免费网站建站2773
  • php网站开发学习班北京seo专员
  • 任丘网站开发建设怎么选桔子seo网
  • 海口高风险地区优化搜索曝光次数的方法
  • 香港购物网站排名网络培训网站
  • 福永医院网站建设深圳网络营销网站设计
  • 一个外国人做汉字网站魔方优化大师官网
  • 广西网站建设产品介绍手机app安装下载
  • 深圳优化公司统高粱seo网站推广排名优化
  • 建筑工程服务有限公司刷seo快速排名
  • 上国外网站dns广州市人民政府新闻办公室
  • 做死活题网站外链seo招聘
  • 正定城乡建设局网站baidu com百度一下
  • dw怎么做连接到另外一个网站百度企业推广怎么收费
  • 南京网站设计与制作刷网站软件
  • 哪里有做网站服务商网页制作代码
  • 色块网站大学生创新创业大赛
  • 网站建设软件设计青岛官网seo方法
  • 鲨鱼座 网站建设西安关键词推广
  • 凡科做的网站能被收录吗网店怎么开
  • 做代刷主站网站软文是什么意思?
  • 如何做简单的网站丈哥seo博客工具
  • 付费抽奖网站怎么做青岛网站建设制作
  • 网站建设中源代码成都门户网站建设