From d17f55435592fdc01a5c1fc5e0e15569f84efcdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=81yszczek?= Date: Sat, 2 Mar 2024 00:13:48 +0100 Subject: [PATCH] examples/embedlog: update example for embedlog-v0.7.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Łyszczek --- examples/embedlog/CMakeLists.txt | 5 ++ examples/embedlog/Kconfig | 33 +++++++++++ examples/embedlog/Makefile | 4 ++ examples/embedlog/embedlog_main.c | 97 +++++++++++++++++-------------- 4 files changed, 96 insertions(+), 43 deletions(-) diff --git a/examples/embedlog/CMakeLists.txt b/examples/embedlog/CMakeLists.txt index a5a598c13..055126498 100644 --- a/examples/embedlog/CMakeLists.txt +++ b/examples/embedlog/CMakeLists.txt @@ -19,6 +19,11 @@ # ############################################################################## if(CONFIG_EXAMPLES_EMBEDLOG) + + if(CONFIG_EXAMPLES_EMBEDLOG_STRIP_ALL_STRINGS) + list(APPEND CFLAGS -DDISABLE_ALL_EMBEDLOG) + endif() + nuttx_add_application( NAME ${CONFIG_EXAMPLES_EMBEDLOG_PROGNAME} diff --git a/examples/embedlog/Kconfig b/examples/embedlog/Kconfig index e258c3948..564823d50 100644 --- a/examples/embedlog/Kconfig +++ b/examples/embedlog/Kconfig @@ -23,6 +23,39 @@ config EXAMPLES_EMBEDLOG if EXAMPLES_EMBEDLOG +config EXAMPLES_EMBEDLOG_STRIP_ALL_STRINGS + bool "Disable embedlog (strip)" + default n + ---help--- + Enabled embedlog so you can disable it... sounds about right. + + Enable this to replace all embedlog function calls with stub + functions that always return OK. This will effectively strip + final binary from all log strings making code considerably + smaller. + + This may be useful in two cases (at least): + + 1) You develop your app on bigger version of target MCU, on + which you have a lot of memory. So on that version of the + build you can afford to enable good diagnostic logs. But + final image may be run on smaller version, on which logs + would not fit. In that case you can strip binary in final + production image. Thanks to that you will get logs in dev + env, but still maintain small footprint on production build. + + 2) You want to hide implementation details that could be + leaked with debug logs from final image. + + It only makes sense to enable this on production type builds. + Linker will optimize out embedlog and remove all unused + functions, just as if embedlog was never built. + + Enabling this will render embedlog example useless - it + will not print anything, but example will stil compile + and final image will be about 15kB smaller. But YMMV + depending how much strings you have in project. + config EXAMPLES_EMBEDLOG_PROGNAME string "Program name" default "embedlog" diff --git a/examples/embedlog/Makefile b/examples/embedlog/Makefile index f3476b3d7..6524a872f 100644 --- a/examples/embedlog/Makefile +++ b/examples/embedlog/Makefile @@ -27,6 +27,10 @@ PRIORITY = $(CONFIG_EXAMPLES_EMBEDLOG_PRIORITY) STACKSIZE = $(CONFIG_EXAMPLES_EMBEDLOG_STACKSIZE) MODULE = $(CONFIG_EXAMPLES_EMBEDLOG) +ifeq ($(CONFIG_EXAMPLES_EMBEDLOG_STRIP_ALL_STRINGS),y) + CFLAGS += -DDISABLE_ALL_EMBEDLOG +endif + # embedlog Example MAINSRC = embedlog_main.c diff --git a/examples/embedlog/embedlog_main.c b/examples/embedlog/embedlog_main.c index 97dbde77b..497fa1452 100644 --- a/examples/embedlog/embedlog_main.c +++ b/examples/embedlog/embedlog_main.c @@ -113,7 +113,6 @@ static void el_print_options(void) el_ooption(&g_el, EL_TS, EL_TS_LONG); el_ooption(&g_el, EL_TS, EL_TS_OFF); el_oprint(OELF, "no time information, if your heart desire it"); - el_ooption(&g_el, EL_TS_FRACT, EL_TS_FRACT_NS); el_ooption(&g_el, EL_FINFO, 1); el_oprint(OELF, "log location is very useful for debugging"); @@ -121,6 +120,10 @@ static void el_print_options(void) el_ooption(&g_el, EL_TS, EL_TS_LONG); el_ooption(&g_el, EL_TS_TM, EL_TS_TM_REALTIME); el_ooption(&g_el, EL_PRINT_LEVEL, 1); + + /* nuttx runs on rather slow cpus, so millisecond precision is enough */ + + el_ooption(&g_el, EL_TS_FRACT, EL_TS_FRACT_MS); el_oprint(OELF, "Different scenarios need different options"); el_oprint(OELA, "So we can mix options however we want"); @@ -188,6 +191,10 @@ static void el_print_memory(void) el_oprint(OELI, "print the same region but this time with nice ascii " "table"); el_opmemory_table(OELI, s, sizeof(s)); + + el_ooption(&g_el, EL_PMEMORY_SPACE, 1); + el_oprint(OELI, "print whole ASCII table with additional spacing"); + el_opmemory(OELI, ascii, sizeof(ascii)); } /**************************************************************************** @@ -221,51 +228,18 @@ static void el_print_file(const char *workdir) snprintf(log_path, sizeof(log_path), "%s/log-rotate", workdir); - /* Enable file rotation, maximum 5 files will be created, none of the log - * files size shall exceed 512 bytes. Rotate size is low to present how - * rotation works, in real life this should be much higher, unless you - * really know what you are doing and understand the consequences of low - * rotate size. - */ - - el_ooption(&g_el, EL_FROTATE_NUMBER, 5); - el_ooption(&g_el, EL_FROTATE_SIZE, 512); - - /* Tell embedlog to sync all buffers and metadata regarding log file. - * There are cases, when data (a lot of data) goes into block device, - * but metadata of the file are not updated when power loss occurs. This - * leads to data loss - even though they landed physically on block device - * like sdcard. To prevent losing too much data, you can define how often - * you want embedlog to call sync() functions. It basically translates to - * "how much data am I ready to loose?". In this example, we sync() once - * every 4096 bytes are stored into file. - */ - - el_ooption(&g_el, EL_FILE_SYNC_EVERY, 4096); - - /* Setting above value to too small value, will cause sync() to be called - * very often (depending on how much data you log) and that may criple - * performance greatly. And there are situations when you are willing to - * loose some info or debug data (up to configured sync every value), but - * when critical error shows up, you want data to be synced immediately to - * minimize chance of losing information about critical error. For that - * you can define which log level will be synced *every* time regardless - * of sync every value. Here we will instruct embedlog to log prints that - * have severity higher or equal to critical (so critial, alert and fatal) - */ - el_ooption(&g_el, EL_FILE_SYNC_LEVEL, EL_CRIT); - /* Print logs to both file and standard error */ - - el_ooption(&g_el, EL_OUT, EL_OUT_FILE | EL_OUT_STDERR); - - /* Register path to log file in embedlog. This will cause logger to look - * for next valid log file (when log rotate in enabled) and will try to - * open file for reading. + /* Enable logging to file with file rotation based on file size. + * Maximum 5 files will be created, none of the log files size shall + * exceed 512 bytes. Rotate size is low to present how rotation works, in + * real life this should be much higher, unless you really know what you + * are doing and understand the consequences of low rotate size. + * This function will also automatically enable file output without + * disabling any - already enabled - outputs. */ - if (el_ooption(&g_el, EL_FPATH, log_path) != 0) + if (el_oenable_file_log(&g_el, log_path, 5, 512)) { if (errno == ENAMETOOLONG || errno == EINVAL) { @@ -286,6 +260,29 @@ static void el_print_file(const char *workdir) return; } + /* Tell embedlog to sync all buffers and metadata regarding log file. + * + * There are cases, when data (a lot of data) goes into block device, + * but metadata of the file are not updated when power loss occurs. This + * leads to data loss - even though they landed physically on block device + * like sdcard. To prevent losing too much data, you can define how often + * you want embedlog to call sync() functions. It basically translates to + * "how much data am I ready to loose?". In this example, we sync() once + * every 4096 bytes are stored into file. + * + * Setting that value to too small value, will cause sync() to be called + * very often (depending on how much data you log) and that may criple + * performance greatly. And there are situations when you are willing to + * loose some info or debug data (up to configured sync every value), but + * when critical error shows up, you want data to be synced immediately to + * minimize chance of losing information about critical error. For that + * you can define which log level will be synced *every* time regardless + * of 'sync every' value. Here we will instruct embedlog to log prints that + * have severity higher or equal to critical (so critial, alert and fatal) + */ + + el_oset_file_sync(&g_el, 4096, EL_CRIT); + /* Now we can print messages */ el_oprint(OELI, "Now we enabled log rotation"); @@ -317,7 +314,21 @@ int main(int argc, FAR char *argv[]) el_oinit(&g_el); el_oprint(OELI, "Right after init, embedlog will print to stderr with " - "just log level information - these are default settings."); + "just log level information - these are default settings."); + + el_oprint(OELI, "You can enable most common and usefull options with just " + "a few special functions"); + + el_oset_timestamp(&g_el, EL_TS_LONG, EL_TS_TM_REALTIME, EL_TS_FRACT_US); + el_oprint_extra_info(&g_el, 1); + + el_oprint(OELI, "timestamp and information about log place in code is " + "most usefull for developer"); + el_oprint(OELI, "If these are not enough, you can always really fine"); + el_oprint(OELI, "tune embedlog behaviour with options"); + + el_oset_timestamp(&g_el, EL_TS_OFF, EL_TS_TM_REALTIME, EL_TS_FRACT_OFF); + el_oprint_extra_info(&g_el, 0); el_print_options(); el_print_memory();