[components][utilities][ulog] Improve the HEX LOG by new formater. (#6490)

- 重构格式化器
- 重写 HEX 日志功能,与标准日志使用相同的格式化器。与标准日志在日志过滤功能和日志头显示功能上一致
This commit is contained in:
朱天龙 (Armink) 2022-10-09 10:33:10 +08:00 committed by GitHub
parent 560a21207e
commit a48f446a0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 126 additions and 167 deletions

View File

@ -246,20 +246,16 @@ static char *get_log_buf(void)
}
}
RT_WEAK rt_size_t ulog_formater(char *log_buf, rt_uint32_t level, const char *tag, rt_bool_t newline,
const char *format, va_list args)
RT_WEAK rt_size_t ulog_head_formater(char *log_buf, rt_uint32_t level, const char *tag)
{
/* the caller has locker, so it can use static variable for reduce stack usage */
static rt_size_t log_len, newline_len;
static int fmt_result;
static rt_size_t log_len;
RT_ASSERT(log_buf);
RT_ASSERT(level <= LOG_LVL_DBG);
RT_ASSERT(tag);
RT_ASSERT(format);
log_len = 0;
newline_len = rt_strlen(ULOG_NEWLINE_SIGN);
#ifdef ULOG_USING_COLOR
/* add CSI start sign and color info */
@ -370,19 +366,18 @@ RT_WEAK rt_size_t ulog_formater(char *log_buf, rt_uint32_t level, const char *ta
#endif /* ULOG_OUTPUT_THREAD_NAME */
log_len += ulog_strcpy(log_len, log_buf + log_len, ": ");
fmt_result = rt_vsnprintf(log_buf + log_len, ULOG_LINE_BUF_SIZE - log_len, format, args);
/* calculate log length */
if ((log_len + fmt_result <= ULOG_LINE_BUF_SIZE) && (fmt_result > -1))
{
log_len += fmt_result;
}
else
{
/* using max length */
log_len = ULOG_LINE_BUF_SIZE;
}
return log_len;
}
RT_WEAK rt_size_t ulog_tail_formater(char *log_buf, rt_size_t log_len, rt_bool_t newline, rt_uint32_t level)
{
/* the caller has locker, so it can use static variable for reduce stack usage */
static rt_size_t newline_len;
RT_ASSERT(log_buf);
newline_len = rt_strlen(ULOG_NEWLINE_SIGN);
/* overflow check and reserve some space for CSI end sign, newline sign and string end sign */
#ifdef ULOG_USING_COLOR
if (log_len + (sizeof(CSI_END) - 1) + newline_len + sizeof((char)'\0') > ULOG_LINE_BUF_SIZE)
@ -423,6 +418,86 @@ RT_WEAK rt_size_t ulog_formater(char *log_buf, rt_uint32_t level, const char *ta
return log_len;
}
RT_WEAK rt_size_t ulog_formater(char *log_buf, rt_uint32_t level, const char *tag, rt_bool_t newline,
const char *format, va_list args)
{
/* the caller has locker, so it can use static variable for reduce stack usage */
static rt_size_t log_len;
static int fmt_result;
RT_ASSERT(log_buf);
RT_ASSERT(format);
/* log head */
log_len = ulog_head_formater(log_buf, level, tag);
/* log content */
fmt_result = rt_vsnprintf(log_buf + log_len, ULOG_LINE_BUF_SIZE - log_len, format, args);
/* calculate log length */
if ((log_len + fmt_result <= ULOG_LINE_BUF_SIZE) && (fmt_result > -1))
{
log_len += fmt_result;
}
else
{
/* using max length */
log_len = ULOG_LINE_BUF_SIZE;
}
/* log tail */
return ulog_tail_formater(log_buf, log_len, newline, level);
}
RT_WEAK rt_size_t ulog_hex_formater(char *log_buf, const char *tag, const rt_uint8_t *buf, rt_size_t size, rt_size_t width, rt_base_t addr)
{
#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
/* the caller has locker, so it can use static variable for reduce stack usage */
static rt_size_t log_len, j;
static int fmt_result;
char dump_string[8];
RT_ASSERT(log_buf);
RT_ASSERT(buf);
/* log head */
log_len = ulog_head_formater(log_buf, LOG_LVL_DBG, tag);
/* log content */
fmt_result = rt_snprintf(log_buf + log_len, ULOG_LINE_BUF_SIZE, "%04X-%04X: ", addr, addr + size);
/* calculate log length */
if ((fmt_result > -1) && (fmt_result <= ULOG_LINE_BUF_SIZE))
{
log_len += fmt_result;
}
else
{
log_len = ULOG_LINE_BUF_SIZE;
}
/* dump hex */
for (j = 0; j < width; j++)
{
if (j < size)
{
rt_snprintf(dump_string, sizeof(dump_string), "%02X ", buf[j]);
}
else
{
rt_strncpy(dump_string, " ", sizeof(dump_string));
}
log_len += ulog_strcpy(log_len, log_buf + log_len, dump_string);
if ((j + 1) % 8 == 0)
{
log_len += ulog_strcpy(log_len, log_buf + log_len, " ");
}
}
log_len += ulog_strcpy(log_len, log_buf + log_len, " ");
/* dump char for hex */
for (j = 0; j < size; j++)
{
rt_snprintf(dump_string, sizeof(dump_string), "%c", __is_print(buf[j]) ? buf[j] : '.');
log_len += ulog_strcpy(log_len, log_buf + log_len, dump_string);
}
/* log tail */
return ulog_tail_formater(log_buf, log_len, RT_TRUE, LOG_LVL_DBG);
}
static void ulog_output_to_all_backend(rt_uint32_t level, const char *tag, rt_bool_t is_raw, const char *log, rt_size_t len)
{
rt_slist_t *node;
@ -552,24 +627,28 @@ static void do_output(rt_uint32_t level, const char *tag, rt_bool_t is_raw, cons
* @param level level
* @param tag tag
* @param newline has_newline
* @param hex_buf != RT_NULL: enable hex log mode, data buffer
* @param hex_size hex data buffer size
* @param hex_width hex log width
* @param hex_addr hex data address
* @param format output format
* @param args variable argument list
*/
void ulog_voutput(rt_uint32_t level, const char *tag, rt_bool_t newline, const char *format, va_list args)
void ulog_voutput(rt_uint32_t level, const char *tag, rt_bool_t newline, const rt_uint8_t *hex_buf, rt_size_t hex_size,
rt_size_t hex_width, rt_base_t hex_addr, const char *format, va_list args)
{
static rt_bool_t ulog_voutput_recursion = RT_FALSE;
char *log_buf = RT_NULL;
rt_size_t log_len = 0;
static rt_size_t log_len = 0;
RT_ASSERT(tag);
RT_ASSERT(format);
RT_ASSERT((format && !hex_buf) || (!format && hex_buf));
#ifndef ULOG_USING_SYSLOG
RT_ASSERT(level <= LOG_LVL_DBG);
#else
RT_ASSERT(LOG_PRI(level) <= LOG_DEBUG);
#endif /* ULOG_USING_SYSLOG */
if (!ulog.init_ok)
{
return;
@ -603,10 +682,10 @@ void ulog_voutput(rt_uint32_t level, const char *tag, rt_bool_t newline, const c
output_lock();
/* If there is a recursion, we use a simple way */
if (ulog_voutput_recursion == RT_TRUE)
if ((ulog_voutput_recursion == RT_TRUE) && (hex_buf == RT_NULL))
{
rt_kprintf(format, args);
if(newline == RT_TRUE)
if (newline == RT_TRUE)
{
rt_kprintf(ULOG_NEWLINE_SIGN);
}
@ -616,12 +695,20 @@ void ulog_voutput(rt_uint32_t level, const char *tag, rt_bool_t newline, const c
ulog_voutput_recursion = RT_TRUE;
if (hex_buf == RT_NULL)
{
#ifndef ULOG_USING_SYSLOG
log_len = ulog_formater(log_buf, level, tag, newline, format, args);
log_len = ulog_formater(log_buf, level, tag, newline, format, args);
#else
extern rt_size_t syslog_formater(char *log_buf, rt_uint8_t level, const char *tag, rt_bool_t newline, const char *format, va_list args);
log_len = syslog_formater(log_buf, level, tag, newline, format, args);
extern rt_size_t syslog_formater(char *log_buf, rt_uint8_t level, const char *tag, rt_bool_t newline, const char *format, va_list args);
log_len = syslog_formater(log_buf, level, tag, newline, format, args);
#endif /* ULOG_USING_SYSLOG */
}
else
{
/* hex mode */
log_len = ulog_hex_formater(log_buf, tag, hex_buf, hex_size, hex_width, hex_addr);
}
#ifdef ULOG_USING_FILTER
/* keyword filter */
@ -664,7 +751,7 @@ void ulog_output(rt_uint32_t level, const char *tag, rt_bool_t newline, const ch
/* args point to the first variable parameter */
va_start(args, format);
ulog_voutput(level, tag, newline, format, args);
ulog_voutput(level, tag, newline, RT_NULL, 0, 0, 0, format, args);
va_end(args);
}
@ -727,150 +814,23 @@ void ulog_raw(const char *format, ...)
* @param buf hex buffer
* @param size buffer size
*/
void ulog_hexdump(const char *tag, rt_size_t width, rt_uint8_t *buf, rt_size_t size)
void ulog_hexdump(const char *tag, rt_size_t width, const rt_uint8_t *buf, rt_size_t size, ...)
{
#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
rt_size_t i, len;
va_list args;
rt_size_t i, j;
rt_size_t log_len = 0, name_len = rt_strlen(tag);
#ifdef ULOG_OUTPUT_TIME
rt_size_t time_head_len = 0;
#endif
char *log_buf = RT_NULL, dump_string[8];
int fmt_result;
va_start(args, size);
RT_ASSERT(ulog.init_ok);
#ifdef ULOG_USING_FILTER
/* level filter */
#ifndef ULOG_USING_SYSLOG
if (LOG_LVL_DBG > ulog.filter.level || LOG_LVL_DBG > ulog_tag_lvl_filter_get(tag))
for (i = 0; i < size; i += width, buf += width)
{
return;
}
#else
if ((LOG_MASK(LOG_DEBUG) & ulog.filter.level) == 0)
{
return;
}
#endif /* ULOG_USING_SYSLOG */
else if (!rt_strstr(tag, ulog.filter.tag))
{
/* tag filter */
return;
}
#endif /* ULOG_USING_FILTER */
#ifdef ULOG_USING_ASYNC_OUTPUT
if (ulog.async_rb == RT_NULL)
{
ulog.async_rb = rt_ringbuffer_create(ULOG_ASYNC_OUTPUT_BUF_SIZE);
}
#endif
/* get log buffer */
log_buf = get_log_buf();
/* lock output */
output_lock();
for (i = 0, log_len = 0; i < size; i += width)
{
/* package header */
if (i == 0)
{
#ifdef ULOG_OUTPUT_TIME
/* add time info */
#ifdef ULOG_TIME_USING_TIMESTAMP
static time_t now;
static struct tm *tm, tm_tmp;
now = time(RT_NULL);
tm = gmtime_r(&now, &tm_tmp);
#ifdef RT_USING_SOFT_RTC
rt_snprintf(log_buf + log_len, ULOG_LINE_BUF_SIZE - log_len, "%02d-%02d %02d:%02d:%02d.%03d ", tm->tm_mon + 1,
tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, rt_tick_get() % 1000);
#else
rt_snprintf(log_buf + log_len, ULOG_LINE_BUF_SIZE - log_len, "%02d-%02d %02d:%02d:%02d ", tm->tm_mon + 1,
tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
#endif /* RT_USING_SOFT_RTC */
#else
static rt_size_t tick_len = 0;
log_buf[log_len] = '[';
tick_len = ulog_ultoa(log_buf + log_len + 1, rt_tick_get());
log_buf[log_len + 1 + tick_len] = ']';
log_buf[log_len + 2 + tick_len] = ' ';
log_buf[log_len + 3 + tick_len] = '\0';
#endif /* ULOG_TIME_USING_TIMESTAMP */
time_head_len = rt_strlen(log_buf + log_len);
log_len += time_head_len;
#endif /* ULOG_OUTPUT_TIME */
log_len += ulog_strcpy(log_len, log_buf + log_len, "D/HEX ");
log_len += ulog_strcpy(log_len, log_buf + log_len, tag);
log_len += ulog_strcpy(log_len, log_buf + log_len, ": ");
}
if (i + size < width)
len = size - i;
else
{
log_len = 6 + name_len + 2;
#ifdef ULOG_OUTPUT_TIME
log_len += time_head_len;
#endif
rt_memset(log_buf, ' ', log_len);
}
fmt_result = rt_snprintf(log_buf + log_len, ULOG_LINE_BUF_SIZE, "%04X-%04X: ", i, i + width - 1);
/* calculate log length */
if ((fmt_result > -1) && (fmt_result <= ULOG_LINE_BUF_SIZE))
{
log_len += fmt_result;
}
else
{
log_len = ULOG_LINE_BUF_SIZE;
}
/* dump hex */
for (j = 0; j < width; j++)
{
if (i + j < size)
{
rt_snprintf(dump_string, sizeof(dump_string), "%02X ", buf[i + j]);
}
else
{
rt_strncpy(dump_string, " ", sizeof(dump_string));
}
log_len += ulog_strcpy(log_len, log_buf + log_len, dump_string);
if ((j + 1) % 8 == 0)
{
log_len += ulog_strcpy(log_len, log_buf + log_len, " ");
}
}
log_len += ulog_strcpy(log_len, log_buf + log_len, " ");
/* dump char for hex */
for (j = 0; j < width; j++)
{
if (i + j < size)
{
rt_snprintf(dump_string, sizeof(dump_string), "%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
log_len += ulog_strcpy(log_len, log_buf + log_len, dump_string);
}
}
/* overflow check and reserve some space for newline sign */
if (log_len + rt_strlen(ULOG_NEWLINE_SIGN) > ULOG_LINE_BUF_SIZE)
{
log_len = ULOG_LINE_BUF_SIZE - rt_strlen(ULOG_NEWLINE_SIGN);
}
/* package newline sign */
log_len += ulog_strcpy(log_len, log_buf + log_len, ULOG_NEWLINE_SIGN);
/*add string end sign*/
log_buf[log_len] = '\0';
/* do log output */
do_output(LOG_LVL_DBG, RT_NULL, RT_TRUE, log_buf, log_len);
len = width;
ulog_voutput(LOG_LVL_DBG, tag, RT_TRUE, buf, len, width, i, RT_NULL, args);
}
/* unlock output */
output_unlock();
va_end(args);
}
#ifdef ULOG_USING_FILTER

View File

@ -87,12 +87,11 @@ rt_err_t ulog_async_waiting_log(rt_int32_t time);
/*
* dump the hex format data to log
*/
void ulog_hexdump(const char *tag, rt_size_t width, rt_uint8_t *buf, rt_size_t size);
void ulog_hexdump(const char *tag, rt_size_t width, const rt_uint8_t *buf, rt_size_t size, ...);
/*
* Another log output API. This API is more difficult to use than LOG_X API.
*/
void ulog_voutput(rt_uint32_t level, const char *tag, rt_bool_t newline, const char *format, va_list args);
void ulog_output(rt_uint32_t level, const char *tag, rt_bool_t newline, const char *format, ...);
void ulog_raw(const char *format, ...);