嵌入式log日志框架实现

在嵌入式开发中,开发阶段打印日志是追踪BUG常用手段,但是一旦到发布阶段,用来打印的日志一般需要不体现在发布中----即不被用户看到,同时在发布的版本出现问题时,还能使用原来的log定位问题源,那么使用一般的print语句,就不合适了,现在给大家介绍一下好用的log用法和框架。
源码在此

一、宏定义log实现

先给大家简单介绍一下常用条件编译相关的预编译指令

#define           定义一个预处理宏
#undef            取消宏的定义
#if               编译预处理中的条件命令,相当于C语法中的if语句
#ifdef            判断某个宏是否被定义,若已定义,执行随后的语句
#ifndef           与#ifdef相反,判断某个宏是否未被定义
#elif             若#if, #ifdef, #ifndef或前面的#elif条件不满足,则执行#elif之后的语句,相当于C语法中的else-if
#else             与#if, #ifdef, #ifndef对应, 若这些条件不满足,则执行#else之后的语句,相当于C语法中的else
#endif            #if, #ifdef, #ifndef这些条件命令的结束标志.
defined          与#if, #elif配合使用,判断某个宏是否被定义

那么使用宏定义头+ifdef语句就可一键开关所有log日志打印

#include <stdio.h>
#define LOGS1 1  //定义宏常量-是
#define LOGS 0   //定义宏常量-否
void main(){
	#ifdef LOGS1	
	printf("log print1\n");
	#endif
	
	#ifdef LOGS
	printf("log print2\n");
	#endif
	
	#ifdef LOGS1
	printf(“log print3\n");
	#endif
}

在这里插入图片描述

二、函数时宏定义log

将log处理过程变为函数,然后以宏定义全局控制
函数介绍:
vsnprintf()作用:
使用vsnprintf()用于向一个字符串缓冲区打印格式化字符串,且可以限定打印的格式化字符串的最大长度。此函数需要C99或者C++11及以上版本才能支持。

int vsnprintf (char * sbuf, size_t n, const char * format, va_list arg);
参数sbuf:用于缓存格式化字符串结果的字符数组
参数n:限定最多打印到缓冲区sbuf的字符的个数为n-1个,因为vsnprintf还要在结果的末尾追加\0。如果格式化字符串长度大于n-1,则多出的部分被丢弃。如果格式化字符串长度小于等于n-1,则可以格式化的字符串完整打印到缓冲区sbuf。一般这里传递的值就是sbuf缓冲区的长度。
参数format:格式化限定字符串
参数arg:可变长度参数列表
返回:成功打印到sbuf中的字符的个数,不包括末尾追加的\0。如果格式化解析失败,则返回负数。

#include <stdio.h>
#include <stdarg.h>
#define OPEN_LOGS2 1
#define LOG_LEVEL LOG_DEBUG

typedef enum
{
  LOG_DEBUG = 0,
  LOG_INFO,
  LOG_WARN,
  LOG_ERROR,
} E_LOGLEVEL;

char *ME_LOGLevelGet(const int level)
{
  if (level == LOG_DEBUG)
  {
    return "DEBUG";
  }
  else if (level == LOG_INFO)
  {
    return "INFO";
  }
  else if (level == LOG_WARN)
  {
    return "LOG_WARN";
  }
  else if (level == LOG_ERROR)
  {
    return "LOG_ERROR";
  }
  return "UNKNON";
}

void ME_LOG(const int level, const char* fun,const int line,const char *fmt, ...)
{
#ifdef OPEN_LOGS2
  va_list arg;        // 宏定义参数
  va_start(arg, fmt); // 获取可变参数列表的第一个参数的地址(arg是类型为va_list的指针,fmt是可变参数最左边的参数)
  char buf[1 + vsnprintf(NULL, 0, fmt, arg)];
  vsnprintf(buf, sizeof(buf), fmt, arg);
  va_end(arg); // 清空va_list可变参数列表
  if (level >= LOG_LEVEL)
    printf("[%s][%s %d]%s\n", ME_LOGLevelGet(level),fun,line,buf);
#endif
}

#define EMLog(level,fmt...) ME_LOG(level,__FUNCTION__,__LINE__,fmt)		
//在这里定义是因为函数ME_LOG的定义范围,__FUNCTION__,__LINE__是内部参数定义,能够显示代码所在函数与行数

void main()
{
  main1();
  int a = 10, b = 11;
  EMLog(LOG_DEBUG, "app start");
  EMLog(LOG_INFO, "A= %d", a);
  EMLog(LOG_WARN, "app LOG_WARN");
  EMLog(LOG_ERROR, "app LOG_ERROR");
}

在这里插入图片描述

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实现在Java Web程序中嵌入式日志收集功能,可以使用 Log4j 或 Logback 等日志框架来收集用户的行为数据。具体的实现过程如下: 1. 引入 Log4j 或 Logback 依赖 在 Maven 项目中,可以在 pom.xml 文件中引入 Log4j 或 Logback 的依赖: ``` <!-- Log4j 依赖 --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <!-- Logback 依赖 --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency> ``` 2. 配置日志框架的 Appender Appender 是日志框架中用于输出日志的组件。可以将日志输出到控制台、文件、数据库等不同的目的地。在这里,我们可以使用 SocketAppender 将日志输出到 Spark DStream 中。具体的配置过程可以参考 Log4j 或 Logback 的官方文档。 3. 在 Java Web 程序中记录用户行为数据 在 Java Web 程序中,可以使用日志框架的 API 来记录用户的行为数据。例如,在 Log4j 中,可以使用以下代码来记录用户点击页面特定按钮的操作: ``` import org.apache.log4j.Logger; public class MyServlet extends HttpServlet { private static final Logger logger = Logger.getLogger(MyServlet.class); protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 处理点击页面特定按钮的操作 logger.info("用户点击了页面特定按钮"); } } ``` 4. 在 Spark 中实时统计数据 使用 SocketAppender 将用户行为数据输出到 Spark DStream 中后,可以使用 Spark Streaming 来实时统计数据。具体的实现过程可以参考 Spark Streaming 的官方文档。 5. 输出统计结果 最后,可以将统计结果输出到控制台、文件、数据库等不同的目的地,或者通过 Web 界面展示给用户。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值