LOG 日志级别,标签输出, 根据标签控制输出日志级别 , 自定义printf输出

功能:

1. 错误,警告, 信息,调试,四个等级输出, 四种颜色区别。 建议使用putty调试

2.标签独立划分等级, 每个标签可单独定义输出等级,控制输出、不输出

3.十进制/十六进制数组输出

4.自定义printf , 标准C库printf输出, 宏切换。

输出效果:

函数说明:

//tag为输出标签, 必须为静态字符或全局字符
//level 为对应标签输出等级
LOG_ADD(tag, level)
LOGE(tag, format, ...)    //输出错误日志, 红色
LOGW(tag, format, ...)    //输出警告日志,绿色
LOGI(tag, format, ...)    //输出信息日志,黄色
LOGD(tag, format, ...)    //输出调试日志,白色

//示例
LOG_ADD(TAG, _LOG_DEBUG);

LOGE(TAG, "put string, %s\n", "hello world");
LOGW(TAG, "put string, %s\n", "hello world");
LOGI(TAG, "put string, %s\n", "hello world");
LOGD(TAG, "put string, %s\n", "hello world");
//十六进制输出数组,默认为答谢
//level ,输出等级
//tag 标签
//title 描述
//buffer , 数组指针
//size 长度
LOG_ARRY_HEX(level, tag, tltle, buffer, size)

//十进制输出数组
LOG_ARRY_DEC(level, tag, tltle, buffer, size)
//示例
LOG_ARRY_HEX(_LOG_DEBUG, TAG, "test buffer", buffer, sizeof(buffer));
LOG_ARRY_DEC(_LOG_DEBUG, TAG, "test buffer", buffer, sizeof(buffer));

 

源码, log.c

#include "log.h"
#include <stdarg.h>

stp_tag_level_t *tag_level = NULL;

static const char log_color[][15] =
	{
		{0},
		{"\033[0;31mE "},
		{"\033[0;32mW "},
		{"\033[0;33mI "},
		{"\033[0;37mD "},
		{0},
};

static const char log_binary[][6] =
	{
		{0},
		{"[DEC]"},
		{"[HEX]"},
		{0},
};

#if (USE_PRINTF == 0)
static const char log_str_cap_num[17] = "0123456789ABCDEF";
static const char log_str_sml_num[17] = "0123456789abcdef";

void stp_put_num(const char *str_num, unsigned long num, int base)
{
	if (num == 0)
	{
		return;
	}
	stp_put_num(str_num, num / base, base);
	putchar(str_num[num % base]);
}

void stp_put_dec(int dec)
{
	if (dec < 0)
	{
		putchar('-');
		dec = abs(dec);
	}

	if (dec == 0)
	{
		putchar('0');
		return;
	}
	else
	{
		stp_put_num(log_str_sml_num, dec, 10);
	}
}

void stp_put_oct(unsigned oct)
{
	if (oct == 0)
	{
		putchar('0');
		return;
	}
	else
	{
		stp_put_num(log_str_sml_num, oct, 8);
	}
}

void stp_put_hex(unsigned hex, char iscap)
{
	if (hex == 0)
	{
		putchar('0');
		return;
	}
	else
	{
		if (iscap)
		{
			stp_put_num(log_str_cap_num, hex, 16);
		}
		else
		{
			stp_put_num(log_str_sml_num, hex, 16);
		}
	}
}

void stp_put_addr(unsigned long addr)
{
	putchar('0');
	putchar('x');
	stp_put_num(log_str_cap_num, addr, 16);
}

void stp_put_str(char *str)
{
	int i = 0;

	while (str[i] != '\0')
	{
		putchar(str[i++]);
	}
}

