Merge pull request #4251 from Lawlieta/chenyong
[ulog] Add backend filtering interface, add async log output control interface, ulog mutex change to semaphore
This commit is contained in:
commit
afd575105d
|
@ -77,7 +77,7 @@
|
||||||
struct rt_ulog
|
struct rt_ulog
|
||||||
{
|
{
|
||||||
rt_bool_t init_ok;
|
rt_bool_t init_ok;
|
||||||
struct rt_mutex output_locker;
|
struct rt_semaphore output_locker;
|
||||||
/* all backends */
|
/* all backends */
|
||||||
rt_slist_t backend_list;
|
rt_slist_t backend_list;
|
||||||
/* the thread log's line buffer */
|
/* the thread log's line buffer */
|
||||||
|
@ -90,6 +90,7 @@ struct rt_ulog
|
||||||
#endif /* ULOG_USING_ISR_LOG */
|
#endif /* ULOG_USING_ISR_LOG */
|
||||||
|
|
||||||
#ifdef ULOG_USING_ASYNC_OUTPUT
|
#ifdef ULOG_USING_ASYNC_OUTPUT
|
||||||
|
rt_bool_t async_enabled;
|
||||||
rt_rbb_t async_rbb;
|
rt_rbb_t async_rbb;
|
||||||
rt_thread_t async_th;
|
rt_thread_t async_th;
|
||||||
struct rt_semaphore async_notice;
|
struct rt_semaphore async_notice;
|
||||||
|
@ -186,7 +187,7 @@ static void output_unlock(void)
|
||||||
/* is in thread context */
|
/* is in thread context */
|
||||||
if (rt_interrupt_get_nest() == 0)
|
if (rt_interrupt_get_nest() == 0)
|
||||||
{
|
{
|
||||||
rt_mutex_release(&ulog.output_locker);
|
rt_sem_release(&ulog.output_locker);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -201,7 +202,7 @@ static void output_lock(void)
|
||||||
/* is in thread context */
|
/* is in thread context */
|
||||||
if (rt_interrupt_get_nest() == 0)
|
if (rt_interrupt_get_nest() == 0)
|
||||||
{
|
{
|
||||||
rt_mutex_take(&ulog.output_locker, RT_WAITING_FOREVER);
|
rt_sem_take(&ulog.output_locker, RT_WAITING_FOREVER);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -393,6 +394,10 @@ void ulog_output_to_all_backend(rt_uint32_t level, const char *tag, rt_bool_t is
|
||||||
for (node = rt_slist_first(&ulog.backend_list); node; node = rt_slist_next(node))
|
for (node = rt_slist_first(&ulog.backend_list); node; node = rt_slist_next(node))
|
||||||
{
|
{
|
||||||
backend = rt_slist_entry(node, struct ulog_backend, list);
|
backend = rt_slist_entry(node, struct ulog_backend, list);
|
||||||
|
if (backend->out_level < level)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
#if !defined(ULOG_USING_COLOR) || defined(ULOG_USING_SYSLOG)
|
#if !defined(ULOG_USING_COLOR) || defined(ULOG_USING_SYSLOG)
|
||||||
backend->output(backend, level, tag, is_raw, log, size);
|
backend->output(backend, level, tag, is_raw, log, size);
|
||||||
#else
|
#else
|
||||||
|
@ -738,6 +743,42 @@ void ulog_hexdump(const char *tag, rt_size_t width, rt_uint8_t *buf, rt_size_t s
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ULOG_USING_FILTER
|
#ifdef ULOG_USING_FILTER
|
||||||
|
/**
|
||||||
|
* Set the filter's level by different backend.
|
||||||
|
* The log on this backend which level is less than it will stop output.
|
||||||
|
*
|
||||||
|
* @param be_name backend name
|
||||||
|
* @param level The filter level. When the level is LOG_FILTER_LVL_SILENT, the log enter silent mode.
|
||||||
|
* When the level is LOG_FILTER_LVL_ALL, it will remove this tag's level filer.
|
||||||
|
* Then all level log will resume output.
|
||||||
|
*
|
||||||
|
* @return 0 : success
|
||||||
|
* -10: level is out of range
|
||||||
|
*/
|
||||||
|
int ulog_be_lvl_filter_set(const char *be_name, rt_uint32_t level)
|
||||||
|
{
|
||||||
|
rt_slist_t *node = RT_NULL;
|
||||||
|
ulog_backend_t backend;
|
||||||
|
int result = RT_EOK;
|
||||||
|
|
||||||
|
if (level > LOG_FILTER_LVL_ALL)
|
||||||
|
return -RT_EINVAL;
|
||||||
|
|
||||||
|
if (!ulog.init_ok)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
for (node = rt_slist_first(&ulog.backend_list); node; node = rt_slist_next(node))
|
||||||
|
{
|
||||||
|
backend = rt_slist_entry(node, struct ulog_backend, list);
|
||||||
|
if (rt_strncmp(backend->name, be_name, RT_NAME_MAX) == 0)
|
||||||
|
{
|
||||||
|
backend->out_level = level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the filter's level by different tag.
|
* Set the filter's level by different tag.
|
||||||
* The log on this tag which level is less than it will stop output.
|
* The log on this tag which level is less than it will stop output.
|
||||||
|
@ -945,6 +986,47 @@ const char *ulog_global_filter_kw_get(void)
|
||||||
#if defined(RT_USING_FINSH) && defined(FINSH_USING_MSH)
|
#if defined(RT_USING_FINSH) && defined(FINSH_USING_MSH)
|
||||||
#include <finsh.h>
|
#include <finsh.h>
|
||||||
|
|
||||||
|
static void _print_lvl_info(void)
|
||||||
|
{
|
||||||
|
#ifndef ULOG_USING_SYSLOG
|
||||||
|
rt_kprintf("Assert : 0\n");
|
||||||
|
rt_kprintf("Error : 3\n");
|
||||||
|
rt_kprintf("Warning : 4\n");
|
||||||
|
rt_kprintf("Info : 6\n");
|
||||||
|
rt_kprintf("Debug : 7\n");
|
||||||
|
#else
|
||||||
|
rt_kprintf("EMERG : 1 (1 << 0)\n");
|
||||||
|
rt_kprintf("ALERT : 2 (1 << 1)\n");
|
||||||
|
rt_kprintf("CRIT : 4 (1 << 2)\n");
|
||||||
|
rt_kprintf("ERR : 8 (1 << 3)\n");
|
||||||
|
rt_kprintf("WARNING : 16 (1 << 4)\n");
|
||||||
|
rt_kprintf("NOTICE : 32 (1 << 5)\n");
|
||||||
|
rt_kprintf("INFO : 64 (1 << 6)\n");
|
||||||
|
rt_kprintf("DEBUG : 128 (1 << 7)\n");
|
||||||
|
#endif /* ULOG_USING_SYSLOG */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ulog_be_lvl(uint8_t argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc > 2)
|
||||||
|
{
|
||||||
|
if ((atoi(argv[2]) <= LOG_FILTER_LVL_ALL) && (atoi(argv[2]) >= 0))
|
||||||
|
{
|
||||||
|
ulog_be_lvl_filter_set(argv[1], atoi(argv[2]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt_kprintf("Please input correct level (0-%d).\n", LOG_FILTER_LVL_ALL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt_kprintf("Please input: ulog_be_lvl <be_name> <level>.\n");
|
||||||
|
_print_lvl_info();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MSH_CMD_EXPORT(ulog_be_lvl, Set ulog filter level by different backend.);
|
||||||
|
|
||||||
static void ulog_tag_lvl(uint8_t argc, char **argv)
|
static void ulog_tag_lvl(uint8_t argc, char **argv)
|
||||||
{
|
{
|
||||||
if (argc > 2)
|
if (argc > 2)
|
||||||
|
@ -961,22 +1043,7 @@ static void ulog_tag_lvl(uint8_t argc, char **argv)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rt_kprintf("Please input: ulog_tag_lvl <tag> <level>.\n");
|
rt_kprintf("Please input: ulog_tag_lvl <tag> <level>.\n");
|
||||||
#ifndef ULOG_USING_SYSLOG
|
_print_lvl_info();
|
||||||
rt_kprintf("Assert : 0\n");
|
|
||||||
rt_kprintf("Error : 3\n");
|
|
||||||
rt_kprintf("Warning : 4\n");
|
|
||||||
rt_kprintf("Info : 6\n");
|
|
||||||
rt_kprintf("Debug : 7\n");
|
|
||||||
#else
|
|
||||||
rt_kprintf("EMERG : 1 (1 << 0)\n");
|
|
||||||
rt_kprintf("ALERT : 2 (1 << 1)\n");
|
|
||||||
rt_kprintf("CRIT : 4 (1 << 2)\n");
|
|
||||||
rt_kprintf("ERR : 8 (1 << 3)\n");
|
|
||||||
rt_kprintf("WARNING : 16 (1 << 4)\n");
|
|
||||||
rt_kprintf("NOTICE : 32 (1 << 5)\n");
|
|
||||||
rt_kprintf("INFO : 64 (1 << 6)\n");
|
|
||||||
rt_kprintf("DEBUG : 128 (1 << 7)\n");
|
|
||||||
#endif /* ULOG_USING_SYSLOG */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MSH_CMD_EXPORT(ulog_tag_lvl, Set ulog filter level by different tag.);
|
MSH_CMD_EXPORT(ulog_tag_lvl, Set ulog filter level by different tag.);
|
||||||
|
@ -997,22 +1064,7 @@ static void ulog_lvl(uint8_t argc, char **argv)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rt_kprintf("Please input: ulog_lvl <level>.\n");
|
rt_kprintf("Please input: ulog_lvl <level>.\n");
|
||||||
#ifndef ULOG_USING_SYSLOG
|
_print_lvl_info();
|
||||||
rt_kprintf("Assert : 0\n");
|
|
||||||
rt_kprintf("Error : 3\n");
|
|
||||||
rt_kprintf("Warning : 4\n");
|
|
||||||
rt_kprintf("Info : 6\n");
|
|
||||||
rt_kprintf("Debug : 7\n");
|
|
||||||
#else
|
|
||||||
rt_kprintf("EMERG : 1 (1 << 0)\n");
|
|
||||||
rt_kprintf("ALERT : 2 (1 << 1)\n");
|
|
||||||
rt_kprintf("CRIT : 4 (1 << 2)\n");
|
|
||||||
rt_kprintf("ERR : 8 (1 << 3)\n");
|
|
||||||
rt_kprintf("WARNING : 16 (1 << 4)\n");
|
|
||||||
rt_kprintf("NOTICE : 32 (1 << 5)\n");
|
|
||||||
rt_kprintf("INFO : 64 (1 << 6)\n");
|
|
||||||
rt_kprintf("DEBUG : 128 (1 << 7)\n");
|
|
||||||
#endif /* ULOG_USING_SYSLOG */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MSH_CMD_EXPORT(ulog_lvl, Set ulog global filter level.);
|
MSH_CMD_EXPORT(ulog_lvl, Set ulog global filter level.);
|
||||||
|
@ -1124,6 +1176,7 @@ rt_err_t ulog_backend_register(ulog_backend_t backend, const char *name, rt_bool
|
||||||
}
|
}
|
||||||
|
|
||||||
backend->support_color = support_color;
|
backend->support_color = support_color;
|
||||||
|
backend->out_level = LOG_FILTER_LVL_ALL;
|
||||||
rt_memcpy(backend->name, name, RT_NAME_MAX);
|
rt_memcpy(backend->name, name, RT_NAME_MAX);
|
||||||
|
|
||||||
level = rt_hw_interrupt_disable();
|
level = rt_hw_interrupt_disable();
|
||||||
|
@ -1163,6 +1216,11 @@ void ulog_async_output(void)
|
||||||
rt_rbb_blk_t log_blk;
|
rt_rbb_blk_t log_blk;
|
||||||
ulog_frame_t log_frame;
|
ulog_frame_t log_frame;
|
||||||
|
|
||||||
|
if (!ulog.async_enabled)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
while ((log_blk = rt_rbb_blk_get(ulog.async_rbb)) != NULL)
|
while ((log_blk = rt_rbb_blk_get(ulog.async_rbb)) != NULL)
|
||||||
{
|
{
|
||||||
log_frame = (ulog_frame_t) log_blk->buf;
|
log_frame = (ulog_frame_t) log_blk->buf;
|
||||||
|
@ -1176,6 +1234,17 @@ void ulog_async_output(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enable or disable asynchronous output mode
|
||||||
|
* the log will be output directly when mode is disabled
|
||||||
|
*
|
||||||
|
* @param enabled RT_TRUE: enabled, RT_FALSE: disabled
|
||||||
|
*/
|
||||||
|
void ulog_async_output_enabled(rt_bool_t enabled)
|
||||||
|
{
|
||||||
|
ulog.async_enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* waiting for get asynchronous output log
|
* waiting for get asynchronous output log
|
||||||
*
|
*
|
||||||
|
@ -1230,7 +1299,7 @@ int ulog_init(void)
|
||||||
if (ulog.init_ok)
|
if (ulog.init_ok)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
rt_mutex_init(&ulog.output_locker, "ulog lock", RT_IPC_FLAG_FIFO);
|
rt_sem_init(&ulog.output_locker, "ulog lock", 1, RT_IPC_FLAG_FIFO);
|
||||||
rt_slist_init(&ulog.backend_list);
|
rt_slist_init(&ulog.backend_list);
|
||||||
|
|
||||||
#ifdef ULOG_USING_FILTER
|
#ifdef ULOG_USING_FILTER
|
||||||
|
@ -1239,29 +1308,16 @@ int ulog_init(void)
|
||||||
|
|
||||||
#ifdef ULOG_USING_ASYNC_OUTPUT
|
#ifdef ULOG_USING_ASYNC_OUTPUT
|
||||||
RT_ASSERT(ULOG_ASYNC_OUTPUT_STORE_LINES >= 2);
|
RT_ASSERT(ULOG_ASYNC_OUTPUT_STORE_LINES >= 2);
|
||||||
|
ulog.async_enabled = RT_TRUE;
|
||||||
/* async output ring block buffer */
|
/* async output ring block buffer */
|
||||||
ulog.async_rbb = rt_rbb_create(RT_ALIGN(ULOG_ASYNC_OUTPUT_BUF_SIZE, RT_ALIGN_SIZE), ULOG_ASYNC_OUTPUT_STORE_LINES);
|
ulog.async_rbb = rt_rbb_create(RT_ALIGN(ULOG_ASYNC_OUTPUT_BUF_SIZE, RT_ALIGN_SIZE), ULOG_ASYNC_OUTPUT_STORE_LINES);
|
||||||
if (ulog.async_rbb == NULL)
|
if (ulog.async_rbb == NULL)
|
||||||
{
|
{
|
||||||
rt_kprintf("Error: ulog init failed! No memory for async rbb.\n");
|
rt_kprintf("Error: ulog init failed! No memory for async rbb.\n");
|
||||||
rt_mutex_detach(&ulog.output_locker);
|
rt_sem_detach(&ulog.output_locker);
|
||||||
return -RT_ENOMEM;
|
return -RT_ENOMEM;
|
||||||
}
|
}
|
||||||
/* async output thread */
|
|
||||||
ulog.async_th = rt_thread_create("ulog_async", async_output_thread_entry, &ulog, ULOG_ASYNC_OUTPUT_THREAD_STACK,
|
|
||||||
ULOG_ASYNC_OUTPUT_THREAD_PRIORITY, 20);
|
|
||||||
if (ulog.async_th == NULL)
|
|
||||||
{
|
|
||||||
rt_kprintf("Error: ulog init failed! No memory for async output thread.\n");
|
|
||||||
rt_mutex_detach(&ulog.output_locker);
|
|
||||||
rt_rbb_destroy(ulog.async_rbb);
|
|
||||||
return -RT_ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
rt_sem_init(&ulog.async_notice, "ulog", 0, RT_IPC_FLAG_FIFO);
|
rt_sem_init(&ulog.async_notice, "ulog", 0, RT_IPC_FLAG_FIFO);
|
||||||
/* async output thread startup */
|
|
||||||
rt_thread_startup(ulog.async_th);
|
|
||||||
|
|
||||||
#endif /* ULOG_USING_ASYNC_OUTPUT */
|
#endif /* ULOG_USING_ASYNC_OUTPUT */
|
||||||
|
|
||||||
#ifdef ULOG_USING_FILTER
|
#ifdef ULOG_USING_FILTER
|
||||||
|
@ -1272,7 +1328,28 @@ int ulog_init(void)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
INIT_PREV_EXPORT(ulog_init);
|
INIT_BOARD_EXPORT(ulog_init);
|
||||||
|
|
||||||
|
#ifdef ULOG_USING_ASYNC_OUTPUT
|
||||||
|
int ulog_async_init(void)
|
||||||
|
{
|
||||||
|
if (ulog.async_th == NULL)
|
||||||
|
{
|
||||||
|
/* async output thread */
|
||||||
|
ulog.async_th = rt_thread_create("ulog_async", async_output_thread_entry, &ulog, ULOG_ASYNC_OUTPUT_THREAD_STACK,
|
||||||
|
ULOG_ASYNC_OUTPUT_THREAD_PRIORITY, 20);
|
||||||
|
if (ulog.async_th == NULL)
|
||||||
|
{
|
||||||
|
rt_kprintf("Error: ulog init failed! No memory for async output thread.\n");
|
||||||
|
return -RT_ENOMEM;
|
||||||
|
}
|
||||||
|
/* async output thread startup */
|
||||||
|
rt_thread_startup(ulog.async_th);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
INIT_PREV_EXPORT(ulog_async_init);
|
||||||
|
#endif /* ULOG_USING_ASYNC_OUTPUT */
|
||||||
|
|
||||||
void ulog_deinit(void)
|
void ulog_deinit(void)
|
||||||
{
|
{
|
||||||
|
@ -1304,7 +1381,7 @@ void ulog_deinit(void)
|
||||||
}
|
}
|
||||||
#endif /* ULOG_USING_FILTER */
|
#endif /* ULOG_USING_FILTER */
|
||||||
|
|
||||||
rt_mutex_detach(&ulog.output_locker);
|
rt_sem_detach(&ulog.output_locker);
|
||||||
|
|
||||||
#ifdef ULOG_USING_ASYNC_OUTPUT
|
#ifdef ULOG_USING_ASYNC_OUTPUT
|
||||||
rt_rbb_destroy(ulog.async_rbb);
|
rt_rbb_destroy(ulog.async_rbb);
|
||||||
|
|
|
@ -24,6 +24,7 @@ extern "C" {
|
||||||
* ulog init and deint
|
* ulog init and deint
|
||||||
*/
|
*/
|
||||||
int ulog_init(void);
|
int ulog_init(void);
|
||||||
|
int ulog_async_init(void);
|
||||||
void ulog_deinit(void);
|
void ulog_deinit(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -78,6 +79,7 @@ void ulog_flush(void);
|
||||||
* asynchronous output API
|
* asynchronous output API
|
||||||
*/
|
*/
|
||||||
void ulog_async_output(void);
|
void ulog_async_output(void);
|
||||||
|
void ulog_async_output_enabled(rt_bool_t enabled);
|
||||||
void ulog_async_waiting_log(rt_int32_t time);
|
void ulog_async_waiting_log(rt_int32_t time);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -201,6 +201,7 @@ struct ulog_backend
|
||||||
{
|
{
|
||||||
char name[RT_NAME_MAX];
|
char name[RT_NAME_MAX];
|
||||||
rt_bool_t support_color;
|
rt_bool_t support_color;
|
||||||
|
rt_uint32_t out_level;
|
||||||
void (*init) (struct ulog_backend *backend);
|
void (*init) (struct ulog_backend *backend);
|
||||||
void (*output)(struct ulog_backend *backend, rt_uint32_t level, const char *tag, rt_bool_t is_raw, const char *log, size_t len);
|
void (*output)(struct ulog_backend *backend, rt_uint32_t level, const char *tag, rt_bool_t is_raw, const char *log, size_t len);
|
||||||
void (*flush) (struct ulog_backend *backend);
|
void (*flush) (struct ulog_backend *backend);
|
||||||
|
|
Loading…
Reference in New Issue