From 022f5d55ac2c98aa0569fb03a98416abdb3d6a0e Mon Sep 17 00:00:00 2001 From: Zhenlin Wang Date: Mon, 1 Sep 2025 22:34:38 +0800 Subject: [PATCH 1/2] refactor log: added chain private data Signed-off-by: Zhenlin Wang --- examples/log/modules.c | 9 ++-- include/bfdev/log.h | 33 +++++++++--- include/bfdev/modules/log.h | 25 ++------- modules/build.cmake | 7 +-- modules/log-hostname.c | 38 -------------- modules/log-localtime.c | 41 --------------- modules/log-pid.c | 33 ------------ modules/log/build.cmake | 21 ++++++++ modules/log/chain-hostname.c | 20 +++++++ modules/log/chain-localtime.c | 23 ++++++++ modules/log/chain-pid.c | 15 ++++++ src/log/color.c | 7 +-- src/log/level.c | 4 +- src/log/log.c | 98 +++++++++++++++++++++++++++-------- 14 files changed, 194 insertions(+), 180 deletions(-) delete mode 100644 modules/log-hostname.c delete mode 100644 modules/log-localtime.c delete mode 100644 modules/log-pid.c create mode 100644 modules/log/build.cmake create mode 100644 modules/log/chain-hostname.c create mode 100644 modules/log/chain-localtime.c create mode 100644 modules/log/chain-pid.c diff --git a/examples/log/modules.c b/examples/log/modules.c index 81009087..5ca5db65 100644 --- a/examples/log/modules.c +++ b/examples/log/modules.c @@ -13,11 +13,14 @@ int main(int argc, const char *argv[]) { + BFDEV_DEFINE_LOG_CHAIN(log_localtime, bfdev_log_chain_localtime, -300, NULL); + BFDEV_DEFINE_LOG_CHAIN(log_hostname, bfdev_log_chain_hostname, -200, NULL); + BFDEV_DEFINE_LOG_CHAIN(log_pid, bfdev_log_chain_pid, -100, NULL); unsigned int count; - bfdev_log_localtime_enable(&bfdev_log_default); - bfdev_log_hostname_enable(&bfdev_log_default); - bfdev_log_pid_enable(&bfdev_log_default); + bfdev_log_chain_register(&bfdev_log_default, &log_localtime); + bfdev_log_chain_register(&bfdev_log_default, &log_hostname); + bfdev_log_chain_register(&bfdev_log_default, &log_pid); for (count = 0; count < 3; ++count) { bfdev_log_info("Hello World!\n"); diff --git a/include/bfdev/log.h b/include/bfdev/log.h index 109c8b78..9891e2ff 100644 --- a/include/bfdev/log.h +++ b/include/bfdev/log.h @@ -34,7 +34,7 @@ typedef int (*bfdev_log_hook_t) (bfdev_log_message_t *msg, void *pdata); typedef int (*bfdev_log_write_t) -(bfdev_log_message_t *msg, void *pdata); +(bfdev_log_message_t *msg); enum bfdev_log_flags { __BFDEV_LOG_COLOR = 0, @@ -48,6 +48,7 @@ struct bfdev_log_chain { bfdev_ilist_node_t list; bfdev_log_hook_t func; int priority; + void *pdata; }; struct bfdev_log { @@ -55,22 +56,23 @@ struct bfdev_log { unsigned int record_level; unsigned long flags; - bfdev_ilist_head_t prefix_hooks; - bfdev_ilist_head_t suffix_hooks; + bfdev_ilist_head_t prefix_chain; + bfdev_ilist_head_t suffix_chain; bfdev_log_write_t write; void *pdata; }; struct bfdev_log_message { + bfdev_log_t *log; unsigned int level; bfdev_size_t length; char *buff; }; #define BFDEV_LOG_STATIC(HEAD, DEFAULT, RECORD, FLAGS, WRITE, PDATA) { \ - .prefix_hooks = BFDEV_ILIST_HEAD_STATIC(&(HEAD)->prefix_hooks), \ - .suffix_hooks = BFDEV_ILIST_HEAD_STATIC(&(HEAD)->suffix_hooks), \ + .prefix_chain = BFDEV_ILIST_HEAD_STATIC(&(HEAD)->prefix_chain), \ + .suffix_chain = BFDEV_ILIST_HEAD_STATIC(&(HEAD)->suffix_chain), \ .default_level = (DEFAULT), .record_level = (RECORD), \ .flags = (FLAGS), .write = (WRITE), .pdata = (PDATA), \ } @@ -81,6 +83,16 @@ struct bfdev_log_message { #define BFDEV_DEFINE_LOG(name, default, record, flags, write, pdata) \ bfdev_log_t name = BFDEV_LOG_INIT(&name, default, record, flags, write, pdata) +#define BFDEV_LOG_CHAIN_STATIC(FUNC, PRIORITY, PDATA) { \ + .func = (FUNC), .priority = (PRIORITY), .pdata = (PDATA), \ +} + +#define BFDEV_LOG_CHAIN_INIT(func, priority, pdata) \ + (bfdev_log_chain_t) BFDEV_LOG_CHAIN_STATIC(func, priority, pdata) + +#define BFDEV_DEFINE_LOG_CHAIN(name, func, priority, pdata) \ + bfdev_log_chain_t name = BFDEV_LOG_CHAIN_INIT(func, priority, pdata) + BFDEV_BITFLAGS_STRUCT( bfdev_log_color, struct bfdev_log, flags, @@ -103,6 +115,13 @@ bfdev_log_init(bfdev_log_t *log, unsigned int def, unsigned int record, *log = BFDEV_LOG_INIT(log, def, record, flags, write, pdata); } +static inline void +bfdev_log_chain_init(bfdev_log_chain_t *chain, bfdev_log_hook_t func, + int priority, void *pdata) +{ + *chain = BFDEV_LOG_CHAIN_INIT(func, priority, pdata); +} + extern unsigned int bfdev_log_level(const char *str, const char **endptr); @@ -119,10 +138,10 @@ extern __bfdev_printf(2, 3) int bfdev_msg_append(bfdev_log_message_t *msg, const char *fmt, ...); extern int -bfdev_log_hook_register(bfdev_log_t *log, bfdev_log_chain_t *hook); +bfdev_log_chain_register(bfdev_log_t *log, bfdev_log_chain_t *hook); extern void -bfdev_log_hook_unregister(bfdev_log_t *log, bfdev_log_chain_t *hook); +bfdev_log_chain_unregister(bfdev_log_t *log, bfdev_log_chain_t *hook); /** * bfdev_log_fmt - used by the bfdev_log_*() macros to generate the bfdev_log format string diff --git a/include/bfdev/modules/log.h b/include/bfdev/modules/log.h index a13bc7f7..2d2037e5 100644 --- a/include/bfdev/modules/log.h +++ b/include/bfdev/modules/log.h @@ -11,32 +11,17 @@ BFDEV_BEGIN_DECLS -extern bfdev_log_chain_t -bfdev_log_chain_hostname; - -extern bfdev_log_chain_t -bfdev_log_chain_localtime; - -extern bfdev_log_chain_t -bfdev_log_chain_pid; - extern int -bfdev_log_localtime_enable(bfdev_log_t *log); - -extern void -bfdev_log_localtime_disable(bfdev_log_t *log); +bfdev_log_chain_hostname(bfdev_log_message_t *msg, void *pdata); extern int -bfdev_log_hostname_enable(bfdev_log_t *log); - -extern void -bfdev_log_hostname_disable(bfdev_log_t *log); +bfdev_log_chain_localtime(bfdev_log_message_t *msg, void *pdata); extern int -bfdev_log_pid_enable(bfdev_log_t *log); +bfdev_log_chain_pid(bfdev_log_message_t *msg, void *pdata); -extern void -bfdev_log_pid_disable(bfdev_log_t *log); +extern int +bfdev_log_write_syslog(bfdev_log_message_t *msg, void *pdata); BFDEV_END_DECLS diff --git a/modules/build.cmake b/modules/build.cmake index 7b249c54..b7e99583 100644 --- a/modules/build.cmake +++ b/modules/build.cmake @@ -3,9 +3,4 @@ # Copyright(c) 2025 Zhenlin Wang # -set(BFDEV_SOURCE - ${BFDEV_SOURCE} - ${CMAKE_CURRENT_LIST_DIR}/log-hostname.c - ${CMAKE_CURRENT_LIST_DIR}/log-localtime.c - ${CMAKE_CURRENT_LIST_DIR}/log-pid.c -) +include(${CMAKE_CURRENT_LIST_DIR}/log/build.cmake) diff --git a/modules/log-hostname.c b/modules/log-hostname.c deleted file mode 100644 index d08be772..00000000 --- a/modules/log-hostname.c +++ /dev/null @@ -1,38 +0,0 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ -/* - * Copyright(c) 2025 Zhenlin Wang - */ - -#include -#include -#include -#include - -static int -log_hook_hostname(bfdev_log_message_t *msg, void *pdata) -{ - struct utsname sys_info; - - if (uname(&sys_info) < 0) - return -BFDEV_EFAULT; - - return bfdev_msg_append(msg, "%s ", sys_info.nodename); -} - -export bfdev_log_chain_t -bfdev_log_chain_hostname = { - .func = log_hook_hostname, - .priority = -200, -}; - -export int -bfdev_log_hostname_enable(bfdev_log_t *log) -{ - return bfdev_log_hook_register(log, &bfdev_log_chain_hostname); -} - -export void -bfdev_log_hostname_disable(bfdev_log_t *log) -{ - bfdev_log_hook_unregister(log, &bfdev_log_chain_hostname); -} diff --git a/modules/log-localtime.c b/modules/log-localtime.c deleted file mode 100644 index 99a35897..00000000 --- a/modules/log-localtime.c +++ /dev/null @@ -1,41 +0,0 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ -/* - * Copyright(c) 2025 Zhenlin Wang - */ - -#include -#include -#include -#include - -static int -log_hook_localtime(bfdev_log_message_t *msg, void *pdata) -{ - struct tm *tm_info; - time_t timestamp; - char buff[64]; - - time(×tamp); - tm_info = localtime(×tamp); - strftime(buff, sizeof(buff), "%a %b %d %H:%M:%S %p %Z %Y", tm_info); - - return bfdev_msg_append(msg, "<%s> ", buff); -} - -export bfdev_log_chain_t -bfdev_log_chain_localtime = { - .func = log_hook_localtime, - .priority = -1000, -}; - -export int -bfdev_log_localtime_enable(bfdev_log_t *log) -{ - return bfdev_log_hook_register(log, &bfdev_log_chain_localtime); -} - -export void -bfdev_log_localtime_disable(bfdev_log_t *log) -{ - bfdev_log_hook_unregister(log, &bfdev_log_chain_localtime); -} diff --git a/modules/log-pid.c b/modules/log-pid.c deleted file mode 100644 index b0069e4f..00000000 --- a/modules/log-pid.c +++ /dev/null @@ -1,33 +0,0 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ -/* - * Copyright(c) 2025 Zhenlin Wang - */ - -#include -#include -#include -#include - -static int -log_hook_pid(bfdev_log_message_t *msg, void *pdata) -{ - return bfdev_msg_append(msg, "(pid: %d) ", getpid()); -} - -export bfdev_log_chain_t -bfdev_log_chain_pid = { - .func = log_hook_pid, - .priority = -100, -}; - -export int -bfdev_log_pid_enable(bfdev_log_t *log) -{ - return bfdev_log_hook_register(log, &bfdev_log_chain_pid); -} - -export void -bfdev_log_pid_disable(bfdev_log_t *log) -{ - bfdev_log_hook_unregister(log, &bfdev_log_chain_pid); -} diff --git a/modules/log/build.cmake b/modules/log/build.cmake new file mode 100644 index 00000000..1e357cc2 --- /dev/null +++ b/modules/log/build.cmake @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright(c) 2025 Zhenlin Wang +# + +set(BFDEV_SOURCE + ${BFDEV_SOURCE} + ${CMAKE_CURRENT_LIST_DIR}/chain-hostname.c + ${CMAKE_CURRENT_LIST_DIR}/chain-localtime.c + ${CMAKE_CURRENT_LIST_DIR}/chain-pid.c +) + +check_header_and_exit("time.h") +check_header_and_exit("unistd.h") +check_header_and_exit("sys/utsname.h") + +check_symbol_and_exit("time.h" "time") +check_symbol_and_exit("time.h" "localtime") +check_symbol_and_exit("time.h" "strftime") +check_symbol_and_exit("unistd.h" "getpid") +check_symbol_and_exit("sys/utsname.h" "uname") diff --git a/modules/log/chain-hostname.c b/modules/log/chain-hostname.c new file mode 100644 index 00000000..60fecd95 --- /dev/null +++ b/modules/log/chain-hostname.c @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* + * Copyright(c) 2025 Zhenlin Wang + */ + +#include +#include +#include +#include + +export int +bfdev_log_chain_hostname(bfdev_log_message_t *msg, void *pdata) +{ + struct utsname sys_info; + + if (uname(&sys_info) < 0) + return -BFDEV_EFAULT; + + return bfdev_msg_append(msg, "%s ", sys_info.nodename); +} diff --git a/modules/log/chain-localtime.c b/modules/log/chain-localtime.c new file mode 100644 index 00000000..9ceade7c --- /dev/null +++ b/modules/log/chain-localtime.c @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* + * Copyright(c) 2025 Zhenlin Wang + */ + +#include +#include +#include +#include + +export int +bfdev_log_chain_localtime(bfdev_log_message_t *msg, void *pdata) +{ + struct tm *tm_info; + time_t timestamp; + char buff[64]; + + time(×tamp); + tm_info = localtime(×tamp); + strftime(buff, sizeof(buff), "%a %b %d %H:%M:%S %p %Z %Y", tm_info); + + return bfdev_msg_append(msg, "<%s> ", buff); +} diff --git a/modules/log/chain-pid.c b/modules/log/chain-pid.c new file mode 100644 index 00000000..4d5bf3ad --- /dev/null +++ b/modules/log/chain-pid.c @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* + * Copyright(c) 2025 Zhenlin Wang + */ + +#include +#include +#include +#include + +export int +bfdev_log_chain_pid(bfdev_log_message_t *msg, void *pdata) +{ + return bfdev_msg_append(msg, "(pid: %d) ", getpid()); +} diff --git a/src/log/color.c b/src/log/color.c index 13948909..270ef643 100644 --- a/src/log/color.c +++ b/src/log/color.c @@ -37,17 +37,12 @@ level_color[] = { int log_color_prefix(bfdev_log_t *log, bfdev_log_message_t *msg) { - if (!bfdev_log_color_test(log)) - return -BFDEV_ENOERR; - + BFDEV_BUG_ON(msg->level > BFDEV_ARRAY_SIZE(level_color)); return bfdev_msg_append(msg, "\e[%dm", level_color[msg->level]); } int log_color_suffix(bfdev_log_t *log, bfdev_log_message_t *msg) { - if (!bfdev_log_color_test(log)) - return -BFDEV_ENOERR; - return bfdev_msg_append(msg, "\e[0m"); } diff --git a/src/log/level.c b/src/log/level.c index 545401bd..176c2b71 100644 --- a/src/log/level.c +++ b/src/log/level.c @@ -24,8 +24,6 @@ level_name[] = { int log_level_prefix(bfdev_log_t *log, bfdev_log_message_t *msg) { - if (!bfdev_log_level_test(log)) - return -BFDEV_ENOERR; - + BFDEV_BUG_ON(msg->level > BFDEV_ARRAY_SIZE(level_name)); return bfdev_msg_append(msg, "[%s] ", level_name[msg->level]); } diff --git a/src/log/log.c b/src/log/log.c index ca214164..e9f8a10b 100644 --- a/src/log/log.c +++ b/src/log/log.c @@ -93,15 +93,20 @@ bfdev_log_level(const char *str, const char **endptr) return level; } +static bfdev_ilist_head_t * +log_priority_chain(bfdev_log_t *log, int priority) +{ + return priority <= 0 ? &log->prefix_chain : &log->suffix_chain; +} + static int -log_call_hooks(bfdev_log_t *log, bfdev_ilist_head_t *chain, - bfdev_log_message_t *msg) +log_call_chain(bfdev_log_message_t *msg, bfdev_ilist_head_t *chain) { bfdev_log_chain_t *node, *tmp; int retval; bfdev_ilist_for_each_entry_safe(node, tmp, chain, list) { - retval = node->func(msg, log->pdata); + retval = node->func(msg, node->pdata); if (retval < 0) return retval; } @@ -110,19 +115,55 @@ log_call_hooks(bfdev_log_t *log, bfdev_ilist_head_t *chain, } static int -log_prefix(bfdev_log_t *log, bfdev_log_message_t *msg) +log_prefix_fixed(bfdev_log_message_t *msg) { + bfdev_log_t *log; int retval; - retval = log_call_hooks(log, &log->prefix_hooks, msg); - if (bfdev_unlikely(retval)) - return retval; + log = msg->log; + if (bfdev_log_level_test(log)) { + retval = log_level_prefix(log, msg); + if (bfdev_unlikely(retval)) + return retval; + } + + if (bfdev_log_color_test(log)) { + retval = log_color_prefix(log, msg); + if (bfdev_unlikely(retval)) + return retval; + } + + return -BFDEV_ENOERR; +} + +static int +log_suffix_fixed(bfdev_log_message_t *msg) +{ + bfdev_log_t *log; + int retval; + + log = msg->log; + if (bfdev_log_color_test(log)) { + retval = log_color_suffix(log, msg); + if (bfdev_unlikely(retval)) + return retval; + } + + return -BFDEV_ENOERR; +} + +static int +log_prefix(bfdev_log_message_t *msg) +{ + bfdev_log_t *log; + int retval; - retval = log_level_prefix(log, msg); + log = msg->log; + retval = log_call_chain(msg, &log->prefix_chain); if (bfdev_unlikely(retval)) return retval; - retval = log_color_prefix(log, msg); + retval = log_prefix_fixed(msg); if (bfdev_unlikely(retval)) return retval; @@ -130,21 +171,35 @@ log_prefix(bfdev_log_t *log, bfdev_log_message_t *msg) } static int -log_suffix(bfdev_log_t *log, bfdev_log_message_t *msg) +log_suffix(bfdev_log_message_t *msg) { + bfdev_log_t *log; int retval; - retval = log_color_suffix(log, msg); + log = msg->log; + retval = log_suffix_fixed(msg); if (bfdev_unlikely(retval)) return retval; - retval = log_call_hooks(log, &log->suffix_hooks, msg); + retval = log_call_chain(msg, &log->suffix_chain); if (bfdev_unlikely(retval)) return retval; return -BFDEV_ENOERR; } +static int +log_write(bfdev_log_message_t *msg) +{ + bfdev_log_t *log; + + log = msg->log; + if (log->write) + return log->write(msg); + + return bfport_log_write(msg); +} + static int log_emit(bfdev_log_t *log, unsigned int level, const char *fmt, bfdev_va_list args) { @@ -161,11 +216,12 @@ log_emit(bfdev_log_t *log, unsigned int level, const char *fmt, bfdev_va_list ar if (level > log->record_level) return -BFDEV_ENOERR; + msg.log = log; msg.level = level; msg.buff = buff; msg.length = 0; - retval = log_prefix(log, &msg); + retval = log_prefix(&msg); if (bfdev_unlikely(retval)) return retval; @@ -173,15 +229,11 @@ log_emit(bfdev_log_t *log, unsigned int level, const char *fmt, bfdev_va_list ar if (bfdev_unlikely(retval)) return retval; - retval = log_suffix(log, &msg); + retval = log_suffix(&msg); if (bfdev_unlikely(retval)) return retval; - if (log->write) - retval = log->write(&msg, log->pdata); - else - retval = bfport_log_write(&msg); - + retval = log_write(&msg); if (bfdev_unlikely(retval < 0)) return -BFDEV_EIO; @@ -212,14 +264,14 @@ bfdev_log_core(bfdev_log_t *log, const char *fmt, ...) } export int -bfdev_log_hook_register(bfdev_log_t *log, bfdev_log_chain_t *hook) +bfdev_log_chain_register(bfdev_log_t *log, bfdev_log_chain_t *hook) { bfdev_ilist_head_t *chain; if (bfdev_unlikely(!hook->func)) return -BFDEV_EINVAL; - chain = hook->priority <= 0 ? &log->prefix_hooks : &log->suffix_hooks; + chain = log_priority_chain(log, hook->priority); bfdev_ilist_node_init(&hook->list); bfdev_ilist_add(chain, &hook->list, log_chain_priority_cmp, BFDEV_NULL); @@ -227,10 +279,10 @@ bfdev_log_hook_register(bfdev_log_t *log, bfdev_log_chain_t *hook) } export void -bfdev_log_hook_unregister(bfdev_log_t *log, bfdev_log_chain_t *hook) +bfdev_log_chain_unregister(bfdev_log_t *log, bfdev_log_chain_t *hook) { bfdev_ilist_head_t *chain; - chain = hook->priority <= 0 ? &log->prefix_hooks : &log->suffix_hooks; + chain = log_priority_chain(log, hook->priority); bfdev_ilist_del(chain, &hook->list); } From 5543ca4d8ce53816f96fcf200f5ecd647cdd7ce1 Mon Sep 17 00:00:00 2001 From: Zhenlin Wang Date: Mon, 1 Sep 2025 22:35:48 +0800 Subject: [PATCH 2/2] feat log: added syslog module Signed-off-by: Zhenlin Wang --- modules/log/build.cmake | 3 +++ modules/log/write-syslog.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 modules/log/write-syslog.c diff --git a/modules/log/build.cmake b/modules/log/build.cmake index 1e357cc2..f11f7da4 100644 --- a/modules/log/build.cmake +++ b/modules/log/build.cmake @@ -8,14 +8,17 @@ set(BFDEV_SOURCE ${CMAKE_CURRENT_LIST_DIR}/chain-hostname.c ${CMAKE_CURRENT_LIST_DIR}/chain-localtime.c ${CMAKE_CURRENT_LIST_DIR}/chain-pid.c + ${CMAKE_CURRENT_LIST_DIR}/write-syslog.c ) check_header_and_exit("time.h") check_header_and_exit("unistd.h") +check_header_and_exit("syslog.h") check_header_and_exit("sys/utsname.h") check_symbol_and_exit("time.h" "time") check_symbol_and_exit("time.h" "localtime") check_symbol_and_exit("time.h" "strftime") check_symbol_and_exit("unistd.h" "getpid") +check_symbol_and_exit("syslog.h" "syslog") check_symbol_and_exit("sys/utsname.h" "uname") diff --git a/modules/log/write-syslog.c b/modules/log/write-syslog.c new file mode 100644 index 00000000..dbc42e90 --- /dev/null +++ b/modules/log/write-syslog.c @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* + * Copyright(c) 2025 Zhenlin Wang + */ + +#include +#include +#include +#include + +static const int +syslog_level[] = { + [BFDEV_LEVEL_EMERG ] = LOG_EMERG, + [BFDEV_LEVEL_ALERT ] = LOG_ALERT, + [BFDEV_LEVEL_CRIT ] = LOG_CRIT, + [BFDEV_LEVEL_ERR ] = LOG_ERR, + [BFDEV_LEVEL_WARNING] = LOG_WARNING, + [BFDEV_LEVEL_NOTICE ] = LOG_NOTICE, + [BFDEV_LEVEL_INFO ] = LOG_INFO, + [BFDEV_LEVEL_DEBUG ] = LOG_DEBUG, +}; + +export int +bfdev_log_write_syslog(bfdev_log_message_t *msg, void *pdata) +{ + int level, priority; + + level = msg->level; + if (level >= BFDEV_ARRAY_SIZE(syslog_level)) + level = BFDEV_LEVEL_INFO; + + priority = syslog_level[level]; + syslog(priority, "%.*s", (int)msg->length, msg->buff); + + return msg->length; +}