void stp_put_float(double f)
{
	int temp;

	temp = (int)f;
	stp_put_num(log_str_sml_num, temp, 10);
	putchar('.');

	f -= temp;
	if (f == 0)
	{
		for (temp = 0; temp < 6; temp++)
		{
			putchar('0');
		}
		return;
	}
	else
	{
		temp = (int)(f * 1000000);
		stp_put_num(log_str_sml_num, temp, 10);
	}
}

void stp_log_print(const char *s, ...)
{
	int i = 0;
	va_list va_ptr;

	va_start(va_ptr, s);
	while (s[i] != '\0')
	{
		if (s[i] != '%')
		{
			putchar(s[i++]);
			continue;
		}

		switch (s[++i])
		{
		case 'd':
			stp_put_dec(va_arg(va_ptr, int));
			break;
		case 'o':
			stp_put_oct(va_arg(va_ptr, unsigned int));
			break;
		case 'x':
			stp_put_hex(va_arg(va_ptr, unsigned int), false);
			break;
		case 'X':
			stp_put_hex(va_arg(va_ptr, unsigned int), true);
			break;
		case 'c':
			putchar(va_arg(va_ptr, int));
			break;
		case 'p':
			stp_put_addr(va_arg(va_ptr, unsigned long));
			break;
		case 'f':
			stp_put_float(va_arg(va_ptr, double));
			break;
		case 's':
			stp_put_str(va_arg(va_ptr, char *));
			break;
		default:
			break;
		}
		i++;
	}
	va_end(va_ptr);
}
#endif

/*
 * Tag must be a static string
 */
uint8_t stp_log_add_tag(char *tag, uint8_t level)
{
	stp_tag_level_t *priv;
	stp_tag_level_t *this;

	if (level >= _LOG_MAX)
	{
		return false;
	}

	this = malloc(sizeof(stp_tag_level_t));
	if (this != NULL)
	{
		this->tag = tag;
		this->level = level;
		this->next = NULL;
		if (tag_level == NULL)
		{
			tag_level = this;
		}
		else
		{
			priv = tag_level;
			while (priv->next != NULL)
			{
				priv = priv->next;
			}
			priv->next = this;
		}
	}
	else
	{
		return false;
	}

	return (true);
}

stp_tag_level_t *stp_log_find_tag(const char *tag)
{
	stp_tag_level_t *priv = tag_level;

	while (priv != NULL)
	{
		if ((strlen(priv->tag) == strlen(tag)) && (strncmp(priv->tag, tag, strlen(tag)) == 0))
		{
			return priv;
		}
		priv = priv->next;
	}

	return NULL;
}

int stp_log_write_str(const char *s, int len)
{
	int ret = 0;

	while (ret != EOF && len--)
	{
		ret = putchar(*s++);
	}

	return ret;
}

/*
 * log printf
 */
#if USE_PRINTF
uint8_t stp_log_write(stp_log_level_t level, const char *tag, const char *format, ...)
{
	char *log_buf;
	stp_tag_level_t *info_tag = NULL;

	int ret;
	va_list arg;

	info_tag = stp_log_find_tag(tag);
	if ((info_tag == NULL) || (info_tag->level < level))
	{
		return false;
	}

	if (level >= _LOG_MAX)
	{
		return false;
	}
	stp_log_write_str(log_color[level], strlen(log_color[level]));

	stp_log_write_str(tag, strlen(tag));
	stp_log_write_str(" : ", strlen(" : "));

	/* compute the length of the formatted message */
	va_start(arg, format);
	ret = vsnprintf(NULL, 0, format, arg);
	va_end(arg);

	/* allocated an array for the formatted message */
	if (ret < 0 || (log_buf = malloc(ret + 1)) == NULL)
	{
		stp_log_write_str(LOG_COLOR_END, strlen(LOG_COLOR_END));
		return -1;
	}
	/* construct the formatted message */
	va_start(arg, format);
	ret = vsnprintf(log_buf, ret + 1, format, arg);
	va_end(arg);

	ret = stp_log_write_str(log_buf, ret);

	stp_log_write_str(LOG_COLOR_END, strlen(LOG_COLOR_END));

	free(log_buf);
	return true;
}



