diff --git a/demo/os/linux/easylogger/inc/elog_cfg.h b/demo/os/linux/easylogger/inc/elog_cfg.h index b33265c..52c8081 100644 --- a/demo/os/linux/easylogger/inc/elog_cfg.h +++ b/demo/os/linux/easylogger/inc/elog_cfg.h @@ -49,6 +49,8 @@ #define ELOG_COLOR_ENABLE /* enable asynchronous output mode */ #define ELOG_ASYNC_OUTPUT_ENABLE +/* the highest output level for async mode, other level will sync output */ +#define ELOG_ASYNC_OUTPUT_LVL ELOG_LVL_DEBUG /* buffer size for asynchronous output mode */ #define ELOG_ASYNC_OUTPUT_BUF_SIZE (ELOG_LINE_BUF_SIZE * 100) /* each asynchronous output's log which must end with newline sign */ diff --git a/demo/os/rt-thread/stm32f10x/components/easylogger/inc/elog_cfg.h b/demo/os/rt-thread/stm32f10x/components/easylogger/inc/elog_cfg.h index 8c6c9c5..859f342 100644 --- a/demo/os/rt-thread/stm32f10x/components/easylogger/inc/elog_cfg.h +++ b/demo/os/rt-thread/stm32f10x/components/easylogger/inc/elog_cfg.h @@ -47,6 +47,8 @@ #define ELOG_NEWLINE_SIGN "\r\n" /* enable asynchronous output mode */ #define ELOG_ASYNC_OUTPUT_ENABLE +/* the highest output level for async mode, other level will sync output */ +#define ELOG_ASYNC_OUTPUT_LVL ELOG_LVL_DEBUG /* buffer size for asynchronous output mode */ #define ELOG_ASYNC_OUTPUT_BUF_SIZE (ELOG_LINE_BUF_SIZE * 10) /* each asynchronous output's log which must end with newline sign */ diff --git a/docs/zh/port/kernel.md b/docs/zh/port/kernel.md index 1820cee..45f9ee3 100644 --- a/docs/zh/port/kernel.md +++ b/docs/zh/port/kernel.md @@ -194,18 +194,25 @@ const char *elog_port_get_t_info(void) - 操作方法:开启、关闭`ELOG_ASYNC_OUTPUT_ENABLE`宏即可 -#### 4.10.1 异步输出模式缓冲区大小 +#### 4.10.1 异步输出日志的最高级别 + +日志低于或等于该级别时,才会通过异步输出。高于该级别的日志都将按照默认的同步方式输出。这样的好处是,提升了较高级别的日志输出的实时性。 + +- 默认级别:`ELOG_LVL_ASSERT` ,不定义此宏,将会自动按照默认值设置 +- 操作方法:修改`ELOG_ASYNC_OUTPUT_LVL`宏对应值即可 + +#### 4.10.2 异步输出模式缓冲区大小 - 默认大小:`(ELOG_LINE_BUF_SIZE * 10)` ,不定义此宏,将会自动按照默认值设置 - 操作方法:修改`ELOG_ASYNC_OUTPUT_BUF_SIZE`宏对应值即可 -#### 4.10.2 异步按行输出日志 +#### 4.10.3 异步按行输出日志 由于异步输出方式内部拥有缓冲区,所以直接输出缓冲区中积累的日志时,日志移植输出方法 (`elog_port_output`) 输出的日志将不会按照 **行日志** (以换行符结尾)的格式进行输出。这使得无法在移植输出方法中完成日志的分析处理。开启此功能后,将会最大限度保证移植输出方法每次输出的日志格式都为行日志。 - 操作方法:开启、关闭`ELOG_ASYNC_LINE_OUTPUT`宏即可 -#### 4.10.3 启用 pthread 库 +#### 4.10.4 启用 pthread 库 异步输出模式默认是使用 POSIX 的 pthread 库来实现,用户的平台如果支持 pthread ,则可以开启此宏。对于一些缺少 pthread 的支持平台,可以关闭此宏,参考 `elog_async.c` 中关于日志异步输出线程的实现方式,自己动手实现此功能。 diff --git a/easylogger/inc/elog.h b/easylogger/inc/elog.h index e17ed55..593c9d2 100644 --- a/easylogger/inc/elog.h +++ b/easylogger/inc/elog.h @@ -50,7 +50,7 @@ extern "C" { #define ELOG_LVL_TOTAL_NUM 6 /* EasyLogger software version number */ -#define ELOG_SW_VERSION "2.0.0" +#define ELOG_SW_VERSION "2.0.1" /* EasyLogger assert for developer. */ #ifdef ELOG_ASSERT_ENABLE diff --git a/easylogger/inc/elog_cfg.h b/easylogger/inc/elog_cfg.h index 5135627..cf62f15 100644 --- a/easylogger/inc/elog_cfg.h +++ b/easylogger/inc/elog_cfg.h @@ -28,7 +28,7 @@ #ifndef _ELOG_CFG_H_ #define _ELOG_CFG_H_ - +/*---------------------------------------------------------------------------*/ /* enable log output. */ #define ELOG_OUTPUT_ENABLE /* setting static output log level. range: from ELOG_LVL_ASSERT to ELOG_LVL_VERBOSE */ @@ -45,7 +45,7 @@ #define ELOG_FILTER_KW_MAX_LEN 16 /* output newline sign */ #define ELOG_NEWLINE_SIGN "\n" - +/*---------------------------------------------------------------------------*/ /* enable log color */ #define ELOG_COLOR_ENABLE /* change the some level logs to not default color if you want */ @@ -55,16 +55,18 @@ #define ELOG_COLOR_INFO (F_CYAN B_NULL S_NORMAL) #define ELOG_COLOR_DEBUG (F_GREEN B_NULL S_NORMAL) #define ELOG_COLOR_VERBOSE (F_BLUE B_NULL S_NORMAL) - +/*---------------------------------------------------------------------------*/ /* enable asynchronous output mode */ #define ELOG_ASYNC_OUTPUT_ENABLE +/* the highest output level for async mode, other level will sync output */ +#define ELOG_ASYNC_OUTPUT_LVL ELOG_LVL_ASSERT /* buffer size for asynchronous output mode */ #define ELOG_ASYNC_OUTPUT_BUF_SIZE (ELOG_LINE_BUF_SIZE * 10) /* each asynchronous output's log which must end with newline sign */ #define ELOG_ASYNC_LINE_OUTPUT /* asynchronous output mode using POSIX pthread implementation */ #define ELOG_ASYNC_OUTPUT_USING_PTHREAD - +/*---------------------------------------------------------------------------*/ /* enable buffered output mode */ #define ELOG_BUF_OUTPUT_ENABLE /* buffer size for buffered output mode */ diff --git a/easylogger/src/elog.c b/easylogger/src/elog.c index 18c8fb6..8377d3d 100644 --- a/easylogger/src/elog.c +++ b/easylogger/src/elog.c @@ -1,7 +1,7 @@ /* * This file is part of the EasyLogger Library. * - * Copyright (c) 2015-2016, Armink, + * Copyright (c) 2015-2017, Armink, * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -355,8 +355,9 @@ void elog_raw(const char *format, ...) { } /* output log */ #if defined(ELOG_ASYNC_OUTPUT_ENABLE) - extern void elog_async_output(const char *log, size_t size); - elog_async_output(log_buf, log_len); + extern void elog_async_output(uint8_t level, const char *log, size_t size); + /* raw log will using assert level */ + elog_async_output(ELOG_LVL_ASSERT, log_buf, log_len); #elif defined(ELOG_BUF_OUTPUT_ENABLE) extern void elog_buf_output(const char *log, size_t size); elog_buf_output(log_buf, log_len); @@ -364,7 +365,7 @@ void elog_raw(const char *format, ...) { elog_port_output(log_buf, log_len); #endif /* unlock output */ - elog_port_output_unlock(); + elog_output_unlock(); va_end(args); } @@ -513,8 +514,8 @@ void elog_output(uint8_t level, const char *tag, const char *file, const char *f } /* output log */ #if defined(ELOG_ASYNC_OUTPUT_ENABLE) - extern void elog_async_output(const char *log, size_t size); - elog_async_output(log_buf, log_len); + extern void elog_async_output(uint8_t level, const char *log, size_t size); + elog_async_output(level, log_buf, log_len); #elif defined(ELOG_BUF_OUTPUT_ENABLE) extern void elog_buf_output(const char *log, size_t size); elog_buf_output(log_buf, log_len); diff --git a/easylogger/src/elog_async.c b/easylogger/src/elog_async.c index 52996e0..6df5f3a 100644 --- a/easylogger/src/elog_async.c +++ b/easylogger/src/elog_async.c @@ -1,7 +1,7 @@ /* * This file is part of the EasyLogger Library. * - * Copyright (c) 2016, Armink, + * Copyright (c) 2016-2017, Armink, * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -30,9 +30,6 @@ #include #ifdef ELOG_ASYNC_OUTPUT_ENABLE -#if !defined(ELOG_ASYNC_OUTPUT_BUF_SIZE) - #error "Please configure buffer size for asynchronous output mode (in elog_cfg.h)" -#endif #ifdef ELOG_ASYNC_OUTPUT_USING_PTHREAD #include @@ -59,14 +56,28 @@ static sem_t output_notice; /* asynchronous output pthread thread */ static pthread_t async_output_thread; -#endif +#endif /* ELOG_ASYNC_OUTPUT_USING_PTHREAD */ + +/* the highest output level for async mode, other level will sync output */ +#ifdef ELOG_ASYNC_OUTPUT_LVL +#define OUTPUT_LVL ELOG_ASYNC_OUTPUT_LVL +#else +#define OUTPUT_LVL ELOG_LVL_ASSERT +#endif /* ELOG_ASYNC_OUTPUT_LVL */ + +/* buffer size for asynchronous output mode */ +#ifdef ELOG_ASYNC_OUTPUT_BUF_SIZE +#define OUTPUT_BUF_SIZE ELOG_ASYNC_OUTPUT_BUF_SIZE +#else +#define OUTPUT_BUF_SIZE (ELOG_LINE_BUF_SIZE * 10) +#endif /* ELOG_ASYNC_OUTPUT_BUF_SIZE */ /* Initialize OK flag */ static bool init_ok = false; /* asynchronous output mode enabled flag */ static bool is_enabled = false; /* asynchronous output mode's ring buffer */ -static char log_buf[ELOG_ASYNC_OUTPUT_BUF_SIZE] = { 0 }; +static char log_buf[OUTPUT_BUF_SIZE] = { 0 }; /* log ring buffer write index */ static size_t write_index = 0; /* log ring buffer read index */ @@ -90,9 +101,9 @@ static size_t elog_async_get_buf_used(void) { return write_index - read_index; } else { if (!buf_is_full && !buf_is_empty) { - return ELOG_ASYNC_OUTPUT_BUF_SIZE - (read_index - write_index); + return OUTPUT_BUF_SIZE - (read_index - write_index); } else if (buf_is_full) { - return ELOG_ASYNC_OUTPUT_BUF_SIZE; + return OUTPUT_BUF_SIZE; } else { return 0; } @@ -105,7 +116,7 @@ static size_t elog_async_get_buf_used(void) { * @return remain space */ static size_t async_get_buf_space(void) { - return ELOG_ASYNC_OUTPUT_BUF_SIZE - elog_async_get_buf_used(); + return OUTPUT_BUF_SIZE - elog_async_get_buf_used(); } /** @@ -131,14 +142,14 @@ static size_t async_put_log(const char *log, size_t size) { buf_is_full = true; } - if (write_index + size < ELOG_ASYNC_OUTPUT_BUF_SIZE) { + if (write_index + size < OUTPUT_BUF_SIZE) { memcpy(log_buf + write_index, log, size); write_index += size; } else { - memcpy(log_buf + write_index, log, ELOG_ASYNC_OUTPUT_BUF_SIZE - write_index); - memcpy(log_buf, log + ELOG_ASYNC_OUTPUT_BUF_SIZE - write_index, - size - (ELOG_ASYNC_OUTPUT_BUF_SIZE - write_index)); - write_index += size - ELOG_ASYNC_OUTPUT_BUF_SIZE; + memcpy(log_buf + write_index, log, OUTPUT_BUF_SIZE - write_index); + memcpy(log_buf, log + OUTPUT_BUF_SIZE - write_index, + size - (OUTPUT_BUF_SIZE - write_index)); + write_index += size - OUTPUT_BUF_SIZE; } buf_is_empty = false; @@ -173,14 +184,14 @@ size_t elog_async_get_line_log(char *log, size_t size) { size = used; } - if (read_index + size < ELOG_ASYNC_OUTPUT_BUF_SIZE) { + if (read_index + size < OUTPUT_BUF_SIZE) { cpy_log_size = elog_cpyln(log, log_buf + read_index, size); read_index += cpy_log_size; } else { - cpy_log_size = elog_cpyln(log, log_buf + read_index, ELOG_ASYNC_OUTPUT_BUF_SIZE - read_index); - if (cpy_log_size == ELOG_ASYNC_OUTPUT_BUF_SIZE - read_index) { + cpy_log_size = elog_cpyln(log, log_buf + read_index, OUTPUT_BUF_SIZE - read_index); + if (cpy_log_size == OUTPUT_BUF_SIZE - read_index) { cpy_log_size += elog_cpyln(log + cpy_log_size, log_buf, size - cpy_log_size); - read_index += cpy_log_size - ELOG_ASYNC_OUTPUT_BUF_SIZE; + read_index += cpy_log_size - OUTPUT_BUF_SIZE; } else { read_index += cpy_log_size; } @@ -224,14 +235,14 @@ size_t elog_async_get_log(char *log, size_t size) { buf_is_empty = true; } - if (read_index + size < ELOG_ASYNC_OUTPUT_BUF_SIZE) { + if (read_index + size < OUTPUT_BUF_SIZE) { memcpy(log, log_buf + read_index, size); read_index += size; } else { - memcpy(log, log_buf + read_index, ELOG_ASYNC_OUTPUT_BUF_SIZE - read_index); - memcpy(log + ELOG_ASYNC_OUTPUT_BUF_SIZE - read_index, log_buf, - size - (ELOG_ASYNC_OUTPUT_BUF_SIZE - read_index)); - read_index += size - ELOG_ASYNC_OUTPUT_BUF_SIZE; + memcpy(log, log_buf + read_index, OUTPUT_BUF_SIZE - read_index); + memcpy(log + OUTPUT_BUF_SIZE - read_index, log_buf, + size - (OUTPUT_BUF_SIZE - read_index)); + read_index += size - OUTPUT_BUF_SIZE; } buf_is_full = false; @@ -243,16 +254,20 @@ __exit: } #endif /* ELOG_ASYNC_LINE_OUTPUT */ -void elog_async_output(const char *log, size_t size) { +void elog_async_output(uint8_t level, const char *log, size_t size) { /* this function must be implement by user when ELOG_ASYNC_OUTPUT_USING_PTHREAD is not defined */ extern void elog_async_output_notice(void); size_t put_size; if (is_enabled) { - put_size = async_put_log(log, size); - /* notify output log thread */ - if (put_size > 0) { - elog_async_output_notice(); + if (level >= OUTPUT_LVL) { + put_size = async_put_log(log, size); + /* notify output log thread */ + if (put_size > 0) { + elog_async_output_notice(); + } + } else { + elog_port_output(log, size); } } else { elog_port_output(log, size);