uint8_t stp_log_write_arry(stp_log_level_t level, char *tag, char *tltle, uint8_t *buffer, int size, stp_log_binary_t binary)
{
	stp_tag_level_t *info_tag = NULL;
	char *log_buf = NULL;
	int len = 0, ret = 0, malloc_size = 0;

	info_tag = stp_log_find_tag(tag);
	if ((info_tag == NULL) || (info_tag->level < level))
	{
		return false;
	}
	if ((level >= _LOG_MAX) || (binary >= _LOG_BINARY_MAX))
	{
		return false;
	}

	malloc_size = strlen(log_color[level]) + strlen(tag) + strlen(" : ") + strlen(tltle);
	malloc_size += snprintf(NULL, 0, "[%d]", size);
	malloc_size += 1;		 // ‘=’ size
	malloc_size += size * 4; //buffer size
	malloc_size += strlen(LOG_COLOR_END);
	malloc_size += 1; //end
	log_buf = malloc(malloc_size);

	ret = snprintf(log_buf, malloc_size + 1, "%s%s : %s%s[%d]=", log_color[level], tag, tltle, log_binary[binary], size);
	if (ret < 0)
	{
		goto log_arry_err;
	}
	while (size--)
	{
		len += ret;
		if (binary == _LOG_BINARY_HEX)
		{
			ret = snprintf(log_buf + len, 4, "%02X ", *buffer++);
 			if (ret < 0)
			{
				goto log_arry_err;
			}
		}
		else if (binary == _LOG_BINARY_DEC)
		{
			ret = snprintf(log_buf + len, 4, "%02d ", *buffer++);
			if (ret < 0)
			{
				goto log_arry_err;
			}
		}
	}
	ret = snprintf(log_buf + len, 15, "%s\n", LOG_COLOR_END);
	if (ret < 0)
	{
		return false;
	}
	len += ret;
	stp_log_write_str(log_buf, len);

	free(log_buf);
	return true;

log_arry_err:
	free(log_buf);
	return false;
}

#else

uint8_t stp_log_write(stp_log_level_t level, const char *tag)
{
	stp_tag_level_t *info_tag = NULL;

	info_tag = stp_log_find_tag(tag);
	if ((info_tag == NULL) || (info_tag->level < level))
	{
		return false;
	}
	if (level >= _LOG_MAX)
	{
		return false;
	}

	stp_log_write_str(log_color[level], strlen(log_color[level]));
	stp_log_write_str(tag, strlen(tag));
	stp_log_write_str(" : ", strlen(" : "));

	return true;
}

uint8_t stp_log_write_arry(stp_log_level_t level, char *tag, char *tltle, uint8_t *buffer, int size, stp_log_binary_t binary)
{
	stp_tag_level_t *info_tag = NULL;

	info_tag = stp_log_find_tag(tag);
	if ((info_tag == NULL) || (info_tag->level < level))
	{
		return false;
	}
	if ((level >= _LOG_MAX) || (binary >= _LOG_BINARY_MAX))
	{
		return false;
	}

	stp_log_write_str(log_color[level], strlen(log_color[level]));
	stp_log_write_str(tag, strlen(tag));
	stp_log_write_str(" : ", strlen(" : "));
	stp_log_write_str(tltle, strlen(tltle));
	stp_log_write_str(log_binary[binary], strlen(log_binary[binary]));
	putchar('[');
	stp_put_dec(size);
	putchar(']');
	putchar('=');
	while (size--)
	{
		if (binary == _LOG_BINARY_HEX)
		{
			stp_put_hex(*buffer++, true);
		}
		else if (binary == _LOG_BINARY_DEC)
		{
			stp_put_dec(*buffer++);
		}
		putchar(' ');
	}
	stp_log_write_str(LOG_COLOR_END, strlen(LOG_COLOR_END));
	putchar('\n');

	return true;
}
#endif

 

log.h

#ifndef __LOG_H__
#define __LOG_H__

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>

/*
*Whether to use the standard C language library, 0 is not used, 1 is used
*/
#define USE_PRINTF (0)

typedef enum
{
	_LOG_NONE = 0,
	_LOG_ERROR,	
	_LOG_WARN,	 
	_LOG_INFO,	 
	_LOG_DEBUG,	
	_LOG_MAX
} stp_log_level_t;

typedef enum
{
	_LOG_BINARY_NONE = 0,
	_LOG_BINARY_DEC,
	_LOG_BINARY_HEX,
	_LOG_BINARY_MAX
} stp_log_binary_t;

typedef struct
{
	char *tag;
	uint8_t level;
	void *next;
} stp_tag_level_t;

#define LOG_COLOR_HEAD "\033[0;%dm"
#define LOG_COLOR_E "\033[0;31m"
#define LOG_COLOR_W "\033[0;32m"
#define LOG_COLOR_I "\033[0;33m"
#define LOG_COLOR_D "\033[0;37m"
#define LOG_COLOR_END "\033[0;39m"

uint8_t stp_log_add_tag(char *tag, uint8_t level);
uint8_t stp_log_write_arry(stp_log_level_t level, char *tag, char *tltle, uint8_t *buffer, int size, stp_log_binary_t binary);

#define LOG_ADD(tag, level) stp_log_add_tag(tag, level)

#if USE_PRINTF
uint8_t stp_log_write(stp_log_level_t level, const char *tag, const char *fmt, ...);

#define LOGE(tag, format, ...) stp_log_write(_LOG_ERROR, tag, format, ##__VA_ARGS__)
#define LOGW(tag, format, ...) stp_log_write(_LOG_WARN, tag, format, ##__VA_ARGS__)
#define LOGI(tag, format, ...) stp_log_write(_LOG_INFO, tag, format, ##__VA_ARGS__)
#define LOGD(tag, format, ...) stp_log_write(_LOG_DEBUG, tag, format, ##__VA_ARGS__)
#else

uint8_t stp_log_write(stp_log_level_t level, const char *tag);
int stp_log_write_str(const char *s, int len);
void stp_log_print(const char *s, ...);
#define LOGE(tag, format, ...)                                   \
	do                                                           \
	{                                                            \
		if (stp_log_write(_LOG_ERROR, tag) == false)             \
		{                                                        \
			break;                                               \
		}                                                        \
		stp_log_print(format, ##__VA_ARGS__);                    \
		stp_log_write_str(LOG_COLOR_END, strlen(LOG_COLOR_END)); \
	} while (0)
#define LOGW(tag, format, ...)                                   \
	do                                                           \
	{                                                            \
		if (stp_log_write(_LOG_WARN, tag) == false)              \
		{                                                        \
			break;                                               \
		}                                                        \
		stp_log_print(format, ##__VA_ARGS__);                    \
		stp_log_write_str(LOG_COLOR_END, strlen(LOG_COLOR_END)); \
	} while (0)
#define LOGI(tag, format, ...)                                   \
	do                                                           \
	{                                                            \
		if (stp_log_write(_LOG_INFO, tag) == false)              \
		{                                                        \
			break;                                               \
		}                                                        \
		stp_log_print(format, ##__VA_ARGS__);                    \
		stp_log_write_str(LOG_COLOR_END, strlen(LOG_COLOR_END)); \
	} while (0)
#define LOGD(tag, format, ...)                                   \
	do                                                           \
	{                                                            \
		if (stp_log_write(_LOG_DEBUG, tag) == false)             \
		{                                                        \
			break;                                               \
		}                                                        \
		stp_log_print(format, ##__VA_ARGS__);                    \
		stp_log_write_str(LOG_COLOR_END, strlen(LOG_COLOR_END)); \
	} while (0)
#endif

#define LOG_ARRY_HEX(level, tag, tltle, buffer, size)                         \
	do                                                                        \
	{                                                                         \
		stp_log_write_arry(level, tag, tltle, buffer, size, _LOG_BINARY_HEX); \
	} while (0)

#define LOG_ARRY_DEC(level, tag, tltle, buffer, size)                         \
	do                                                                        \
	{                                                                         \
		stp_log_write_arry(level, tag, tltle, buffer, size, _LOG_BINARY_DEC); \
	} while (0)

#endif /*end of file*/

 

工程文件,Github: https://github.com/KarmaStone/stp_coms.git

 

后续此工程文件会陆续添加其他功能, 比如:基于Freertos的 串口命令(类似shell) , MQTT , protocol buffer, http  , mebdTLS(AES, RSA ,MD5, BASE64) , simcom800 , w5500 , BC28 等

 

下片:  基于串口的调试 , 串口命令解析cmd   类似uboot命令输入

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 `log4j.properties` 中配置自定义日志输出路径,可以按照以下步骤进行操作: 1. 在 `log4j.properties` 文件中添加一个新的 appender,指定日志输出路径。例如: ```properties log4j.appender.custom=org.apache.log4j.RollingFileAppender log4j.appender.custom.File=/path/to/custom.log log4j.appender.custom.MaxFileSize=10MB log4j.appender.custom.MaxBackupIndex=10 log4j.appender.custom.layout=org.apache.log4j.PatternLayout log4j.appender.custom.layout.ConversionPattern=%d{ISO8601} [%t] %-5p %c %x - %m%n ``` 在上面的配置中,`custom` 是 appender 的名称,`/path/to/custom.log` 是自定义日志输出路径,`MaxFileSize` 和 `MaxBackupIndex` 分别指定文件大小和备份文件数。 2. 在 `log4j.properties` 文件中指定日志输出目的地。例如: ```properties log4j.rootLogger=INFO, custom ``` 在上面的配置中,`custom` 是上一步中定义的 appender 名称。 3. 在代码中获取 Logger 对象并使用。例如: ```java import org.apache.log4j.Logger; public class MyApplication { private static final Logger logger = Logger.getLogger(MyApplication.class); public static void main(String[] args) { logger.info("Hello, world!"); } } ``` 在上面的代码中,使用 `Logger.getLogger(MyApplication.class)` 获取 Logger 对象,并调用 `logger.info("Hello, world!")` 输出日志信息。日志信息将会输出自定义日志输出路径 `/path/to/custom.log`。 注意:如果你已经在 `log4j.properties` 文件中定义了其他的 appender 和日志输出目的地,需要将自定义的 appender 和日志输出目的地添加到现有配置中。例如: ```properties log4j.rootLogger=INFO, console, file, custom log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.Target=System.out log4j.appender.console.layout=org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=%d{ISO8601} [%t] %-5p %c %x - %m%n log4j.appender.file=org.apache.log4j.RollingFileAppender log4j.appender.file.File=/path/to/file.log log4j.appender.file.MaxFileSize=10MB log4j.appender.file.MaxBackupIndex=10 log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{ISO8601} [%t] %-5p %c %x - %m%n log4j.appender.custom=org.apache.log4j.RollingFileAppender log4j.appender.custom.File=/path/to/custom.log log4j.appender.custom.MaxFileSize=10MB log4j.appender.custom.MaxBackupIndex=10 log4j.appender.custom.layout=org.apache.log4j.PatternLayout log4j.appender.custom.layout.ConversionPattern=%d{ISO8601} [%t] %-5p %c %x - %m%n ``` 在上面的配置中,`console` 和 `file` 是已经定义的 appender 和日志输出目的地,`custom` 是自定义的 appender 和日志输出目的地。注意在 `log4j.rootLogger` 中将它们都添加进去。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值