eal: add option to put timestamp on console output
PATCH v23 13/15 log: add support for systemd journal
In reply to Stephen HemmingerIf DPDK application is being run as a systemd service, then it can use the journal protocol which allows putting more information in the log such as priority and other information.
The use of journal protocol is automatically detected and handled. Rather than having a dependency on libsystemd, just use the protocol directly as defined in:
https://systemd.io/JOURNAL_NATIVE_PROTOCOL/
--- doc/guides/prog_guide/log_lib.rst | 14 ++ lib/eal/common/eal_common_options.c | 15 +++ lib/eal/common/eal_options.h | 2 + lib/log/log.c | 4 +- lib/log/log_internal.h | 3 + lib/log/log_journal.c | 200 ++++++++++++++++++++++++++++ lib/log/log_private.h | 16 +++ lib/log/meson.build | 4 + lib/log/version.map | 1 + 9 files changed, 258 insertions(+), 1 deletion(-) create mode 100644 lib/log/log_journal.c
doc/guides/prog_guide/log_lib.rst +14 -0
@@ -100,6 +100,20 @@ option. There are three possible settings for this option: If ``--syslog`` option is not specified, then only console (stderr) will be used. +Messages can be redirected to systemd journal which is an enhanced version of syslog with the ``--log-journal`` option. + +There are three possible settings for this option: + +*auto* + If stderr is redirected to journal by ``systemd`` service + then use journal socket to instead of stderr for log. + This is the default. + +*never* + Do not try to use journal. + +*always* + Always try to direct messages to journal socket. Using Logging APIs to Generate Log Messages
lib/eal/common/eal_common_options.c +15 -0
@@ -74,6 +74,7 @@ eal_long_options[] = { {OPT_IOVA_MODE, 1, NULL, OPT_IOVA_MODE_NUM }, {OPT_LCORES, 1, NULL, OPT_LCORES_NUM }, {OPT_LOG_LEVEL, 1, NULL, OPT_LOG_LEVEL_NUM }, + {OPT_LOG_JOURNAL, 2, NULL, OPT_LOG_JOURNAL_NUM }, {OPT_LOG_TIMESTAMP, 2, NULL, OPT_LOG_TIMESTAMP_NUM }, {OPT_TRACE, 1, NULL, OPT_TRACE_NUM }, {OPT_TRACE_DIR, 1, NULL, OPT_TRACE_DIR_NUM },
@@ -1617,6 +1618,7 @@ eal_log_level_parse(int argc, char * const argv[])switch (opt) {case OPT_LOG_LEVEL_NUM :case OPT_SYSLOG_NUM : +case OPT_LOG_JOURNAL_NUM :case OPT_LOG_TIMESTAMP_NUM :if (eal_parse_common_option (opt, optarg, internal_conf) <0 )return -1 ;
@@ -1845,6 +1847,16 @@ eal_parse_common_option(int opt, const char *optarg,break ;#endif +#ifdef RTE_EXEC_ENV_LINUX +case OPT_LOG_JOURNAL_NUM : +if (eal_log_journal (optarg) <0 ) { +EAL_LOG (ERR ,"invalid parameters for --" +OPT_LOG_JOURNAL ); +return -1 ; + } +break ; +#endif +case OPT_LOG_LEVEL_NUM :if (eal_parse_log_level (optarg) <0 ) { EAL_LOG(ERR,
@@ -2222,6 +2234,9 @@ eal_common_usage(void) " --"OPT_PROC_TYPE" Type of this process (primary|secondary|auto)\n" #ifndef RTE_EXEC_ENV_WINDOWS " --"OPT_SYSLOG"[=<when>] Enable use of syslog\n" +#endif +#ifdef RTE_EXEC_ENV_LINUX + " --"OPT_LOG_JOURNAL"[=<when>] Enable use of systemd journal\n"#endif " --" OPT_LOG_LEVEL "=<level> Set global log level\n" " --" OPT_LOG_LEVEL "=<type-match>:<level>\n"
lib/eal/common/eal_options.h +2 -0
@@ -35,6 +35,8 @@ enum {OPT_LCORES_NUM , #define OPT_LOG_LEVEL "log-level"OPT_LOG_LEVEL_NUM , +#define OPT_LOG_JOURNAL "log-journal" +OPT_LOG_JOURNAL_NUM , #define OPT_LOG_TIMESTAMP "log-timestamp"OPT_LOG_TIMESTAMP_NUM , #define OPT_TRACE "trace"
lib/log/log.c +3 -1
@@ -511,7 +511,9 @@ eal_log_init(const char *id) is_terminal =isatty (STDERR_FILENO );#endif -if (log_syslog_enabled (is_terminal)) +if (log_journal_enabled ()) +log_journal_open (id); +else if (log_syslog_enabled (is_terminal))log_syslog_open (id, is_terminal);else if (log_timestamp_enabled ()) rte_logs.print_func = log_print_with_timestamp;
lib/log/log_internal.h +3 -0
@@ -29,6 +29,9 @@ int eal_log_save_pattern(const char *pattern, uint32_t level);__rte_internal int eal_log_syslog(const char *name); +__rte_internal +int eal_log_journal(const char *opt); +/* * Convert log level to string. */
lib/log/log_journal.c new file +200 -0
200 lines not on this page · raw message
lib/log/log_private.h +16 -0
@@ -34,4 +34,20 @@ bool log_syslog_enabled(bool is_tty);void log_syslog_open (const char *id,bool is_terminal);#endif +#ifdef RTE_EXEC_ENV_LINUX +bool log_journal_enabled (void ); +void log_journal_open (const char *id); +#else +static inline bool +log_journal_enabled (void ) +{ +return false; +} + +static inline void +log_journal_open(const char *id __rte_unused) +{ +} +#endif /* !RTE_EXEC_ENV_LINUX */ +#endif /* LOG_PRIVATE_H */
lib/log/meson.build +4 -0
@@ -11,4 +11,8 @@ if not is_windows sources += files('log_syslog.c') endif +if is_linux + sources += files('log_journal.c') +endif + headers = files('rte_log.h')
lib/log/version.map +1 -0
@@ -26,6 +26,7 @@ INTERNAL { global: eal_log_init; + eal_log_journal; # WINDOWS_NO_EXPORT eal_log_level2str; eal_log_save_pattern; eal_log_save_regexp;
Signature · 1 line
2.45.2
PATCH v23 14/15 log: colorize log output
In reply to Stephen HemmingerLike dmesg, colorize the log output (unless redirected to file). Timestamp is green, the subsystem is in yellow and the message is red if urgent, boldface if an error, and normal for info and debug messages.
--- app/test/test_eal_flags.c | 24 +++++ doc/guides/prog_guide/log_lib.rst | 15 +++ lib/eal/common/eal_common_options.c | 11 +++ lib/eal/common/eal_options.h | 6 +- lib/log/log.c | 19 ++-- lib/log/log_color.c | 148 ++++++++++++++++++++++++++++ lib/log/log_internal.h | 5 + lib/log/log_private.h | 8 ++ lib/log/meson.build | 1 + lib/log/version.map | 1 + 10 files changed, 230 insertions(+), 8 deletions(-) create mode 100644 lib/log/log_color.c
app/test/test_eal_flags.c +24 -0
@@ -1067,6 +1067,18 @@ test_misc_flags(void)const char *const argv25[] = {prgname, prefix, mp_flag,"--log-timestamp=invalid" }; +/* Try running with --log-color */ +const char *const argv26[] = {prgname, prefix, mp_flag, +"--log-color" }; + +/* Try running with --log-color=never */ +const char *const argv27[] = {prgname, prefix, mp_flag, +"--log-color=never" }; + +/* Try running with --log-color=invalid */ +const char *const argv28[] = {prgname, prefix, mp_flag, +"--log-color=invalid" }; +/* run all tests also applicable to FreeBSD first */
@@ -1187,6 +1199,18 @@ test_misc_flags(void)printf ("Error - process did run ok with --log-timestamp=invalid parameter\n" ); goto fail; } +if (launch_proc (argv26) !=0 ) { +printf ("Error - process did not run ok with --log-color parameter\n" ); + goto fail; + } +if (launch_proc (argv27) !=0 ) { +printf ("Error - process did not run ok with --log-color=none parameter\n" ); + goto fail; + } +if (launch_proc (argv28) ==0 ) { +printf ("Error - process did run ok with --log-timestamp=invalid parameter\n" ); + goto fail; + }rmdir (hugepath_dir3);
doc/guides/prog_guide/log_lib.rst +15 -0
@@ -59,6 +59,21 @@ For example:: Within an application, the same result can be got using the ``rte_log_set_level_pattern()`` or ``rte_log_set_level_regex()`` APIs. +Color output +~~~~~~~~~~~~ + +The log library will highlight important messages. +This is controlled by the ``--log-color`` option. +he optional argument ``when`` can be ``auto``, ``never``, or ``always``. +The default setting is ``auto`` which enables color when the output to +``stderr`` is a terminal. +If the ``when`` argument is omitted, it defaults to ``always``. + +For example to turn off all coloring:: + + /path/to/app --log-color=none + + Log timestamp ~~~~~~~~~~~~~
lib/eal/common/eal_common_options.c +11 -0
@@ -73,6 +73,7 @@ eal_long_options[] = { {OPT_HUGE_UNLINK, 2, NULL, OPT_HUGE_UNLINK_NUM }, {OPT_IOVA_MODE, 1, NULL, OPT_IOVA_MODE_NUM }, {OPT_LCORES, 1, NULL, OPT_LCORES_NUM }, + {OPT_LOG_COLOR, 2, NULL, OPT_LOG_COLOR_NUM }, {OPT_LOG_LEVEL, 1, NULL, OPT_LOG_LEVEL_NUM }, {OPT_LOG_JOURNAL, 2, NULL, OPT_LOG_JOURNAL_NUM }, {OPT_LOG_TIMESTAMP, 2, NULL, OPT_LOG_TIMESTAMP_NUM },
@@ -1620,6 +1621,7 @@ eal_log_level_parse(int argc, char * const argv[])case OPT_SYSLOG_NUM :case OPT_LOG_JOURNAL_NUM :case OPT_LOG_TIMESTAMP_NUM : +case OPT_LOG_COLOR_NUM :if (eal_parse_common_option (opt, optarg, internal_conf) <0 )return -1 ;break ;
@@ -1874,6 +1876,14 @@ eal_parse_common_option(int opt, const char *optarg, }break ; +case OPT_LOG_COLOR_NUM : +if (eal_log_color (optarg) <0 ) { +EAL_LOG (ERR ,"invalid parameters for --" +OPT_LOG_COLOR ); +return -1 ; + } +break ; +#ifndef RTE_EXEC_ENV_WINDOWS case OPT_TRACE_NUM : {if (eal_trace_args_save (optarg) <0 ) {
@@ -2243,6 +2253,7 @@ eal_common_usage(void)" Set specific log level\n" " --" OPT_LOG_LEVEL "=help Show log types and levels\n" " --" OPT_LOG_TIMESTAMP "[=<format>] Timestamp log output\n" +" --" OPT_LOG_COLOR "[=<when>] Colorize log messages\n" #ifndef RTE_EXEC_ENV_WINDOWS" --" OPT_TRACE "=<regex-match>\n" " Enable trace based on regular expression trace name.\n"
lib/eal/common/eal_options.h +4 -2
@@ -33,10 +33,12 @@ enum {OPT_HUGE_UNLINK_NUM , #define OPT_LCORES "lcores"OPT_LCORES_NUM , -#define OPT_LOG_LEVEL "log-level" -OPT_LOG_LEVEL_NUM , +#define OPT_LOG_COLOR "log-color" +OPT_LOG_COLOR_NUM , #define OPT_LOG_JOURNAL "log-journal"OPT_LOG_JOURNAL_NUM , +#define OPT_LOG_LEVEL "log-level" +OPT_LOG_LEVEL_NUM , #define OPT_LOG_TIMESTAMP "log-timestamp"OPT_LOG_TIMESTAMP_NUM , #define OPT_TRACE "trace"
lib/log/log.c +13 -6
@@ -511,14 +511,21 @@ eal_log_init(const char *id) is_terminal =isatty (STDERR_FILENO );#endif -if (log_journal_enabled ()) +if (log_journal_enabled ()) {log_journal_open (id); -else if (log_syslog_enabled (is_terminal)) + }else if (log_syslog_enabled (is_terminal)) {log_syslog_open (id, is_terminal); -else if (log_timestamp_enabled ()) - rte_logs.print_func = log_print_with_timestamp; -else - rte_logs.print_func = vfprintf; + }else if (log_timestamp_enabled ()) { +if (log_color_enabled (is_terminal)) + rte_logs.print_func = color_print_with_timestamp; +else + rte_logs.print_func = log_print_with_timestamp; + }else { +if (log_color_enabled (is_terminal)) + rte_logs.print_func = color_print; +else + rte_logs.print_func = vfprintf; + }#if RTE_LOG_DP_LEVEL >=RTE_LOG_DEBUG RTE_LOG(NOTICE, EAL,
lib/log/log_color.c new file +148 -0
148 lines not on this page · raw message
lib/log/log_internal.h +5 -0
@@ -50,5 +50,10 @@ void rte_eal_log_cleanup(void);__rte_internal int eal_log_timestamp(const char *fmt); +/* +* Enable or disable color in log messages +*/ +__rte_internal +int eal_log_color(const char *mode);#endif /* LOG_INTERNAL_H */
lib/log/log_private.h +8 -0
@@ -50,4 +50,12 @@ log_journal_open(const char *id __rte_unused) }#endif /* !RTE_EXEC_ENV_LINUX */ +bool log_color_enabled (bool is_tty); + +__rte_format_printf(2, 0) +int color_print (FILE *f,const char *format,va_list ap); + +__rte_format_printf(2, 0) +int color_print_with_timestamp (FILE *f,const char *format,va_list ap); +#endif /* LOG_PRIVATE_H */
lib/log/meson.build +1 -0
@@ -4,6 +4,7 @@ includes += global_inc sources = files( 'log.c', + 'log_color.c', 'log_timestamp.c', )
lib/log/version.map +1 -0
@@ -25,6 +25,7 @@ DPDK_25 { INTERNAL { global: + eal_log_color; eal_log_init; eal_log_journal; # WINDOWS_NO_EXPORT eal_log_level2str;
Signature · 1 line
2.45.2
Re: [PATCH v23 14/15] log: colorize log output
Quoted 7 lines · Stephen Hemminger
Like dmesg, colorize the log output (unless redirected to file). Timestamp is green, the subsystem is in yellow and the message is red if urgent, boldface if an error, and normal for info and debug messages.
Signed-off-by Stephen Hemminger <[email protected]>Acked-by Morten Brørup <[email protected]>
PATCH v23 15/15 doc: add release note about log library
In reply to Stephen HemmingerSignificant enough to add some documentation.
--- doc/guides/rel_notes/release_24_11.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
doc/guides/rel_notes/release_24_11.rst +15 -0
@@ -55,6 +55,21 @@ New Features Also, make sure to start the actual text at the margin. ======================================================= +* **Enhancements to logging library.** + + * The log is initialized earlier in startup so all messages go through the library. + + * An option is added to timestamp log messages, which is useful for debugging delays in + application and driver startup. + + * Log messages are now in color if going to a terminal (similar to dmesg). + The default format shows timestamp in green, subsystem in yellow, + and the message is bold, boldface or normal depending on severity. + + * If the application is a systemd service and the log output is being + sent of standard error then DPDK will switch to journal native protocol. + + * On FreeBSD the log library can syslog the same as Linux. Removed Items -------------
Signature · 1 line
2.45.2
Re: [PATCH v23 15/15] doc: add release note about log library
Quoted 34 lines · Stephen Hemminger
Significant enough to add some documentation.
Signed-off-by Stephen Hemminger <[email protected]>Acked-by Morten Brørup <[email protected]>--- doc/guides/rel_notes/release_24_11.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+)doc/guides/rel_notes/release_24_11.rst +15
-0@@ -55,6 +55,21 @@ New Features Also, make sure to start the actual text at the margin. ======================================================= +* **Enhancements to logging library.** + + * The log is initialized earlier in startup so all messages go through the library. + + * An option is added to timestamp log messages, which is useful for debugging delays in + application and driver startup. + + * Log messages are now in color if going to a terminal (similar to dmesg). + The default format shows timestamp in green, subsystem in yellow, + and the message is bold, boldface or normal depending on severity. + + * If the application is a systemd service and the log output is being + sent of standard error then DPDK will switch to journal native protocol. + + * On FreeBSD the log library can syslog the same as Linux. Removed Items -------------
Re: [PATCH v23 00/15] Logging improvements
In reply to Stephen HemmingerQuoted 38 lines · Stephen Hemminger
Improvements and unification of logging library.
This version works on all platforms: Linux, Windows and FreeBSD.This is update to rework patch set. It adds several new features to the console log output.
* Putting a timestamp on console output which is useful for analyzing performance of startup codes. Timestamp is optional and must be enabled on command line.
* Displaying console output with colors.
It uses the standard conventions used by many other Linux commands for colorized display. The default is to enable color if the console output is going to a terminal. But it can be always on or disabled by command line flag. This default was chosen based on what dmesg(1) command does.Color is used by many tools (vi, iproute2, git) because it is helpful; DPDK drivers and libraries print lots of not very useful messages. And having error messages highlighted in bold face helps. This might also get users to pay more attention to error messages. Many bug reports have earlier messages that are lost because there are so many info messages.
* Add support for automatic detection of systemd journal protocol. If running as systemd service will get enhanced logging.
* Use of syslog is optional and the meaning of the --syslog flag has changed. The default is *not* to use syslog if output is going to a terminal.
Add myself as maintainer for log because by now have added more than previous authors.
v23 - simplify and fix Windows and FreeBSD builds; fix #ifdefs.
Change from defining stubs to using inline functions inlog_private.h.
Quoted 17 lines
Stephen Hemminger (15):
maintainers: add for log library
windows: make getopt functions have const properties
windows: add os shim forlocaltime_r
eal: makeeal_log_level_parsecommon
eal: do not duplicaterte_init_alert()messages
eal: changerte_exit()output to matchrte_log()
log: move handling of syslog facility out of eal
eal: initialize log before everything else
log: drop syslog support, and make code common
log: add hook for printing log messages
log: add timestamp option
log: add optional support of syslog
log: add support for systemd journal
log: colorize log output
doc: add release note about log library
Thanks for the cleanup.
v24 cover Logging enhancements for 24.11
In reply to Stephen HemmingerImprovements and unification of logging library.
This version works on all platforms: Linux, Windows and FreeBSD.
This is update to rework patch set. It adds several new features to the console log output.
* Putting a timestamp on console output which is useful for analyzing performance of startup codes. Timestamp is optional and must be enabled on command line.
* Displaying console output with colors.
It uses the standard conventions used by many other Linux commands for colorized display. The default is to enable color if the console output is going to a terminal. But it can be always on or disabled by command line flag. This default was chosen based on what dmesg(1) command does.
Color is used by many tools (vi, iproute2, git) because it is helpful; DPDK drivers and libraries print lots of not very useful messages. And having error messages highlighted in bold face helps. This might also get users to pay more attention to error messages. Many bug reports have earlier messages that are lost because there are so many info messages.
* Add support for automatic detection of systemd journal protocol. If running as systemd service will get enhanced logging.
* Use of syslog is optional and the meaning of the --syslog flag has changed. The default is *not* to use syslog if output is going to a terminal.
Add myself as maintainer for log because by now have added more than previous authors.
v24 - incorporate a couple of small review feedback items.
expand the release note.
Stephen Hemminger (15):
maintainers: add for log library
windows: make getopt functions have const properties
windows: add os shim for localtime_r
eal: make eal_log_level_parse common
eal: do not duplicate rte_init_alert() messages
eal: change rte_exit() output to match rte_log()
log: move handling of syslog facility out of eal
eal: initialize log before everything else
log: drop syslog support, and make code common
log: add hook for printing log messages
log: add timestamp option
log: add optional support of syslog
log: add support for systemd journal
log: colorize log output
doc: add release note about log library
MAINTAINERS | 1 + app/test/test_eal_flags.c | 64 +++++- doc/guides/linux_gsg/linux_eal_parameters.rst | 27 --- doc/guides/prog_guide/log_lib.rst | 72 ++++++ doc/guides/rel_notes/release_24_11.rst | 27 +++ lib/eal/common/eal_common_debug.c | 6 +- lib/eal/common/eal_common_options.c | 135 ++++++----- lib/eal/common/eal_options.h | 7 + lib/eal/freebsd/eal.c | 64 ++---- lib/eal/linux/eal.c | 68 ++---- lib/eal/windows/eal.c | 49 +--- lib/eal/windows/getopt.c | 23 +- lib/eal/windows/include/getopt.h | 8 +- lib/eal/windows/include/rte_os_shim.h | 10 + lib/log/log.c | 71 +++--- lib/log/log_color.c | 148 ++++++++++++ lib/log/log_freebsd.c | 12 - lib/log/log_internal.h | 28 ++- lib/log/log_journal.c | 200 +++++++++++++++++ lib/log/log_linux.c | 61 ----- lib/log/log_private.h | 61 +++++ lib/log/log_syslog.c | 88 ++++++++ lib/log/log_timestamp.c | 210 ++++++++++++++++++ lib/log/log_windows.c | 18 -- lib/log/meson.build | 12 +- lib/log/version.map | 5 +- 26 files changed, 1099 insertions(+), 376 deletions(-) create mode 100644 lib/log/log_color.c delete mode 100644 lib/log/log_freebsd.c create mode 100644 lib/log/log_journal.c delete mode 100644 lib/log/log_linux.c create mode 100644 lib/log/log_private.h create mode 100644 lib/log/log_syslog.c create mode 100644 lib/log/log_timestamp.c delete mode 100644 lib/log/log_windows.c
Signature · 1 line
2.45.2
PATCH v24 1/15 maintainers: add for log library
"You touch it you own it"
Add myself as maintainer for log library.
--- MAINTAINERS | 1 + 1 file changed, 1 insertion(+)
MAINTAINERS +1 -0
@@ -185,6 +185,7 @@ F: app/test/test_threads.c F: app/test/test_version.c Logging +M: Stephen Hemminger <[email protected]> F: lib/log/ F: doc/guides/prog_guide/log_lib.rst F: app/test/test_logs.c
Signature · 1 line
2.45.2
PATCH v24 2/15 windows: make getopt functions have const properties
In reply to Stephen HemmingerHaving different prototypes on different platforms can lead to lots of unnecessary workarounds. Looks like the version of getopt used from windows was based on an older out of date version from FreeBSD.
This patch changes getopt, getopt_long, etc to have the same const attributes as Linux and FreeBSD. The changes are derived from the current FreeBSD version of getopt_long.
--- lib/eal/windows/getopt.c | 23 ++++++++++++----------- lib/eal/windows/include/getopt.h | 8 ++++---- 2 files changed, 16 insertions(+), 15 deletions(-)
lib/eal/windows/getopt.c +12 -11
@@ -20,7 +20,7 @@#include <string.h> #include <stdlib.h> -const char *optarg;/* argument associated with option */ +char *optarg;/* argument associated with option */ int opterr =1 ;/* if error message should be printed */ int optind =1 ;/* index into parent argv vector */ int optopt ='?' ;/* character checked for validity */
@@ -39,9 +39,9 @@ static void pass(const char *a) {(void) a; }#define BADARG ((*options == ':') ? (int)':' : (int)'?')#define INORDER 1 -#define EMSG "" +static char EMSG [] ="" ; -static const char *place =EMSG ;/* option letter processing */ +static char *place =EMSG ;/* option letter processing */ /* XXX: set optreset to 1 rather than these two */ static int nonopt_start =-1 ;/* first non option argument (for permute) */
@@ -80,7 +80,7 @@ gcd(int a, int b)*/ static void permute_args (int panonopt_start,int panonopt_end,int opt_end, -char **nargv) +char *const *nargv) {int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;char *swap;
@@ -101,11 +101,12 @@ permute_args(int panonopt_start, int panonopt_end, int opt_end, pos -= nnonopts; else pos += nopts; + swap = nargv[pos];/* LINTED const cast */ - ((char **) nargv)[pos] = nargv[cstart]; + ((char **)(uintptr_t )nargv)[pos] = nargv[cstart];/* LINTED const cast */ - ((char **)nargv)[cstart] = swap; + ((char **)(uintptr_t )nargv)[cstart] = swap; } } }
@@ -116,7 +117,7 @@ permute_args(int panonopt_start, int panonopt_end, int opt_end,* Returns -1 if short_too is set and the option does not match long_options. */ static int -parse_long_options (char **nargv,const char *options, +parse_long_options (char *const *nargv,const char *options,const struct option *long_options,int *idx,int short_too) {const char *current_argv;
@@ -236,7 +237,7 @@ parse_long_options(char **nargv, const char *options,* Parse argc/argv argument vector. Called by user level routines. */ static int -getopt_internal (int nargc,char **nargv,const char *options, +getopt_internal (int nargc,char *const nargv[],const char *options,const struct option *long_options,int *idx,int flags) {char *oli;/* option letter list index */
@@ -434,7 +435,7 @@ getopt_internal(int nargc, char **nargv, const char *options,* Parse argc/argv argument vector. */ int -getopt (int nargc,char *nargv[],const char *options) +getopt (int nargc,char *const nargv[],const char *options) {return getopt_internal (nargc, nargv, options,NULL ,NULL ,FLAG_PERMUTE );
@@ -445,7 +446,7 @@ getopt(int nargc, char *nargv[], const char *options)* Parse argc/argv argument vector. */ int -getopt_long (int nargc,char *nargv[],const char *options, +getopt_long (int nargc,char *const nargv[],const char *options,const struct option *long_options,int *idx) {
@@ -458,7 +459,7 @@ getopt_long(int nargc, char *nargv[], const char *options,* Parse argc/argv argument vector. */ int -getopt_long_only (int nargc,char *nargv[],const char *options, +getopt_long_only (int nargc,char *const nargv[],const char *options,const struct option *long_options,int *idx) {
lib/eal/windows/include/getopt.h +4 -4
@@ -44,7 +44,7 @@/** argument to current option, or NULL if it has none */ -extern const char *optarg; +extern char *optarg;/** Current position in arg string. Starts from 1. * Setting to 0 resets state. */
@@ -80,14 +80,14 @@ struct option { };/** Compat: getopt */ -int getopt (int argc,char *argv[],const char *options); +int getopt (int argc,char *const argv[],const char *options);/** Compat: getopt_long */ -int getopt_long (int argc,char *argv[],const char *options, +int getopt_long (int argc,char *const argv[],const char *options,const struct option *longopts,int *longindex);/** Compat: getopt_long_only */ -int getopt_long_only (int nargc,char *argv[],const char *options, +int getopt_long_only (int nargc,char *const argv[],const char *options,const struct option *long_options,int *idx);
Signature · 1 line
2.45.2
PATCH v24 3/15 windows: add os shim for localtime_r
In reply to Stephen HemmingerWindows does not have localtime_r but it does have a similar function that can be used instead.
--- lib/eal/windows/include/rte_os_shim.h | 10 ++++++++++ 1 file changed, 10 insertions(+)
lib/eal/windows/include/rte_os_shim.h +10 -0
@@ -110,4 +110,14 @@ rte_clock_gettime(clockid_t clock_id, struct timespec *tp) }#define clock_gettime (clock_id, tp) rte_clock_gettime(clock_id, tp) +static inline struct tm * +rte_localtime_r (const time_t *timep,struct tm *result) +{ +if (localtime_s (result, timep) ==0 ) +return result; +else +return NULL ; +} +#define localtime_r (timep, result) rte_localtime_r(timep, result) +#endif /* _RTE_OS_SHIM_ */
Signature · 1 line
2.45.2
Re: [PATCH v24 03/15] windows: add os shim for localtime_r
Quoted 30 lines · Stephen Hemminger
Windows does not have
localtime_rbut it does have a similar function that can be used instead.Signed-off-by Stephen Hemminger <[email protected]>Acked-by Tyler Retzlaff <[email protected]>Acked-by Morten Brørup <[email protected]>Acked-by Bruce Richardson <[email protected]>--- lib/eal/windows/include/rte_os_shim.h | 10 ++++++++++ 1 file changed, 10 insertions(+)lib/eal/windows/include/rte_os_shim.h +10
-0@@ -110,4 +110,14 @@ rte_clock_gettime(clockid_t clock_id, struct timespec *tp) }#define clock_gettime (clock_id, tp) rte_clock_gettime(clock_id, tp) +static inline struct tm * +rte_localtime_r (const time_t *timep,struct tm *result) +{ +if (localtime_s (result, timep) ==0 ) +return result; +else +return NULL ; +} +#define localtime_r (timep, result) rte_localtime_r(timep, result) +#endif /* _RTE_OS_SHIM_ */
PATCH v24 4/15 eal: make eal_log_level_parse common
In reply to Stephen HemmingerThe code to parse for log-level option should be same on all OS variants.
--- lib/eal/common/eal_common_options.c | 40 +++++++++++++++++++++++++++ lib/eal/common/eal_options.h | 1 + lib/eal/freebsd/eal.c | 42 ----------------------------- lib/eal/linux/eal.c | 39 --------------------------- lib/eal/windows/eal.c | 35 ------------------------ 5 files changed, 41 insertions(+), 116 deletions(-)
lib/eal/common/eal_common_options.c +40 -0
@@ -1640,6 +1640,46 @@ eal_parse_huge_unlink(const char *arg, struct hugepage_file_discipline *out)return -1 ; } +/* Parse the all arguments looking for log related ones */ +int +eal_log_level_parse (int argc,char *const argv[]) +{ +struct internal_config *internal_conf =eal_get_internal_configuration (); +int option_index, opt; +const int old_optind = optind; +const int old_optopt = optopt; +const int old_opterr = opterr; +char *old_optarg = optarg; +#ifdef RTE_EXEC_ENV_FREEBSD +const int old_optreset = optreset; + optreset =1 ; +#endif + + optind =1 ; + opterr =0 ; + +while ((opt =getopt_long (argc, argv, eal_short_options, + eal_long_options, &option_index)) !=EOF ) { + +switch (opt) { +case OPT_LOG_LEVEL_NUM : +if (eal_parse_common_option (opt, optarg, internal_conf) <0 ) +return -1 ; +break ; + } + } + +/* restore getopt lib */ + optind = old_optind; + optopt = old_optopt; + optarg = old_optarg; + opterr = old_opterr; +#ifdef RTE_EXEC_ENV_FREEBSD + optreset = old_optreset; +#endif +return 0 ; +} +int eal_parse_common_option (int opt,const char *optarg,struct internal_config *conf)
lib/eal/common/eal_options.h +1 -0
@@ -96,6 +96,7 @@ enum {extern const char eal_short_options[];extern const struct option eal_long_options[]; +int eal_log_level_parse (int argc,char *const argv[]);int eal_parse_common_option (int opt,const char *argv,struct internal_config *conf);int eal_option_device_parse (void );
lib/eal/freebsd/eal.c +0 -42
48 lines not on this page · raw message
lib/eal/linux/eal.c +0 -39
@@ -546,45 +546,6 @@ eal_parse_vfio_vf_token(const char *vf_token)return -1 ; } -/* Parse the arguments for --log-level only */ -static void -eal_log_level_parse (int argc,char **argv) -{ -int opt; -char **argvopt; -int option_index; -const int old_optind = optind; -const int old_optopt = optopt; -char *const old_optarg = optarg; -struct internal_config *internal_conf = -eal_get_internal_configuration (); - - argvopt = argv; - optind =1 ; - -while ((opt =getopt_long (argc, argvopt, eal_short_options, - eal_long_options, &option_index)) !=EOF ) { - -int ret; - -/* getopt is not happy, stop right now */ -if (opt =='?' ) -break ; - - ret = (opt ==OPT_LOG_LEVEL_NUM ) ? -eal_parse_common_option (opt, optarg, internal_conf) :0 ; - -/* common parser is not happy */ -if (ret <0 ) -break ; - } - -/* restore getopt lib */ - optind = old_optind; - optopt = old_optopt; - optarg = old_optarg; -} -static int eal_parse_huge_worker_stack (const char *arg) {
lib/eal/windows/eal.c +0 -35
@@ -96,41 +96,6 @@ eal_usage(const char *prgname) } } -/* Parse the arguments for --log-level only */ -static void -eal_log_level_parse (int argc,char **argv) -{ -int opt; -char **argvopt; -int option_index; -struct internal_config *internal_conf = -eal_get_internal_configuration (); - - argvopt = argv; - -eal_reset_internal_config (internal_conf); - -while ((opt =getopt_long (argc, argvopt, eal_short_options, - eal_long_options, &option_index)) !=EOF ) { - -int ret; - -/* getopt is not happy, stop right now */ -if (opt =='?' ) -break ; - - ret = (opt ==OPT_LOG_LEVEL_NUM ) ? -eal_parse_common_option (opt, optarg, - internal_conf) :0 ; - -/* common parser is not happy */ -if (ret <0 ) -break ; - } - - optind =0 ;/* reset getopt lib */ -} -/* Parse the argument given in the command line of the application */ static int eal_parse_args (int argc,char **argv)
Signature · 1 line
2.45.2
PATCH v24 5/15 eal: do not duplicate rte_init_alert() messages
In reply to Stephen HemmingerThe message already goes through logging, and does not need to be printed on stderr. Message level should be ALERT to match function name.
--- lib/eal/freebsd/eal.c | 3 +-- lib/eal/linux/eal.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-)
lib/eal/freebsd/eal.c +1 -2
@@ -529,8 +529,7 @@ rte_eal_iopl_init(void)static void rte_eal_init_alert (const char *msg) { -fprintf (stderr,"EAL: FATAL: %s\n" , msg); -EAL_LOG (ERR ,"%s" , msg); +EAL_LOG (ALERT ,"%s" , msg); }/* Launch threads, called at application init(). */
lib/eal/linux/eal.c +1 -2
@@ -840,8 +840,7 @@ static int rte_eal_vfio_setup(void)static void rte_eal_init_alert (const char *msg) { -fprintf (stderr,"EAL: FATAL: %s\n" , msg); -EAL_LOG (ERR ,"%s" , msg); +EAL_LOG (ALERT ,"%s" , msg); }/*
Signature · 1 line
2.45.2
PATCH v24 6/15 eal: change rte_exit() output to match rte_log()
In reply to Stephen HemmingerThe rte_exit() output format confuses the timestamp and coloring options. Change it to use be a single line with proper prefix.
Before:
[ 0.006481] EAL: Error - exiting with code: 1 Cause: [ 0.006489] Cannot init EAL: Permission denied
After:
[ 0.006238] EAL: Error - exiting with code: 1 [ 0.006250] EAL: Cannot init EAL: Permission denied
--- lib/eal/common/eal_common_debug.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
lib/eal/common/eal_common_debug.c +2 -4
@@ -36,15 +36,13 @@ rte_exit(int exit_code, const char *format, ...)va_list ap;if (exit_code !=0 ) -RTE_LOG (CRIT ,EAL ,"Error - exiting with code: %d\n" -" Cause: " , exit_code); +EAL_LOG (CRIT ,"Error - exiting with code: %d" , exit_code);va_start (ap, format);rte_vlog (RTE_LOG_CRIT ,RTE_LOGTYPE_EAL , format, ap);va_end (ap);if (rte_eal_cleanup () !=0 && rte_errno !=EALREADY ) -EAL_LOG (CRIT , -"EAL could not release all resources" ); +EAL_LOG (CRIT ,"EAL could not release all resources" );exit (exit_code); }
Signature · 1 line
2.45.2
Re: [PATCH v24 06/15] eal: change rte_exit() output to match rte_log()
Quoted 41 lines · Stephen Hemminger
The
rte_exit()output format confuses the timestamp and coloring options. Change it to use be a single line with proper prefix.Before:
[ 0.006481] EAL: Error - exiting with code: 1 Cause: [ 0.006489] Cannot init EAL: Permission deniedAfter:
[ 0.006238] EAL: Error - exiting with code: 1 [ 0.006250] EAL: Cannot init EAL: Permission deniedSigned-off-by Stephen Hemminger <[email protected]>Acked-by Tyler Retzlaff <[email protected]>Acked-by Morten Brørup <[email protected]>Acked-by Bruce Richardson <[email protected]>--- lib/eal/common/eal_common_debug.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)lib/eal/common/eal_common_debug.c +2
-4@@ -36,15 +36,13 @@ rte_exit(int exit_code, const char *format, ...)va_list ap;if (exit_code !=0 ) -RTE_LOG (CRIT ,EAL ,"Error - exiting with code: %d\n" -" Cause: " , exit_code); +EAL_LOG (CRIT ,"Error - exiting with code: %d" , exit_code);va_start (ap, format);rte_vlog (RTE_LOG_CRIT ,RTE_LOGTYPE_EAL , format, ap);va_end (ap);if (rte_eal_cleanup () !=0 && rte_errno !=EALREADY ) -EAL_LOG (CRIT , -"EAL could not release all resources" ); +EAL_LOG (CRIT ,"EAL could not release all resources" );exit (exit_code); }
PATCH v24 7/15 log: move handling of syslog facility out of eal
In reply to Stephen HemmingerThe syslog facility property is better handled in lib/log rather than in eal. This also allows for changes to what syslog flag means in later steps.
--- lib/eal/common/eal_common_options.c | 51 ++--------------------------- lib/eal/freebsd/eal.c | 5 ++- lib/eal/linux/eal.c | 7 ++-- lib/eal/windows/eal.c | 6 ++-- lib/log/log.c | 2 ++ lib/log/log_freebsd.c | 2 +- lib/log/log_internal.h | 5 ++- lib/log/log_linux.c | 47 ++++++++++++++++++++++++-- lib/log/log_windows.c | 8 ++++- lib/log/version.map | 1 + 10 files changed, 70 insertions(+), 64 deletions(-)
lib/eal/common/eal_common_options.c +2 -49
@@ -6,9 +6,6 @@#include <stdlib.h> #include <string.h> #include <pthread.h> -#ifndef RTE_EXEC_ENV_WINDOWS -#include <syslog.h> -#endif #include <ctype.h> #include <limits.h> #include <errno.h>
@@ -349,10 +346,6 @@ eal_reset_internal_config(struct internal_config *internal_cfg) } internal_cfg->base_virtaddr =0 ; -#ifdef LOG_DAEMON - internal_cfg->syslog_facility =LOG_DAEMON ; -#endif -/* if set to NONE, interrupt mode is determined automatically */ internal_cfg->vfio_intr_mode =RTE_INTR_MODE_NONE ; memset(internal_cfg->vfio_vf_token, 0,
@@ -1297,47 +1290,6 @@ eal_parse_lcores(const char *lcores)return ret; } -#ifndef RTE_EXEC_ENV_WINDOWS -static int -eal_parse_syslog (const char *facility,struct internal_config *conf) -{ -int i; -static const struct { -const char *name; -int value; - } map[] = { - {"auth" ,LOG_AUTH }, - {"cron" ,LOG_CRON }, - {"daemon" ,LOG_DAEMON }, - {"ftp" ,LOG_FTP }, - {"kern" ,LOG_KERN }, - {"lpr" ,LOG_LPR }, - {"mail" ,LOG_MAIL }, - {"news" ,LOG_NEWS }, - {"syslog" ,LOG_SYSLOG }, - {"user" ,LOG_USER }, - {"uucp" ,LOG_UUCP }, - {"local0" ,LOG_LOCAL0 }, - {"local1" ,LOG_LOCAL1 }, - {"local2" ,LOG_LOCAL2 }, - {"local3" ,LOG_LOCAL3 }, - {"local4" ,LOG_LOCAL4 }, - {"local5" ,LOG_LOCAL5 }, - {"local6" ,LOG_LOCAL6 }, - {"local7" ,LOG_LOCAL7 }, - {NULL ,0 } - }; - -for (i =0 ; map[i].name; i++) { -if (!strcmp (facility, map[i].name)) { - conf->syslog_facility = map[i].value; -return 0 ; - } - } -return -1 ; -} -#endif -static void eal_log_usage (void ) {
@@ -1663,6 +1615,7 @@ eal_log_level_parse(int argc, char * const argv[])switch (opt) {case OPT_LOG_LEVEL_NUM : +case OPT_SYSLOG_NUM :if (eal_parse_common_option (opt, optarg, internal_conf) <0 )return -1 ;break ;
@@ -1877,7 +1830,7 @@ eal_parse_common_option(int opt, const char *optarg,#ifndef RTE_EXEC_ENV_WINDOWS case OPT_SYSLOG_NUM : -if (eal_parse_syslog (optarg, conf) <0 ) { +if (eal_log_syslog (optarg) <0 ) {EAL_LOG (ERR ,"invalid parameters for --" OPT_SYSLOG );return -1 ;
lib/eal/freebsd/eal.c +2 -3
@@ -11,7 +11,6 @@#include <stdarg.h> #include <unistd.h> #include <pthread.h> -#include <syslog.h> #include <getopt.h> #include <sys/file.h> #include <stddef.h>
@@ -392,8 +391,8 @@ eal_parse_args(int argc, char **argv) goto out; } -/* eal_log_level_parse() already handled this option */ -if (opt ==OPT_LOG_LEVEL_NUM ) +/* eal_log_level_parse() already handled these */ +if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_LOG_SYSLOG_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
lib/eal/linux/eal.c +3 -4
@@ -610,8 +610,8 @@ eal_parse_args(int argc, char **argv) goto out; } -/* eal_log_level_parse() already handled this option */ -if (opt ==OPT_LOG_LEVEL_NUM ) +/* eal_log_level_parse() already handled these options */ +if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_SYSLOG_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
@@ -1113,8 +1113,7 @@ rte_eal_init(int argc, char **argv)#endif } -if (eal_log_init (program_invocation_short_name, - internal_conf->syslog_facility) <0 ) { +if (eal_log_init (program_invocation_short_name) <0 ) {rte_eal_init_alert ("Cannot init logging." ); rte_errno =ENOMEM ;rte_atomic_store_explicit (&run_once,0 , rte_memory_order_relaxed);
lib/eal/windows/eal.c +3 -3
@@ -120,8 +120,8 @@ eal_parse_args(int argc, char **argv)return -1 ; } -/* eal_log_level_parse() already handled this option */ -if (opt ==OPT_LOG_LEVEL_NUM ) +/* eal_log_level_parse() already handled these options */ +if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_SYSLOG_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
@@ -250,7 +250,7 @@ rte_eal_init(int argc, char **argv)char cpuset[RTE_CPU_AFFINITY_STR_LEN ];char thread_name[RTE_THREAD_NAME_SIZE ]; -eal_log_init (NULL ,0 ); +eal_log_init (NULL );eal_log_level_parse (argc, argv);
lib/log/log.c +2 -0
@@ -2,6 +2,7 @@* Copyright(c) 2010-2014 Intel Corporation */ +#include <stdbool.h> #include <stdio.h> #include <stdint.h> #include <stdarg.h>
@@ -12,6 +13,7 @@#include <fnmatch.h> #include <sys/queue.h> +#include <rte_common.h> #include <rte_log.h> #include <rte_per_lcore.h>
lib/log/log_freebsd.c +1 -1
@@ -6,7 +6,7 @@#include "log_internal.h" int -eal_log_init(__rte_unused const char *id, __rte_unused int facility) +eal_log_init(__rte_unused const char *id) {return 0 ; }
lib/log/log_internal.h +4 -1
@@ -14,7 +14,7 @@* Initialize the default log stream. */ __rte_internal -int eal_log_init(const char *id, int facility); +int eal_log_init(const char *id);/* * Determine where log data is written when no call to rte_openlog_stream.
@@ -30,6 +30,9 @@ int eal_log_save_regexp(const char *regexp, uint32_t level);__rte_internal int eal_log_save_pattern(const char *pattern, uint32_t level); +__rte_internal +int eal_log_syslog(const char *name); +/* * Convert log level to string. */
lib/log/log_linux.c +45 -2
72 lines not on this page · raw message
lib/log/log_windows.c +7 -1
@@ -6,9 +6,15 @@#include <rte_log.h> #include "log_internal.h" +int +eal_log_syslog(const char *name __rte_unused) +{ +return -1 ;/* not used */ +} +/* set the log to default function, called during eal init process. */ int -eal_log_init(__rte_unused const char *id, __rte_unused int facility) +eal_log_init(__rte_unused const char *id) {rte_openlog_stream (stderr);
lib/log/version.map +1 -0
@@ -30,5 +30,6 @@ INTERNAL { eal_log_save_pattern; eal_log_save_regexp; eal_log_set_default; + eal_log_syslog; rte_eal_log_cleanup; };
Signature · 1 line
2.45.2
PATCH v24 8/15 eal: initialize log before everything else
In reply to Stephen HemmingerIn order for all log messages (including CPU mismatch) to come out through the logging library, it must be initialized as early in rte_eal_init() as possible on all platforms.
Where it was done before was likely historical based on the support of non-OS isolated CPU's which required a shared memory buffer; that support was dropped before DPDK was publicly released.
--- lib/eal/freebsd/eal.c | 12 +++++++++--- lib/eal/linux/eal.c | 19 +++++++++---------- lib/eal/windows/eal.c | 8 ++++++-- lib/log/log_freebsd.c | 3 +-- lib/log/log_internal.h | 2 +- lib/log/log_linux.c | 14 ++++++-------- lib/log/log_windows.c | 4 +--- 7 files changed, 33 insertions(+), 29 deletions(-)
lib/eal/freebsd/eal.c +9 -3
@@ -52,6 +52,7 @@#include "eal_options.h" #include "eal_memcfg.h" #include "eal_trace.h" +#include "log_internal.h" #define MEMSIZE_IF_NO_HUGE_PAGE (64ULL * 1024ULL * 1024ULL)
@@ -546,6 +547,14 @@ rte_eal_init(int argc, char **argv)bool has_phys_addr;enum rte_iova_mode iova_mode; +/* setup log as early as possible */ +if (eal_log_level_parse (argc, argv) <0 ) { +rte_eal_init_alert ("invalid log arguments." ); + rte_errno =EINVAL ; +return -1 ; + } +eal_log_init (getprogname ()); +/* checks if the machine is adequate */ if (!rte_cpu_is_supported ()) {rte_eal_init_alert ("unsupported cpu type." );
@@ -572,9 +581,6 @@ rte_eal_init(int argc, char **argv)/* clone argv to report out later in telemetry */ eal_save_args (argc, argv); -/* set log level as early as possible */ -eal_log_level_parse (argc, argv); -if (rte_eal_cpu_init () <0 ) {rte_eal_init_alert ("Cannot detect lcores." ); rte_errno =ENOTSUP ;
lib/eal/linux/eal.c +9 -10
@@ -936,6 +936,15 @@ rte_eal_init(int argc, char **argv)struct internal_config *internal_conf =eal_get_internal_configuration (); +/* setup log as early as possible */ +if (eal_log_level_parse (argc, argv) <0 ) { +rte_eal_init_alert ("invalid log arguments." ); + rte_errno =EINVAL ; +return -1 ; + } + +eal_log_init (program_invocation_short_name); +/* checks if the machine is adequate */ if (!rte_cpu_is_supported ()) {rte_eal_init_alert ("unsupported cpu type." );
@@ -959,9 +968,6 @@ rte_eal_init(int argc, char **argv)eal_reset_internal_config (internal_conf); -/* set log level as early as possible */ -eal_log_level_parse (argc, argv); -/* clone argv to report out later in telemetry */ eal_save_args (argc, argv);
@@ -1113,13 +1119,6 @@ rte_eal_init(int argc, char **argv)#endif } -if (eal_log_init (program_invocation_short_name) <0 ) { -rte_eal_init_alert ("Cannot init logging." ); - rte_errno =ENOMEM ; -rte_atomic_store_explicit (&run_once,0 , rte_memory_order_relaxed); -return -1 ; - } -#ifdef VFIO_PRESENT if (rte_eal_vfio_setup () <0 ) {rte_eal_init_alert ("Cannot init VFIO" );
lib/eal/windows/eal.c +6 -2
@@ -250,9 +250,13 @@ rte_eal_init(int argc, char **argv)char cpuset[RTE_CPU_AFFINITY_STR_LEN ];char thread_name[RTE_THREAD_NAME_SIZE ]; -eal_log_init (NULL ); +if (eal_log_level_parse (argc, argv) <0 ) { +rte_eal_init_alert ("invalid log arguments." ); + rte_errno =EINVAL ; +return -1 ; + } -eal_log_level_parse (argc, argv); +eal_log_init (NULL );if (eal_create_cpu_map () <0 ) {rte_eal_init_alert ("Cannot discover CPU and NUMA." );
lib/log/log_freebsd.c +1 -2
@@ -5,8 +5,7 @@#include <rte_common.h> #include "log_internal.h" -int +void eal_log_init(__rte_unused const char *id) { -return 0 ; }
lib/log/log_internal.h +1 -1
@@ -14,7 +14,7 @@* Initialize the default log stream. */ __rte_internal -int eal_log_init(const char *id); +void eal_log_init(const char *id);/* * Determine where log data is written when no call to rte_openlog_stream.
lib/log/log_linux.c +6 -8
@@ -87,18 +87,16 @@ static cookie_io_functions_t console_log_func = {* set the log to default function, called during eal init process, * once memzones are available. */ -int +void eal_log_init (const char *id) {FILE *log_stream; - log_stream =fopencookie (NULL ,"w+" , console_log_func); -if (log_stream ==NULL ) -return -1 ; -openlog (id,LOG_NDELAY |LOG_PID , log_facility); -eal_log_set_default (log_stream); - -return 0 ; + log_stream =fopencookie (NULL ,"w+" , console_log_func); +if (log_stream !=NULL ) +eal_log_set_default (log_stream); +else +eal_log_set_default (stderr); }
lib/log/log_windows.c +1 -3
@@ -13,12 +13,10 @@ eal_log_syslog(const char *name __rte_unused) }/* set the log to default function, called during eal init process. */ -int +void eal_log_init(__rte_unused const char *id) {rte_openlog_stream (stderr);eal_log_set_default (stderr); - -return 0 ; }
Signature · 1 line
2.45.2
PATCH v24 9/15 log: drop syslog support, and make code common
In reply to Stephen HemmingerThis patch makes the log setup code common across all platforms.
Drops syslog support for now, will come back in later patch.
--- app/test/test_eal_flags.c | 11 ++- lib/eal/common/eal_common_options.c | 3 - lib/log/log.c | 41 +++++------ lib/log/log_freebsd.c | 11 --- lib/log/log_internal.h | 6 -- lib/log/log_linux.c | 102 ---------------------------- lib/log/log_windows.c | 22 ------ lib/log/meson.build | 5 +- lib/log/version.map | 1 - 9 files changed, 23 insertions(+), 179 deletions(-) delete mode 100644 lib/log/log_freebsd.c delete mode 100644 lib/log/log_linux.c delete mode 100644 lib/log/log_windows.c
app/test/test_eal_flags.c +5 -6
@@ -984,11 +984,10 @@ test_misc_flags(void)const char *argv1[] = {prgname, prefix, mp_flag,"--no-pci" };/* With -v */ const char *argv2[] = {prgname, prefix, mp_flag,"-v" }; +/* With empty --syslog */ +const char *argv3[] = {prgname, prefix, mp_flag,"--syslog" };/* With valid --syslog */ -const char *argv3[] = {prgname, prefix, mp_flag, -"--syslog" ,"syslog" }; -/* With empty --syslog (should fail) */ -const char *argv4[] = {prgname, prefix, mp_flag,"--syslog" }; +const char *argv4[] = {prgname, prefix, mp_flag,"--syslog" ,"always" };/* With invalid --syslog */ const char *argv5[] = {prgname, prefix, mp_flag,"--syslog" ,"error" };/* With no-sh-conf, also use no-huge to ensure this test runs on BSD */
@@ -1083,8 +1082,8 @@ test_misc_flags(void)printf ("Error - process did not run ok with --syslog flag\n" ); goto fail; } -if (launch_proc (argv4) ==0 ) { -printf ("Error - process run ok with empty --syslog flag\n" ); +if (launch_proc (argv4) !=0 ) { +printf ("Error - process did not with --syslog always flag\n" ); goto fail; }if (launch_proc (argv5) ==0 ) {
lib/eal/common/eal_common_options.c +0 -3
@@ -2206,9 +2206,6 @@ eal_common_usage(void)" (can be used multiple times)\n" " --" OPT_VMWARE_TSC_MAP " Use VMware TSC map instead of native RDTSC\n" " --" OPT_PROC_TYPE " Type of this process (primary|secondary|auto)\n" -#ifndef RTE_EXEC_ENV_WINDOWS -" --" OPT_SYSLOG " Set syslog facility\n" -#endif" --" OPT_LOG_LEVEL "=<level> Set global log level\n" " --" OPT_LOG_LEVEL "=<type-match>:<level>\n" " Set specific log level\n"
lib/log/log.c +17 -24
73 lines not on this page · raw message
lib/log/log_freebsd.c deleted +0 -11
@@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause -* Copyright(c) 2023 Intel Corporation -*/ - -#include <rte_common.h> -#include "log_internal.h" - -void -eal_log_init(__rte_unused const char *id) -{ -}
lib/log/log_internal.h +0 -6
@@ -16,12 +16,6 @@__rte_internal void eal_log_init(const char *id); -/* -* Determine where log data is written when no call to rte_openlog_stream. -*/ -__rte_internal -void eal_log_set_default(FILE *default_log); -/* * Save a log option for later. */
lib/log/log_linux.c deleted +0 -102
102 lines not on this page · raw message
lib/log/log_windows.c deleted +0 -22
@@ -1,22 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause -* Copyright(c) 2017-2018 Intel Corporation -*/ - -#include <rte_common.h> -#include <rte_log.h> -#include "log_internal.h" - -int -eal_log_syslog(const char *name __rte_unused) -{ -return -1 ;/* not used */ -} - -/* set the log to default function, called during eal init process. */ -void -eal_log_init(__rte_unused const char *id) -{ -rte_openlog_stream (stderr); - -eal_log_set_default (stderr); -}
lib/log/meson.build +1 -4
@@ -2,8 +2,5 @@ # Copyright(c) 2023 Intel Corporation includes += global_inc -sources = files( - 'log.c', - 'log_' + exec_env + '.c', -) +sources = files('log.c') headers = files('rte_log.h')
lib/log/version.map +0 -1
@@ -29,7 +29,6 @@ INTERNAL { eal_log_level2str; eal_log_save_pattern; eal_log_save_regexp; - eal_log_set_default; eal_log_syslog; rte_eal_log_cleanup; };
Signature · 1 line
2.45.2
PATCH v24 10/15 log: add hook for printing log messages
In reply to Stephen HemmingerThis is useful for when decorating log output for console or journal. Provide basic version in this patch.
--- lib/log/log.c | 6 +++++- lib/log/log_private.h | 9 +++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 lib/log/log_private.h
lib/log/log.c +5 -1
@@ -18,6 +18,7 @@#include <rte_per_lcore.h> #include "log_internal.h" +#include "log_private.h" #ifdef RTE_EXEC_ENV_WINDOWS #define strdup _strdup
@@ -33,11 +34,13 @@ static struct rte_logs {uint32_t type;/**< Bitfield with enabled logs. */ uint32_t level;/**< Log level. */ FILE *file;/**< Output file set by rte_openlog_stream, or NULL. */ +log_print_t print_func;size_t dynamic_types_len;struct rte_log_dynamic_type *dynamic_types; } rte_logs = { .type = UINT32_MAX, .level = RTE_LOG_DEBUG, + .print_func = vfprintf, };struct rte_eal_opt_loglevel {
@@ -74,6 +77,7 @@ int rte_openlog_stream(FILE *f) { rte_logs.file = f; + rte_logs.print_func = vfprintf;return 0 ; }
@@ -470,7 +474,7 @@ rte_vlog(uint32_t level, uint32_t logtype, const char *format, va_list ap)RTE_PER_LCORE (log_cur_msg).loglevel = level;RTE_PER_LCORE (log_cur_msg).logtype = logtype; - ret =vfprintf (f, format, ap); + ret = (*rte_logs.print_func)(f, format, ap);fflush (f);return ret; }
lib/log/log_private.h new file +9 -0
@@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#ifndef LOG_PRIVATE_H +#define LOG_PRIVATE_H + +/* Note: same as vfprintf() */ +typedef int (*log_print_t )(FILE *f,const char *fmt,va_list ap); + +#endif /* LOG_PRIVATE_H */
Signature · 1 line
2.45.2
PATCH v24 11/15 log: add timestamp option
In reply to Stephen HemmingerWhen debugging driver or startup issues, it is useful to have a timestamp on each message printed. The messages in syslog already have a timestamp, but often syslog is not available during testing.
There are multiple timestamp formats similar to Linux dmesg. The default is time relative since startup (when first step of logging initialization is done by constructor). Other alternative formats are delta, ctime, reltime and iso formats.
Example:
$ dpdk-testpmd --log-timestamp -- -i [ 0.008610] EAL: Detected CPU lcores: 8 [ 0.008634] EAL: Detected NUMA nodes: 1 [ 0.008792] EAL: Detected static linkage of DPDK [ 0.010620] EAL: Multi-process socket /var/run/dpdk/rte/mp_socket [ 0.012618] EAL: Selected IOVA mode 'VA' [ 0.016675] testpmd: No probed ethernet devices Interactive-mode selected
--- app/test/test_eal_flags.c | 26 ++++ doc/guides/prog_guide/log_lib.rst | 26 ++++ lib/eal/common/eal_common_options.c | 14 +- lib/eal/common/eal_options.h | 2 + lib/eal/freebsd/eal.c | 6 +- lib/eal/linux/eal.c | 4 +- lib/eal/windows/eal.c | 4 +- lib/log/log.c | 7 +- lib/log/log_internal.h | 9 ++ lib/log/log_private.h | 11 ++ lib/log/log_timestamp.c | 210 ++++++++++++++++++++++++++++ lib/log/meson.build | 6 +- lib/log/version.map | 1 + 13 files changed, 318 insertions(+), 8 deletions(-) create mode 100644 lib/log/log_timestamp.c
app/test/test_eal_flags.c +26 -0
@@ -1054,6 +1054,19 @@ test_misc_flags(void)const char *const argv22[] = {prgname, prefix, mp_flag,"--huge-worker-stack=512" }; +/* Try running with --log-timestamp */ +const char *const argv23[] = {prgname, prefix, mp_flag, +"--log-timestamp" }; + +/* Try running with --log-timestamp=iso */ +const char *const argv24[] = {prgname, prefix, mp_flag, +"--log-timestamp=iso" }; + +/* Try running with invalid timestamp */ +const char *const argv25[] = {prgname, prefix, mp_flag, +"--log-timestamp=invalid" }; + +/* run all tests also applicable to FreeBSD first */ if (launch_proc (argv0) ==0 ) {
@@ -1161,6 +1174,19 @@ test_misc_flags(void)printf ("Error - process did not run ok with --huge-worker-stack=size parameter\n" ); goto fail; } +if (launch_proc (argv23) !=0 ) { +printf ("Error - process did not run ok with --log-timestamp parameter\n" ); + goto fail; + } +if (launch_proc (argv24) !=0 ) { +printf ("Error - process did not run ok with --log-timestamp=iso parameter\n" ); + goto fail; + } +if (launch_proc (argv25) ==0 ) { +printf ("Error - process did run ok with --log-timestamp=invalid parameter\n" ); + goto fail; + } +rmdir (hugepath_dir3);rmdir (hugepath_dir2);
doc/guides/prog_guide/log_lib.rst +26 -0
@@ -59,6 +59,32 @@ For example:: Within an application, the same result can be got using the ``rte_log_set_level_pattern()`` or ``rte_log_set_level_regex()`` APIs. +Log timestamp +~~~~~~~~~~~~~ + +An optional timestamp can be added before each message +by adding the ``--log-timestamp`` option. +For example:: + + /path/to/app --log-level=lib.*:debug --log-timestamp + +Multiple timestamp alternative timestamp formats are available: + +.. csv-table:: Log time stamp format + :header: "Format", "Description", "Example" + :widths: 6, 30, 32 + + "ctime", "Unix ctime", "``[Wed Mar 20 07:26:12 2024]``" + "delta", "Offset since last", "``[< 3.162373>]``" + "reltime", "Seconds since last or time if minute changed", "``[ +3.001791]`` or ``[Mar20 07:26:12]``" + "iso", "ISO-8601", "``[2024-03-20T07:26:12−07:00]``" + +To prefix all console messages with ISO format time the syntax is:: + + /path/to/app --log-timestamp=iso + + + Using Logging APIs to Generate Log Messages -------------------------------------------
lib/eal/common/eal_common_options.c +12 -2
@@ -74,6 +74,7 @@ eal_long_options[] = { {OPT_IOVA_MODE, 1, NULL, OPT_IOVA_MODE_NUM }, {OPT_LCORES, 1, NULL, OPT_LCORES_NUM }, {OPT_LOG_LEVEL, 1, NULL, OPT_LOG_LEVEL_NUM }, + {OPT_LOG_TIMESTAMP, 2, NULL, OPT_LOG_TIMESTAMP_NUM }, {OPT_TRACE, 1, NULL, OPT_TRACE_NUM }, {OPT_TRACE_DIR, 1, NULL, OPT_TRACE_DIR_NUM }, {OPT_TRACE_BUF_SIZE, 1, NULL, OPT_TRACE_BUF_SIZE_NUM },
@@ -1616,6 +1617,7 @@ eal_log_level_parse(int argc, char * const argv[])switch (opt) {case OPT_LOG_LEVEL_NUM :case OPT_SYSLOG_NUM : +case OPT_LOG_TIMESTAMP_NUM :if (eal_parse_common_option (opt, optarg, internal_conf) <0 )return -1 ;break ;
@@ -1838,7 +1840,7 @@ eal_parse_common_option(int opt, const char *optarg,break ;#endif -case OPT_LOG_LEVEL_NUM : { +case OPT_LOG_LEVEL_NUM :if (eal_parse_log_level (optarg) <0 ) {EAL_LOG (ERR , "invalid parameters for --"
@@ -1846,7 +1848,14 @@ eal_parse_common_option(int opt, const char *optarg,return -1 ; }break ; - } + +case OPT_LOG_TIMESTAMP_NUM : +if (eal_log_timestamp (optarg) <0 ) { +EAL_LOG (ERR ,"invalid parameters for --" +OPT_LOG_TIMESTAMP ); +return -1 ; + } +break ;#ifndef RTE_EXEC_ENV_WINDOWS case OPT_TRACE_NUM : {
@@ -2210,6 +2219,7 @@ eal_common_usage(void)" --" OPT_LOG_LEVEL "=<type-match>:<level>\n" " Set specific log level\n" " --" OPT_LOG_LEVEL "=help Show log types and levels\n" +" --" OPT_LOG_TIMESTAMP "[=<format>] Timestamp log output\n" #ifndef RTE_EXEC_ENV_WINDOWS" --" OPT_TRACE "=<regex-match>\n" " Enable trace based on regular expression trace name.\n"
lib/eal/common/eal_options.h +2 -0
@@ -35,6 +35,8 @@ enum {OPT_LCORES_NUM , #define OPT_LOG_LEVEL "log-level"OPT_LOG_LEVEL_NUM , +#define OPT_LOG_TIMESTAMP "log-timestamp" +OPT_LOG_TIMESTAMP_NUM , #define OPT_TRACE "trace"OPT_TRACE_NUM , #define OPT_TRACE_DIR "trace-dir"
lib/eal/freebsd/eal.c +4 -2
@@ -392,8 +392,10 @@ eal_parse_args(int argc, char **argv) goto out; } -/* eal_log_level_parse() already handled these */ -if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_LOG_SYSLOG_NUM ) +/* eal_log_level_parse() already handled these options */ +if (opt ==OPT_LOG_LEVEL_NUM || + opt ==OPT_SYSLOG_NUM || + opt ==OPT_LOG_TIMESTAMP_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
lib/eal/linux/eal.c +3 -1
@@ -611,7 +611,9 @@ eal_parse_args(int argc, char **argv) }/* eal_log_level_parse() already handled these options */ -if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_SYSLOG_NUM ) +if (opt ==OPT_LOG_LEVEL_NUM || + opt ==OPT_SYSLOG_NUM || + opt ==OPT_LOG_TIMESTAMP_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
lib/eal/windows/eal.c +3 -1
@@ -121,7 +121,9 @@ eal_parse_args(int argc, char **argv) }/* eal_log_level_parse() already handled these options */ -if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_SYSLOG_NUM ) +if (opt ==OPT_LOG_LEVEL_NUM || + opt ==OPT_SYSLOG_NUM || + opt ==OPT_LOG_TIMESTAMP_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
lib/log/log.c +6 -1
@@ -21,7 +21,7 @@#include "log_private.h" #ifdef RTE_EXEC_ENV_WINDOWS -#define strdup _strdup +#include <rte_os_shim.h> #endif struct rte_log_dynamic_type {
@@ -509,6 +509,11 @@ eal_log_syslog(const char *mode __rte_unused)void eal_log_init(const char *id __rte_unused) { +if (log_timestamp_enabled ()) + rte_logs.print_func = log_print_with_timestamp; +else + rte_logs.print_func = vfprintf; +#if RTE_LOG_DP_LEVEL >=RTE_LOG_DEBUG RTE_LOG (NOTICE ,EAL ,"Debug dataplane logs available - lower performance\n" );
lib/log/log_internal.h +9 -0
@@ -5,8 +5,10 @@#ifndef LOG_INTERNAL_H #define LOG_INTERNAL_H +#include <stdbool.h> #include <stdio.h> #include <stdint.h> +#include <time.h> #include <rte_compat.h>
@@ -39,4 +41,11 @@ const char *eal_log_level2str(uint32_t level);__rte_internal void rte_eal_log_cleanup(void); +/* +* Add timestamp to console logs +*/ +__rte_internal +int eal_log_timestamp(const char *fmt); + +#endif /* LOG_INTERNAL_H */
lib/log/log_private.h +11 -0
@@ -3,7 +3,18 @@#ifndef LOG_PRIVATE_H #define LOG_PRIVATE_H +/* Defined in limits.h on Linux */ +#ifndef LINE_MAX +#define LINE_MAX 2048/* _POSIX2_LINE_MAX */ +#endif +/* Note: same as vfprintf() */ typedef int (*log_print_t )(FILE *f,const char *fmt,va_list ap); +bool log_timestamp_enabled (void ); +ssize_t log_timestamp (char *tsbuf,size_t tsbuflen); + +__rte_format_printf(2, 0) +int log_print_with_timestamp (FILE *f,const char *format,va_list ap); +#endif /* LOG_PRIVATE_H */
lib/log/log_timestamp.c new file +210 -0
210 lines not on this page · raw message
lib/log/meson.build +5 -1
@@ -2,5 +2,9 @@ # Copyright(c) 2023 Intel Corporation includes += global_inc -sources = files('log.c') +sources = files( + 'log.c', + 'log_timestamp.c', +) + headers = files('rte_log.h')
lib/log/version.map +1 -0
@@ -30,5 +30,6 @@ INTERNAL { eal_log_save_pattern; eal_log_save_regexp; eal_log_syslog; + eal_log_timestamp; rte_eal_log_cleanup; };
Signature · 1 line
2.45.2
PATCH v24 12/15 log: add optional support of syslog
In reply to Stephen HemmingerLog to syslog only if option is specified. And if syslog is used then normally only log to syslog, don't duplicate output. Also enables syslog support on FreeBSD.
--- app/test/test_eal_flags.c | 5 +- doc/guides/linux_gsg/linux_eal_parameters.rst | 27 ------ doc/guides/prog_guide/log_lib.rst | 17 ++++ lib/eal/common/eal_common_options.c | 5 +- lib/log/log.c | 28 +++--- lib/log/log_private.h | 17 ++++ lib/log/log_syslog.c | 88 +++++++++++++++++++ lib/log/meson.build | 4 + lib/log/version.map | 2 +- 9 files changed, 150 insertions(+), 43 deletions(-) create mode 100644 lib/log/log_syslog.c
app/test/test_eal_flags.c +3 -2
@@ -987,9 +987,10 @@ test_misc_flags(void)/* With empty --syslog */ const char *argv3[] = {prgname, prefix, mp_flag,"--syslog" };/* With valid --syslog */ -const char *argv4[] = {prgname, prefix, mp_flag,"--syslog" ,"always" }; +const char *argv4[] = {prgname, prefix, mp_flag,"--syslog=both" };/* With invalid --syslog */ -const char *argv5[] = {prgname, prefix, mp_flag,"--syslog" ,"error" }; +const char *argv5[] = {prgname, prefix, mp_flag,"--syslog=invalid" }; +/* With no-sh-conf, also use no-huge to ensure this test runs on BSD */ const char *argv6[] = {prgname,"-m" ,DEFAULT_MEM_SIZE , no_shconf, nosh_prefix, no_huge};
doc/guides/linux_gsg/linux_eal_parameters.rst +0 -27
@@ -108,30 +108,3 @@ Memory-related options * ``--match-allocations`` Free hugepages back to system exactly as they were originally allocated. - -Other options -~~~~~~~~~~~~~ - -* ``--syslog <syslog facility>`` - - Set syslog facility. Valid syslog facilities are:: - - auth - cron - daemon - ftp - kern - lpr - mail - news - syslog - user - uucp - local0 - local1 - local2 - local3 - local4 - local5 - local6 - local7
doc/guides/prog_guide/log_lib.rst +17 -0
@@ -83,6 +83,23 @@ To prefix all console messages with ISO format time the syntax is:: /path/to/app --log-timestamp=iso +Log output +~~~~~~~~~~ + +If desired, messages can be redirected to syslog (on Linux and FreeBSD) with the ``--syslog`` +option. There are three possible settings for this option: + +*always* + Redirect all log output to syslog. + +*auto* + Use console if it is a terminal, and use syslog if is not. + +*both* + Print to both console and syslog. + +If ``--syslog`` option is not specified, then only console (stderr) will be used. + Using Logging APIs to Generate Log Messages
lib/eal/common/eal_common_options.c +4 -1
@@ -91,7 +91,7 @@ eal_long_options[] = { {OPT_PROC_TYPE, 1, NULL, OPT_PROC_TYPE_NUM }, {OPT_SOCKET_MEM, 1, NULL, OPT_SOCKET_MEM_NUM }, {OPT_SOCKET_LIMIT, 1, NULL, OPT_SOCKET_LIMIT_NUM }, - {OPT_SYSLOG, 1, NULL, OPT_SYSLOG_NUM }, + {OPT_SYSLOG, 2, NULL, OPT_SYSLOG_NUM }, {OPT_VDEV, 1, NULL, OPT_VDEV_NUM }, {OPT_VFIO_INTR, 1, NULL, OPT_VFIO_INTR_NUM }, {OPT_VFIO_VF_TOKEN, 1, NULL, OPT_VFIO_VF_TOKEN_NUM },
@@ -2215,6 +2215,9 @@ eal_common_usage(void)" (can be used multiple times)\n" " --" OPT_VMWARE_TSC_MAP " Use VMware TSC map instead of native RDTSC\n" " --" OPT_PROC_TYPE " Type of this process (primary|secondary|auto)\n" +#ifndef RTE_EXEC_ENV_WINDOWS +" --" OPT_SYSLOG "[=<when>] Enable use of syslog\n" +#endif " --"OPT_LOG_LEVEL"=<level> Set global log level\n"" --" OPT_LOG_LEVEL "=<type-match>:<level>\n" " Set specific log level\n"
lib/log/log.c +16 -12
@@ -12,18 +12,19 @@#include <regex.h> #include <fnmatch.h> #include <sys/queue.h> +#include <unistd.h> #include <rte_common.h> #include <rte_log.h> #include <rte_per_lcore.h> -#include "log_internal.h" -#include "log_private.h" -#ifdef RTE_EXEC_ENV_WINDOWS #include <rte_os_shim.h> #endif +#include "log_internal.h" +#include "log_private.h" +struct rte_log_dynamic_type {const char *name;uint32_t loglevel;
@@ -496,20 +497,23 @@ rte_log(uint32_t level, uint32_t logtype, const char *format, ...)return ret; } -/* Placeholder */ -int -eal_log_syslog(const char *mode __rte_unused) -{ -return -1 ; -} -/* * Called by rte_eal_init */ void -eal_log_init(const char *id __rte_unused) +eal_log_init (const char *id) { -if (log_timestamp_enabled ()) +bool is_terminal; + +#ifdef RTE_EXEC_ENV_WINDOWS + is_terminal =_isatty (_fileno (stderr)); +#else + is_terminal =isatty (STDERR_FILENO ); +#endif + +if (log_syslog_enabled (is_terminal)) +log_syslog_open (id, is_terminal); +else if (log_timestamp_enabled ()) rte_logs.print_func = log_print_with_timestamp;else rte_logs.print_func = vfprintf;
lib/log/log_private.h +17 -0
@@ -17,4 +17,21 @@ ssize_t log_timestamp(char *tsbuf, size_t tsbuflen); __rte_format_printf(2, 0)int log_print_with_timestamp (FILE *f,const char *format,va_list ap); +#ifdef RTE_EXEC_ENV_WINDOWS +static inline bool +log_syslog_enabled(bool is_tty __rte_unused) +{ +return false; +} + +static inline void +log_syslog_open(const char *id __rte_unused, bool is_terminal __rte_unused) +{ +} +#else + +bool log_syslog_enabled (bool is_tty); +void log_syslog_open (const char *id,bool is_terminal); +#endif +#endif /* LOG_PRIVATE_H */
lib/log/log_syslog.c new file +88 -0
88 lines not on this page · raw message
lib/log/meson.build +4 -0
@@ -7,4 +7,8 @@ sources = files( 'log_timestamp.c', ) +if not is_windows + sources += files('log_syslog.c') +endif + headers = files('rte_log.h')
lib/log/version.map +1 -1
@@ -29,7 +29,7 @@ INTERNAL { eal_log_level2str; eal_log_save_pattern; eal_log_save_regexp; - eal_log_syslog; + eal_log_syslog; # WINDOWS_NO_EXPORT eal_log_timestamp; rte_eal_log_cleanup; };
Signature · 1 line
2.45.2
PATCH v24 13/15 log: add support for systemd journal
In reply to Stephen HemmingerIf DPDK application is being run as a systemd service, then it can use the journal protocol which allows putting more information in the log such as priority and other information.
The use of journal protocol is automatically detected and handled. Rather than having a dependency on libsystemd, just use the protocol directly as defined in:
https://systemd.io/JOURNAL_NATIVE_PROTOCOL/
--- doc/guides/prog_guide/log_lib.rst | 14 ++ lib/eal/common/eal_common_options.c | 15 +++ lib/eal/common/eal_options.h | 2 + lib/log/log.c | 4 +- lib/log/log_internal.h | 3 + lib/log/log_journal.c | 200 ++++++++++++++++++++++++++++ lib/log/log_private.h | 16 +++ lib/log/meson.build | 4 + lib/log/version.map | 1 + 9 files changed, 258 insertions(+), 1 deletion(-) create mode 100644 lib/log/log_journal.c
doc/guides/prog_guide/log_lib.rst +14 -0
@@ -100,6 +100,20 @@ option. There are three possible settings for this option: If ``--syslog`` option is not specified, then only console (stderr) will be used. +Messages can be redirected to systemd journal which is an enhanced version of syslog with the ``--log-journal`` option. + +There are three possible settings for this option: + +*auto* + If stderr is redirected to journal by ``systemd`` service + then use journal socket to instead of stderr for log. + This is the default. + +*never* + Do not try to use journal. + +*always* + Always try to direct messages to journal socket. Using Logging APIs to Generate Log Messages
lib/eal/common/eal_common_options.c +15 -0
@@ -74,6 +74,7 @@ eal_long_options[] = { {OPT_IOVA_MODE, 1, NULL, OPT_IOVA_MODE_NUM }, {OPT_LCORES, 1, NULL, OPT_LCORES_NUM }, {OPT_LOG_LEVEL, 1, NULL, OPT_LOG_LEVEL_NUM }, + {OPT_LOG_JOURNAL, 2, NULL, OPT_LOG_JOURNAL_NUM }, {OPT_LOG_TIMESTAMP, 2, NULL, OPT_LOG_TIMESTAMP_NUM }, {OPT_TRACE, 1, NULL, OPT_TRACE_NUM }, {OPT_TRACE_DIR, 1, NULL, OPT_TRACE_DIR_NUM },
@@ -1617,6 +1618,7 @@ eal_log_level_parse(int argc, char * const argv[])switch (opt) {case OPT_LOG_LEVEL_NUM :case OPT_SYSLOG_NUM : +case OPT_LOG_JOURNAL_NUM :case OPT_LOG_TIMESTAMP_NUM :if (eal_parse_common_option (opt, optarg, internal_conf) <0 )return -1 ;
@@ -1840,6 +1842,16 @@ eal_parse_common_option(int opt, const char *optarg,break ;#endif +#ifdef RTE_EXEC_ENV_LINUX +case OPT_LOG_JOURNAL_NUM : +if (eal_log_journal (optarg) <0 ) { +EAL_LOG (ERR ,"invalid parameters for --" +OPT_LOG_JOURNAL ); +return -1 ; + } +break ; +#endif +case OPT_LOG_LEVEL_NUM :if (eal_parse_log_level (optarg) <0 ) { EAL_LOG(ERR,
@@ -2217,6 +2229,9 @@ eal_common_usage(void) " --"OPT_PROC_TYPE" Type of this process (primary|secondary|auto)\n" #ifndef RTE_EXEC_ENV_WINDOWS " --"OPT_SYSLOG"[=<when>] Enable use of syslog\n" +#endif +#ifdef RTE_EXEC_ENV_LINUX + " --"OPT_LOG_JOURNAL"[=<when>] Enable use of systemd journal\n"#endif " --" OPT_LOG_LEVEL "=<level> Set global log level\n" " --" OPT_LOG_LEVEL "=<type-match>:<level>\n"
lib/eal/common/eal_options.h +2 -0
@@ -35,6 +35,8 @@ enum {OPT_LCORES_NUM , #define OPT_LOG_LEVEL "log-level"OPT_LOG_LEVEL_NUM , +#define OPT_LOG_JOURNAL "log-journal" +OPT_LOG_JOURNAL_NUM , #define OPT_LOG_TIMESTAMP "log-timestamp"OPT_LOG_TIMESTAMP_NUM , #define OPT_TRACE "trace"
lib/log/log.c +3 -1
@@ -511,7 +511,9 @@ eal_log_init(const char *id) is_terminal =isatty (STDERR_FILENO );#endif -if (log_syslog_enabled (is_terminal)) +if (log_journal_enabled ()) +log_journal_open (id); +else if (log_syslog_enabled (is_terminal))log_syslog_open (id, is_terminal);else if (log_timestamp_enabled ()) rte_logs.print_func = log_print_with_timestamp;
lib/log/log_internal.h +3 -0
@@ -29,6 +29,9 @@ int eal_log_save_pattern(const char *pattern, uint32_t level);__rte_internal int eal_log_syslog(const char *name); +__rte_internal +int eal_log_journal(const char *opt); +/* * Convert log level to string. */
lib/log/log_journal.c new file +200 -0
200 lines not on this page · raw message
lib/log/log_private.h +16 -0
@@ -34,4 +34,20 @@ bool log_syslog_enabled(bool is_tty);void log_syslog_open (const char *id,bool is_terminal);#endif +#ifdef RTE_EXEC_ENV_LINUX +bool log_journal_enabled (void ); +void log_journal_open (const char *id); +#else +static inline bool +log_journal_enabled (void ) +{ +return false; +} + +static inline void +log_journal_open(const char *id __rte_unused) +{ +} +#endif /* !RTE_EXEC_ENV_LINUX */ +#endif /* LOG_PRIVATE_H */
lib/log/meson.build +4 -0
@@ -11,4 +11,8 @@ if not is_windows sources += files('log_syslog.c') endif +if is_linux + sources += files('log_journal.c') +endif + headers = files('rte_log.h')
lib/log/version.map +1 -0
@@ -26,6 +26,7 @@ INTERNAL { global: eal_log_init; + eal_log_journal; # WINDOWS_NO_EXPORT eal_log_level2str; eal_log_save_pattern; eal_log_save_regexp;
Signature · 1 line
2.45.2
PATCH v24 14/15 log: colorize log output
In reply to Stephen HemmingerLike dmesg, colorize the log output (unless redirected to file). Timestamp is green, the subsystem is in yellow and the message is red if urgent, boldface if an error, and normal for info and debug messages.
--- app/test/test_eal_flags.c | 24 +++++ doc/guides/prog_guide/log_lib.rst | 15 +++ lib/eal/common/eal_common_options.c | 11 +++ lib/eal/common/eal_options.h | 6 +- lib/log/log.c | 19 ++-- lib/log/log_color.c | 148 ++++++++++++++++++++++++++++ lib/log/log_internal.h | 5 + lib/log/log_private.h | 8 ++ lib/log/meson.build | 1 + lib/log/version.map | 1 + 10 files changed, 230 insertions(+), 8 deletions(-) create mode 100644 lib/log/log_color.c
app/test/test_eal_flags.c +24 -0
@@ -1067,6 +1067,18 @@ test_misc_flags(void)const char *const argv25[] = {prgname, prefix, mp_flag,"--log-timestamp=invalid" }; +/* Try running with --log-color */ +const char *const argv26[] = {prgname, prefix, mp_flag, +"--log-color" }; + +/* Try running with --log-color=never */ +const char *const argv27[] = {prgname, prefix, mp_flag, +"--log-color=never" }; + +/* Try running with --log-color=invalid */ +const char *const argv28[] = {prgname, prefix, mp_flag, +"--log-color=invalid" }; +/* run all tests also applicable to FreeBSD first */
@@ -1187,6 +1199,18 @@ test_misc_flags(void)printf ("Error - process did run ok with --log-timestamp=invalid parameter\n" ); goto fail; } +if (launch_proc (argv26) !=0 ) { +printf ("Error - process did not run ok with --log-color parameter\n" ); + goto fail; + } +if (launch_proc (argv27) !=0 ) { +printf ("Error - process did not run ok with --log-color=none parameter\n" ); + goto fail; + } +if (launch_proc (argv28) ==0 ) { +printf ("Error - process did run ok with --log-timestamp=invalid parameter\n" ); + goto fail; + }rmdir (hugepath_dir3);
doc/guides/prog_guide/log_lib.rst +15 -0
@@ -59,6 +59,21 @@ For example:: Within an application, the same result can be got using the ``rte_log_set_level_pattern()`` or ``rte_log_set_level_regex()`` APIs. +Color output +~~~~~~~~~~~~ + +The log library will highlight important messages. +This is controlled by the ``--log-color`` option. +he optional argument ``when`` can be ``auto``, ``never``, or ``always``. +The default setting is ``auto`` which enables color when the output to +``stderr`` is a terminal. +If the ``when`` argument is omitted, it defaults to ``always``. + +For example to turn off all coloring:: + + /path/to/app --log-color=none + + Log timestamp ~~~~~~~~~~~~~
lib/eal/common/eal_common_options.c +11 -0
@@ -73,6 +73,7 @@ eal_long_options[] = { {OPT_HUGE_UNLINK, 2, NULL, OPT_HUGE_UNLINK_NUM }, {OPT_IOVA_MODE, 1, NULL, OPT_IOVA_MODE_NUM }, {OPT_LCORES, 1, NULL, OPT_LCORES_NUM }, + {OPT_LOG_COLOR, 2, NULL, OPT_LOG_COLOR_NUM }, {OPT_LOG_LEVEL, 1, NULL, OPT_LOG_LEVEL_NUM }, {OPT_LOG_JOURNAL, 2, NULL, OPT_LOG_JOURNAL_NUM }, {OPT_LOG_TIMESTAMP, 2, NULL, OPT_LOG_TIMESTAMP_NUM },
@@ -1620,6 +1621,7 @@ eal_log_level_parse(int argc, char * const argv[])case OPT_SYSLOG_NUM :case OPT_LOG_JOURNAL_NUM :case OPT_LOG_TIMESTAMP_NUM : +case OPT_LOG_COLOR_NUM :if (eal_parse_common_option (opt, optarg, internal_conf) <0 )return -1 ;break ;
@@ -1869,6 +1871,14 @@ eal_parse_common_option(int opt, const char *optarg, }break ; +case OPT_LOG_COLOR_NUM : +if (eal_log_color (optarg) <0 ) { +EAL_LOG (ERR ,"invalid parameters for --" +OPT_LOG_COLOR ); +return -1 ; + } +break ; +#ifndef RTE_EXEC_ENV_WINDOWS case OPT_TRACE_NUM : {if (eal_trace_args_save (optarg) <0 ) {
@@ -2238,6 +2248,7 @@ eal_common_usage(void)" Set specific log level\n" " --" OPT_LOG_LEVEL "=help Show log types and levels\n" " --" OPT_LOG_TIMESTAMP "[=<format>] Timestamp log output\n" +" --" OPT_LOG_COLOR "[=<when>] Colorize log messages\n" #ifndef RTE_EXEC_ENV_WINDOWS" --" OPT_TRACE "=<regex-match>\n" " Enable trace based on regular expression trace name.\n"
lib/eal/common/eal_options.h +4 -2
@@ -33,10 +33,12 @@ enum {OPT_HUGE_UNLINK_NUM , #define OPT_LCORES "lcores"OPT_LCORES_NUM , -#define OPT_LOG_LEVEL "log-level" -OPT_LOG_LEVEL_NUM , +#define OPT_LOG_COLOR "log-color" +OPT_LOG_COLOR_NUM , #define OPT_LOG_JOURNAL "log-journal"OPT_LOG_JOURNAL_NUM , +#define OPT_LOG_LEVEL "log-level" +OPT_LOG_LEVEL_NUM , #define OPT_LOG_TIMESTAMP "log-timestamp"OPT_LOG_TIMESTAMP_NUM , #define OPT_TRACE "trace"
lib/log/log.c +13 -6
@@ -511,14 +511,21 @@ eal_log_init(const char *id) is_terminal =isatty (STDERR_FILENO );#endif -if (log_journal_enabled ()) +if (log_journal_enabled ()) {log_journal_open (id); -else if (log_syslog_enabled (is_terminal)) + }else if (log_syslog_enabled (is_terminal)) {log_syslog_open (id, is_terminal); -else if (log_timestamp_enabled ()) - rte_logs.print_func = log_print_with_timestamp; -else - rte_logs.print_func = vfprintf; + }else if (log_timestamp_enabled ()) { +if (log_color_enabled (is_terminal)) + rte_logs.print_func = color_print_with_timestamp; +else + rte_logs.print_func = log_print_with_timestamp; + }else { +if (log_color_enabled (is_terminal)) + rte_logs.print_func = color_print; +else + rte_logs.print_func = vfprintf; + }#if RTE_LOG_DP_LEVEL >=RTE_LOG_DEBUG RTE_LOG(NOTICE, EAL,
lib/log/log_color.c new file +148 -0
148 lines not on this page · raw message
lib/log/log_internal.h +5 -0
@@ -50,5 +50,10 @@ void rte_eal_log_cleanup(void);__rte_internal int eal_log_timestamp(const char *fmt); +/* +* Enable or disable color in log messages +*/ +__rte_internal +int eal_log_color(const char *mode);#endif /* LOG_INTERNAL_H */
lib/log/log_private.h +8 -0
@@ -50,4 +50,12 @@ log_journal_open(const char *id __rte_unused) }#endif /* !RTE_EXEC_ENV_LINUX */ +bool log_color_enabled (bool is_tty); + +__rte_format_printf(2, 0) +int color_print (FILE *f,const char *format,va_list ap); + +__rte_format_printf(2, 0) +int color_print_with_timestamp (FILE *f,const char *format,va_list ap); +#endif /* LOG_PRIVATE_H */
lib/log/meson.build +1 -0
@@ -4,6 +4,7 @@ includes += global_inc sources = files( 'log.c', + 'log_color.c', 'log_timestamp.c', )
lib/log/version.map +1 -0
@@ -25,6 +25,7 @@ DPDK_25 { INTERNAL { global: + eal_log_color; eal_log_init; eal_log_journal; # WINDOWS_NO_EXPORT eal_log_level2str;
Signature · 1 line
2.45.2
PATCH v24 15/15 doc: add release note about log library
In reply to Stephen HemmingerSignificant enough to add some documentation.
--- doc/guides/rel_notes/release_24_11.rst | 27 ++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
doc/guides/rel_notes/release_24_11.rst +27 -0
@@ -55,6 +55,33 @@ New Features Also, make sure to start the actual text at the margin. ======================================================= +* **Enhancements to logging library.** + + * Syslog related changes + + * The meaning of the *--syslog* option has changed. + Use of syslog is controlled by the *--syslog* option. + The default is now *auto* which uses syslog only if stderr + is not a terminal device. + + * The syslog facility is now set to **LOG_USER** if stderr is a terminal + and **LOG_DAEMON** otherwise. + + * Syslog is now supported on FreeBSD (but not on Windows). + + * The log is initialized earlier in startup so all messages go through + the library. + + * Added a new option to timestamp log messages, which is useful for + debugging delays in application and driver startup. + + * Log messages are now in color if going to a terminal (similar to dmesg). + The default format shows timestamp in green, subsystem in yellow, + and the message is bold, boldface or normal depending on severity. + + * If the application is a systemd service and the log output is being + sent of standard error then DPDK will switch to journal native protocol. + Removed Items -------------
Signature · 1 line
2.45.2
v25 cover Logging enhancements for 24.11
In reply to Stephen Hemmingermprovements and unification of logging library.
This version works on all platforms: Linux, Windows and FreeBSD.
This is update to rework patch set. It adds several new features to the console log output.
* Putting a timestamp on console output which is useful for analyzing performance of startup codes. Timestamp is optional and must be enabled on command line.
* Displaying console output with colors.
It uses the standard conventions used by many other Linux commands for colorized display. The default is to enable color if the console output is going to a terminal. But it can be always on or disabled by command line flag. This default was chosen based on what dmesg(1) command does.
Color is used by many tools (vi, iproute2, git) because it is helpful; DPDK drivers and libraries print lots of not very useful messages. And having error messages highlighted in bold face helps. This might also get users to pay more attention to error messages. Many bug reports have earlier messages that are lost because there are so many info messages.
* Add support for automatic detection of systemd journal protocol. If running as systemd service will get enhanced logging.
* Use of syslog is optional and the meaning of the --syslog flag has changed. The default is *not* to use syslog if output is going to a terminal.
Add myself as maintainer for log because by now have added more than previous authors.
v25 - make the delta and relative time stamp formats thread safe.
Use atomic 64 bit value (nanoseconds) and convert to timespec.
Stephen Hemminger (15):
maintainers: add for log library
windows: make getopt functions have const properties
windows: add os shim for localtime_r
eal: make eal_log_level_parse common
eal: do not duplicate rte_init_alert() messages
eal: change rte_exit() output to match rte_log()
log: move handling of syslog facility out of eal
eal: initialize log before everything else
log: drop syslog support, and make code common
log: add hook for printing log messages
log: add timestamp option
log: add optional support of syslog
log: add support for systemd journal
log: colorize log output
doc: add release note about log library
MAINTAINERS | 1 + app/test/test_eal_flags.c | 64 ++++- doc/guides/linux_gsg/linux_eal_parameters.rst | 27 -- doc/guides/prog_guide/log_lib.rst | 72 ++++++ doc/guides/rel_notes/release_24_11.rst | 27 ++ lib/eal/common/eal_common_debug.c | 6 +- lib/eal/common/eal_common_options.c | 135 ++++++---- lib/eal/common/eal_internal_cfg.h | 1 - lib/eal/common/eal_options.h | 7 + lib/eal/freebsd/eal.c | 64 +---- lib/eal/linux/eal.c | 68 +---- lib/eal/windows/eal.c | 49 +--- lib/eal/windows/getopt.c | 23 +- lib/eal/windows/include/getopt.h | 8 +- lib/eal/windows/include/rte_os_shim.h | 10 + lib/log/log.c | 71 ++++-- lib/log/log_color.c | 148 +++++++++++ lib/log/log_freebsd.c | 12 - lib/log/log_internal.h | 28 +- lib/log/log_journal.c | 200 +++++++++++++++ lib/log/log_linux.c | 61 ----- lib/log/log_private.h | 61 +++++ lib/log/log_syslog.c | 88 +++++++ lib/log/log_timestamp.c | 240 ++++++++++++++++++ lib/log/log_windows.c | 18 -- lib/log/meson.build | 12 +- lib/log/version.map | 5 +- 27 files changed, 1129 insertions(+), 377 deletions(-) create mode 100644 lib/log/log_color.c delete mode 100644 lib/log/log_freebsd.c create mode 100644 lib/log/log_journal.c delete mode 100644 lib/log/log_linux.c create mode 100644 lib/log/log_private.h create mode 100644 lib/log/log_syslog.c create mode 100644 lib/log/log_timestamp.c delete mode 100644 lib/log/log_windows.c
Signature · 1 line
2.45.2
PATCH v25 1/15 maintainers: add for log library
"You touch it you own it"
Add myself as maintainer for log library.
--- MAINTAINERS | 1 + 1 file changed, 1 insertion(+)
MAINTAINERS +1 -0
@@ -185,6 +185,7 @@ F: app/test/test_threads.c F: app/test/test_version.c Logging +M: Stephen Hemminger <[email protected]> F: lib/log/ F: doc/guides/prog_guide/log_lib.rst F: app/test/test_logs.c
Signature · 1 line
2.45.2
PATCH v25 2/15 windows: make getopt functions have const properties
In reply to Stephen HemmingerHaving different prototypes on different platforms can lead to lots of unnecessary workarounds. Looks like the version of getopt used from windows was based on an older out of date version from FreeBSD.
This patch changes getopt, getopt_long, etc to have the same const attributes as Linux and FreeBSD. The changes are derived from the current FreeBSD version of getopt_long.
--- lib/eal/windows/getopt.c | 23 ++++++++++++----------- lib/eal/windows/include/getopt.h | 8 ++++---- 2 files changed, 16 insertions(+), 15 deletions(-)
lib/eal/windows/getopt.c +12 -11
@@ -20,7 +20,7 @@#include <string.h> #include <stdlib.h> -const char *optarg;/* argument associated with option */ +char *optarg;/* argument associated with option */ int opterr =1 ;/* if error message should be printed */ int optind =1 ;/* index into parent argv vector */ int optopt ='?' ;/* character checked for validity */
@@ -39,9 +39,9 @@ static void pass(const char *a) {(void) a; }#define BADARG ((*options == ':') ? (int)':' : (int)'?')#define INORDER 1 -#define EMSG "" +static char EMSG [] ="" ; -static const char *place =EMSG ;/* option letter processing */ +static char *place =EMSG ;/* option letter processing */ /* XXX: set optreset to 1 rather than these two */ static int nonopt_start =-1 ;/* first non option argument (for permute) */
@@ -80,7 +80,7 @@ gcd(int a, int b)*/ static void permute_args (int panonopt_start,int panonopt_end,int opt_end, -char **nargv) +char *const *nargv) {int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;char *swap;
@@ -101,11 +101,12 @@ permute_args(int panonopt_start, int panonopt_end, int opt_end, pos -= nnonopts; else pos += nopts; + swap = nargv[pos];/* LINTED const cast */ - ((char **) nargv)[pos] = nargv[cstart]; + ((char **)(uintptr_t )nargv)[pos] = nargv[cstart];/* LINTED const cast */ - ((char **)nargv)[cstart] = swap; + ((char **)(uintptr_t )nargv)[cstart] = swap; } } }
@@ -116,7 +117,7 @@ permute_args(int panonopt_start, int panonopt_end, int opt_end,* Returns -1 if short_too is set and the option does not match long_options. */ static int -parse_long_options (char **nargv,const char *options, +parse_long_options (char *const *nargv,const char *options,const struct option *long_options,int *idx,int short_too) {const char *current_argv;
@@ -236,7 +237,7 @@ parse_long_options(char **nargv, const char *options,* Parse argc/argv argument vector. Called by user level routines. */ static int -getopt_internal (int nargc,char **nargv,const char *options, +getopt_internal (int nargc,char *const nargv[],const char *options,const struct option *long_options,int *idx,int flags) {char *oli;/* option letter list index */
@@ -434,7 +435,7 @@ getopt_internal(int nargc, char **nargv, const char *options,* Parse argc/argv argument vector. */ int -getopt (int nargc,char *nargv[],const char *options) +getopt (int nargc,char *const nargv[],const char *options) {return getopt_internal (nargc, nargv, options,NULL ,NULL ,FLAG_PERMUTE );
@@ -445,7 +446,7 @@ getopt(int nargc, char *nargv[], const char *options)* Parse argc/argv argument vector. */ int -getopt_long (int nargc,char *nargv[],const char *options, +getopt_long (int nargc,char *const nargv[],const char *options,const struct option *long_options,int *idx) {
@@ -458,7 +459,7 @@ getopt_long(int nargc, char *nargv[], const char *options,* Parse argc/argv argument vector. */ int -getopt_long_only (int nargc,char *nargv[],const char *options, +getopt_long_only (int nargc,char *const nargv[],const char *options,const struct option *long_options,int *idx) {
lib/eal/windows/include/getopt.h +4 -4
@@ -44,7 +44,7 @@/** argument to current option, or NULL if it has none */ -extern const char *optarg; +extern char *optarg;/** Current position in arg string. Starts from 1. * Setting to 0 resets state. */
@@ -80,14 +80,14 @@ struct option { };/** Compat: getopt */ -int getopt (int argc,char *argv[],const char *options); +int getopt (int argc,char *const argv[],const char *options);/** Compat: getopt_long */ -int getopt_long (int argc,char *argv[],const char *options, +int getopt_long (int argc,char *const argv[],const char *options,const struct option *longopts,int *longindex);/** Compat: getopt_long_only */ -int getopt_long_only (int nargc,char *argv[],const char *options, +int getopt_long_only (int nargc,char *const argv[],const char *options,const struct option *long_options,int *idx);
Signature · 1 line
2.45.2
PATCH v25 3/15 windows: add os shim for localtime_r
In reply to Stephen HemmingerWindows does not have localtime_r but it does have a similar function that can be used instead.
--- lib/eal/windows/include/rte_os_shim.h | 10 ++++++++++ 1 file changed, 10 insertions(+)
lib/eal/windows/include/rte_os_shim.h +10 -0
@@ -110,4 +110,14 @@ rte_clock_gettime(clockid_t clock_id, struct timespec *tp) }#define clock_gettime (clock_id, tp) rte_clock_gettime(clock_id, tp) +static inline struct tm * +rte_localtime_r (const time_t *timep,struct tm *result) +{ +if (localtime_s (result, timep) ==0 ) +return result; +else +return NULL ; +} +#define localtime_r (timep, result) rte_localtime_r(timep, result) +#endif /* _RTE_OS_SHIM_ */
Signature · 1 line
2.45.2
PATCH v25 4/15 eal: make eal_log_level_parse common
In reply to Stephen HemmingerThe code to parse for log-level option should be same on all OS variants.
--- lib/eal/common/eal_common_options.c | 40 +++++++++++++++++++++++++++ lib/eal/common/eal_options.h | 1 + lib/eal/freebsd/eal.c | 42 ----------------------------- lib/eal/linux/eal.c | 39 --------------------------- lib/eal/windows/eal.c | 35 ------------------------ 5 files changed, 41 insertions(+), 116 deletions(-)
lib/eal/common/eal_common_options.c +40 -0
@@ -1640,6 +1640,46 @@ eal_parse_huge_unlink(const char *arg, struct hugepage_file_discipline *out)return -1 ; } +/* Parse the all arguments looking for log related ones */ +int +eal_log_level_parse (int argc,char *const argv[]) +{ +struct internal_config *internal_conf =eal_get_internal_configuration (); +int option_index, opt; +const int old_optind = optind; +const int old_optopt = optopt; +const int old_opterr = opterr; +char *old_optarg = optarg; +#ifdef RTE_EXEC_ENV_FREEBSD +const int old_optreset = optreset; + optreset =1 ; +#endif + + optind =1 ; + opterr =0 ; + +while ((opt =getopt_long (argc, argv, eal_short_options, + eal_long_options, &option_index)) !=EOF ) { + +switch (opt) { +case OPT_LOG_LEVEL_NUM : +if (eal_parse_common_option (opt, optarg, internal_conf) <0 ) +return -1 ; +break ; + } + } + +/* restore getopt lib */ + optind = old_optind; + optopt = old_optopt; + optarg = old_optarg; + opterr = old_opterr; +#ifdef RTE_EXEC_ENV_FREEBSD + optreset = old_optreset; +#endif +return 0 ; +} +int eal_parse_common_option (int opt,const char *optarg,struct internal_config *conf)
lib/eal/common/eal_options.h +1 -0
@@ -96,6 +96,7 @@ enum {extern const char eal_short_options[];extern const struct option eal_long_options[]; +int eal_log_level_parse (int argc,char *const argv[]);int eal_parse_common_option (int opt,const char *argv,struct internal_config *conf);int eal_option_device_parse (void );
lib/eal/freebsd/eal.c +0 -42
48 lines not on this page · raw message
lib/eal/linux/eal.c +0 -39
@@ -546,45 +546,6 @@ eal_parse_vfio_vf_token(const char *vf_token)return -1 ; } -/* Parse the arguments for --log-level only */ -static void -eal_log_level_parse (int argc,char **argv) -{ -int opt; -char **argvopt; -int option_index; -const int old_optind = optind; -const int old_optopt = optopt; -char *const old_optarg = optarg; -struct internal_config *internal_conf = -eal_get_internal_configuration (); - - argvopt = argv; - optind =1 ; - -while ((opt =getopt_long (argc, argvopt, eal_short_options, - eal_long_options, &option_index)) !=EOF ) { - -int ret; - -/* getopt is not happy, stop right now */ -if (opt =='?' ) -break ; - - ret = (opt ==OPT_LOG_LEVEL_NUM ) ? -eal_parse_common_option (opt, optarg, internal_conf) :0 ; - -/* common parser is not happy */ -if (ret <0 ) -break ; - } - -/* restore getopt lib */ - optind = old_optind; - optopt = old_optopt; - optarg = old_optarg; -} -static int eal_parse_huge_worker_stack (const char *arg) {
lib/eal/windows/eal.c +0 -35
@@ -96,41 +96,6 @@ eal_usage(const char *prgname) } } -/* Parse the arguments for --log-level only */ -static void -eal_log_level_parse (int argc,char **argv) -{ -int opt; -char **argvopt; -int option_index; -struct internal_config *internal_conf = -eal_get_internal_configuration (); - - argvopt = argv; - -eal_reset_internal_config (internal_conf); - -while ((opt =getopt_long (argc, argvopt, eal_short_options, - eal_long_options, &option_index)) !=EOF ) { - -int ret; - -/* getopt is not happy, stop right now */ -if (opt =='?' ) -break ; - - ret = (opt ==OPT_LOG_LEVEL_NUM ) ? -eal_parse_common_option (opt, optarg, - internal_conf) :0 ; - -/* common parser is not happy */ -if (ret <0 ) -break ; - } - - optind =0 ;/* reset getopt lib */ -} -/* Parse the argument given in the command line of the application */ static int eal_parse_args (int argc,char **argv)
Signature · 1 line
2.45.2
PATCH v25 5/15 eal: do not duplicate rte_init_alert() messages
In reply to Stephen HemmingerThe message already goes through logging, and does not need to be printed on stderr. Message level should be ALERT to match function name.
--- lib/eal/freebsd/eal.c | 3 +-- lib/eal/linux/eal.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-)
lib/eal/freebsd/eal.c +1 -2
@@ -529,8 +529,7 @@ rte_eal_iopl_init(void)static void rte_eal_init_alert (const char *msg) { -fprintf (stderr,"EAL: FATAL: %s\n" , msg); -EAL_LOG (ERR ,"%s" , msg); +EAL_LOG (ALERT ,"%s" , msg); }/* Launch threads, called at application init(). */
lib/eal/linux/eal.c +1 -2
@@ -840,8 +840,7 @@ static int rte_eal_vfio_setup(void)static void rte_eal_init_alert (const char *msg) { -fprintf (stderr,"EAL: FATAL: %s\n" , msg); -EAL_LOG (ERR ,"%s" , msg); +EAL_LOG (ALERT ,"%s" , msg); }/*
Signature · 1 line
2.45.2
PATCH v25 6/15 eal: change rte_exit() output to match rte_log()
In reply to Stephen HemmingerThe rte_exit() output format confuses the timestamp and coloring options. Change it to use be a single line with proper prefix.
Before:
[ 0.006481] EAL: Error - exiting with code: 1 Cause: [ 0.006489] Cannot init EAL: Permission denied
After:
[ 0.006238] EAL: Error - exiting with code: 1 [ 0.006250] EAL: Cannot init EAL: Permission denied
--- lib/eal/common/eal_common_debug.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
lib/eal/common/eal_common_debug.c +2 -4
@@ -36,15 +36,13 @@ rte_exit(int exit_code, const char *format, ...)va_list ap;if (exit_code !=0 ) -RTE_LOG (CRIT ,EAL ,"Error - exiting with code: %d\n" -" Cause: " , exit_code); +EAL_LOG (CRIT ,"Error - exiting with code: %d" , exit_code);va_start (ap, format);rte_vlog (RTE_LOG_CRIT ,RTE_LOGTYPE_EAL , format, ap);va_end (ap);if (rte_eal_cleanup () !=0 && rte_errno !=EALREADY ) -EAL_LOG (CRIT , -"EAL could not release all resources" ); +EAL_LOG (CRIT ,"EAL could not release all resources" );exit (exit_code); }
Signature · 1 line
2.45.2
PATCH v25 7/15 log: move handling of syslog facility out of eal
In reply to Stephen HemmingerThe syslog facility property is better handled in lib/log rather than in eal. This also allows for changes to what syslog flag means in later steps.
--- lib/eal/common/eal_common_options.c | 51 ++--------------------------- lib/eal/common/eal_internal_cfg.h | 1 - lib/eal/freebsd/eal.c | 5 ++- lib/eal/linux/eal.c | 7 ++-- lib/eal/windows/eal.c | 6 ++-- lib/log/log.c | 2 ++ lib/log/log_freebsd.c | 2 +- lib/log/log_internal.h | 5 ++- lib/log/log_linux.c | 47 ++++++++++++++++++++++++-- lib/log/log_windows.c | 8 ++++- lib/log/version.map | 1 + 11 files changed, 70 insertions(+), 65 deletions(-)
lib/eal/common/eal_common_options.c +2 -49
@@ -6,9 +6,6 @@#include <stdlib.h> #include <string.h> #include <pthread.h> -#ifndef RTE_EXEC_ENV_WINDOWS -#include <syslog.h> -#endif #include <ctype.h> #include <limits.h> #include <errno.h>
@@ -349,10 +346,6 @@ eal_reset_internal_config(struct internal_config *internal_cfg) } internal_cfg->base_virtaddr =0 ; -#ifdef LOG_DAEMON - internal_cfg->syslog_facility =LOG_DAEMON ; -#endif -/* if set to NONE, interrupt mode is determined automatically */ internal_cfg->vfio_intr_mode =RTE_INTR_MODE_NONE ; memset(internal_cfg->vfio_vf_token, 0,
@@ -1297,47 +1290,6 @@ eal_parse_lcores(const char *lcores)return ret; } -#ifndef RTE_EXEC_ENV_WINDOWS -static int -eal_parse_syslog (const char *facility,struct internal_config *conf) -{ -int i; -static const struct { -const char *name; -int value; - } map[] = { - {"auth" ,LOG_AUTH }, - {"cron" ,LOG_CRON }, - {"daemon" ,LOG_DAEMON }, - {"ftp" ,LOG_FTP }, - {"kern" ,LOG_KERN }, - {"lpr" ,LOG_LPR }, - {"mail" ,LOG_MAIL }, - {"news" ,LOG_NEWS }, - {"syslog" ,LOG_SYSLOG }, - {"user" ,LOG_USER }, - {"uucp" ,LOG_UUCP }, - {"local0" ,LOG_LOCAL0 }, - {"local1" ,LOG_LOCAL1 }, - {"local2" ,LOG_LOCAL2 }, - {"local3" ,LOG_LOCAL3 }, - {"local4" ,LOG_LOCAL4 }, - {"local5" ,LOG_LOCAL5 }, - {"local6" ,LOG_LOCAL6 }, - {"local7" ,LOG_LOCAL7 }, - {NULL ,0 } - }; - -for (i =0 ; map[i].name; i++) { -if (!strcmp (facility, map[i].name)) { - conf->syslog_facility = map[i].value; -return 0 ; - } - } -return -1 ; -} -#endif -static void eal_log_usage (void ) {
@@ -1663,6 +1615,7 @@ eal_log_level_parse(int argc, char * const argv[])switch (opt) {case OPT_LOG_LEVEL_NUM : +case OPT_SYSLOG_NUM :if (eal_parse_common_option (opt, optarg, internal_conf) <0 )return -1 ;break ;
@@ -1877,7 +1830,7 @@ eal_parse_common_option(int opt, const char *optarg,#ifndef RTE_EXEC_ENV_WINDOWS case OPT_SYSLOG_NUM : -if (eal_parse_syslog (optarg, conf) <0 ) { +if (eal_log_syslog (optarg) <0 ) {EAL_LOG (ERR ,"invalid parameters for --" OPT_SYSLOG );return -1 ;
lib/eal/common/eal_internal_cfg.h +0 -1
@@ -84,7 +84,6 @@ struct internal_config {/**< true if storing all pages within single files (per-page-size, * per-node) non-legacy mode only. */ -volatile int syslog_facility;/**< facility passed to openlog() */ /** default interrupt mode for VFIO */ volatile enum rte_intr_mode vfio_intr_mode;/** the shared VF token for VFIO-PCI bound PF and VFs devices */
lib/eal/freebsd/eal.c +2 -3
@@ -11,7 +11,6 @@#include <stdarg.h> #include <unistd.h> #include <pthread.h> -#include <syslog.h> #include <getopt.h> #include <sys/file.h> #include <stddef.h>
@@ -392,8 +391,8 @@ eal_parse_args(int argc, char **argv) goto out; } -/* eal_log_level_parse() already handled this option */ -if (opt ==OPT_LOG_LEVEL_NUM ) +/* eal_log_level_parse() already handled these */ +if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_LOG_SYSLOG_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
lib/eal/linux/eal.c +3 -4
@@ -610,8 +610,8 @@ eal_parse_args(int argc, char **argv) goto out; } -/* eal_log_level_parse() already handled this option */ -if (opt ==OPT_LOG_LEVEL_NUM ) +/* eal_log_level_parse() already handled these options */ +if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_SYSLOG_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
@@ -1113,8 +1113,7 @@ rte_eal_init(int argc, char **argv)#endif } -if (eal_log_init (program_invocation_short_name, - internal_conf->syslog_facility) <0 ) { +if (eal_log_init (program_invocation_short_name) <0 ) {rte_eal_init_alert ("Cannot init logging." ); rte_errno =ENOMEM ;rte_atomic_store_explicit (&run_once,0 , rte_memory_order_relaxed);
lib/eal/windows/eal.c +3 -3
@@ -120,8 +120,8 @@ eal_parse_args(int argc, char **argv)return -1 ; } -/* eal_log_level_parse() already handled this option */ -if (opt ==OPT_LOG_LEVEL_NUM ) +/* eal_log_level_parse() already handled these options */ +if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_SYSLOG_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
@@ -250,7 +250,7 @@ rte_eal_init(int argc, char **argv)char cpuset[RTE_CPU_AFFINITY_STR_LEN ];char thread_name[RTE_THREAD_NAME_SIZE ]; -eal_log_init (NULL ,0 ); +eal_log_init (NULL );eal_log_level_parse (argc, argv);
lib/log/log.c +2 -0
@@ -2,6 +2,7 @@* Copyright(c) 2010-2014 Intel Corporation */ +#include <stdbool.h> #include <stdio.h> #include <stdint.h> #include <stdarg.h>
@@ -12,6 +13,7 @@#include <fnmatch.h> #include <sys/queue.h> +#include <rte_common.h> #include <rte_log.h> #include <rte_per_lcore.h>
lib/log/log_freebsd.c +1 -1
@@ -6,7 +6,7 @@#include "log_internal.h" int -eal_log_init(__rte_unused const char *id, __rte_unused int facility) +eal_log_init(__rte_unused const char *id) {return 0 ; }
lib/log/log_internal.h +4 -1
@@ -14,7 +14,7 @@* Initialize the default log stream. */ __rte_internal -int eal_log_init(const char *id, int facility); +int eal_log_init(const char *id);/* * Determine where log data is written when no call to rte_openlog_stream.
@@ -30,6 +30,9 @@ int eal_log_save_regexp(const char *regexp, uint32_t level);__rte_internal int eal_log_save_pattern(const char *pattern, uint32_t level); +__rte_internal +int eal_log_syslog(const char *name); +/* * Convert log level to string. */
lib/log/log_linux.c +45 -2
72 lines not on this page · raw message
lib/log/log_windows.c +7 -1
@@ -6,9 +6,15 @@#include <rte_log.h> #include "log_internal.h" +int +eal_log_syslog(const char *name __rte_unused) +{ +return -1 ;/* not used */ +} +/* set the log to default function, called during eal init process. */ int -eal_log_init(__rte_unused const char *id, __rte_unused int facility) +eal_log_init(__rte_unused const char *id) {rte_openlog_stream (stderr);
lib/log/version.map +1 -0
@@ -30,5 +30,6 @@ INTERNAL { eal_log_save_pattern; eal_log_save_regexp; eal_log_set_default; + eal_log_syslog; rte_eal_log_cleanup; };
Signature · 1 line
2.45.2
PATCH v25 8/15 eal: initialize log before everything else
In reply to Stephen HemmingerIn order for all log messages (including CPU mismatch) to come out through the logging library, it must be initialized as early in rte_eal_init() as possible on all platforms.
Where it was done before was likely historical based on the support of non-OS isolated CPU's which required a shared memory buffer; that support was dropped before DPDK was publicly released.
--- lib/eal/freebsd/eal.c | 12 +++++++++--- lib/eal/linux/eal.c | 19 +++++++++---------- lib/eal/windows/eal.c | 8 ++++++-- lib/log/log_freebsd.c | 3 +-- lib/log/log_internal.h | 2 +- lib/log/log_linux.c | 14 ++++++-------- lib/log/log_windows.c | 4 +--- 7 files changed, 33 insertions(+), 29 deletions(-)
lib/eal/freebsd/eal.c +9 -3
@@ -52,6 +52,7 @@#include "eal_options.h" #include "eal_memcfg.h" #include "eal_trace.h" +#include "log_internal.h" #define MEMSIZE_IF_NO_HUGE_PAGE (64ULL * 1024ULL * 1024ULL)
@@ -546,6 +547,14 @@ rte_eal_init(int argc, char **argv)bool has_phys_addr;enum rte_iova_mode iova_mode; +/* setup log as early as possible */ +if (eal_log_level_parse (argc, argv) <0 ) { +rte_eal_init_alert ("invalid log arguments." ); + rte_errno =EINVAL ; +return -1 ; + } +eal_log_init (getprogname ()); +/* checks if the machine is adequate */ if (!rte_cpu_is_supported ()) {rte_eal_init_alert ("unsupported cpu type." );
@@ -572,9 +581,6 @@ rte_eal_init(int argc, char **argv)/* clone argv to report out later in telemetry */ eal_save_args (argc, argv); -/* set log level as early as possible */ -eal_log_level_parse (argc, argv); -if (rte_eal_cpu_init () <0 ) {rte_eal_init_alert ("Cannot detect lcores." ); rte_errno =ENOTSUP ;
lib/eal/linux/eal.c +9 -10
@@ -936,6 +936,15 @@ rte_eal_init(int argc, char **argv)struct internal_config *internal_conf =eal_get_internal_configuration (); +/* setup log as early as possible */ +if (eal_log_level_parse (argc, argv) <0 ) { +rte_eal_init_alert ("invalid log arguments." ); + rte_errno =EINVAL ; +return -1 ; + } + +eal_log_init (program_invocation_short_name); +/* checks if the machine is adequate */ if (!rte_cpu_is_supported ()) {rte_eal_init_alert ("unsupported cpu type." );
@@ -959,9 +968,6 @@ rte_eal_init(int argc, char **argv)eal_reset_internal_config (internal_conf); -/* set log level as early as possible */ -eal_log_level_parse (argc, argv); -/* clone argv to report out later in telemetry */ eal_save_args (argc, argv);
@@ -1113,13 +1119,6 @@ rte_eal_init(int argc, char **argv)#endif } -if (eal_log_init (program_invocation_short_name) <0 ) { -rte_eal_init_alert ("Cannot init logging." ); - rte_errno =ENOMEM ; -rte_atomic_store_explicit (&run_once,0 , rte_memory_order_relaxed); -return -1 ; - } -#ifdef VFIO_PRESENT if (rte_eal_vfio_setup () <0 ) {rte_eal_init_alert ("Cannot init VFIO" );
lib/eal/windows/eal.c +6 -2
@@ -250,9 +250,13 @@ rte_eal_init(int argc, char **argv)char cpuset[RTE_CPU_AFFINITY_STR_LEN ];char thread_name[RTE_THREAD_NAME_SIZE ]; -eal_log_init (NULL ); +if (eal_log_level_parse (argc, argv) <0 ) { +rte_eal_init_alert ("invalid log arguments." ); + rte_errno =EINVAL ; +return -1 ; + } -eal_log_level_parse (argc, argv); +eal_log_init (NULL );if (eal_create_cpu_map () <0 ) {rte_eal_init_alert ("Cannot discover CPU and NUMA." );
lib/log/log_freebsd.c +1 -2
@@ -5,8 +5,7 @@#include <rte_common.h> #include "log_internal.h" -int +void eal_log_init(__rte_unused const char *id) { -return 0 ; }
lib/log/log_internal.h +1 -1
@@ -14,7 +14,7 @@* Initialize the default log stream. */ __rte_internal -int eal_log_init(const char *id); +void eal_log_init(const char *id);/* * Determine where log data is written when no call to rte_openlog_stream.
lib/log/log_linux.c +6 -8
@@ -87,18 +87,16 @@ static cookie_io_functions_t console_log_func = {* set the log to default function, called during eal init process, * once memzones are available. */ -int +void eal_log_init (const char *id) {FILE *log_stream; - log_stream =fopencookie (NULL ,"w+" , console_log_func); -if (log_stream ==NULL ) -return -1 ; -openlog (id,LOG_NDELAY |LOG_PID , log_facility); -eal_log_set_default (log_stream); - -return 0 ; + log_stream =fopencookie (NULL ,"w+" , console_log_func); +if (log_stream !=NULL ) +eal_log_set_default (log_stream); +else +eal_log_set_default (stderr); }
lib/log/log_windows.c +1 -3
@@ -13,12 +13,10 @@ eal_log_syslog(const char *name __rte_unused) }/* set the log to default function, called during eal init process. */ -int +void eal_log_init(__rte_unused const char *id) {rte_openlog_stream (stderr);eal_log_set_default (stderr); - -return 0 ; }
Signature · 1 line
2.45.2
PATCH v25 9/15 log: drop syslog support, and make code common
In reply to Stephen HemmingerThis patch makes the log setup code common across all platforms.
Drops syslog support for now, will come back in later patch.
--- app/test/test_eal_flags.c | 11 ++- lib/eal/common/eal_common_options.c | 3 - lib/log/log.c | 41 +++++------ lib/log/log_freebsd.c | 11 --- lib/log/log_internal.h | 6 -- lib/log/log_linux.c | 102 ---------------------------- lib/log/log_windows.c | 22 ------ lib/log/meson.build | 5 +- lib/log/version.map | 1 - 9 files changed, 23 insertions(+), 179 deletions(-) delete mode 100644 lib/log/log_freebsd.c delete mode 100644 lib/log/log_linux.c delete mode 100644 lib/log/log_windows.c
app/test/test_eal_flags.c +5 -6
@@ -984,11 +984,10 @@ test_misc_flags(void)const char *argv1[] = {prgname, prefix, mp_flag,"--no-pci" };/* With -v */ const char *argv2[] = {prgname, prefix, mp_flag,"-v" }; +/* With empty --syslog */ +const char *argv3[] = {prgname, prefix, mp_flag,"--syslog" };/* With valid --syslog */ -const char *argv3[] = {prgname, prefix, mp_flag, -"--syslog" ,"syslog" }; -/* With empty --syslog (should fail) */ -const char *argv4[] = {prgname, prefix, mp_flag,"--syslog" }; +const char *argv4[] = {prgname, prefix, mp_flag,"--syslog" ,"always" };/* With invalid --syslog */ const char *argv5[] = {prgname, prefix, mp_flag,"--syslog" ,"error" };/* With no-sh-conf, also use no-huge to ensure this test runs on BSD */
@@ -1083,8 +1082,8 @@ test_misc_flags(void)printf ("Error - process did not run ok with --syslog flag\n" ); goto fail; } -if (launch_proc (argv4) ==0 ) { -printf ("Error - process run ok with empty --syslog flag\n" ); +if (launch_proc (argv4) !=0 ) { +printf ("Error - process did not with --syslog always flag\n" ); goto fail; }if (launch_proc (argv5) ==0 ) {
lib/eal/common/eal_common_options.c +0 -3
@@ -2206,9 +2206,6 @@ eal_common_usage(void)" (can be used multiple times)\n" " --" OPT_VMWARE_TSC_MAP " Use VMware TSC map instead of native RDTSC\n" " --" OPT_PROC_TYPE " Type of this process (primary|secondary|auto)\n" -#ifndef RTE_EXEC_ENV_WINDOWS -" --" OPT_SYSLOG " Set syslog facility\n" -#endif" --" OPT_LOG_LEVEL "=<level> Set global log level\n" " --" OPT_LOG_LEVEL "=<type-match>:<level>\n" " Set specific log level\n"
lib/log/log.c +17 -24
73 lines not on this page · raw message
lib/log/log_freebsd.c deleted +0 -11
@@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause -* Copyright(c) 2023 Intel Corporation -*/ - -#include <rte_common.h> -#include "log_internal.h" - -void -eal_log_init(__rte_unused const char *id) -{ -}
lib/log/log_internal.h +0 -6
@@ -16,12 +16,6 @@__rte_internal void eal_log_init(const char *id); -/* -* Determine where log data is written when no call to rte_openlog_stream. -*/ -__rte_internal -void eal_log_set_default(FILE *default_log); -/* * Save a log option for later. */
lib/log/log_linux.c deleted +0 -102
102 lines not on this page · raw message
lib/log/log_windows.c deleted +0 -22
@@ -1,22 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause -* Copyright(c) 2017-2018 Intel Corporation -*/ - -#include <rte_common.h> -#include <rte_log.h> -#include "log_internal.h" - -int -eal_log_syslog(const char *name __rte_unused) -{ -return -1 ;/* not used */ -} - -/* set the log to default function, called during eal init process. */ -void -eal_log_init(__rte_unused const char *id) -{ -rte_openlog_stream (stderr); - -eal_log_set_default (stderr); -}
lib/log/meson.build +1 -4
@@ -2,8 +2,5 @@ # Copyright(c) 2023 Intel Corporation includes += global_inc -sources = files( - 'log.c', - 'log_' + exec_env + '.c', -) +sources = files('log.c') headers = files('rte_log.h')
lib/log/version.map +0 -1
@@ -29,7 +29,6 @@ INTERNAL { eal_log_level2str; eal_log_save_pattern; eal_log_save_regexp; - eal_log_set_default; eal_log_syslog; rte_eal_log_cleanup; };
Signature · 1 line
2.45.2
PATCH v25 10/15 log: add hook for printing log messages
In reply to Stephen HemmingerThis is useful for when decorating log output for console or journal. Provide basic version in this patch.
--- lib/log/log.c | 6 +++++- lib/log/log_private.h | 9 +++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 lib/log/log_private.h
lib/log/log.c +5 -1
@@ -18,6 +18,7 @@#include <rte_per_lcore.h> #include "log_internal.h" +#include "log_private.h" #ifdef RTE_EXEC_ENV_WINDOWS #define strdup _strdup
@@ -33,11 +34,13 @@ static struct rte_logs {uint32_t type;/**< Bitfield with enabled logs. */ uint32_t level;/**< Log level. */ FILE *file;/**< Output file set by rte_openlog_stream, or NULL. */ +log_print_t print_func;size_t dynamic_types_len;struct rte_log_dynamic_type *dynamic_types; } rte_logs = { .type = UINT32_MAX, .level = RTE_LOG_DEBUG, + .print_func = vfprintf, };struct rte_eal_opt_loglevel {
@@ -74,6 +77,7 @@ int rte_openlog_stream(FILE *f) { rte_logs.file = f; + rte_logs.print_func = vfprintf;return 0 ; }
@@ -470,7 +474,7 @@ rte_vlog(uint32_t level, uint32_t logtype, const char *format, va_list ap)RTE_PER_LCORE (log_cur_msg).loglevel = level;RTE_PER_LCORE (log_cur_msg).logtype = logtype; - ret =vfprintf (f, format, ap); + ret = (*rte_logs.print_func)(f, format, ap);fflush (f);return ret; }
lib/log/log_private.h new file +9 -0
@@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#ifndef LOG_PRIVATE_H +#define LOG_PRIVATE_H + +/* Note: same as vfprintf() */ +typedef int (*log_print_t )(FILE *f,const char *fmt,va_list ap); + +#endif /* LOG_PRIVATE_H */
Signature · 1 line
2.45.2
PATCH v25 11/15 log: add timestamp option
In reply to Stephen HemmingerWhen debugging driver or startup issues, it is useful to have a timestamp on each message printed. The messages in syslog already have a timestamp, but often syslog is not available during testing.
There are multiple timestamp formats similar to Linux dmesg. The default is time relative since startup (when first step of logging initialization is done by constructor). Other alternative formats are delta, ctime, reltime and iso formats.
Example:
$ dpdk-testpmd --log-timestamp -- -i [ 0.008610] EAL: Detected CPU lcores: 8 [ 0.008634] EAL: Detected NUMA nodes: 1 [ 0.008792] EAL: Detected static linkage of DPDK [ 0.010620] EAL: Multi-process socket /var/run/dpdk/rte/mp_socket [ 0.012618] EAL: Selected IOVA mode 'VA' [ 0.016675] testpmd: No probed ethernet devices Interactive-mode selected
--- app/test/test_eal_flags.c | 26 +++ doc/guides/prog_guide/log_lib.rst | 26 +++ lib/eal/common/eal_common_options.c | 14 +- lib/eal/common/eal_options.h | 2 + lib/eal/freebsd/eal.c | 6 +- lib/eal/linux/eal.c | 4 +- lib/eal/windows/eal.c | 4 +- lib/log/log.c | 7 +- lib/log/log_internal.h | 9 ++ lib/log/log_private.h | 11 ++ lib/log/log_timestamp.c | 240 ++++++++++++++++++++++++++++ lib/log/meson.build | 6 +- lib/log/version.map | 1 + 13 files changed, 348 insertions(+), 8 deletions(-) create mode 100644 lib/log/log_timestamp.c
app/test/test_eal_flags.c +26 -0
@@ -1054,6 +1054,19 @@ test_misc_flags(void)const char *const argv22[] = {prgname, prefix, mp_flag,"--huge-worker-stack=512" }; +/* Try running with --log-timestamp */ +const char *const argv23[] = {prgname, prefix, mp_flag, +"--log-timestamp" }; + +/* Try running with --log-timestamp=iso */ +const char *const argv24[] = {prgname, prefix, mp_flag, +"--log-timestamp=iso" }; + +/* Try running with invalid timestamp */ +const char *const argv25[] = {prgname, prefix, mp_flag, +"--log-timestamp=invalid" }; + +/* run all tests also applicable to FreeBSD first */ if (launch_proc (argv0) ==0 ) {
@@ -1161,6 +1174,19 @@ test_misc_flags(void)printf ("Error - process did not run ok with --huge-worker-stack=size parameter\n" ); goto fail; } +if (launch_proc (argv23) !=0 ) { +printf ("Error - process did not run ok with --log-timestamp parameter\n" ); + goto fail; + } +if (launch_proc (argv24) !=0 ) { +printf ("Error - process did not run ok with --log-timestamp=iso parameter\n" ); + goto fail; + } +if (launch_proc (argv25) ==0 ) { +printf ("Error - process did run ok with --log-timestamp=invalid parameter\n" ); + goto fail; + } +rmdir (hugepath_dir3);rmdir (hugepath_dir2);
doc/guides/prog_guide/log_lib.rst +26 -0
@@ -59,6 +59,32 @@ For example:: Within an application, the same result can be got using the ``rte_log_set_level_pattern()`` or ``rte_log_set_level_regex()`` APIs. +Log timestamp +~~~~~~~~~~~~~ + +An optional timestamp can be added before each message +by adding the ``--log-timestamp`` option. +For example:: + + /path/to/app --log-level=lib.*:debug --log-timestamp + +Multiple timestamp alternative timestamp formats are available: + +.. csv-table:: Log time stamp format + :header: "Format", "Description", "Example" + :widths: 6, 30, 32 + + "ctime", "Unix ctime", "``[Wed Mar 20 07:26:12 2024]``" + "delta", "Offset since last", "``[< 3.162373>]``" + "reltime", "Seconds since last or time if minute changed", "``[ +3.001791]`` or ``[Mar20 07:26:12]``" + "iso", "ISO-8601", "``[2024-03-20T07:26:12−07:00]``" + +To prefix all console messages with ISO format time the syntax is:: + + /path/to/app --log-timestamp=iso + + + Using Logging APIs to Generate Log Messages -------------------------------------------
lib/eal/common/eal_common_options.c +12 -2
@@ -74,6 +74,7 @@ eal_long_options[] = { {OPT_IOVA_MODE, 1, NULL, OPT_IOVA_MODE_NUM }, {OPT_LCORES, 1, NULL, OPT_LCORES_NUM }, {OPT_LOG_LEVEL, 1, NULL, OPT_LOG_LEVEL_NUM }, + {OPT_LOG_TIMESTAMP, 2, NULL, OPT_LOG_TIMESTAMP_NUM }, {OPT_TRACE, 1, NULL, OPT_TRACE_NUM }, {OPT_TRACE_DIR, 1, NULL, OPT_TRACE_DIR_NUM }, {OPT_TRACE_BUF_SIZE, 1, NULL, OPT_TRACE_BUF_SIZE_NUM },
@@ -1616,6 +1617,7 @@ eal_log_level_parse(int argc, char * const argv[])switch (opt) {case OPT_LOG_LEVEL_NUM :case OPT_SYSLOG_NUM : +case OPT_LOG_TIMESTAMP_NUM :if (eal_parse_common_option (opt, optarg, internal_conf) <0 )return -1 ;break ;
@@ -1838,7 +1840,7 @@ eal_parse_common_option(int opt, const char *optarg,break ;#endif -case OPT_LOG_LEVEL_NUM : { +case OPT_LOG_LEVEL_NUM :if (eal_parse_log_level (optarg) <0 ) {EAL_LOG (ERR , "invalid parameters for --"
@@ -1846,7 +1848,14 @@ eal_parse_common_option(int opt, const char *optarg,return -1 ; }break ; - } + +case OPT_LOG_TIMESTAMP_NUM : +if (eal_log_timestamp (optarg) <0 ) { +EAL_LOG (ERR ,"invalid parameters for --" +OPT_LOG_TIMESTAMP ); +return -1 ; + } +break ;#ifndef RTE_EXEC_ENV_WINDOWS case OPT_TRACE_NUM : {
@@ -2210,6 +2219,7 @@ eal_common_usage(void)" --" OPT_LOG_LEVEL "=<type-match>:<level>\n" " Set specific log level\n" " --" OPT_LOG_LEVEL "=help Show log types and levels\n" +" --" OPT_LOG_TIMESTAMP "[=<format>] Timestamp log output\n" #ifndef RTE_EXEC_ENV_WINDOWS" --" OPT_TRACE "=<regex-match>\n" " Enable trace based on regular expression trace name.\n"
lib/eal/common/eal_options.h +2 -0
@@ -35,6 +35,8 @@ enum {OPT_LCORES_NUM , #define OPT_LOG_LEVEL "log-level"OPT_LOG_LEVEL_NUM , +#define OPT_LOG_TIMESTAMP "log-timestamp" +OPT_LOG_TIMESTAMP_NUM , #define OPT_TRACE "trace"OPT_TRACE_NUM , #define OPT_TRACE_DIR "trace-dir"
lib/eal/freebsd/eal.c +4 -2
@@ -392,8 +392,10 @@ eal_parse_args(int argc, char **argv) goto out; } -/* eal_log_level_parse() already handled these */ -if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_LOG_SYSLOG_NUM ) +/* eal_log_level_parse() already handled these options */ +if (opt ==OPT_LOG_LEVEL_NUM || + opt ==OPT_SYSLOG_NUM || + opt ==OPT_LOG_TIMESTAMP_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
lib/eal/linux/eal.c +3 -1
@@ -611,7 +611,9 @@ eal_parse_args(int argc, char **argv) }/* eal_log_level_parse() already handled these options */ -if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_SYSLOG_NUM ) +if (opt ==OPT_LOG_LEVEL_NUM || + opt ==OPT_SYSLOG_NUM || + opt ==OPT_LOG_TIMESTAMP_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
lib/eal/windows/eal.c +3 -1
@@ -121,7 +121,9 @@ eal_parse_args(int argc, char **argv) }/* eal_log_level_parse() already handled these options */ -if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_SYSLOG_NUM ) +if (opt ==OPT_LOG_LEVEL_NUM || + opt ==OPT_SYSLOG_NUM || + opt ==OPT_LOG_TIMESTAMP_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
lib/log/log.c +6 -1
@@ -21,7 +21,7 @@#include "log_private.h" #ifdef RTE_EXEC_ENV_WINDOWS -#define strdup _strdup +#include <rte_os_shim.h> #endif struct rte_log_dynamic_type {
@@ -509,6 +509,11 @@ eal_log_syslog(const char *mode __rte_unused)void eal_log_init(const char *id __rte_unused) { +if (log_timestamp_enabled ()) + rte_logs.print_func = log_print_with_timestamp; +else + rte_logs.print_func = vfprintf; +#if RTE_LOG_DP_LEVEL >=RTE_LOG_DEBUG RTE_LOG (NOTICE ,EAL ,"Debug dataplane logs available - lower performance\n" );
lib/log/log_internal.h +9 -0
@@ -5,8 +5,10 @@#ifndef LOG_INTERNAL_H #define LOG_INTERNAL_H +#include <stdbool.h> #include <stdio.h> #include <stdint.h> +#include <time.h> #include <rte_compat.h>
@@ -39,4 +41,11 @@ const char *eal_log_level2str(uint32_t level);__rte_internal void rte_eal_log_cleanup(void); +/* +* Add timestamp to console logs +*/ +__rte_internal +int eal_log_timestamp(const char *fmt); + +#endif /* LOG_INTERNAL_H */
lib/log/log_private.h +11 -0
@@ -3,7 +3,18 @@#ifndef LOG_PRIVATE_H #define LOG_PRIVATE_H +/* Defined in limits.h on Linux */ +#ifndef LINE_MAX +#define LINE_MAX 2048/* _POSIX2_LINE_MAX */ +#endif +/* Note: same as vfprintf() */ typedef int (*log_print_t )(FILE *f,const char *fmt,va_list ap); +bool log_timestamp_enabled (void ); +ssize_t log_timestamp (char *tsbuf,size_t tsbuflen); + +__rte_format_printf(2, 0) +int log_print_with_timestamp (FILE *f,const char *format,va_list ap); +#endif /* LOG_PRIVATE_H */
lib/log/log_timestamp.c new file +240 -0
240 lines not on this page · raw message
lib/log/meson.build +5 -1
@@ -2,5 +2,9 @@ # Copyright(c) 2023 Intel Corporation includes += global_inc -sources = files('log.c') +sources = files( + 'log.c', + 'log_timestamp.c', +) + headers = files('rte_log.h')
lib/log/version.map +1 -0
@@ -30,5 +30,6 @@ INTERNAL { eal_log_save_pattern; eal_log_save_regexp; eal_log_syslog; + eal_log_timestamp; rte_eal_log_cleanup; };
Signature · 1 line
2.45.2
PATCH v25 12/15 log: add optional support of syslog
In reply to Stephen HemmingerLog to syslog only if option is specified. And if syslog is used then normally only log to syslog, don't duplicate output. Also enables syslog support on FreeBSD.
--- app/test/test_eal_flags.c | 5 +- doc/guides/linux_gsg/linux_eal_parameters.rst | 27 ------ doc/guides/prog_guide/log_lib.rst | 17 ++++ lib/eal/common/eal_common_options.c | 5 +- lib/log/log.c | 28 +++--- lib/log/log_private.h | 17 ++++ lib/log/log_syslog.c | 88 +++++++++++++++++++ lib/log/meson.build | 4 + lib/log/version.map | 2 +- 9 files changed, 150 insertions(+), 43 deletions(-) create mode 100644 lib/log/log_syslog.c
app/test/test_eal_flags.c +3 -2
@@ -987,9 +987,10 @@ test_misc_flags(void)/* With empty --syslog */ const char *argv3[] = {prgname, prefix, mp_flag,"--syslog" };/* With valid --syslog */ -const char *argv4[] = {prgname, prefix, mp_flag,"--syslog" ,"always" }; +const char *argv4[] = {prgname, prefix, mp_flag,"--syslog=both" };/* With invalid --syslog */ -const char *argv5[] = {prgname, prefix, mp_flag,"--syslog" ,"error" }; +const char *argv5[] = {prgname, prefix, mp_flag,"--syslog=invalid" }; +/* With no-sh-conf, also use no-huge to ensure this test runs on BSD */ const char *argv6[] = {prgname,"-m" ,DEFAULT_MEM_SIZE , no_shconf, nosh_prefix, no_huge};
doc/guides/linux_gsg/linux_eal_parameters.rst +0 -27
@@ -108,30 +108,3 @@ Memory-related options * ``--match-allocations`` Free hugepages back to system exactly as they were originally allocated. - -Other options -~~~~~~~~~~~~~ - -* ``--syslog <syslog facility>`` - - Set syslog facility. Valid syslog facilities are:: - - auth - cron - daemon - ftp - kern - lpr - mail - news - syslog - user - uucp - local0 - local1 - local2 - local3 - local4 - local5 - local6 - local7
doc/guides/prog_guide/log_lib.rst +17 -0
@@ -83,6 +83,23 @@ To prefix all console messages with ISO format time the syntax is:: /path/to/app --log-timestamp=iso +Log output +~~~~~~~~~~ + +If desired, messages can be redirected to syslog (on Linux and FreeBSD) with the ``--syslog`` +option. There are three possible settings for this option: + +*always* + Redirect all log output to syslog. + +*auto* + Use console if it is a terminal, and use syslog if is not. + +*both* + Print to both console and syslog. + +If ``--syslog`` option is not specified, then only console (stderr) will be used. + Using Logging APIs to Generate Log Messages
lib/eal/common/eal_common_options.c +4 -1
@@ -91,7 +91,7 @@ eal_long_options[] = { {OPT_PROC_TYPE, 1, NULL, OPT_PROC_TYPE_NUM }, {OPT_SOCKET_MEM, 1, NULL, OPT_SOCKET_MEM_NUM }, {OPT_SOCKET_LIMIT, 1, NULL, OPT_SOCKET_LIMIT_NUM }, - {OPT_SYSLOG, 1, NULL, OPT_SYSLOG_NUM }, + {OPT_SYSLOG, 2, NULL, OPT_SYSLOG_NUM }, {OPT_VDEV, 1, NULL, OPT_VDEV_NUM }, {OPT_VFIO_INTR, 1, NULL, OPT_VFIO_INTR_NUM }, {OPT_VFIO_VF_TOKEN, 1, NULL, OPT_VFIO_VF_TOKEN_NUM },
@@ -2215,6 +2215,9 @@ eal_common_usage(void)" (can be used multiple times)\n" " --" OPT_VMWARE_TSC_MAP " Use VMware TSC map instead of native RDTSC\n" " --" OPT_PROC_TYPE " Type of this process (primary|secondary|auto)\n" +#ifndef RTE_EXEC_ENV_WINDOWS +" --" OPT_SYSLOG "[=<when>] Enable use of syslog\n" +#endif " --"OPT_LOG_LEVEL"=<level> Set global log level\n"" --" OPT_LOG_LEVEL "=<type-match>:<level>\n" " Set specific log level\n"
lib/log/log.c +16 -12
@@ -12,18 +12,19 @@#include <regex.h> #include <fnmatch.h> #include <sys/queue.h> +#include <unistd.h> #include <rte_common.h> #include <rte_log.h> #include <rte_per_lcore.h> -#include "log_internal.h" -#include "log_private.h" -#ifdef RTE_EXEC_ENV_WINDOWS #include <rte_os_shim.h> #endif +#include "log_internal.h" +#include "log_private.h" +struct rte_log_dynamic_type {const char *name;uint32_t loglevel;
@@ -496,20 +497,23 @@ rte_log(uint32_t level, uint32_t logtype, const char *format, ...)return ret; } -/* Placeholder */ -int -eal_log_syslog(const char *mode __rte_unused) -{ -return -1 ; -} -/* * Called by rte_eal_init */ void -eal_log_init(const char *id __rte_unused) +eal_log_init (const char *id) { -if (log_timestamp_enabled ()) +bool is_terminal; + +#ifdef RTE_EXEC_ENV_WINDOWS + is_terminal =_isatty (_fileno (stderr)); +#else + is_terminal =isatty (STDERR_FILENO ); +#endif + +if (log_syslog_enabled (is_terminal)) +log_syslog_open (id, is_terminal); +else if (log_timestamp_enabled ()) rte_logs.print_func = log_print_with_timestamp;else rte_logs.print_func = vfprintf;
lib/log/log_private.h +17 -0
@@ -17,4 +17,21 @@ ssize_t log_timestamp(char *tsbuf, size_t tsbuflen); __rte_format_printf(2, 0)int log_print_with_timestamp (FILE *f,const char *format,va_list ap); +#ifdef RTE_EXEC_ENV_WINDOWS +static inline bool +log_syslog_enabled(bool is_tty __rte_unused) +{ +return false; +} + +static inline void +log_syslog_open(const char *id __rte_unused, bool is_terminal __rte_unused) +{ +} +#else + +bool log_syslog_enabled (bool is_tty); +void log_syslog_open (const char *id,bool is_terminal); +#endif +#endif /* LOG_PRIVATE_H */
lib/log/log_syslog.c new file +88 -0
88 lines not on this page · raw message
lib/log/meson.build +4 -0
@@ -7,4 +7,8 @@ sources = files( 'log_timestamp.c', ) +if not is_windows + sources += files('log_syslog.c') +endif + headers = files('rte_log.h')
lib/log/version.map +1 -1
@@ -29,7 +29,7 @@ INTERNAL { eal_log_level2str; eal_log_save_pattern; eal_log_save_regexp; - eal_log_syslog; + eal_log_syslog; # WINDOWS_NO_EXPORT eal_log_timestamp; rte_eal_log_cleanup; };
Signature · 1 line
2.45.2
PATCH v25 13/15 log: add support for systemd journal
In reply to Stephen HemmingerIf DPDK application is being run as a systemd service, then it can use the journal protocol which allows putting more information in the log such as priority and other information.
The use of journal protocol is automatically detected and handled. Rather than having a dependency on libsystemd, just use the protocol directly as defined in:
https://systemd.io/JOURNAL_NATIVE_PROTOCOL/
--- doc/guides/prog_guide/log_lib.rst | 14 ++ lib/eal/common/eal_common_options.c | 15 +++ lib/eal/common/eal_options.h | 2 + lib/log/log.c | 4 +- lib/log/log_internal.h | 3 + lib/log/log_journal.c | 200 ++++++++++++++++++++++++++++ lib/log/log_private.h | 16 +++ lib/log/meson.build | 4 + lib/log/version.map | 1 + 9 files changed, 258 insertions(+), 1 deletion(-) create mode 100644 lib/log/log_journal.c
doc/guides/prog_guide/log_lib.rst +14 -0
@@ -100,6 +100,20 @@ option. There are three possible settings for this option: If ``--syslog`` option is not specified, then only console (stderr) will be used. +Messages can be redirected to systemd journal which is an enhanced version of syslog with the ``--log-journal`` option. + +There are three possible settings for this option: + +*auto* + If stderr is redirected to journal by ``systemd`` service + then use journal socket to instead of stderr for log. + This is the default. + +*never* + Do not try to use journal. + +*always* + Always try to direct messages to journal socket. Using Logging APIs to Generate Log Messages
lib/eal/common/eal_common_options.c +15 -0
@@ -74,6 +74,7 @@ eal_long_options[] = { {OPT_IOVA_MODE, 1, NULL, OPT_IOVA_MODE_NUM }, {OPT_LCORES, 1, NULL, OPT_LCORES_NUM }, {OPT_LOG_LEVEL, 1, NULL, OPT_LOG_LEVEL_NUM }, + {OPT_LOG_JOURNAL, 2, NULL, OPT_LOG_JOURNAL_NUM }, {OPT_LOG_TIMESTAMP, 2, NULL, OPT_LOG_TIMESTAMP_NUM }, {OPT_TRACE, 1, NULL, OPT_TRACE_NUM }, {OPT_TRACE_DIR, 1, NULL, OPT_TRACE_DIR_NUM },
@@ -1617,6 +1618,7 @@ eal_log_level_parse(int argc, char * const argv[])switch (opt) {case OPT_LOG_LEVEL_NUM :case OPT_SYSLOG_NUM : +case OPT_LOG_JOURNAL_NUM :case OPT_LOG_TIMESTAMP_NUM :if (eal_parse_common_option (opt, optarg, internal_conf) <0 )return -1 ;
@@ -1840,6 +1842,16 @@ eal_parse_common_option(int opt, const char *optarg,break ;#endif +#ifdef RTE_EXEC_ENV_LINUX +case OPT_LOG_JOURNAL_NUM : +if (eal_log_journal (optarg) <0 ) { +EAL_LOG (ERR ,"invalid parameters for --" +OPT_LOG_JOURNAL ); +return -1 ; + } +break ; +#endif +case OPT_LOG_LEVEL_NUM :if (eal_parse_log_level (optarg) <0 ) { EAL_LOG(ERR,
@@ -2217,6 +2229,9 @@ eal_common_usage(void) " --"OPT_PROC_TYPE" Type of this process (primary|secondary|auto)\n" #ifndef RTE_EXEC_ENV_WINDOWS " --"OPT_SYSLOG"[=<when>] Enable use of syslog\n" +#endif +#ifdef RTE_EXEC_ENV_LINUX + " --"OPT_LOG_JOURNAL"[=<when>] Enable use of systemd journal\n"#endif " --" OPT_LOG_LEVEL "=<level> Set global log level\n" " --" OPT_LOG_LEVEL "=<type-match>:<level>\n"
lib/eal/common/eal_options.h +2 -0
@@ -35,6 +35,8 @@ enum {OPT_LCORES_NUM , #define OPT_LOG_LEVEL "log-level"OPT_LOG_LEVEL_NUM , +#define OPT_LOG_JOURNAL "log-journal" +OPT_LOG_JOURNAL_NUM , #define OPT_LOG_TIMESTAMP "log-timestamp"OPT_LOG_TIMESTAMP_NUM , #define OPT_TRACE "trace"
lib/log/log.c +3 -1
@@ -511,7 +511,9 @@ eal_log_init(const char *id) is_terminal =isatty (STDERR_FILENO );#endif -if (log_syslog_enabled (is_terminal)) +if (log_journal_enabled ()) +log_journal_open (id); +else if (log_syslog_enabled (is_terminal))log_syslog_open (id, is_terminal);else if (log_timestamp_enabled ()) rte_logs.print_func = log_print_with_timestamp;
lib/log/log_internal.h +3 -0
@@ -29,6 +29,9 @@ int eal_log_save_pattern(const char *pattern, uint32_t level);__rte_internal int eal_log_syslog(const char *name); +__rte_internal +int eal_log_journal(const char *opt); +/* * Convert log level to string. */
lib/log/log_journal.c new file +200 -0
200 lines not on this page · raw message
lib/log/log_private.h +16 -0
@@ -34,4 +34,20 @@ bool log_syslog_enabled(bool is_tty);void log_syslog_open (const char *id,bool is_terminal);#endif +#ifdef RTE_EXEC_ENV_LINUX +bool log_journal_enabled (void ); +void log_journal_open (const char *id); +#else +static inline bool +log_journal_enabled (void ) +{ +return false; +} + +static inline void +log_journal_open(const char *id __rte_unused) +{ +} +#endif /* !RTE_EXEC_ENV_LINUX */ +#endif /* LOG_PRIVATE_H */
lib/log/meson.build +4 -0
@@ -11,4 +11,8 @@ if not is_windows sources += files('log_syslog.c') endif +if is_linux + sources += files('log_journal.c') +endif + headers = files('rte_log.h')
lib/log/version.map +1 -0
@@ -26,6 +26,7 @@ INTERNAL { global: eal_log_init; + eal_log_journal; # WINDOWS_NO_EXPORT eal_log_level2str; eal_log_save_pattern; eal_log_save_regexp;
Signature · 1 line
2.45.2
PATCH v25 14/15 log: colorize log output
In reply to Stephen HemmingerLike dmesg, colorize the log output (unless redirected to file). Timestamp is green, the subsystem is in yellow and the message is red if urgent, boldface if an error, and normal for info and debug messages.
--- app/test/test_eal_flags.c | 24 +++++ doc/guides/prog_guide/log_lib.rst | 15 +++ lib/eal/common/eal_common_options.c | 11 +++ lib/eal/common/eal_options.h | 6 +- lib/log/log.c | 19 ++-- lib/log/log_color.c | 148 ++++++++++++++++++++++++++++ lib/log/log_internal.h | 5 + lib/log/log_private.h | 8 ++ lib/log/meson.build | 1 + lib/log/version.map | 1 + 10 files changed, 230 insertions(+), 8 deletions(-) create mode 100644 lib/log/log_color.c
app/test/test_eal_flags.c +24 -0
@@ -1067,6 +1067,18 @@ test_misc_flags(void)const char *const argv25[] = {prgname, prefix, mp_flag,"--log-timestamp=invalid" }; +/* Try running with --log-color */ +const char *const argv26[] = {prgname, prefix, mp_flag, +"--log-color" }; + +/* Try running with --log-color=never */ +const char *const argv27[] = {prgname, prefix, mp_flag, +"--log-color=never" }; + +/* Try running with --log-color=invalid */ +const char *const argv28[] = {prgname, prefix, mp_flag, +"--log-color=invalid" }; +/* run all tests also applicable to FreeBSD first */
@@ -1187,6 +1199,18 @@ test_misc_flags(void)printf ("Error - process did run ok with --log-timestamp=invalid parameter\n" ); goto fail; } +if (launch_proc (argv26) !=0 ) { +printf ("Error - process did not run ok with --log-color parameter\n" ); + goto fail; + } +if (launch_proc (argv27) !=0 ) { +printf ("Error - process did not run ok with --log-color=none parameter\n" ); + goto fail; + } +if (launch_proc (argv28) ==0 ) { +printf ("Error - process did run ok with --log-timestamp=invalid parameter\n" ); + goto fail; + }rmdir (hugepath_dir3);
doc/guides/prog_guide/log_lib.rst +15 -0
@@ -59,6 +59,21 @@ For example:: Within an application, the same result can be got using the ``rte_log_set_level_pattern()`` or ``rte_log_set_level_regex()`` APIs. +Color output +~~~~~~~~~~~~ + +The log library will highlight important messages. +This is controlled by the ``--log-color`` option. +he optional argument ``when`` can be ``auto``, ``never``, or ``always``. +The default setting is ``auto`` which enables color when the output to +``stderr`` is a terminal. +If the ``when`` argument is omitted, it defaults to ``always``. + +For example to turn off all coloring:: + + /path/to/app --log-color=none + + Log timestamp ~~~~~~~~~~~~~
lib/eal/common/eal_common_options.c +11 -0
@@ -73,6 +73,7 @@ eal_long_options[] = { {OPT_HUGE_UNLINK, 2, NULL, OPT_HUGE_UNLINK_NUM }, {OPT_IOVA_MODE, 1, NULL, OPT_IOVA_MODE_NUM }, {OPT_LCORES, 1, NULL, OPT_LCORES_NUM }, + {OPT_LOG_COLOR, 2, NULL, OPT_LOG_COLOR_NUM }, {OPT_LOG_LEVEL, 1, NULL, OPT_LOG_LEVEL_NUM }, {OPT_LOG_JOURNAL, 2, NULL, OPT_LOG_JOURNAL_NUM }, {OPT_LOG_TIMESTAMP, 2, NULL, OPT_LOG_TIMESTAMP_NUM },
@@ -1620,6 +1621,7 @@ eal_log_level_parse(int argc, char * const argv[])case OPT_SYSLOG_NUM :case OPT_LOG_JOURNAL_NUM :case OPT_LOG_TIMESTAMP_NUM : +case OPT_LOG_COLOR_NUM :if (eal_parse_common_option (opt, optarg, internal_conf) <0 )return -1 ;break ;
@@ -1869,6 +1871,14 @@ eal_parse_common_option(int opt, const char *optarg, }break ; +case OPT_LOG_COLOR_NUM : +if (eal_log_color (optarg) <0 ) { +EAL_LOG (ERR ,"invalid parameters for --" +OPT_LOG_COLOR ); +return -1 ; + } +break ; +#ifndef RTE_EXEC_ENV_WINDOWS case OPT_TRACE_NUM : {if (eal_trace_args_save (optarg) <0 ) {
@@ -2238,6 +2248,7 @@ eal_common_usage(void)" Set specific log level\n" " --" OPT_LOG_LEVEL "=help Show log types and levels\n" " --" OPT_LOG_TIMESTAMP "[=<format>] Timestamp log output\n" +" --" OPT_LOG_COLOR "[=<when>] Colorize log messages\n" #ifndef RTE_EXEC_ENV_WINDOWS" --" OPT_TRACE "=<regex-match>\n" " Enable trace based on regular expression trace name.\n"
lib/eal/common/eal_options.h +4 -2
@@ -33,10 +33,12 @@ enum {OPT_HUGE_UNLINK_NUM , #define OPT_LCORES "lcores"OPT_LCORES_NUM , -#define OPT_LOG_LEVEL "log-level" -OPT_LOG_LEVEL_NUM , +#define OPT_LOG_COLOR "log-color" +OPT_LOG_COLOR_NUM , #define OPT_LOG_JOURNAL "log-journal"OPT_LOG_JOURNAL_NUM , +#define OPT_LOG_LEVEL "log-level" +OPT_LOG_LEVEL_NUM , #define OPT_LOG_TIMESTAMP "log-timestamp"OPT_LOG_TIMESTAMP_NUM , #define OPT_TRACE "trace"
lib/log/log.c +13 -6
@@ -511,14 +511,21 @@ eal_log_init(const char *id) is_terminal =isatty (STDERR_FILENO );#endif -if (log_journal_enabled ()) +if (log_journal_enabled ()) {log_journal_open (id); -else if (log_syslog_enabled (is_terminal)) + }else if (log_syslog_enabled (is_terminal)) {log_syslog_open (id, is_terminal); -else if (log_timestamp_enabled ()) - rte_logs.print_func = log_print_with_timestamp; -else - rte_logs.print_func = vfprintf; + }else if (log_timestamp_enabled ()) { +if (log_color_enabled (is_terminal)) + rte_logs.print_func = color_print_with_timestamp; +else + rte_logs.print_func = log_print_with_timestamp; + }else { +if (log_color_enabled (is_terminal)) + rte_logs.print_func = color_print; +else + rte_logs.print_func = vfprintf; + }#if RTE_LOG_DP_LEVEL >=RTE_LOG_DEBUG RTE_LOG(NOTICE, EAL,
lib/log/log_color.c new file +148 -0
148 lines not on this page · raw message
lib/log/log_internal.h +5 -0
@@ -50,5 +50,10 @@ void rte_eal_log_cleanup(void);__rte_internal int eal_log_timestamp(const char *fmt); +/* +* Enable or disable color in log messages +*/ +__rte_internal +int eal_log_color(const char *mode);#endif /* LOG_INTERNAL_H */
lib/log/log_private.h +8 -0
@@ -50,4 +50,12 @@ log_journal_open(const char *id __rte_unused) }#endif /* !RTE_EXEC_ENV_LINUX */ +bool log_color_enabled (bool is_tty); + +__rte_format_printf(2, 0) +int color_print (FILE *f,const char *format,va_list ap); + +__rte_format_printf(2, 0) +int color_print_with_timestamp (FILE *f,const char *format,va_list ap); +#endif /* LOG_PRIVATE_H */
lib/log/meson.build +1 -0
@@ -4,6 +4,7 @@ includes += global_inc sources = files( 'log.c', + 'log_color.c', 'log_timestamp.c', )
lib/log/version.map +1 -0
@@ -25,6 +25,7 @@ DPDK_25 { INTERNAL { global: + eal_log_color; eal_log_init; eal_log_journal; # WINDOWS_NO_EXPORT eal_log_level2str;
Signature · 1 line
2.45.2
PATCH v25 15/15 doc: add release note about log library
In reply to Stephen HemmingerSignificant enough to add some documentation.
--- doc/guides/rel_notes/release_24_11.rst | 27 ++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
doc/guides/rel_notes/release_24_11.rst +27 -0
@@ -55,6 +55,33 @@ New Features Also, make sure to start the actual text at the margin. ======================================================= +* **Enhancements to logging library.** + + * Syslog related changes + + * The meaning of the *--syslog* option has changed. + Use of syslog is controlled by the *--syslog* option. + The default is now *auto* which uses syslog only if stderr + is not a terminal device. + + * The syslog facility is now set to **LOG_USER** if stderr is a terminal + and **LOG_DAEMON** otherwise. + + * Syslog is now supported on FreeBSD (but not on Windows). + + * The log is initialized earlier in startup so all messages go through + the library. + + * Added a new option to timestamp log messages, which is useful for + debugging delays in application and driver startup. + + * Log messages are now in color if going to a terminal (similar to dmesg). + The default format shows timestamp in green, subsystem in yellow, + and the message is bold, boldface or normal depending on severity. + + * If the application is a systemd service and the log output is being + sent of standard error then DPDK will switch to journal native protocol. + Removed Items -------------
Signature · 1 line
2.45.2
Re: [PATCH v25 15/15] doc: add release note about log library
Quoted 7 lines · Stephen Hemminger
Significant enough to add some documentation.
Signed-off-by Stephen Hemminger <[email protected]>Acked-by Morten Brørup <[email protected]>Acked-by Bruce Richardson <[email protected]>Acked-by Chengwen Feng <[email protected]>---
Re: [PATCH v25 00/15] Logging enhancements for 24.11
In reply to Stephen HemmingerRecheck-request: iol-marvell-Functional
putting in a ci lab retest for the failures on this series.
v26 cover Log subsystem improvements
In reply to Stephen HemmingerImprovements and unification of logging library.
This version works on all platforms: Linux, Windows and FreeBSD.
This is update to rework patch set. It adds several new features to the console log output.
* Putting a timestamp on console output which is useful for analyzing performance of startup codes. Timestamp is optional and must be enabled on command line.
* Displaying console output with colors.
It uses the standard conventions used by many other Linux commands for colorized display. The default is to enable color if the console output is going to a terminal. But it can be always on or disabled by command line flag. This default was chosen based on what dmesg(1) command does.
Color is used by many tools (vi, iproute2, git) because it is helpful; DPDK drivers and libraries print lots of not very useful messages. And having error messages highlighted in bold face helps. This might also get users to pay more attention to error messages. Many bug reports have earlier messages that are lost because there are so many info messages.
* Add support for automatic detection of systemd journal protocol. If running as systemd service will get enhanced logging.
* Use of syslog is optional and the meaning of the --syslog flag has changed. The default is *not* to use syslog if output is going to a terminal.
Add myself as maintainer for log because by now have added more than previous authors.
v26 - rebase and change release note
- by default, do not disable color
- support dark mode with colors
- when using color format message to string then print to avoid getting multiple threads intermixing on output.
Stephen Hemminger (15):
maintainers: add for log library
windows: make getopt functions have const properties
windows: add os shim for localtime_r
eal: make eal_log_level_parse common
eal: do not duplicate rte_init_alert() messages
eal: change rte_exit() output to match rte_log()
log: move handling of syslog facility out of eal
eal: initialize log before everything else
log: drop syslog support, and make code common
log: add hook for printing log messages
log: add timestamp option
log: add optional support of syslog
log: add support for systemd journal
log: colorize log output
doc: add release note about log library
MAINTAINERS | 1 + app/test/test_eal_flags.c | 64 ++++- doc/guides/linux_gsg/linux_eal_parameters.rst | 27 -- doc/guides/prog_guide/log_lib.rst | 76 +++++- doc/guides/rel_notes/release_24_11.rst | 26 ++ lib/eal/common/eal_common_debug.c | 6 +- lib/eal/common/eal_common_options.c | 135 ++++++---- lib/eal/common/eal_internal_cfg.h | 1 - lib/eal/common/eal_options.h | 7 + lib/eal/freebsd/eal.c | 64 +---- lib/eal/linux/eal.c | 68 +---- lib/eal/windows/eal.c | 49 +--- lib/eal/windows/getopt.c | 23 +- lib/eal/windows/include/getopt.h | 8 +- lib/eal/windows/include/rte_os_shim.h | 10 + lib/log/log.c | 71 ++++-- lib/log/log_color.c | 216 ++++++++++++++++ lib/log/log_freebsd.c | 12 - lib/log/log_internal.h | 28 +- lib/log/log_journal.c | 200 +++++++++++++++ lib/log/log_linux.c | 61 ----- lib/log/log_private.h | 61 +++++ lib/log/log_syslog.c | 88 +++++++ lib/log/log_timestamp.c | 240 ++++++++++++++++++ lib/log/log_windows.c | 18 -- lib/log/meson.build | 12 +- lib/log/version.map | 5 +- 27 files changed, 1197 insertions(+), 380 deletions(-) create mode 100644 lib/log/log_color.c delete mode 100644 lib/log/log_freebsd.c create mode 100644 lib/log/log_journal.c delete mode 100644 lib/log/log_linux.c create mode 100644 lib/log/log_private.h create mode 100644 lib/log/log_syslog.c create mode 100644 lib/log/log_timestamp.c delete mode 100644 lib/log/log_windows.c
Signature · 1 line
2.45.2
PATCH v26 1/15 maintainers: add for log library
"You touch it you own it"
Add myself as maintainer for log library.
--- MAINTAINERS | 1 + 1 file changed, 1 insertion(+)
MAINTAINERS +1 -0
@@ -186,6 +186,7 @@ F: app/test/test_threads.c F: app/test/test_version.c Logging +M: Stephen Hemminger <[email protected]> F: lib/log/ F: doc/guides/prog_guide/log_lib.rst F: app/test/test_logs.c
Signature · 1 line
2.45.2
PATCH v26 2/15 windows: make getopt functions have const properties
In reply to Stephen HemmingerHaving different prototypes on different platforms can lead to lots of unnecessary workarounds. Looks like the version of getopt used from windows was based on an older out of date version from FreeBSD.
This patch changes getopt, getopt_long, etc to have the same const attributes as Linux and FreeBSD. The changes are derived from the current FreeBSD version of getopt_long.
--- lib/eal/windows/getopt.c | 23 ++++++++++++----------- lib/eal/windows/include/getopt.h | 8 ++++---- 2 files changed, 16 insertions(+), 15 deletions(-)
lib/eal/windows/getopt.c +12 -11
@@ -20,7 +20,7 @@#include <string.h> #include <stdlib.h> -const char *optarg;/* argument associated with option */ +char *optarg;/* argument associated with option */ int opterr =1 ;/* if error message should be printed */ int optind =1 ;/* index into parent argv vector */ int optopt ='?' ;/* character checked for validity */
@@ -39,9 +39,9 @@ static void pass(const char *a) {(void) a; }#define BADARG ((*options == ':') ? (int)':' : (int)'?')#define INORDER 1 -#define EMSG "" +static char EMSG [] ="" ; -static const char *place =EMSG ;/* option letter processing */ +static char *place =EMSG ;/* option letter processing */ /* XXX: set optreset to 1 rather than these two */ static int nonopt_start =-1 ;/* first non option argument (for permute) */
@@ -80,7 +80,7 @@ gcd(int a, int b)*/ static void permute_args (int panonopt_start,int panonopt_end,int opt_end, -char **nargv) +char *const *nargv) {int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;char *swap;
@@ -101,11 +101,12 @@ permute_args(int panonopt_start, int panonopt_end, int opt_end, pos -= nnonopts; else pos += nopts; + swap = nargv[pos];/* LINTED const cast */ - ((char **) nargv)[pos] = nargv[cstart]; + ((char **)(uintptr_t )nargv)[pos] = nargv[cstart];/* LINTED const cast */ - ((char **)nargv)[cstart] = swap; + ((char **)(uintptr_t )nargv)[cstart] = swap; } } }
@@ -116,7 +117,7 @@ permute_args(int panonopt_start, int panonopt_end, int opt_end,* Returns -1 if short_too is set and the option does not match long_options. */ static int -parse_long_options (char **nargv,const char *options, +parse_long_options (char *const *nargv,const char *options,const struct option *long_options,int *idx,int short_too) {const char *current_argv;
@@ -236,7 +237,7 @@ parse_long_options(char **nargv, const char *options,* Parse argc/argv argument vector. Called by user level routines. */ static int -getopt_internal (int nargc,char **nargv,const char *options, +getopt_internal (int nargc,char *const nargv[],const char *options,const struct option *long_options,int *idx,int flags) {char *oli;/* option letter list index */
@@ -434,7 +435,7 @@ getopt_internal(int nargc, char **nargv, const char *options,* Parse argc/argv argument vector. */ int -getopt (int nargc,char *nargv[],const char *options) +getopt (int nargc,char *const nargv[],const char *options) {return getopt_internal (nargc, nargv, options,NULL ,NULL ,FLAG_PERMUTE );
@@ -445,7 +446,7 @@ getopt(int nargc, char *nargv[], const char *options)* Parse argc/argv argument vector. */ int -getopt_long (int nargc,char *nargv[],const char *options, +getopt_long (int nargc,char *const nargv[],const char *options,const struct option *long_options,int *idx) {
@@ -458,7 +459,7 @@ getopt_long(int nargc, char *nargv[], const char *options,* Parse argc/argv argument vector. */ int -getopt_long_only (int nargc,char *nargv[],const char *options, +getopt_long_only (int nargc,char *const nargv[],const char *options,const struct option *long_options,int *idx) {
lib/eal/windows/include/getopt.h +4 -4
@@ -44,7 +44,7 @@/** argument to current option, or NULL if it has none */ -extern const char *optarg; +extern char *optarg;/** Current position in arg string. Starts from 1. * Setting to 0 resets state. */
@@ -80,14 +80,14 @@ struct option { };/** Compat: getopt */ -int getopt (int argc,char *argv[],const char *options); +int getopt (int argc,char *const argv[],const char *options);/** Compat: getopt_long */ -int getopt_long (int argc,char *argv[],const char *options, +int getopt_long (int argc,char *const argv[],const char *options,const struct option *longopts,int *longindex);/** Compat: getopt_long_only */ -int getopt_long_only (int nargc,char *argv[],const char *options, +int getopt_long_only (int nargc,char *const argv[],const char *options,const struct option *long_options,int *idx);
Signature · 1 line
2.45.2
PATCH v26 3/15 windows: add os shim for localtime_r
In reply to Stephen HemmingerWindows does not have localtime_r but it does have a similar function that can be used instead.
--- lib/eal/windows/include/rte_os_shim.h | 10 ++++++++++ 1 file changed, 10 insertions(+)
lib/eal/windows/include/rte_os_shim.h +10 -0
@@ -110,4 +110,14 @@ rte_clock_gettime(clockid_t clock_id, struct timespec *tp) }#define clock_gettime (clock_id, tp) rte_clock_gettime(clock_id, tp) +static inline struct tm * +rte_localtime_r (const time_t *timep,struct tm *result) +{ +if (localtime_s (result, timep) ==0 ) +return result; +else +return NULL ; +} +#define localtime_r (timep, result) rte_localtime_r(timep, result) +#endif /* _RTE_OS_SHIM_ */
Signature · 1 line
2.45.2
PATCH v26 4/15 eal: make eal_log_level_parse common
In reply to Stephen HemmingerThe code to parse for log-level option should be same on all OS variants.
--- lib/eal/common/eal_common_options.c | 40 +++++++++++++++++++++++++++ lib/eal/common/eal_options.h | 1 + lib/eal/freebsd/eal.c | 42 ----------------------------- lib/eal/linux/eal.c | 39 --------------------------- lib/eal/windows/eal.c | 35 ------------------------ 5 files changed, 41 insertions(+), 116 deletions(-)
lib/eal/common/eal_common_options.c +40 -0
@@ -1640,6 +1640,46 @@ eal_parse_huge_unlink(const char *arg, struct hugepage_file_discipline *out)return -1 ; } +/* Parse the all arguments looking for log related ones */ +int +eal_log_level_parse (int argc,char *const argv[]) +{ +struct internal_config *internal_conf =eal_get_internal_configuration (); +int option_index, opt; +const int old_optind = optind; +const int old_optopt = optopt; +const int old_opterr = opterr; +char *old_optarg = optarg; +#ifdef RTE_EXEC_ENV_FREEBSD +const int old_optreset = optreset; + optreset =1 ; +#endif + + optind =1 ; + opterr =0 ; + +while ((opt =getopt_long (argc, argv, eal_short_options, + eal_long_options, &option_index)) !=EOF ) { + +switch (opt) { +case OPT_LOG_LEVEL_NUM : +if (eal_parse_common_option (opt, optarg, internal_conf) <0 ) +return -1 ; +break ; + } + } + +/* restore getopt lib */ + optind = old_optind; + optopt = old_optopt; + optarg = old_optarg; + opterr = old_opterr; +#ifdef RTE_EXEC_ENV_FREEBSD + optreset = old_optreset; +#endif +return 0 ; +} +int eal_parse_common_option (int opt,const char *optarg,struct internal_config *conf)
lib/eal/common/eal_options.h +1 -0
@@ -96,6 +96,7 @@ enum {extern const char eal_short_options[];extern const struct option eal_long_options[]; +int eal_log_level_parse (int argc,char *const argv[]);int eal_parse_common_option (int opt,const char *argv,struct internal_config *conf);int eal_option_device_parse (void );
lib/eal/freebsd/eal.c +0 -42
48 lines not on this page · raw message
lib/eal/linux/eal.c +0 -39
@@ -546,45 +546,6 @@ eal_parse_vfio_vf_token(const char *vf_token)return -1 ; } -/* Parse the arguments for --log-level only */ -static void -eal_log_level_parse (int argc,char **argv) -{ -int opt; -char **argvopt; -int option_index; -const int old_optind = optind; -const int old_optopt = optopt; -char *const old_optarg = optarg; -struct internal_config *internal_conf = -eal_get_internal_configuration (); - - argvopt = argv; - optind =1 ; - -while ((opt =getopt_long (argc, argvopt, eal_short_options, - eal_long_options, &option_index)) !=EOF ) { - -int ret; - -/* getopt is not happy, stop right now */ -if (opt =='?' ) -break ; - - ret = (opt ==OPT_LOG_LEVEL_NUM ) ? -eal_parse_common_option (opt, optarg, internal_conf) :0 ; - -/* common parser is not happy */ -if (ret <0 ) -break ; - } - -/* restore getopt lib */ - optind = old_optind; - optopt = old_optopt; - optarg = old_optarg; -} -static int eal_parse_huge_worker_stack (const char *arg) {
lib/eal/windows/eal.c +0 -35
@@ -96,41 +96,6 @@ eal_usage(const char *prgname) } } -/* Parse the arguments for --log-level only */ -static void -eal_log_level_parse (int argc,char **argv) -{ -int opt; -char **argvopt; -int option_index; -struct internal_config *internal_conf = -eal_get_internal_configuration (); - - argvopt = argv; - -eal_reset_internal_config (internal_conf); - -while ((opt =getopt_long (argc, argvopt, eal_short_options, - eal_long_options, &option_index)) !=EOF ) { - -int ret; - -/* getopt is not happy, stop right now */ -if (opt =='?' ) -break ; - - ret = (opt ==OPT_LOG_LEVEL_NUM ) ? -eal_parse_common_option (opt, optarg, - internal_conf) :0 ; - -/* common parser is not happy */ -if (ret <0 ) -break ; - } - - optind =0 ;/* reset getopt lib */ -} -/* Parse the argument given in the command line of the application */ static int eal_parse_args (int argc,char **argv)
Signature · 1 line
2.45.2
PATCH v26 5/15 eal: do not duplicate rte_init_alert() messages
In reply to Stephen HemmingerThe message already goes through logging, and does not need to be printed on stderr. Message level should be ALERT to match function name.
--- lib/eal/freebsd/eal.c | 3 +-- lib/eal/linux/eal.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-)
lib/eal/freebsd/eal.c +1 -2
@@ -529,8 +529,7 @@ rte_eal_iopl_init(void)static void rte_eal_init_alert (const char *msg) { -fprintf (stderr,"EAL: FATAL: %s\n" , msg); -EAL_LOG (ERR ,"%s" , msg); +EAL_LOG (ALERT ,"%s" , msg); }/* Launch threads, called at application init(). */
lib/eal/linux/eal.c +1 -2
@@ -830,8 +830,7 @@ rte_eal_iopl_init(void)static void rte_eal_init_alert (const char *msg) { -fprintf (stderr,"EAL: FATAL: %s\n" , msg); -EAL_LOG (ERR ,"%s" , msg); +EAL_LOG (ALERT ,"%s" , msg); }/*
Signature · 1 line
2.45.2
Re: [PATCH v26 05/15] eal: do not duplicate rte_init_alert() messages
Hello,
Quoted 34 lines · Stephen Hemminger
The message already goes through logging, and does not need to be printed on stderr. Message level should be ALERT to match function name.
Signed-off-by Stephen Hemminger <[email protected]>Acked-by Tyler Retzlaff <[email protected]>Acked-by Morten Brørup <[email protected]>Acked-by Bruce Richardson <[email protected]>Acked-by Chengwen Feng <[email protected]>--- lib/eal/freebsd/eal.c | 3 +-- lib/eal/linux/eal.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-)lib/eal/freebsd/eal.c +1
-2@@ -529,8 +529,7 @@ rte_eal_iopl_init(void)static void rte_eal_init_alert (const char *msg) { -fprintf (stderr,"EAL: FATAL: %s\n" , msg); -EAL_LOG (ERR ,"%s" , msg); +EAL_LOG (ALERT ,"%s" , msg); }/* Launch threads, called at application init(). */ lib/eal/linux/eal.c +0
-0
lib/eal/linux/eal.c rte_eal_iopl_init(void) · line 836
Quoted 9 lines
lib/eal/linux/eal.c +1
-2@@ -830,8 +830,7 @@ rte_eal_iopl_init(void)static void rte_eal_init_alert (const char *msg) { -fprintf (stderr,"EAL: FATAL: %s\n" , msg); -EAL_LOG (ERR ,"%s" , msg); +EAL_LOG (ALERT ,"%s" , msg); }/*
Any reason why Windows was not changed?
I can add the missing bit when applying.
Signature · 1 line
David Marchand
Re: [PATCH v26 05/15] eal: do not duplicate rte_init_alert() messages
Quoted 13 lines · On Thu, 17 Oct 2024 18:47:54 +0200 David Marchand <[email protected]>…
Quoted 13 lines
lib/eal/linux/eal.c +1
-2@@ -830,8 +830,7 @@ rte_eal_iopl_init(void)static void rte_eal_init_alert (const char *msg) { -fprintf (stderr,"EAL: FATAL: %s\n" , msg); -EAL_LOG (ERR ,"%s" , msg); +EAL_LOG (ALERT ,"%s" , msg); }
Quoted 5 lines
lib/eal/linux/eal.c rte_eal_iopl_init(void) · line 836
Quoted 1 line
lib/eal/linux/eal.c +0
-0/* Any reason why Windows was not changed?
I can add the missing bit when applying.
No reason that Windows was not changed, just forgot about it.
PATCH v26 6/15 eal: change rte_exit() output to match rte_log()
In reply to Stephen HemmingerThe rte_exit() output format confuses the timestamp and coloring options. Change it to use be a single line with proper prefix.
Before:
[ 0.006481] EAL: Error - exiting with code: 1 Cause: [ 0.006489] Cannot init EAL: Permission denied
After:
[ 0.006238] EAL: Error - exiting with code: 1 [ 0.006250] EAL: Cannot init EAL: Permission denied
--- lib/eal/common/eal_common_debug.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
lib/eal/common/eal_common_debug.c +2 -4
@@ -36,15 +36,13 @@ rte_exit(int exit_code, const char *format, ...)va_list ap;if (exit_code !=0 ) -RTE_LOG (CRIT ,EAL ,"Error - exiting with code: %d\n" -" Cause: " , exit_code); +EAL_LOG (CRIT ,"Error - exiting with code: %d" , exit_code);va_start (ap, format);rte_vlog (RTE_LOG_CRIT ,RTE_LOGTYPE_EAL , format, ap);va_end (ap);if (rte_eal_cleanup () !=0 && rte_errno !=EALREADY ) -EAL_LOG (CRIT , -"EAL could not release all resources" ); +EAL_LOG (CRIT ,"EAL could not release all resources" );exit (exit_code); }
Signature · 1 line
2.45.2
PATCH v26 7/15 log: move handling of syslog facility out of eal
In reply to Stephen HemmingerThe syslog facility property is better handled in lib/log rather than in eal. This also allows for changes to what syslog flag means in later steps.
--- lib/eal/common/eal_common_options.c | 51 ++--------------------------- lib/eal/common/eal_internal_cfg.h | 1 - lib/eal/freebsd/eal.c | 5 ++- lib/eal/linux/eal.c | 7 ++-- lib/eal/windows/eal.c | 6 ++-- lib/log/log.c | 2 ++ lib/log/log_freebsd.c | 2 +- lib/log/log_internal.h | 5 ++- lib/log/log_linux.c | 47 ++++++++++++++++++++++++-- lib/log/log_windows.c | 8 ++++- lib/log/version.map | 1 + 11 files changed, 70 insertions(+), 65 deletions(-)
lib/eal/common/eal_common_options.c +2 -49
@@ -6,9 +6,6 @@#include <stdlib.h> #include <string.h> #include <pthread.h> -#ifndef RTE_EXEC_ENV_WINDOWS -#include <syslog.h> -#endif #include <ctype.h> #include <limits.h> #include <errno.h>
@@ -349,10 +346,6 @@ eal_reset_internal_config(struct internal_config *internal_cfg) } internal_cfg->base_virtaddr =0 ; -#ifdef LOG_DAEMON - internal_cfg->syslog_facility =LOG_DAEMON ; -#endif -/* if set to NONE, interrupt mode is determined automatically */ internal_cfg->vfio_intr_mode =RTE_INTR_MODE_NONE ; memset(internal_cfg->vfio_vf_token, 0,
@@ -1297,47 +1290,6 @@ eal_parse_lcores(const char *lcores)return ret; } -#ifndef RTE_EXEC_ENV_WINDOWS -static int -eal_parse_syslog (const char *facility,struct internal_config *conf) -{ -int i; -static const struct { -const char *name; -int value; - } map[] = { - {"auth" ,LOG_AUTH }, - {"cron" ,LOG_CRON }, - {"daemon" ,LOG_DAEMON }, - {"ftp" ,LOG_FTP }, - {"kern" ,LOG_KERN }, - {"lpr" ,LOG_LPR }, - {"mail" ,LOG_MAIL }, - {"news" ,LOG_NEWS }, - {"syslog" ,LOG_SYSLOG }, - {"user" ,LOG_USER }, - {"uucp" ,LOG_UUCP }, - {"local0" ,LOG_LOCAL0 }, - {"local1" ,LOG_LOCAL1 }, - {"local2" ,LOG_LOCAL2 }, - {"local3" ,LOG_LOCAL3 }, - {"local4" ,LOG_LOCAL4 }, - {"local5" ,LOG_LOCAL5 }, - {"local6" ,LOG_LOCAL6 }, - {"local7" ,LOG_LOCAL7 }, - {NULL ,0 } - }; - -for (i =0 ; map[i].name; i++) { -if (!strcmp (facility, map[i].name)) { - conf->syslog_facility = map[i].value; -return 0 ; - } - } -return -1 ; -} -#endif -static void eal_log_usage (void ) {
@@ -1663,6 +1615,7 @@ eal_log_level_parse(int argc, char * const argv[])switch (opt) {case OPT_LOG_LEVEL_NUM : +case OPT_SYSLOG_NUM :if (eal_parse_common_option (opt, optarg, internal_conf) <0 )return -1 ;break ;
@@ -1877,7 +1830,7 @@ eal_parse_common_option(int opt, const char *optarg,#ifndef RTE_EXEC_ENV_WINDOWS case OPT_SYSLOG_NUM : -if (eal_parse_syslog (optarg, conf) <0 ) { +if (eal_log_syslog (optarg) <0 ) {EAL_LOG (ERR ,"invalid parameters for --" OPT_SYSLOG );return -1 ;
lib/eal/common/eal_internal_cfg.h +0 -1
@@ -84,7 +84,6 @@ struct internal_config {/**< true if storing all pages within single files (per-page-size, * per-node) non-legacy mode only. */ -volatile int syslog_facility;/**< facility passed to openlog() */ /** default interrupt mode for VFIO */ volatile enum rte_intr_mode vfio_intr_mode;/** the shared VF token for VFIO-PCI bound PF and VFs devices */
lib/eal/freebsd/eal.c +2 -3
@@ -11,7 +11,6 @@#include <stdarg.h> #include <unistd.h> #include <pthread.h> -#include <syslog.h> #include <getopt.h> #include <sys/file.h> #include <stddef.h>
@@ -392,8 +391,8 @@ eal_parse_args(int argc, char **argv) goto out; } -/* eal_log_level_parse() already handled this option */ -if (opt ==OPT_LOG_LEVEL_NUM ) +/* eal_log_level_parse() already handled these */ +if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_LOG_SYSLOG_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
lib/eal/linux/eal.c +3 -4
@@ -610,8 +610,8 @@ eal_parse_args(int argc, char **argv) goto out; } -/* eal_log_level_parse() already handled this option */ -if (opt ==OPT_LOG_LEVEL_NUM ) +/* eal_log_level_parse() already handled these options */ +if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_SYSLOG_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
@@ -1103,8 +1103,7 @@ rte_eal_init(int argc, char **argv)#endif } -if (eal_log_init (program_invocation_short_name, - internal_conf->syslog_facility) <0 ) { +if (eal_log_init (program_invocation_short_name) <0 ) {rte_eal_init_alert ("Cannot init logging." ); rte_errno =ENOMEM ;rte_atomic_store_explicit (&run_once,0 , rte_memory_order_relaxed);
lib/eal/windows/eal.c +3 -3
@@ -120,8 +120,8 @@ eal_parse_args(int argc, char **argv)return -1 ; } -/* eal_log_level_parse() already handled this option */ -if (opt ==OPT_LOG_LEVEL_NUM ) +/* eal_log_level_parse() already handled these options */ +if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_SYSLOG_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
@@ -250,7 +250,7 @@ rte_eal_init(int argc, char **argv)char cpuset[RTE_CPU_AFFINITY_STR_LEN ];char thread_name[RTE_THREAD_NAME_SIZE ]; -eal_log_init (NULL ,0 ); +eal_log_init (NULL );eal_log_level_parse (argc, argv);
lib/log/log.c +2 -0
@@ -2,6 +2,7 @@* Copyright(c) 2010-2014 Intel Corporation */ +#include <stdbool.h> #include <stdio.h> #include <stdint.h> #include <stdarg.h>
@@ -12,6 +13,7 @@#include <fnmatch.h> #include <sys/queue.h> +#include <rte_common.h> #include <rte_log.h> #include <rte_per_lcore.h>
lib/log/log_freebsd.c +1 -1
@@ -6,7 +6,7 @@#include "log_internal.h" int -eal_log_init(__rte_unused const char *id, __rte_unused int facility) +eal_log_init(__rte_unused const char *id) {return 0 ; }
lib/log/log_internal.h +4 -1
@@ -14,7 +14,7 @@* Initialize the default log stream. */ __rte_internal -int eal_log_init(const char *id, int facility); +int eal_log_init(const char *id);/* * Determine where log data is written when no call to rte_openlog_stream.
@@ -30,6 +30,9 @@ int eal_log_save_regexp(const char *regexp, uint32_t level);__rte_internal int eal_log_save_pattern(const char *pattern, uint32_t level); +__rte_internal +int eal_log_syslog(const char *name); +/* * Convert log level to string. */
lib/log/log_linux.c +45 -2
72 lines not on this page · raw message
lib/log/log_windows.c +7 -1
@@ -6,9 +6,15 @@#include <rte_log.h> #include "log_internal.h" +int +eal_log_syslog(const char *name __rte_unused) +{ +return -1 ;/* not used */ +} +/* set the log to default function, called during eal init process. */ int -eal_log_init(__rte_unused const char *id, __rte_unused int facility) +eal_log_init(__rte_unused const char *id) {rte_openlog_stream (stderr);
lib/log/version.map +1 -0
@@ -30,5 +30,6 @@ INTERNAL { eal_log_save_pattern; eal_log_save_regexp; eal_log_set_default; + eal_log_syslog; rte_eal_log_cleanup; };
Signature · 1 line
2.45.2
PATCH v26 8/15 eal: initialize log before everything else
In reply to Stephen HemmingerIn order for all log messages (including CPU mismatch) to come out through the logging library, it must be initialized as early in rte_eal_init() as possible on all platforms.
Where it was done before was likely historical based on the support of non-OS isolated CPU's which required a shared memory buffer; that support was dropped before DPDK was publicly released.
--- lib/eal/freebsd/eal.c | 12 +++++++++--- lib/eal/linux/eal.c | 19 +++++++++---------- lib/eal/windows/eal.c | 8 ++++++-- lib/log/log_freebsd.c | 3 +-- lib/log/log_internal.h | 2 +- lib/log/log_linux.c | 14 ++++++-------- lib/log/log_windows.c | 4 +--- 7 files changed, 33 insertions(+), 29 deletions(-)
lib/eal/freebsd/eal.c +9 -3
@@ -52,6 +52,7 @@#include "eal_options.h" #include "eal_memcfg.h" #include "eal_trace.h" +#include "log_internal.h" #define MEMSIZE_IF_NO_HUGE_PAGE (64ULL * 1024ULL * 1024ULL)
@@ -546,6 +547,14 @@ rte_eal_init(int argc, char **argv)bool has_phys_addr;enum rte_iova_mode iova_mode; +/* setup log as early as possible */ +if (eal_log_level_parse (argc, argv) <0 ) { +rte_eal_init_alert ("invalid log arguments." ); + rte_errno =EINVAL ; +return -1 ; + } +eal_log_init (getprogname ()); +/* checks if the machine is adequate */ if (!rte_cpu_is_supported ()) {rte_eal_init_alert ("unsupported cpu type." );
@@ -572,9 +581,6 @@ rte_eal_init(int argc, char **argv)/* clone argv to report out later in telemetry */ eal_save_args (argc, argv); -/* set log level as early as possible */ -eal_log_level_parse (argc, argv); -if (rte_eal_cpu_init () <0 ) {rte_eal_init_alert ("Cannot detect lcores." ); rte_errno =ENOTSUP ;
lib/eal/linux/eal.c +9 -10
@@ -926,6 +926,15 @@ rte_eal_init(int argc, char **argv)struct internal_config *internal_conf =eal_get_internal_configuration (); +/* setup log as early as possible */ +if (eal_log_level_parse (argc, argv) <0 ) { +rte_eal_init_alert ("invalid log arguments." ); + rte_errno =EINVAL ; +return -1 ; + } + +eal_log_init (program_invocation_short_name); +/* checks if the machine is adequate */ if (!rte_cpu_is_supported ()) {rte_eal_init_alert ("unsupported cpu type." );
@@ -949,9 +958,6 @@ rte_eal_init(int argc, char **argv)eal_reset_internal_config (internal_conf); -/* set log level as early as possible */ -eal_log_level_parse (argc, argv); -/* clone argv to report out later in telemetry */ eal_save_args (argc, argv);
@@ -1103,13 +1109,6 @@ rte_eal_init(int argc, char **argv)#endif } -if (eal_log_init (program_invocation_short_name) <0 ) { -rte_eal_init_alert ("Cannot init logging." ); - rte_errno =ENOMEM ; -rte_atomic_store_explicit (&run_once,0 , rte_memory_order_relaxed); -return -1 ; - } -#ifdef VFIO_PRESENT if (rte_vfio_enable ("vfio" )) {rte_eal_init_alert ("Cannot init VFIO" );
lib/eal/windows/eal.c +6 -2
@@ -250,9 +250,13 @@ rte_eal_init(int argc, char **argv)char cpuset[RTE_CPU_AFFINITY_STR_LEN ];char thread_name[RTE_THREAD_NAME_SIZE ]; -eal_log_init (NULL ); +if (eal_log_level_parse (argc, argv) <0 ) { +rte_eal_init_alert ("invalid log arguments." ); + rte_errno =EINVAL ; +return -1 ; + } -eal_log_level_parse (argc, argv); +eal_log_init (NULL );if (eal_create_cpu_map () <0 ) {rte_eal_init_alert ("Cannot discover CPU and NUMA." );
lib/log/log_freebsd.c +1 -2
@@ -5,8 +5,7 @@#include <rte_common.h> #include "log_internal.h" -int +void eal_log_init(__rte_unused const char *id) { -return 0 ; }
lib/log/log_internal.h +1 -1
@@ -14,7 +14,7 @@* Initialize the default log stream. */ __rte_internal -int eal_log_init(const char *id); +void eal_log_init(const char *id);/* * Determine where log data is written when no call to rte_openlog_stream.
lib/log/log_linux.c +6 -8
@@ -87,18 +87,16 @@ static cookie_io_functions_t console_log_func = {* set the log to default function, called during eal init process, * once memzones are available. */ -int +void eal_log_init (const char *id) {FILE *log_stream; - log_stream =fopencookie (NULL ,"w+" , console_log_func); -if (log_stream ==NULL ) -return -1 ; -openlog (id,LOG_NDELAY |LOG_PID , log_facility); -eal_log_set_default (log_stream); - -return 0 ; + log_stream =fopencookie (NULL ,"w+" , console_log_func); +if (log_stream !=NULL ) +eal_log_set_default (log_stream); +else +eal_log_set_default (stderr); }
lib/log/log_windows.c +1 -3
@@ -13,12 +13,10 @@ eal_log_syslog(const char *name __rte_unused) }/* set the log to default function, called during eal init process. */ -int +void eal_log_init(__rte_unused const char *id) {rte_openlog_stream (stderr);eal_log_set_default (stderr); - -return 0 ; }
Signature · 1 line
2.45.2
PATCH v26 9/15 log: drop syslog support, and make code common
In reply to Stephen HemmingerThis patch makes the log setup code common across all platforms.
Drops syslog support for now, will come back in later patch.
--- app/test/test_eal_flags.c | 11 ++- lib/eal/common/eal_common_options.c | 3 - lib/log/log.c | 41 +++++------ lib/log/log_freebsd.c | 11 --- lib/log/log_internal.h | 6 -- lib/log/log_linux.c | 102 ---------------------------- lib/log/log_windows.c | 22 ------ lib/log/meson.build | 5 +- lib/log/version.map | 1 - 9 files changed, 23 insertions(+), 179 deletions(-) delete mode 100644 lib/log/log_freebsd.c delete mode 100644 lib/log/log_linux.c delete mode 100644 lib/log/log_windows.c
app/test/test_eal_flags.c +5 -6
@@ -984,11 +984,10 @@ test_misc_flags(void)const char *argv1[] = {prgname, prefix, mp_flag,"--no-pci" };/* With -v */ const char *argv2[] = {prgname, prefix, mp_flag,"-v" }; +/* With empty --syslog */ +const char *argv3[] = {prgname, prefix, mp_flag,"--syslog" };/* With valid --syslog */ -const char *argv3[] = {prgname, prefix, mp_flag, -"--syslog" ,"syslog" }; -/* With empty --syslog (should fail) */ -const char *argv4[] = {prgname, prefix, mp_flag,"--syslog" }; +const char *argv4[] = {prgname, prefix, mp_flag,"--syslog" ,"always" };/* With invalid --syslog */ const char *argv5[] = {prgname, prefix, mp_flag,"--syslog" ,"error" };/* With no-sh-conf, also use no-huge to ensure this test runs on BSD */
@@ -1083,8 +1082,8 @@ test_misc_flags(void)printf ("Error - process did not run ok with --syslog flag\n" ); goto fail; } -if (launch_proc (argv4) ==0 ) { -printf ("Error - process run ok with empty --syslog flag\n" ); +if (launch_proc (argv4) !=0 ) { +printf ("Error - process did not with --syslog always flag\n" ); goto fail; }if (launch_proc (argv5) ==0 ) {
lib/eal/common/eal_common_options.c +0 -3
@@ -2206,9 +2206,6 @@ eal_common_usage(void)" (can be used multiple times)\n" " --" OPT_VMWARE_TSC_MAP " Use VMware TSC map instead of native RDTSC\n" " --" OPT_PROC_TYPE " Type of this process (primary|secondary|auto)\n" -#ifndef RTE_EXEC_ENV_WINDOWS -" --" OPT_SYSLOG " Set syslog facility\n" -#endif" --" OPT_LOG_LEVEL "=<level> Set global log level\n" " --" OPT_LOG_LEVEL "=<type-match>:<level>\n" " Set specific log level\n"
lib/log/log.c +17 -24
73 lines not on this page · raw message
lib/log/log_freebsd.c deleted +0 -11
@@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause -* Copyright(c) 2023 Intel Corporation -*/ - -#include <rte_common.h> -#include "log_internal.h" - -void -eal_log_init(__rte_unused const char *id) -{ -}
lib/log/log_internal.h +0 -6
@@ -16,12 +16,6 @@__rte_internal void eal_log_init(const char *id); -/* -* Determine where log data is written when no call to rte_openlog_stream. -*/ -__rte_internal -void eal_log_set_default(FILE *default_log); -/* * Save a log option for later. */
lib/log/log_linux.c deleted +0 -102
102 lines not on this page · raw message
lib/log/log_windows.c deleted +0 -22
@@ -1,22 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause -* Copyright(c) 2017-2018 Intel Corporation -*/ - -#include <rte_common.h> -#include <rte_log.h> -#include "log_internal.h" - -int -eal_log_syslog(const char *name __rte_unused) -{ -return -1 ;/* not used */ -} - -/* set the log to default function, called during eal init process. */ -void -eal_log_init(__rte_unused const char *id) -{ -rte_openlog_stream (stderr); - -eal_log_set_default (stderr); -}
lib/log/meson.build +1 -4
@@ -2,8 +2,5 @@ # Copyright(c) 2023 Intel Corporation includes += global_inc -sources = files( - 'log.c', - 'log_' + exec_env + '.c', -) +sources = files('log.c') headers = files('rte_log.h')
lib/log/version.map +0 -1
@@ -29,7 +29,6 @@ INTERNAL { eal_log_level2str; eal_log_save_pattern; eal_log_save_regexp; - eal_log_set_default; eal_log_syslog; rte_eal_log_cleanup; };
Signature · 1 line
2.45.2
PATCH v26 10/15 log: add hook for printing log messages
In reply to Stephen HemmingerThis is useful for when decorating log output for console or journal. Provide basic version in this patch.
--- lib/log/log.c | 6 +++++- lib/log/log_private.h | 9 +++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 lib/log/log_private.h
lib/log/log.c +5 -1
@@ -18,6 +18,7 @@#include <rte_per_lcore.h> #include "log_internal.h" +#include "log_private.h" #ifdef RTE_EXEC_ENV_WINDOWS #define strdup _strdup
@@ -33,11 +34,13 @@ static struct rte_logs {uint32_t type;/**< Bitfield with enabled logs. */ uint32_t level;/**< Log level. */ FILE *file;/**< Output file set by rte_openlog_stream, or NULL. */ +log_print_t print_func;size_t dynamic_types_len;struct rte_log_dynamic_type *dynamic_types; } rte_logs = { .type = UINT32_MAX, .level = RTE_LOG_DEBUG, + .print_func = vfprintf, };struct rte_eal_opt_loglevel {
@@ -74,6 +77,7 @@ int rte_openlog_stream(FILE *f) { rte_logs.file = f; + rte_logs.print_func = vfprintf;return 0 ; }
@@ -470,7 +474,7 @@ rte_vlog(uint32_t level, uint32_t logtype, const char *format, va_list ap)RTE_PER_LCORE (log_cur_msg).loglevel = level;RTE_PER_LCORE (log_cur_msg).logtype = logtype; - ret =vfprintf (f, format, ap); + ret = (*rte_logs.print_func)(f, format, ap);fflush (f);return ret; }
lib/log/log_private.h new file +9 -0
@@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#ifndef LOG_PRIVATE_H +#define LOG_PRIVATE_H + +/* Note: same as vfprintf() */ +typedef int (*log_print_t )(FILE *f,const char *fmt,va_list ap); + +#endif /* LOG_PRIVATE_H */
Signature · 1 line
2.45.2
PATCH v26 11/15 log: add timestamp option
In reply to Stephen HemmingerWhen debugging driver or startup issues, it is useful to have a timestamp on each message printed. The messages in syslog already have a timestamp, but often syslog is not available during testing.
There are multiple timestamp formats similar to Linux dmesg. The default is time relative since startup (when first step of logging initialization is done by constructor). Other alternative formats are delta, ctime, reltime and iso formats.
Example:
$ dpdk-testpmd --log-timestamp -- -i [ 0.008610] EAL: Detected CPU lcores: 8 [ 0.008634] EAL: Detected NUMA nodes: 1 [ 0.008792] EAL: Detected static linkage of DPDK [ 0.010620] EAL: Multi-process socket /var/run/dpdk/rte/mp_socket [ 0.012618] EAL: Selected IOVA mode 'VA' [ 0.016675] testpmd: No probed ethernet devices Interactive-mode selected
--- app/test/test_eal_flags.c | 26 +++ doc/guides/prog_guide/log_lib.rst | 26 +++ lib/eal/common/eal_common_options.c | 14 +- lib/eal/common/eal_options.h | 2 + lib/eal/freebsd/eal.c | 6 +- lib/eal/linux/eal.c | 4 +- lib/eal/windows/eal.c | 4 +- lib/log/log.c | 7 +- lib/log/log_internal.h | 9 ++ lib/log/log_private.h | 11 ++ lib/log/log_timestamp.c | 240 ++++++++++++++++++++++++++++ lib/log/meson.build | 6 +- lib/log/version.map | 1 + 13 files changed, 348 insertions(+), 8 deletions(-) create mode 100644 lib/log/log_timestamp.c
app/test/test_eal_flags.c +26 -0
@@ -1054,6 +1054,19 @@ test_misc_flags(void)const char *const argv22[] = {prgname, prefix, mp_flag,"--huge-worker-stack=512" }; +/* Try running with --log-timestamp */ +const char *const argv23[] = {prgname, prefix, mp_flag, +"--log-timestamp" }; + +/* Try running with --log-timestamp=iso */ +const char *const argv24[] = {prgname, prefix, mp_flag, +"--log-timestamp=iso" }; + +/* Try running with invalid timestamp */ +const char *const argv25[] = {prgname, prefix, mp_flag, +"--log-timestamp=invalid" }; + +/* run all tests also applicable to FreeBSD first */ if (launch_proc (argv0) ==0 ) {
@@ -1161,6 +1174,19 @@ test_misc_flags(void)printf ("Error - process did not run ok with --huge-worker-stack=size parameter\n" ); goto fail; } +if (launch_proc (argv23) !=0 ) { +printf ("Error - process did not run ok with --log-timestamp parameter\n" ); + goto fail; + } +if (launch_proc (argv24) !=0 ) { +printf ("Error - process did not run ok with --log-timestamp=iso parameter\n" ); + goto fail; + } +if (launch_proc (argv25) ==0 ) { +printf ("Error - process did run ok with --log-timestamp=invalid parameter\n" ); + goto fail; + } +rmdir (hugepath_dir3);rmdir (hugepath_dir2);
doc/guides/prog_guide/log_lib.rst +26 -0
@@ -59,6 +59,32 @@ For example:: Within an application, the same result can be got using the ``rte_log_set_level_pattern()`` or ``rte_log_set_level_regex()`` APIs. +Log timestamp +~~~~~~~~~~~~~ + +An optional timestamp can be added before each message +by adding the ``--log-timestamp`` option. +For example:: + + /path/to/app --log-level=lib.*:debug --log-timestamp + +Multiple timestamp alternative timestamp formats are available: + +.. csv-table:: Log time stamp format + :header: "Format", "Description", "Example" + :widths: 6, 30, 32 + + "ctime", "Unix ctime", "``[Wed Mar 20 07:26:12 2024]``" + "delta", "Offset since last", "``[< 3.162373>]``" + "reltime", "Seconds since last or time if minute changed", "``[ +3.001791]`` or ``[Mar20 07:26:12]``" + "iso", "ISO-8601", "``[2024-03-20T07:26:12−07:00]``" + +To prefix all console messages with ISO format time the syntax is:: + + /path/to/app --log-timestamp=iso + + + Using Logging APIs to Generate Log Messages -------------------------------------------
lib/eal/common/eal_common_options.c +12 -2
@@ -74,6 +74,7 @@ eal_long_options[] = { {OPT_IOVA_MODE, 1, NULL, OPT_IOVA_MODE_NUM }, {OPT_LCORES, 1, NULL, OPT_LCORES_NUM }, {OPT_LOG_LEVEL, 1, NULL, OPT_LOG_LEVEL_NUM }, + {OPT_LOG_TIMESTAMP, 2, NULL, OPT_LOG_TIMESTAMP_NUM }, {OPT_TRACE, 1, NULL, OPT_TRACE_NUM }, {OPT_TRACE_DIR, 1, NULL, OPT_TRACE_DIR_NUM }, {OPT_TRACE_BUF_SIZE, 1, NULL, OPT_TRACE_BUF_SIZE_NUM },
@@ -1616,6 +1617,7 @@ eal_log_level_parse(int argc, char * const argv[])switch (opt) {case OPT_LOG_LEVEL_NUM :case OPT_SYSLOG_NUM : +case OPT_LOG_TIMESTAMP_NUM :if (eal_parse_common_option (opt, optarg, internal_conf) <0 )return -1 ;break ;
@@ -1838,7 +1840,7 @@ eal_parse_common_option(int opt, const char *optarg,break ;#endif -case OPT_LOG_LEVEL_NUM : { +case OPT_LOG_LEVEL_NUM :if (eal_parse_log_level (optarg) <0 ) {EAL_LOG (ERR , "invalid parameters for --"
@@ -1846,7 +1848,14 @@ eal_parse_common_option(int opt, const char *optarg,return -1 ; }break ; - } + +case OPT_LOG_TIMESTAMP_NUM : +if (eal_log_timestamp (optarg) <0 ) { +EAL_LOG (ERR ,"invalid parameters for --" +OPT_LOG_TIMESTAMP ); +return -1 ; + } +break ;#ifndef RTE_EXEC_ENV_WINDOWS case OPT_TRACE_NUM : {
@@ -2210,6 +2219,7 @@ eal_common_usage(void)" --" OPT_LOG_LEVEL "=<type-match>:<level>\n" " Set specific log level\n" " --" OPT_LOG_LEVEL "=help Show log types and levels\n" +" --" OPT_LOG_TIMESTAMP "[=<format>] Timestamp log output\n" #ifndef RTE_EXEC_ENV_WINDOWS" --" OPT_TRACE "=<regex-match>\n" " Enable trace based on regular expression trace name.\n"
lib/eal/common/eal_options.h +2 -0
@@ -35,6 +35,8 @@ enum {OPT_LCORES_NUM , #define OPT_LOG_LEVEL "log-level"OPT_LOG_LEVEL_NUM , +#define OPT_LOG_TIMESTAMP "log-timestamp" +OPT_LOG_TIMESTAMP_NUM , #define OPT_TRACE "trace"OPT_TRACE_NUM , #define OPT_TRACE_DIR "trace-dir"
lib/eal/freebsd/eal.c +4 -2
@@ -392,8 +392,10 @@ eal_parse_args(int argc, char **argv) goto out; } -/* eal_log_level_parse() already handled these */ -if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_LOG_SYSLOG_NUM ) +/* eal_log_level_parse() already handled these options */ +if (opt ==OPT_LOG_LEVEL_NUM || + opt ==OPT_SYSLOG_NUM || + opt ==OPT_LOG_TIMESTAMP_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
lib/eal/linux/eal.c +3 -1
@@ -611,7 +611,9 @@ eal_parse_args(int argc, char **argv) }/* eal_log_level_parse() already handled these options */ -if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_SYSLOG_NUM ) +if (opt ==OPT_LOG_LEVEL_NUM || + opt ==OPT_SYSLOG_NUM || + opt ==OPT_LOG_TIMESTAMP_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
lib/eal/windows/eal.c +3 -1
@@ -121,7 +121,9 @@ eal_parse_args(int argc, char **argv) }/* eal_log_level_parse() already handled these options */ -if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_SYSLOG_NUM ) +if (opt ==OPT_LOG_LEVEL_NUM || + opt ==OPT_SYSLOG_NUM || + opt ==OPT_LOG_TIMESTAMP_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
lib/log/log.c +6 -1
@@ -21,7 +21,7 @@#include "log_private.h" #ifdef RTE_EXEC_ENV_WINDOWS -#define strdup _strdup +#include <rte_os_shim.h> #endif struct rte_log_dynamic_type {
@@ -509,6 +509,11 @@ eal_log_syslog(const char *mode __rte_unused)void eal_log_init(const char *id __rte_unused) { +if (log_timestamp_enabled ()) + rte_logs.print_func = log_print_with_timestamp; +else + rte_logs.print_func = vfprintf; +#if RTE_LOG_DP_LEVEL >=RTE_LOG_DEBUG RTE_LOG (NOTICE ,EAL ,"Debug dataplane logs available - lower performance\n" );
lib/log/log_internal.h +9 -0
@@ -5,8 +5,10 @@#ifndef LOG_INTERNAL_H #define LOG_INTERNAL_H +#include <stdbool.h> #include <stdio.h> #include <stdint.h> +#include <time.h> #include <rte_compat.h>
@@ -39,4 +41,11 @@ const char *eal_log_level2str(uint32_t level);__rte_internal void rte_eal_log_cleanup(void); +/* +* Add timestamp to console logs +*/ +__rte_internal +int eal_log_timestamp(const char *fmt); + +#endif /* LOG_INTERNAL_H */
lib/log/log_private.h +11 -0
@@ -3,7 +3,18 @@#ifndef LOG_PRIVATE_H #define LOG_PRIVATE_H +/* Defined in limits.h on Linux */ +#ifndef LINE_MAX +#define LINE_MAX 2048/* _POSIX2_LINE_MAX */ +#endif +/* Note: same as vfprintf() */ typedef int (*log_print_t )(FILE *f,const char *fmt,va_list ap); +bool log_timestamp_enabled (void ); +ssize_t log_timestamp (char *tsbuf,size_t tsbuflen); + +__rte_format_printf(2, 0) +int log_print_with_timestamp (FILE *f,const char *format,va_list ap); +#endif /* LOG_PRIVATE_H */
lib/log/log_timestamp.c new file +240 -0
240 lines not on this page · raw message
lib/log/meson.build +5 -1
@@ -2,5 +2,9 @@ # Copyright(c) 2023 Intel Corporation includes += global_inc -sources = files('log.c') +sources = files( + 'log.c', + 'log_timestamp.c', +) + headers = files('rte_log.h')
lib/log/version.map +1 -0
@@ -30,5 +30,6 @@ INTERNAL { eal_log_save_pattern; eal_log_save_regexp; eal_log_syslog; + eal_log_timestamp; rte_eal_log_cleanup; };
Signature · 1 line
2.45.2
PATCH v26 12/15 log: add optional support of syslog
In reply to Stephen HemmingerLog to syslog only if option is specified. And if syslog is used then normally only log to syslog, don't duplicate output. Also enables syslog support on FreeBSD.
--- app/test/test_eal_flags.c | 5 +- doc/guides/linux_gsg/linux_eal_parameters.rst | 27 ------ doc/guides/prog_guide/log_lib.rst | 21 ++++- lib/eal/common/eal_common_options.c | 5 +- lib/log/log.c | 28 +++--- lib/log/log_private.h | 17 ++++ lib/log/log_syslog.c | 88 +++++++++++++++++++ lib/log/meson.build | 4 + lib/log/version.map | 2 +- 9 files changed, 151 insertions(+), 46 deletions(-) create mode 100644 lib/log/log_syslog.c
app/test/test_eal_flags.c +3 -2
@@ -987,9 +987,10 @@ test_misc_flags(void)/* With empty --syslog */ const char *argv3[] = {prgname, prefix, mp_flag,"--syslog" };/* With valid --syslog */ -const char *argv4[] = {prgname, prefix, mp_flag,"--syslog" ,"always" }; +const char *argv4[] = {prgname, prefix, mp_flag,"--syslog=both" };/* With invalid --syslog */ -const char *argv5[] = {prgname, prefix, mp_flag,"--syslog" ,"error" }; +const char *argv5[] = {prgname, prefix, mp_flag,"--syslog=invalid" }; +/* With no-sh-conf, also use no-huge to ensure this test runs on BSD */ const char *argv6[] = {prgname,"-m" ,DEFAULT_MEM_SIZE , no_shconf, nosh_prefix, no_huge};
doc/guides/linux_gsg/linux_eal_parameters.rst +0 -27
@@ -108,30 +108,3 @@ Memory-related options * ``--match-allocations`` Free hugepages back to system exactly as they were originally allocated. - -Other options -~~~~~~~~~~~~~ - -* ``--syslog <syslog facility>`` - - Set syslog facility. Valid syslog facilities are:: - - auth - cron - daemon - ftp - kern - lpr - mail - news - syslog - user - uucp - local0 - local1 - local2 - local3 - local4 - local5 - local6 - local7
doc/guides/prog_guide/log_lib.rst +18 -3
@@ -5,9 +5,7 @@ Log Library =========== The DPDK Log library provides the logging functionality for other DPDK libraries and drivers. -By default, in a Linux application, logs are sent to syslog and also to the console. -On FreeBSD and Windows applications, logs are sent only to the console. -However, the log function can be overridden by the user to use a different logging mechanism. +The messages can be sent to one or more sources controlled by the EAL command line options. Log Levels ----------
@@ -83,6 +81,23 @@ To prefix all console messages with ISO format time the syntax is:: /path/to/app --log-timestamp=iso +Log output +~~~~~~~~~~ + +If desired, messages can be redirected to syslog (on Linux and FreeBSD) with the ``--syslog`` +option. There are three possible settings for this option: + +*always* + Redirect all log output to syslog. + +*auto* + Use console if it is a terminal, and use syslog if is not. + +*both* + Print to both console and syslog. + +If ``--syslog`` option is not specified, then only console (stderr) will be used. + Using Logging APIs to Generate Log Messages
lib/eal/common/eal_common_options.c +4 -1
@@ -91,7 +91,7 @@ eal_long_options[] = { {OPT_PROC_TYPE, 1, NULL, OPT_PROC_TYPE_NUM }, {OPT_SOCKET_MEM, 1, NULL, OPT_SOCKET_MEM_NUM }, {OPT_SOCKET_LIMIT, 1, NULL, OPT_SOCKET_LIMIT_NUM }, - {OPT_SYSLOG, 1, NULL, OPT_SYSLOG_NUM }, + {OPT_SYSLOG, 2, NULL, OPT_SYSLOG_NUM }, {OPT_VDEV, 1, NULL, OPT_VDEV_NUM }, {OPT_VFIO_INTR, 1, NULL, OPT_VFIO_INTR_NUM }, {OPT_VFIO_VF_TOKEN, 1, NULL, OPT_VFIO_VF_TOKEN_NUM },
@@ -2215,6 +2215,9 @@ eal_common_usage(void)" (can be used multiple times)\n" " --" OPT_VMWARE_TSC_MAP " Use VMware TSC map instead of native RDTSC\n" " --" OPT_PROC_TYPE " Type of this process (primary|secondary|auto)\n" +#ifndef RTE_EXEC_ENV_WINDOWS +" --" OPT_SYSLOG "[=<when>] Enable use of syslog\n" +#endif " --"OPT_LOG_LEVEL"=<level> Set global log level\n"" --" OPT_LOG_LEVEL "=<type-match>:<level>\n" " Set specific log level\n"
lib/log/log.c +16 -12
@@ -12,18 +12,19 @@#include <regex.h> #include <fnmatch.h> #include <sys/queue.h> +#include <unistd.h> #include <rte_common.h> #include <rte_log.h> #include <rte_per_lcore.h> -#include "log_internal.h" -#include "log_private.h" -#ifdef RTE_EXEC_ENV_WINDOWS #include <rte_os_shim.h> #endif +#include "log_internal.h" +#include "log_private.h" +struct rte_log_dynamic_type {const char *name;uint32_t loglevel;
@@ -496,20 +497,23 @@ rte_log(uint32_t level, uint32_t logtype, const char *format, ...)return ret; } -/* Placeholder */ -int -eal_log_syslog(const char *mode __rte_unused) -{ -return -1 ; -} -/* * Called by rte_eal_init */ void -eal_log_init(const char *id __rte_unused) +eal_log_init (const char *id) { -if (log_timestamp_enabled ()) +bool is_terminal; + +#ifdef RTE_EXEC_ENV_WINDOWS + is_terminal =_isatty (_fileno (stderr)); +#else + is_terminal =isatty (STDERR_FILENO ); +#endif + +if (log_syslog_enabled (is_terminal)) +log_syslog_open (id, is_terminal); +else if (log_timestamp_enabled ()) rte_logs.print_func = log_print_with_timestamp;else rte_logs.print_func = vfprintf;
lib/log/log_private.h +17 -0
@@ -17,4 +17,21 @@ ssize_t log_timestamp(char *tsbuf, size_t tsbuflen); __rte_format_printf(2, 0)int log_print_with_timestamp (FILE *f,const char *format,va_list ap); +#ifdef RTE_EXEC_ENV_WINDOWS +static inline bool +log_syslog_enabled(bool is_tty __rte_unused) +{ +return false; +} + +static inline void +log_syslog_open(const char *id __rte_unused, bool is_terminal __rte_unused) +{ +} +#else + +bool log_syslog_enabled (bool is_tty); +void log_syslog_open (const char *id,bool is_terminal); +#endif +#endif /* LOG_PRIVATE_H */
lib/log/log_syslog.c new file +88 -0
88 lines not on this page · raw message
lib/log/meson.build +4 -0
@@ -7,4 +7,8 @@ sources = files( 'log_timestamp.c', ) +if not is_windows + sources += files('log_syslog.c') +endif + headers = files('rte_log.h')
lib/log/version.map +1 -1
@@ -29,7 +29,7 @@ INTERNAL { eal_log_level2str; eal_log_save_pattern; eal_log_save_regexp; - eal_log_syslog; + eal_log_syslog; # WINDOWS_NO_EXPORT eal_log_timestamp; rte_eal_log_cleanup; };
Signature · 1 line
2.45.2
PATCH v26 13/15 log: add support for systemd journal
In reply to Stephen HemmingerIf DPDK application is being run as a systemd service, then it can use the journal protocol which allows putting more information in the log such as priority and other information.
The use of journal protocol is automatically detected and handled. Rather than having a dependency on libsystemd, just use the protocol directly as defined in:
https://systemd.io/JOURNAL_NATIVE_PROTOCOL/
--- doc/guides/prog_guide/log_lib.rst | 14 ++ lib/eal/common/eal_common_options.c | 15 +++ lib/eal/common/eal_options.h | 2 + lib/log/log.c | 4 +- lib/log/log_internal.h | 3 + lib/log/log_journal.c | 200 ++++++++++++++++++++++++++++ lib/log/log_private.h | 16 +++ lib/log/meson.build | 4 + lib/log/version.map | 1 + 9 files changed, 258 insertions(+), 1 deletion(-) create mode 100644 lib/log/log_journal.c
doc/guides/prog_guide/log_lib.rst +14 -0
@@ -98,6 +98,20 @@ option. There are three possible settings for this option: If ``--syslog`` option is not specified, then only console (stderr) will be used. +Messages can be redirected to systemd journal which is an enhanced version of syslog with the ``--log-journal`` option. + +There are three possible settings for this option: + +*auto* + If stderr is redirected to journal by ``systemd`` service + then use journal socket to instead of stderr for log. + This is the default. + +*never* + Do not try to use journal. + +*always* + Always try to direct messages to journal socket. Using Logging APIs to Generate Log Messages
lib/eal/common/eal_common_options.c +15 -0
@@ -74,6 +74,7 @@ eal_long_options[] = { {OPT_IOVA_MODE, 1, NULL, OPT_IOVA_MODE_NUM }, {OPT_LCORES, 1, NULL, OPT_LCORES_NUM }, {OPT_LOG_LEVEL, 1, NULL, OPT_LOG_LEVEL_NUM }, + {OPT_LOG_JOURNAL, 2, NULL, OPT_LOG_JOURNAL_NUM }, {OPT_LOG_TIMESTAMP, 2, NULL, OPT_LOG_TIMESTAMP_NUM }, {OPT_TRACE, 1, NULL, OPT_TRACE_NUM }, {OPT_TRACE_DIR, 1, NULL, OPT_TRACE_DIR_NUM },
@@ -1617,6 +1618,7 @@ eal_log_level_parse(int argc, char * const argv[])switch (opt) {case OPT_LOG_LEVEL_NUM :case OPT_SYSLOG_NUM : +case OPT_LOG_JOURNAL_NUM :case OPT_LOG_TIMESTAMP_NUM :if (eal_parse_common_option (opt, optarg, internal_conf) <0 )return -1 ;
@@ -1840,6 +1842,16 @@ eal_parse_common_option(int opt, const char *optarg,break ;#endif +#ifdef RTE_EXEC_ENV_LINUX +case OPT_LOG_JOURNAL_NUM : +if (eal_log_journal (optarg) <0 ) { +EAL_LOG (ERR ,"invalid parameters for --" +OPT_LOG_JOURNAL ); +return -1 ; + } +break ; +#endif +case OPT_LOG_LEVEL_NUM :if (eal_parse_log_level (optarg) <0 ) { EAL_LOG(ERR,
@@ -2217,6 +2229,9 @@ eal_common_usage(void) " --"OPT_PROC_TYPE" Type of this process (primary|secondary|auto)\n" #ifndef RTE_EXEC_ENV_WINDOWS " --"OPT_SYSLOG"[=<when>] Enable use of syslog\n" +#endif +#ifdef RTE_EXEC_ENV_LINUX + " --"OPT_LOG_JOURNAL"[=<when>] Enable use of systemd journal\n"#endif " --" OPT_LOG_LEVEL "=<level> Set global log level\n" " --" OPT_LOG_LEVEL "=<type-match>:<level>\n"
lib/eal/common/eal_options.h +2 -0
@@ -35,6 +35,8 @@ enum {OPT_LCORES_NUM , #define OPT_LOG_LEVEL "log-level"OPT_LOG_LEVEL_NUM , +#define OPT_LOG_JOURNAL "log-journal" +OPT_LOG_JOURNAL_NUM , #define OPT_LOG_TIMESTAMP "log-timestamp"OPT_LOG_TIMESTAMP_NUM , #define OPT_TRACE "trace"
lib/log/log.c +3 -1
@@ -511,7 +511,9 @@ eal_log_init(const char *id) is_terminal =isatty (STDERR_FILENO );#endif -if (log_syslog_enabled (is_terminal)) +if (log_journal_enabled ()) +log_journal_open (id); +else if (log_syslog_enabled (is_terminal))log_syslog_open (id, is_terminal);else if (log_timestamp_enabled ()) rte_logs.print_func = log_print_with_timestamp;
lib/log/log_internal.h +3 -0
@@ -29,6 +29,9 @@ int eal_log_save_pattern(const char *pattern, uint32_t level);__rte_internal int eal_log_syslog(const char *name); +__rte_internal +int eal_log_journal(const char *opt); +/* * Convert log level to string. */
lib/log/log_journal.c new file +200 -0
200 lines not on this page · raw message
lib/log/log_private.h +16 -0
@@ -34,4 +34,20 @@ bool log_syslog_enabled(bool is_tty);void log_syslog_open (const char *id,bool is_terminal);#endif +#ifdef RTE_EXEC_ENV_LINUX +bool log_journal_enabled (void ); +void log_journal_open (const char *id); +#else +static inline bool +log_journal_enabled (void ) +{ +return false; +} + +static inline void +log_journal_open(const char *id __rte_unused) +{ +} +#endif /* !RTE_EXEC_ENV_LINUX */ +#endif /* LOG_PRIVATE_H */
lib/log/meson.build +4 -0
@@ -11,4 +11,8 @@ if not is_windows sources += files('log_syslog.c') endif +if is_linux + sources += files('log_journal.c') +endif + headers = files('rte_log.h')
lib/log/version.map +1 -0
@@ -26,6 +26,7 @@ INTERNAL { global: eal_log_init; + eal_log_journal; # WINDOWS_NO_EXPORT eal_log_level2str; eal_log_save_pattern; eal_log_save_regexp;
Signature · 1 line
2.45.2
PATCH v26 14/15 log: colorize log output
In reply to Stephen HemmingerLike dmesg, colorize the log output (unless redirected to file). Timestamp is green, the subsystem is in yellow and the message is red if urgent, boldface if an error, and normal for info and debug messages.
The default is to not use color since it may disturb automatic tests and other embedded usage.
log dark
--- app/test/test_eal_flags.c | 24 ++++ doc/guides/prog_guide/log_lib.rst | 15 ++ lib/eal/common/eal_common_options.c | 11 ++ lib/eal/common/eal_options.h | 6 +- lib/log/log.c | 19 ++- lib/log/log_color.c | 216 ++++++++++++++++++++++++++++ lib/log/log_internal.h | 5 + lib/log/log_private.h | 8 ++ lib/log/meson.build | 1 + lib/log/version.map | 1 + 10 files changed, 298 insertions(+), 8 deletions(-) create mode 100644 lib/log/log_color.c
app/test/test_eal_flags.c +24 -0
@@ -1067,6 +1067,18 @@ test_misc_flags(void)const char *const argv25[] = {prgname, prefix, mp_flag,"--log-timestamp=invalid" }; +/* Try running with --log-color */ +const char *const argv26[] = {prgname, prefix, mp_flag, +"--log-color" }; + +/* Try running with --log-color=never */ +const char *const argv27[] = {prgname, prefix, mp_flag, +"--log-color=never" }; + +/* Try running with --log-color=invalid */ +const char *const argv28[] = {prgname, prefix, mp_flag, +"--log-color=invalid" }; +/* run all tests also applicable to FreeBSD first */
@@ -1187,6 +1199,18 @@ test_misc_flags(void)printf ("Error - process did run ok with --log-timestamp=invalid parameter\n" ); goto fail; } +if (launch_proc (argv26) !=0 ) { +printf ("Error - process did not run ok with --log-color parameter\n" ); + goto fail; + } +if (launch_proc (argv27) !=0 ) { +printf ("Error - process did not run ok with --log-color=none parameter\n" ); + goto fail; + } +if (launch_proc (argv28) ==0 ) { +printf ("Error - process did run ok with --log-timestamp=invalid parameter\n" ); + goto fail; + }rmdir (hugepath_dir3);
doc/guides/prog_guide/log_lib.rst +15 -0
@@ -57,6 +57,21 @@ For example:: Within an application, the same result can be got using the ``rte_log_set_level_pattern()`` or ``rte_log_set_level_regex()`` APIs. +Color output +~~~~~~~~~~~~ + +The log library will highlight important messages. +This is controlled by the ``--log-color`` option. +he optional argument ``when`` can be ``auto``, ``never``, or ``always``. +The default setting is ``auto`` which enables color when the output to +``stderr`` is a terminal. +If the ``when`` argument is omitted, it defaults to ``always``. + +For example to turn off all coloring:: + + /path/to/app --log-color=none + + Log timestamp ~~~~~~~~~~~~~
lib/eal/common/eal_common_options.c +11 -0
@@ -73,6 +73,7 @@ eal_long_options[] = { {OPT_HUGE_UNLINK, 2, NULL, OPT_HUGE_UNLINK_NUM }, {OPT_IOVA_MODE, 1, NULL, OPT_IOVA_MODE_NUM }, {OPT_LCORES, 1, NULL, OPT_LCORES_NUM }, + {OPT_LOG_COLOR, 2, NULL, OPT_LOG_COLOR_NUM }, {OPT_LOG_LEVEL, 1, NULL, OPT_LOG_LEVEL_NUM }, {OPT_LOG_JOURNAL, 2, NULL, OPT_LOG_JOURNAL_NUM }, {OPT_LOG_TIMESTAMP, 2, NULL, OPT_LOG_TIMESTAMP_NUM },
@@ -1620,6 +1621,7 @@ eal_log_level_parse(int argc, char * const argv[])case OPT_SYSLOG_NUM :case OPT_LOG_JOURNAL_NUM :case OPT_LOG_TIMESTAMP_NUM : +case OPT_LOG_COLOR_NUM :if (eal_parse_common_option (opt, optarg, internal_conf) <0 )return -1 ;break ;
@@ -1869,6 +1871,14 @@ eal_parse_common_option(int opt, const char *optarg, }break ; +case OPT_LOG_COLOR_NUM : +if (eal_log_color (optarg) <0 ) { +EAL_LOG (ERR ,"invalid parameters for --" +OPT_LOG_COLOR ); +return -1 ; + } +break ; +#ifndef RTE_EXEC_ENV_WINDOWS case OPT_TRACE_NUM : {if (eal_trace_args_save (optarg) <0 ) {
@@ -2238,6 +2248,7 @@ eal_common_usage(void)" Set specific log level\n" " --" OPT_LOG_LEVEL "=help Show log types and levels\n" " --" OPT_LOG_TIMESTAMP "[=<format>] Timestamp log output\n" +" --" OPT_LOG_COLOR "[=<when>] Colorize log messages\n" #ifndef RTE_EXEC_ENV_WINDOWS" --" OPT_TRACE "=<regex-match>\n" " Enable trace based on regular expression trace name.\n"
lib/eal/common/eal_options.h +4 -2
@@ -33,10 +33,12 @@ enum {OPT_HUGE_UNLINK_NUM , #define OPT_LCORES "lcores"OPT_LCORES_NUM , -#define OPT_LOG_LEVEL "log-level" -OPT_LOG_LEVEL_NUM , +#define OPT_LOG_COLOR "log-color" +OPT_LOG_COLOR_NUM , #define OPT_LOG_JOURNAL "log-journal"OPT_LOG_JOURNAL_NUM , +#define OPT_LOG_LEVEL "log-level" +OPT_LOG_LEVEL_NUM , #define OPT_LOG_TIMESTAMP "log-timestamp"OPT_LOG_TIMESTAMP_NUM , #define OPT_TRACE "trace"
lib/log/log.c +13 -6
@@ -511,14 +511,21 @@ eal_log_init(const char *id) is_terminal =isatty (STDERR_FILENO );#endif -if (log_journal_enabled ()) +if (log_journal_enabled ()) {log_journal_open (id); -else if (log_syslog_enabled (is_terminal)) + }else if (log_syslog_enabled (is_terminal)) {log_syslog_open (id, is_terminal); -else if (log_timestamp_enabled ()) - rte_logs.print_func = log_print_with_timestamp; -else - rte_logs.print_func = vfprintf; + }else if (log_timestamp_enabled ()) { +if (log_color_enabled (is_terminal)) + rte_logs.print_func = color_print_with_timestamp; +else + rte_logs.print_func = log_print_with_timestamp; + }else { +if (log_color_enabled (is_terminal)) + rte_logs.print_func = color_print; +else + rte_logs.print_func = vfprintf; + }#if RTE_LOG_DP_LEVEL >=RTE_LOG_DEBUG RTE_LOG(NOTICE, EAL,
lib/log/log_color.c new file +216 -0
216 lines not on this page · raw message
lib/log/log_internal.h +5 -0
@@ -50,5 +50,10 @@ void rte_eal_log_cleanup(void);__rte_internal int eal_log_timestamp(const char *fmt); +/* +* Enable or disable color in log messages +*/ +__rte_internal +int eal_log_color(const char *mode);#endif /* LOG_INTERNAL_H */
lib/log/log_private.h +8 -0
@@ -50,4 +50,12 @@ log_journal_open(const char *id __rte_unused) }#endif /* !RTE_EXEC_ENV_LINUX */ +bool log_color_enabled (bool is_tty); + +__rte_format_printf(2, 0) +int color_print (FILE *f,const char *format,va_list ap); + +__rte_format_printf(2, 0) +int color_print_with_timestamp (FILE *f,const char *format,va_list ap); +#endif /* LOG_PRIVATE_H */
lib/log/meson.build +1 -0
@@ -4,6 +4,7 @@ includes += global_inc sources = files( 'log.c', + 'log_color.c', 'log_timestamp.c', )
lib/log/version.map +1 -0
@@ -25,6 +25,7 @@ DPDK_25 { INTERNAL { global: + eal_log_color; eal_log_init; eal_log_journal; # WINDOWS_NO_EXPORT eal_log_level2str;
Signature · 1 line
2.45.2
PATCH v26 15/15 doc: add release note about log library
In reply to Stephen HemmingerSignificant enough to add some documentation.
--- doc/guides/rel_notes/release_24_11.rst | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
doc/guides/rel_notes/release_24_11.rst +26 -0
@@ -276,6 +276,32 @@ API Changes and replaced it with a new shared devarg ``llq_policy`` that keeps the same logic. +* **Logging library changes** + + * The log is initialized earlier in startup so all messages go through + the library. + + * Added a new option to timestamp log messages, which is useful for + debugging delays in application and driver startup. + + * Syslog related changes + + * The meaning of the *--syslog* option has changed. + Use of syslog is controlled by the *--syslog* option. + The default is now *auto* which uses syslog only if stderr + is not a terminal device. + + * The syslog facility is now set to **LOG_USER** if stderr is a terminal + and **LOG_DAEMON** otherwise. + + * Syslog is now supported on FreeBSD (but not on Windows). + + * If the application is a systemd service and the log output is being + sent of standard error then DPDK will switch to journal native protocol. + + * Log messages can be optionally marked with colors. + + ABI Changes -----------
Signature · 1 line
2.45.2
Re: [PATCH v26 00/15] Log subsystem improvements
In reply to Stephen HemmingerHello Stephen,
Quoted 29 lines · Stephen Hemminger
Improvements and unification of logging library.
This version works on all platforms: Linux, Windows and FreeBSD.This is update to rework patch set. It adds several new features to the console log output.
* Putting a timestamp on console output which is useful for analyzing performance of startup codes. Timestamp is optional and must be enabled on command line.
* Displaying console output with colors.
It uses the standard conventions used by many other Linux commands for colorized display. The default is to enable color if the console output is going to a terminal. But it can be always on or disabled by command line flag. This default was chosen based on what dmesg(1) command does.Color is used by many tools (vi, iproute2, git) because it is helpful; DPDK drivers and libraries print lots of not very useful messages. And having error messages highlighted in bold face helps. This might also get users to pay more attention to error messages. Many bug reports have earlier messages that are lost because there are so many info messages.
* Add support for automatic detection of systemd journal protocol. If running as systemd service will get enhanced logging.
Quoted 6 lines
* Use of syslog is optional and the meaning of the --syslog flag has changed. The default is *not* to use syslog if output is going to a terminal.
Add myself as maintainer for log because by now have added more than previous authors.
Thanks for the series.
Overall, it looks good, but I am too short on time for merging in rc1 and I have some comments.
I'll consider merging it in rc2.
- The main point is the "automatic" aspect but we want to provide some way to force where the logs end up.
With this series, the user has --syslog (whose meaning is changed) and --log-journal options to affect where the logs go.
Can we get a single option?
Like maybe --log-destination=console|syslog|journal|auto ?
- I don't really understand why changing the --syslog is better. We lose the ability to select the syslog facility. Either this feature was useless, and I would rather deprecate or remove it explicitly (and the --syslog with it).
Or we should keep it as is for compat reason.
- The color and timestamping options only affect the console output, which is not clear with the --log-color / --log-timestamp names. Maybe we can enhance with some other name?
- Did you test redirecting all logs to an external logging function? I suppose it still works, but it is important not to break such feature for OVS.
Signature · 1 line
David Marchand
Re: [PATCH v26 00/15] Log subsystem improvements
Quoted 47 lines · On Fri, 18 Oct 2024 19:07:18 +0200 David Marchand <[email protected]>…
Hello Stephen,
Quoted 29 lines · Stephen Hemminger
Improvements and unification of logging library.
This version works on all platforms: Linux, Windows and FreeBSD.This is update to rework patch set. It adds several new features to the console log output.
* Putting a timestamp on console output which is useful for analyzing performance of startup codes. Timestamp is optional and must be enabled on command line.
* Displaying console output with colors.
It uses the standard conventions used by many other Linux commands for colorized display. The default is to enable color if the console output is going to a terminal. But it can be always on or disabled by command line flag. This default was chosen based on what dmesg(1) command does.Color is used by many tools (vi, iproute2, git) because it is helpful; DPDK drivers and libraries print lots of not very useful messages. And having error messages highlighted in bold face helps. This might also get users to pay more attention to error messages. Many bug reports have earlier messages that are lost because there are so many info messages.
* Add support for automatic detection of systemd journal protocol. If running as systemd service will get enhanced logging.
Quoted 6 lines
* Use of syslog is optional and the meaning of the --syslog flag has changed. The default is *not* to use syslog if output is going to a terminal.
Add myself as maintainer for log because by now have added more than previous authors.
Thanks for the series.
Overall, it looks good, but I am too short on time for merging in rc1 and I have some comments.
I'll consider merging it in rc2.
Quoted 6 lines
- The main point is the "automatic" aspect but we want to provide some way to force where the logs end up.
With this series, the user has --syslog (whose meaning is changed) and --log-journal options to affect where the logs go.
Can we get a single option?
Like maybe --log-destination=console|syslog|journal|auto ?
That could work. The goal here is to do the right thing without options. And reduce the duplication. Right now, applications end up logging to both console and syslog.
Quoted 6 lines
- I don't really understand why changing the --syslog is better. We lose the ability to select the syslog facility. Either this feature was useless, and I would rather deprecate or remove it explicitly (and the --syslog with it).
Or we should keep it as is for compat reason.
Syslog facility really was pretty useless. The number of facilities is too small and there never was a good reason to have it.
Maybe keep old option syntax as fallback?
Quoted 4 lines
- The color and timestamping options only affect the console output, which is not clear with the --log-color / --log-timestamp names. Maybe we can enhance with some other name?
Timestamp is unneeded with syslog or journal since they do it already. It is possible to force timestamp or color when going to a file (by setting log stream).
Did consider that options could be: --color and --timestamp but seemed better to keep all log related options together.
Quoted 3 lines
- Did you test redirecting all logs to an external logging function? I suppose it still works, but it is important not to break such feature for OVS.
Did not have test for that, should be put in functional tests.
I flip/flopped on default for color. I like the auto mode and it might make users see errors more. But concerned that things like CI which are capturing via pseudo-terminals might get color and not know what to do with it. Final version defaults to off.
Re: [PATCH v26 00/15] Log subsystem improvements
In reply to Stephen HemmingerHi,
I'm not sure about the proper way to do a code review here, feel free to educate me if there is a better way to do it. I couldn't find the actual patches text in the mail and patchwork has no interface to write comments on the line itself but I may very well have missed something.
https://patches.dpdk.org/project/dpdk/patch/[email protected]/
Why not provide an option to disable the syslog with --syslog=none? It will allow overriding a previous setting if one was given as well.
(the same applies to the --log-journal option)
https://patches.dpdk.org/project/dpdk/patch/[email protected]/
You have both --log-color=never and --log-color=none, you probably need to make up your mind, my vote would be with none for better compatibility with the syslog/journal options I made above. But I don't care that much about it.
Would also be good to document about the dark mode option so people don't need to find it only in the code.
Baruch
Quoted 99 lines · Stephen Hemminger
Improvements and unification of logging library.
This version works on all platforms: Linux, Windows and FreeBSD.This is update to rework patch set. It adds several new features to the console log output.
* Putting a timestamp on console output which is useful for analyzing performance of startup codes. Timestamp is optional and must be enabled on command line.
* Displaying console output with colors.
It uses the standard conventions used by many other Linux commands for colorized display. The default is to enable color if the console output is going to a terminal. But it can be always on or disabled by command line flag. This default was chosen based on what dmesg(1) command does.Color is used by many tools (vi, iproute2, git) because it is helpful; DPDK drivers and libraries print lots of not very useful messages. And having error messages highlighted in bold face helps. This might also get users to pay more attention to error messages. Many bug reports have earlier messages that are lost because there are so many info messages.
* Add support for automatic detection of systemd journal protocol. If running as systemd service will get enhanced logging.
* Use of syslog is optional and the meaning of the --syslog flag has changed. The default is *not* to use syslog if output is going to a terminal.
Add myself as maintainer for log because by now have added more than previous authors.
v26 - rebase and change release note
- by default, do not disable color
- support dark mode with colors
- when using color format message to string then print to avoid getting multiple threads intermixing on output.Stephen Hemminger (15):
maintainers: add for log library
windows: make getopt functions have const properties
windows: add os shim forlocaltime_r
eal: makeeal_log_level_parsecommon
eal: do not duplicaterte_init_alert()messages
eal: changerte_exit()output to matchrte_log()
log: move handling of syslog facility out of eal
eal: initialize log before everything else
log: drop syslog support, and make code common
log: add hook for printing log messages
log: add timestamp option
log: add optional support of syslog
log: add support for systemd journal
log: colorize log output
doc: add release note about log libraryMAINTAINERS | 1 + app/test/test_eal_flags.c | 64 ++++- doc/guides/linux_gsg/linux_eal_parameters.rst | 27 -- doc/guides/prog_guide/log_lib.rst | 76 +++++- doc/guides/rel_notes/release_24_11.rst | 26 ++ lib/eal/common/eal_common_debug.c | 6 +- lib/eal/common/eal_common_options.c | 135 ++++++---- lib/eal/common/eal_internal_cfg.h | 1 - lib/eal/common/eal_options.h | 7 + lib/eal/freebsd/eal.c | 64 +---- lib/eal/linux/eal.c | 68 +---- lib/eal/windows/eal.c | 49 +--- lib/eal/windows/getopt.c | 23 +- lib/eal/windows/include/getopt.h | 8 +- lib/eal/windows/include/rte_os_shim.h | 10 + lib/log/log.c | 71 ++++-- lib/log/log_color.c | 216 ++++++++++++++++ lib/log/log_freebsd.c | 12 - lib/log/log_internal.h | 28 +- lib/log/log_journal.c | 200 +++++++++++++++ lib/log/log_linux.c | 61 ----- lib/log/log_private.h | 61 +++++ lib/log/log_syslog.c | 88 +++++++ lib/log/log_timestamp.c | 240 ++++++++++++++++++ lib/log/log_windows.c | 18 -- lib/log/meson.build | 12 +- lib/log/version.map | 5 +- 27 files changed, 1197 insertions(+), 380 deletions(-) create mode 100644 lib/log/log_color.c delete mode 100644 lib/log/log_freebsd.c create mode 100644 lib/log/log_journal.c delete mode 100644 lib/log/log_linux.c create mode 100644 lib/log/log_private.h create mode 100644 lib/log/log_syslog.c create mode 100644 lib/log/log_timestamp.c delete mode 100644 lib/log/log_windows.c--
2.45.2
Signature · 6 lines
Baruch Even Platform Technical Lead at WEKA E [email protected]* *W https://www.weka.io* * [image: App Banner Image] <https://www.weka.io/trends-in-AI-emsig?utm_campaign=signature&utm_source=WiseStamp&utm_medium=email>
v27 cover Log subsystem changes
In reply to Stephen HemmingerImprovements and unification of logging library.
This version works on all platforms: Linux, Windows and FreeBSD.
This is update to rework patch set. It adds several new features to the console log output.
* Putting a timestamp on console output which is useful for analyzing performance of startup codes. Timestamp is optional and must be enabled on command line.
* Displaying console output with colors.
It uses the standard conventions used by many other Linux commands for colorized display. The default is to enable color if the console output is going to a terminal. But it can be always on or disabled by command line flag. This default was chosen based on what dmesg(1) command does.
Color is used by many tools (vi, iproute2, git) because it is helpful; DPDK drivers and libraries print lots of not very useful messages. And having error messages highlighted in bold face helps. This might also get users to pay more attention to error messages. Many bug reports have earlier messages that are lost because there are so many info messages.
* Add support for automatic detection of systemd journal protocol. If running as systemd service will get enhanced logging.
* Use of syslog is optional and the meaning of the --syslog flag has changed. The default is *not* to use unless requested.
Add myself as maintainer for log because by now have added more than previous authors.
v27 - review feedback
- consolidate and simplify
- keep the meaning of --syslog=facility the same as before.
v26 - rebase and change release note
- by default, do not disable color
- support dark mode with colors
- when using color format message to string then print to avoid getting multiple threads intermixing on output.
Stephen Hemminger (14):
maintainers: add for log library
windows: make getopt functions have const properties
windows: update os shim
eal: make eal_log_level_parse common
eal: do not duplicate rte_init_alert() messages
eal: change rte_exit() output to match rte_log()
log: move handling of syslog facility out of eal
eal: initialize log before everything else
log: add hook for printing log messages
log: modify syslog handling
log: add timestamp option
log: add support for systemd journal
log: colorize log output
doc: add release note about log library
MAINTAINERS | 1 + app/test/test_eal_flags.c | 66 ++++- doc/guides/linux_gsg/linux_eal_parameters.rst | 27 -- doc/guides/prog_guide/log_lib.rst | 57 +++- doc/guides/rel_notes/release_24_11.rst | 19 ++ lib/eal/common/eal_common_debug.c | 6 +- lib/eal/common/eal_common_options.c | 122 +++++---- lib/eal/common/eal_internal_cfg.h | 1 - lib/eal/common/eal_options.h | 5 + lib/eal/freebsd/eal.c | 64 +---- lib/eal/linux/eal.c | 68 +---- lib/eal/windows/eal.c | 50 +--- lib/eal/windows/getopt.c | 23 +- lib/eal/windows/include/getopt.h | 8 +- lib/eal/windows/include/rte_os_shim.h | 10 + lib/log/log.c | 76 ++++-- lib/log/log_color.c | 216 +++++++++++++++ lib/log/log_freebsd.c | 12 - lib/log/log_internal.h | 28 +- lib/log/log_journal.c | 154 +++++++++++ lib/log/log_linux.c | 61 ----- lib/log/log_private.h | 36 +++ lib/log/log_syslog.c | 106 ++++++++ lib/log/log_timestamp.c | 245 ++++++++++++++++++ lib/log/log_windows.c | 18 -- lib/log/meson.build | 12 +- lib/log/version.map | 5 +- 27 files changed, 1114 insertions(+), 382 deletions(-) create mode 100644 lib/log/log_color.c delete mode 100644 lib/log/log_freebsd.c create mode 100644 lib/log/log_journal.c delete mode 100644 lib/log/log_linux.c create mode 100644 lib/log/log_private.h create mode 100644 lib/log/log_syslog.c create mode 100644 lib/log/log_timestamp.c delete mode 100644 lib/log/log_windows.c
Signature · 1 line
2.45.2
PATCH v27 1/14 maintainers: add for log library
"You touch it you own it"
Add myself as maintainer for log library.
--- MAINTAINERS | 1 + 1 file changed, 1 insertion(+)
MAINTAINERS +1 -0
@@ -186,6 +186,7 @@ F: app/test/test_threads.c F: app/test/test_version.c Logging +M: Stephen Hemminger <[email protected]> F: lib/log/ F: doc/guides/prog_guide/log_lib.rst F: app/test/test_logs.c
Signature · 1 line
2.45.2
PATCH v27 2/14 windows: make getopt functions have const properties
In reply to Stephen HemmingerHaving different prototypes on different platforms can lead to lots of unnecessary workarounds. Looks like the version of getopt used from windows was based on an older out of date version from FreeBSD.
This patch changes getopt, getopt_long, etc to have the same const attributes as Linux and FreeBSD. The changes are derived from the current FreeBSD version of getopt_long.
--- lib/eal/windows/getopt.c | 23 ++++++++++++----------- lib/eal/windows/include/getopt.h | 8 ++++---- 2 files changed, 16 insertions(+), 15 deletions(-)
lib/eal/windows/getopt.c +12 -11
@@ -20,7 +20,7 @@#include <string.h> #include <stdlib.h> -const char *optarg;/* argument associated with option */ +char *optarg;/* argument associated with option */ int opterr =1 ;/* if error message should be printed */ int optind =1 ;/* index into parent argv vector */ int optopt ='?' ;/* character checked for validity */
@@ -39,9 +39,9 @@ static void pass(const char *a) {(void) a; }#define BADARG ((*options == ':') ? (int)':' : (int)'?')#define INORDER 1 -#define EMSG "" +static char EMSG [] ="" ; -static const char *place =EMSG ;/* option letter processing */ +static char *place =EMSG ;/* option letter processing */ /* XXX: set optreset to 1 rather than these two */ static int nonopt_start =-1 ;/* first non option argument (for permute) */
@@ -80,7 +80,7 @@ gcd(int a, int b)*/ static void permute_args (int panonopt_start,int panonopt_end,int opt_end, -char **nargv) +char *const *nargv) {int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;char *swap;
@@ -101,11 +101,12 @@ permute_args(int panonopt_start, int panonopt_end, int opt_end, pos -= nnonopts; else pos += nopts; + swap = nargv[pos];/* LINTED const cast */ - ((char **) nargv)[pos] = nargv[cstart]; + ((char **)(uintptr_t )nargv)[pos] = nargv[cstart];/* LINTED const cast */ - ((char **)nargv)[cstart] = swap; + ((char **)(uintptr_t )nargv)[cstart] = swap; } } }
@@ -116,7 +117,7 @@ permute_args(int panonopt_start, int panonopt_end, int opt_end,* Returns -1 if short_too is set and the option does not match long_options. */ static int -parse_long_options (char **nargv,const char *options, +parse_long_options (char *const *nargv,const char *options,const struct option *long_options,int *idx,int short_too) {const char *current_argv;
@@ -236,7 +237,7 @@ parse_long_options(char **nargv, const char *options,* Parse argc/argv argument vector. Called by user level routines. */ static int -getopt_internal (int nargc,char **nargv,const char *options, +getopt_internal (int nargc,char *const nargv[],const char *options,const struct option *long_options,int *idx,int flags) {char *oli;/* option letter list index */
@@ -434,7 +435,7 @@ getopt_internal(int nargc, char **nargv, const char *options,* Parse argc/argv argument vector. */ int -getopt (int nargc,char *nargv[],const char *options) +getopt (int nargc,char *const nargv[],const char *options) {return getopt_internal (nargc, nargv, options,NULL ,NULL ,FLAG_PERMUTE );
@@ -445,7 +446,7 @@ getopt(int nargc, char *nargv[], const char *options)* Parse argc/argv argument vector. */ int -getopt_long (int nargc,char *nargv[],const char *options, +getopt_long (int nargc,char *const nargv[],const char *options,const struct option *long_options,int *idx) {
@@ -458,7 +459,7 @@ getopt_long(int nargc, char *nargv[], const char *options,* Parse argc/argv argument vector. */ int -getopt_long_only (int nargc,char *nargv[],const char *options, +getopt_long_only (int nargc,char *const nargv[],const char *options,const struct option *long_options,int *idx) {
lib/eal/windows/include/getopt.h +4 -4
@@ -44,7 +44,7 @@/** argument to current option, or NULL if it has none */ -extern const char *optarg; +extern char *optarg;/** Current position in arg string. Starts from 1. * Setting to 0 resets state. */
@@ -80,14 +80,14 @@ struct option { };/** Compat: getopt */ -int getopt (int argc,char *argv[],const char *options); +int getopt (int argc,char *const argv[],const char *options);/** Compat: getopt_long */ -int getopt_long (int argc,char *argv[],const char *options, +int getopt_long (int argc,char *const argv[],const char *options,const struct option *longopts,int *longindex);/** Compat: getopt_long_only */ -int getopt_long_only (int nargc,char *argv[],const char *options, +int getopt_long_only (int nargc,char *const argv[],const char *options,const struct option *long_options,int *idx);
Signature · 1 line
2.45.2
PATCH v27 3/14 windows: update os shim
In reply to Stephen HemmingerWindows does not have localtime_r but it does have a similar function that can be used instead.
Use rte_os_shim.h in lib/log instead of redefine of strdup.
--- lib/eal/windows/include/rte_os_shim.h | 10 ++++++++++ lib/log/log.c | 7 +++---- 2 files changed, 13 insertions(+), 4 deletions(-)
lib/eal/windows/include/rte_os_shim.h +10 -0
@@ -110,4 +110,14 @@ rte_clock_gettime(clockid_t clock_id, struct timespec *tp) }#define clock_gettime (clock_id, tp) rte_clock_gettime(clock_id, tp) +static inline struct tm * +rte_localtime_r (const time_t *timep,struct tm *result) +{ +if (localtime_s (result, timep) ==0 ) +return result; +else +return NULL ; +} +#define localtime_r (timep, result) rte_localtime_r(timep, result) +#endif /* _RTE_OS_SHIM_ */
lib/log/log.c +3 -4
@@ -14,13 +14,12 @@#include <rte_log.h> #include <rte_per_lcore.h> - -#include "log_internal.h" -#ifdef RTE_EXEC_ENV_WINDOWS -#define strdup _strdup +#include <rte_os_shim.h> #endif +#include "log_internal.h" +struct rte_log_dynamic_type {const char *name;uint32_t loglevel;
Signature · 1 line
2.45.2
PATCH v27 4/14 eal: make eal_log_level_parse common
In reply to Stephen HemmingerThe code to parse for log-level option should be same on all OS variants.
--- lib/eal/common/eal_common_options.c | 40 +++++++++++++++++++++++++++ lib/eal/common/eal_options.h | 1 + lib/eal/freebsd/eal.c | 42 ----------------------------- lib/eal/linux/eal.c | 39 --------------------------- lib/eal/windows/eal.c | 35 ------------------------ 5 files changed, 41 insertions(+), 116 deletions(-)
lib/eal/common/eal_common_options.c +40 -0
@@ -1640,6 +1640,46 @@ eal_parse_huge_unlink(const char *arg, struct hugepage_file_discipline *out)return -1 ; } +/* Parse the all arguments looking for log related ones */ +int +eal_log_level_parse (int argc,char *const argv[]) +{ +struct internal_config *internal_conf =eal_get_internal_configuration (); +int option_index, opt; +const int old_optind = optind; +const int old_optopt = optopt; +const int old_opterr = opterr; +char *old_optarg = optarg; +#ifdef RTE_EXEC_ENV_FREEBSD +const int old_optreset = optreset; + optreset =1 ; +#endif + + optind =1 ; + opterr =0 ; + +while ((opt =getopt_long (argc, argv, eal_short_options, + eal_long_options, &option_index)) !=EOF ) { + +switch (opt) { +case OPT_LOG_LEVEL_NUM : +if (eal_parse_common_option (opt, optarg, internal_conf) <0 ) +return -1 ; +break ; + } + } + +/* restore getopt lib */ + optind = old_optind; + optopt = old_optopt; + optarg = old_optarg; + opterr = old_opterr; +#ifdef RTE_EXEC_ENV_FREEBSD + optreset = old_optreset; +#endif +return 0 ; +} +int eal_parse_common_option (int opt,const char *optarg,struct internal_config *conf)
lib/eal/common/eal_options.h +1 -0
@@ -96,6 +96,7 @@ enum {extern const char eal_short_options[];extern const struct option eal_long_options[]; +int eal_log_level_parse (int argc,char *const argv[]);int eal_parse_common_option (int opt,const char *argv,struct internal_config *conf);int eal_option_device_parse (void );
lib/eal/freebsd/eal.c +0 -42
48 lines not on this page · raw message
lib/eal/linux/eal.c +0 -39
@@ -546,45 +546,6 @@ eal_parse_vfio_vf_token(const char *vf_token)return -1 ; } -/* Parse the arguments for --log-level only */ -static void -eal_log_level_parse (int argc,char **argv) -{ -int opt; -char **argvopt; -int option_index; -const int old_optind = optind; -const int old_optopt = optopt; -char *const old_optarg = optarg; -struct internal_config *internal_conf = -eal_get_internal_configuration (); - - argvopt = argv; - optind =1 ; - -while ((opt =getopt_long (argc, argvopt, eal_short_options, - eal_long_options, &option_index)) !=EOF ) { - -int ret; - -/* getopt is not happy, stop right now */ -if (opt =='?' ) -break ; - - ret = (opt ==OPT_LOG_LEVEL_NUM ) ? -eal_parse_common_option (opt, optarg, internal_conf) :0 ; - -/* common parser is not happy */ -if (ret <0 ) -break ; - } - -/* restore getopt lib */ - optind = old_optind; - optopt = old_optopt; - optarg = old_optarg; -} -static int eal_parse_huge_worker_stack (const char *arg) {
lib/eal/windows/eal.c +0 -35
@@ -96,41 +96,6 @@ eal_usage(const char *prgname) } } -/* Parse the arguments for --log-level only */ -static void -eal_log_level_parse (int argc,char **argv) -{ -int opt; -char **argvopt; -int option_index; -struct internal_config *internal_conf = -eal_get_internal_configuration (); - - argvopt = argv; - -eal_reset_internal_config (internal_conf); - -while ((opt =getopt_long (argc, argvopt, eal_short_options, - eal_long_options, &option_index)) !=EOF ) { - -int ret; - -/* getopt is not happy, stop right now */ -if (opt =='?' ) -break ; - - ret = (opt ==OPT_LOG_LEVEL_NUM ) ? -eal_parse_common_option (opt, optarg, - internal_conf) :0 ; - -/* common parser is not happy */ -if (ret <0 ) -break ; - } - - optind =0 ;/* reset getopt lib */ -} -/* Parse the argument given in the command line of the application */ static int eal_parse_args (int argc,char **argv)
Signature · 1 line
2.45.2
PATCH v27 5/14 eal: do not duplicate rte_init_alert() messages
In reply to Stephen HemmingerThe message already goes through logging, and does not need to be printed on stderr. Message level should be ALERT to match function name.
--- lib/eal/freebsd/eal.c | 3 +-- lib/eal/linux/eal.c | 3 +-- lib/eal/windows/eal.c | 1 - 3 files changed, 2 insertions(+), 5 deletions(-)
lib/eal/freebsd/eal.c +1 -2
@@ -529,8 +529,7 @@ rte_eal_iopl_init(void)static void rte_eal_init_alert (const char *msg) { -fprintf (stderr,"EAL: FATAL: %s\n" , msg); -EAL_LOG (ERR ,"%s" , msg); +EAL_LOG (ALERT ,"%s" , msg); }/* Launch threads, called at application init(). */
lib/eal/linux/eal.c +1 -2
@@ -830,8 +830,7 @@ rte_eal_iopl_init(void)static void rte_eal_init_alert (const char *msg) { -fprintf (stderr,"EAL: FATAL: %s\n" , msg); -EAL_LOG (ERR ,"%s" , msg); +EAL_LOG (ALERT ,"%s" , msg); }/*
lib/eal/windows/eal.c +0 -1
@@ -181,7 +181,6 @@ sync_func(void *arg __rte_unused)static void rte_eal_init_alert (const char *msg) { -fprintf (stderr,"EAL: FATAL: %s\n" , msg);EAL_LOG (ERR ,"%s" , msg); }
Signature · 1 line
2.45.2
PATCH v27 6/14 eal: change rte_exit() output to match rte_log()
In reply to Stephen HemmingerThe rte_exit() output format confuses the timestamp and coloring options. Change it to use be a single line with proper prefix.
Before:
[ 0.006481] EAL: Error - exiting with code: 1 Cause: [ 0.006489] Cannot init EAL: Permission denied
After:
[ 0.006238] EAL: Error - exiting with code: 1 [ 0.006250] EAL: Cannot init EAL: Permission denied
--- lib/eal/common/eal_common_debug.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
lib/eal/common/eal_common_debug.c +2 -4
@@ -36,15 +36,13 @@ rte_exit(int exit_code, const char *format, ...)va_list ap;if (exit_code !=0 ) -RTE_LOG (CRIT ,EAL ,"Error - exiting with code: %d\n" -" Cause: " , exit_code); +EAL_LOG (CRIT ,"Error - exiting with code: %d" , exit_code);va_start (ap, format);rte_vlog (RTE_LOG_CRIT ,RTE_LOGTYPE_EAL , format, ap);va_end (ap);if (rte_eal_cleanup () !=0 && rte_errno !=EALREADY ) -EAL_LOG (CRIT , -"EAL could not release all resources" ); +EAL_LOG (CRIT ,"EAL could not release all resources" );exit (exit_code); }
Signature · 1 line
2.45.2
PATCH v27 7/14 log: move handling of syslog facility out of eal
In reply to Stephen HemmingerThe syslog facility property is better handled in lib/log rather than in eal. This also add syslog support to FreeBSD.
--- lib/eal/common/eal_common_options.c | 53 ++-------------- lib/eal/common/eal_internal_cfg.h | 1 - lib/eal/freebsd/eal.c | 5 +- lib/eal/linux/eal.c | 7 +-- lib/eal/windows/eal.c | 6 +- lib/log/log.c | 2 + lib/log/log_freebsd.c | 2 +- lib/log/log_internal.h | 5 +- lib/log/log_linux.c | 61 ------------------ lib/log/log_syslog.c | 98 +++++++++++++++++++++++++++++ lib/log/log_windows.c | 8 ++- lib/log/meson.build | 6 +- lib/log/version.map | 1 + 13 files changed, 130 insertions(+), 125 deletions(-) delete mode 100644 lib/log/log_linux.c create mode 100644 lib/log/log_syslog.c
lib/eal/common/eal_common_options.c +4 -49
@@ -6,9 +6,6 @@#include <stdlib.h> #include <string.h> #include <pthread.h> -#ifndef RTE_EXEC_ENV_WINDOWS -#include <syslog.h> -#endif #include <ctype.h> #include <limits.h> #include <errno.h>
@@ -93,7 +90,9 @@ eal_long_options[] = { {OPT_PROC_TYPE, 1, NULL, OPT_PROC_TYPE_NUM }, {OPT_SOCKET_MEM, 1, NULL, OPT_SOCKET_MEM_NUM }, {OPT_SOCKET_LIMIT, 1, NULL, OPT_SOCKET_LIMIT_NUM }, +#ifndef RTE_EXEC_ENV_WINDOWS {OPT_SYSLOG, 1, NULL, OPT_SYSLOG_NUM }, +#endif {OPT_VDEV, 1, NULL, OPT_VDEV_NUM }, {OPT_VFIO_INTR, 1, NULL, OPT_VFIO_INTR_NUM }, {OPT_VFIO_VF_TOKEN, 1, NULL, OPT_VFIO_VF_TOKEN_NUM },
@@ -349,10 +348,6 @@ eal_reset_internal_config(struct internal_config *internal_cfg) } internal_cfg->base_virtaddr =0 ; -#ifdef LOG_DAEMON - internal_cfg->syslog_facility =LOG_DAEMON ; -#endif -/* if set to NONE, interrupt mode is determined automatically */ internal_cfg->vfio_intr_mode =RTE_INTR_MODE_NONE ; memset(internal_cfg->vfio_vf_token, 0,
@@ -1297,47 +1292,6 @@ eal_parse_lcores(const char *lcores)return ret; } -#ifndef RTE_EXEC_ENV_WINDOWS -static int -eal_parse_syslog (const char *facility,struct internal_config *conf) -{ -int i; -static const struct { -const char *name; -int value; - } map[] = { - {"auth" ,LOG_AUTH }, - {"cron" ,LOG_CRON }, - {"daemon" ,LOG_DAEMON }, - {"ftp" ,LOG_FTP }, - {"kern" ,LOG_KERN }, - {"lpr" ,LOG_LPR }, - {"mail" ,LOG_MAIL }, - {"news" ,LOG_NEWS }, - {"syslog" ,LOG_SYSLOG }, - {"user" ,LOG_USER }, - {"uucp" ,LOG_UUCP }, - {"local0" ,LOG_LOCAL0 }, - {"local1" ,LOG_LOCAL1 }, - {"local2" ,LOG_LOCAL2 }, - {"local3" ,LOG_LOCAL3 }, - {"local4" ,LOG_LOCAL4 }, - {"local5" ,LOG_LOCAL5 }, - {"local6" ,LOG_LOCAL6 }, - {"local7" ,LOG_LOCAL7 }, - {NULL ,0 } - }; - -for (i =0 ; map[i].name; i++) { -if (!strcmp (facility, map[i].name)) { - conf->syslog_facility = map[i].value; -return 0 ; - } - } -return -1 ; -} -#endif -static void eal_log_usage (void ) {
@@ -1663,6 +1617,7 @@ eal_log_level_parse(int argc, char * const argv[])switch (opt) {case OPT_LOG_LEVEL_NUM : +case OPT_SYSLOG_NUM :if (eal_parse_common_option (opt, optarg, internal_conf) <0 )return -1 ;break ;
@@ -1877,7 +1832,7 @@ eal_parse_common_option(int opt, const char *optarg,#ifndef RTE_EXEC_ENV_WINDOWS case OPT_SYSLOG_NUM : -if (eal_parse_syslog (optarg, conf) <0 ) { +if (eal_log_syslog (optarg) <0 ) {EAL_LOG (ERR ,"invalid parameters for --" OPT_SYSLOG );return -1 ;
lib/eal/common/eal_internal_cfg.h +0 -1
@@ -84,7 +84,6 @@ struct internal_config {/**< true if storing all pages within single files (per-page-size, * per-node) non-legacy mode only. */ -volatile int syslog_facility;/**< facility passed to openlog() */ /** default interrupt mode for VFIO */ volatile enum rte_intr_mode vfio_intr_mode;/** the shared VF token for VFIO-PCI bound PF and VFs devices */
lib/eal/freebsd/eal.c +2 -3
@@ -11,7 +11,6 @@#include <stdarg.h> #include <unistd.h> #include <pthread.h> -#include <syslog.h> #include <getopt.h> #include <sys/file.h> #include <stddef.h>
@@ -392,8 +391,8 @@ eal_parse_args(int argc, char **argv) goto out; } -/* eal_log_level_parse() already handled this option */ -if (opt ==OPT_LOG_LEVEL_NUM ) +/* eal_log_level_parse() already handled these */ +if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_LOG_SYSLOG_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
lib/eal/linux/eal.c +3 -4
@@ -610,8 +610,8 @@ eal_parse_args(int argc, char **argv) goto out; } -/* eal_log_level_parse() already handled this option */ -if (opt ==OPT_LOG_LEVEL_NUM ) +/* eal_log_level_parse() already handled these options */ +if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_SYSLOG_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
@@ -1103,8 +1103,7 @@ rte_eal_init(int argc, char **argv)#endif } -if (eal_log_init (program_invocation_short_name, - internal_conf->syslog_facility) <0 ) { +if (eal_log_init (program_invocation_short_name) <0 ) {rte_eal_init_alert ("Cannot init logging." ); rte_errno =ENOMEM ;rte_atomic_store_explicit (&run_once,0 , rte_memory_order_relaxed);
lib/eal/windows/eal.c +3 -3
@@ -120,8 +120,8 @@ eal_parse_args(int argc, char **argv)return -1 ; } -/* eal_log_level_parse() already handled this option */ -if (opt ==OPT_LOG_LEVEL_NUM ) +/* eal_log_level_parse() already handled these options */ +if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_SYSLOG_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
@@ -249,7 +249,7 @@ rte_eal_init(int argc, char **argv)char cpuset[RTE_CPU_AFFINITY_STR_LEN ];char thread_name[RTE_THREAD_NAME_SIZE ]; -eal_log_init (NULL ,0 ); +eal_log_init (NULL );eal_log_level_parse (argc, argv);
lib/log/log.c +2 -0
@@ -2,6 +2,7 @@* Copyright(c) 2010-2014 Intel Corporation */ +#include <stdbool.h> #include <stdio.h> #include <stdint.h> #include <stdarg.h>
@@ -12,6 +13,7 @@#include <fnmatch.h> #include <sys/queue.h> +#include <rte_common.h> #include <rte_log.h> #include <rte_per_lcore.h> #ifdef RTE_EXEC_ENV_WINDOWS
lib/log/log_freebsd.c +1 -1
@@ -6,7 +6,7 @@#include "log_internal.h" int -eal_log_init(__rte_unused const char *id, __rte_unused int facility) +eal_log_init(__rte_unused const char *id) {return 0 ; }
lib/log/log_internal.h +4 -1
@@ -14,7 +14,7 @@* Initialize the default log stream. */ __rte_internal -int eal_log_init(const char *id, int facility); +int eal_log_init(const char *id);/* * Determine where log data is written when no call to rte_openlog_stream.
@@ -30,6 +30,9 @@ int eal_log_save_regexp(const char *regexp, uint32_t level);__rte_internal int eal_log_save_pattern(const char *pattern, uint32_t level); +__rte_internal +int eal_log_syslog(const char *name); +/* * Convert log level to string. */
lib/log/log_linux.c deleted +0 -61
61 lines not on this page · raw message
lib/log/log_syslog.c new file +98 -0
98 lines not on this page · raw message
lib/log/log_windows.c +7 -1
@@ -6,9 +6,15 @@#include <rte_log.h> #include "log_internal.h" +int +eal_log_syslog(const char *name __rte_unused) +{ +return -1 ;/* not used */ +} +/* set the log to default function, called during eal init process. */ int -eal_log_init(__rte_unused const char *id, __rte_unused int facility) +eal_log_init(__rte_unused const char *id) {rte_openlog_stream (stderr);
lib/log/meson.build +5 -1
@@ -4,6 +4,10 @@ includes += global_inc sources = files( 'log.c', - 'log_' + exec_env + '.c', ) + +if not is_windows + sources += files('log_syslog.c') +endif + headers = files('rte_log.h')
lib/log/version.map +1 -0
@@ -30,5 +30,6 @@ INTERNAL { eal_log_save_pattern; eal_log_save_regexp; eal_log_set_default; + eal_log_syslog; rte_eal_log_cleanup; };
Signature · 1 line
2.45.2
PATCH v27 8/14 eal: initialize log before everything else
In reply to Stephen HemmingerIn order for all log messages (including CPU mismatch) to come out through the logging library, it must be initialized as early in rte_eal_init() as possible on all platforms.
Where it was done before was likely historical based on the support of non-OS isolated CPU's which required a shared memory buffer; that support was dropped before DPDK was publicly released.
--- lib/eal/freebsd/eal.c | 12 +++++++++--- lib/eal/linux/eal.c | 19 +++++++++---------- lib/eal/windows/eal.c | 8 ++++++-- lib/log/log_freebsd.c | 3 +-- lib/log/log_internal.h | 2 +- lib/log/log_syslog.c | 14 ++++++-------- lib/log/log_windows.c | 4 +--- 7 files changed, 33 insertions(+), 29 deletions(-)
lib/eal/freebsd/eal.c +9 -3
@@ -52,6 +52,7 @@#include "eal_options.h" #include "eal_memcfg.h" #include "eal_trace.h" +#include "log_internal.h" #define MEMSIZE_IF_NO_HUGE_PAGE (64ULL * 1024ULL * 1024ULL)
@@ -546,6 +547,14 @@ rte_eal_init(int argc, char **argv)bool has_phys_addr;enum rte_iova_mode iova_mode; +/* setup log as early as possible */ +if (eal_log_level_parse (argc, argv) <0 ) { +rte_eal_init_alert ("invalid log arguments." ); + rte_errno =EINVAL ; +return -1 ; + } +eal_log_init (getprogname ()); +/* checks if the machine is adequate */ if (!rte_cpu_is_supported ()) {rte_eal_init_alert ("unsupported cpu type." );
@@ -572,9 +581,6 @@ rte_eal_init(int argc, char **argv)/* clone argv to report out later in telemetry */ eal_save_args (argc, argv); -/* set log level as early as possible */ -eal_log_level_parse (argc, argv); -if (rte_eal_cpu_init () <0 ) {rte_eal_init_alert ("Cannot detect lcores." ); rte_errno =ENOTSUP ;
lib/eal/linux/eal.c +9 -10
@@ -926,6 +926,15 @@ rte_eal_init(int argc, char **argv)struct internal_config *internal_conf =eal_get_internal_configuration (); +/* setup log as early as possible */ +if (eal_log_level_parse (argc, argv) <0 ) { +rte_eal_init_alert ("invalid log arguments." ); + rte_errno =EINVAL ; +return -1 ; + } + +eal_log_init (program_invocation_short_name); +/* checks if the machine is adequate */ if (!rte_cpu_is_supported ()) {rte_eal_init_alert ("unsupported cpu type." );
@@ -949,9 +958,6 @@ rte_eal_init(int argc, char **argv)eal_reset_internal_config (internal_conf); -/* set log level as early as possible */ -eal_log_level_parse (argc, argv); -/* clone argv to report out later in telemetry */ eal_save_args (argc, argv);
@@ -1103,13 +1109,6 @@ rte_eal_init(int argc, char **argv)#endif } -if (eal_log_init (program_invocation_short_name) <0 ) { -rte_eal_init_alert ("Cannot init logging." ); - rte_errno =ENOMEM ; -rte_atomic_store_explicit (&run_once,0 , rte_memory_order_relaxed); -return -1 ; - } -#ifdef VFIO_PRESENT if (rte_vfio_enable ("vfio" )) {rte_eal_init_alert ("Cannot init VFIO" );
lib/eal/windows/eal.c +6 -2
@@ -249,9 +249,13 @@ rte_eal_init(int argc, char **argv)char cpuset[RTE_CPU_AFFINITY_STR_LEN ];char thread_name[RTE_THREAD_NAME_SIZE ]; -eal_log_init (NULL ); +if (eal_log_level_parse (argc, argv) <0 ) { +rte_eal_init_alert ("invalid log arguments." ); + rte_errno =EINVAL ; +return -1 ; + } -eal_log_level_parse (argc, argv); +eal_log_init (NULL );if (eal_create_cpu_map () <0 ) {rte_eal_init_alert ("Cannot discover CPU and NUMA." );
lib/log/log_freebsd.c +1 -2
@@ -5,8 +5,7 @@#include <rte_common.h> #include "log_internal.h" -int +void eal_log_init(__rte_unused const char *id) { -return 0 ; }
lib/log/log_internal.h +1 -1
@@ -14,7 +14,7 @@* Initialize the default log stream. */ __rte_internal -int eal_log_init(const char *id); +void eal_log_init(const char *id);/* * Determine where log data is written when no call to rte_openlog_stream.
lib/log/log_syslog.c +6 -8
@@ -81,18 +81,16 @@ static cookie_io_functions_t log_syslog_func = {* set the log to default function, called during eal init process, * once memzones are available. */ -int +void eal_log_init (const char *id) {FILE *log_stream; - log_stream =fopencookie (NULL ,"w+" , log_syslog_func); -if (log_stream ==NULL ) -return -1 ; -openlog (id,LOG_NDELAY |LOG_PID |LOG_PERROR , log_facility); -eal_log_set_default (log_stream); - -return 0 ; + log_stream =fopencookie (NULL ,"w+" , log_syslog_func); +if (log_stream !=NULL ) +eal_log_set_default (log_stream); +else +eal_log_set_default (stderr); }
lib/log/log_windows.c +1 -3
@@ -13,12 +13,10 @@ eal_log_syslog(const char *name __rte_unused) }/* set the log to default function, called during eal init process. */ -int +void eal_log_init(__rte_unused const char *id) {rte_openlog_stream (stderr);eal_log_set_default (stderr); - -return 0 ; }
Signature · 1 line
2.45.2
PATCH v27 9/14 log: add hook for printing log messages
In reply to Stephen HemmingerThis is useful for when decorating log output for console or journal. Provide basic version in this patch.
--- lib/log/log.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
lib/log/log.c +7 -1
@@ -27,16 +27,21 @@ struct rte_log_dynamic_type {uint32_t loglevel; }; +/* Note: same as vfprintf() */ +typedef int (*log_print_t )(FILE *f,const char *fmt,va_list ap); +/** The rte_log structure. */ static struct rte_logs {uint32_t type;/**< Bitfield with enabled logs. */ uint32_t level;/**< Log level. */ FILE *file;/**< Output file set by rte_openlog_stream, or NULL. */ +log_print_t print_func;size_t dynamic_types_len;struct rte_log_dynamic_type *dynamic_types; } rte_logs = { .type =UINT32_MAX , .level =RTE_LOG_DEBUG , + .print_func = vfprintf, };struct rte_eal_opt_loglevel {
@@ -78,6 +83,7 @@ int rte_openlog_stream(FILE *f) { rte_logs.file = f; + rte_logs.print_func = vfprintf;return 0 ; }
@@ -484,7 +490,7 @@ rte_vlog(uint32_t level, uint32_t logtype, const char *format, va_list ap)RTE_PER_LCORE (log_cur_msg).loglevel = level;RTE_PER_LCORE (log_cur_msg).logtype = logtype; - ret =vfprintf (f, format, ap); + ret = (*rte_logs.print_func)(f, format, ap);fflush (f);return ret; }
Signature · 1 line
2.45.2
PATCH v27 10/14 log: modify syslog handling
In reply to Stephen HemmingerLog to syslog only if option is specified.
If no --syslog is given then use console only.
--- app/test/test_eal_flags.c | 16 +++---- doc/guides/linux_gsg/linux_eal_parameters.rst | 27 ------------ doc/guides/prog_guide/log_lib.rst | 5 +-- lib/eal/common/eal_common_options.c | 4 +- lib/log/log.c | 43 +++++++++---------- lib/log/log_freebsd.c | 11 ----- lib/log/log_internal.h | 6 --- lib/log/log_private.h | 10 +++++ lib/log/log_syslog.c | 21 ++++----- lib/log/log_windows.c | 22 ---------- lib/log/version.map | 3 +- 11 files changed, 51 insertions(+), 117 deletions(-) delete mode 100644 lib/log/log_freebsd.c create mode 100644 lib/log/log_private.h delete mode 100644 lib/log/log_windows.c
app/test/test_eal_flags.c +8 -8
@@ -985,12 +985,12 @@ test_misc_flags(void)/* With -v */ const char *argv2[] = {prgname, prefix, mp_flag,"-v" };/* With valid --syslog */ -const char *argv3[] = {prgname, prefix, mp_flag, -"--syslog" ,"syslog" }; -/* With empty --syslog (should fail) */ +const char *argv3[] = {prgname, prefix, mp_flag,"--syslog=user" }; +/* With empty --syslog (now defaults) */ const char *argv4[] = {prgname, prefix, mp_flag,"--syslog" };/* With invalid --syslog */ -const char *argv5[] = {prgname, prefix, mp_flag,"--syslog" ,"error" }; +const char *argv5[] = {prgname, prefix, mp_flag,"--syslog=invalid" }; +/* With no-sh-conf, also use no-huge to ensure this test runs on BSD */ const char *argv6[] = {prgname,"-m" ,DEFAULT_MEM_SIZE , no_shconf, nosh_prefix, no_huge};
@@ -1080,15 +1080,15 @@ test_misc_flags(void)#endif if (launch_proc (argv3) !=0 ) { -printf ("Error - process did not run ok with --syslog flag\n" ); +printf ("Error - process did not run ok with --syslog=user flag\n" ); goto fail; } -if (launch_proc (argv4) ==0 ) { -printf ("Error - process run ok with empty --syslog flag\n" ); +if (launch_proc (argv4) !=0 ) { +printf ("Error - process did not run ok with --syslog flag\n" ); goto fail; }if (launch_proc (argv5) ==0 ) { -printf ("Error - process run ok with invalid --syslog flag\n" ); +printf ("Error - process run ok with --syslog=invalid flag\n" ); goto fail; }if (launch_proc (argv7) !=0 ) {
doc/guides/linux_gsg/linux_eal_parameters.rst +0 -27
@@ -108,30 +108,3 @@ Memory-related options * ``--match-allocations`` Free hugepages back to system exactly as they were originally allocated. - -Other options -~~~~~~~~~~~~~ - -* ``--syslog <syslog facility>`` - - Set syslog facility. Valid syslog facilities are:: - - auth - cron - daemon - ftp - kern - lpr - mail - news - syslog - user - uucp - local0 - local1 - local2 - local3 - local4 - local5 - local6 - local7
doc/guides/prog_guide/log_lib.rst +2 -3
@@ -5,9 +5,7 @@ Log Library =========== The DPDK Log library provides the logging functionality for other DPDK libraries and drivers. -By default, in a Linux application, logs are sent to syslog and also to the console. -On FreeBSD and Windows applications, logs are sent only to the console. -However, the log function can be overridden by the user to use a different logging mechanism. +The messages can be sent to one or more sources controlled by the EAL command line options. Log Levels ----------
@@ -59,6 +57,7 @@ For example:: Within an application, the same result can be got using the ``rte_log_set_level_pattern()`` or ``rte_log_set_level_regex()`` APIs. + Using Logging APIs to Generate Log Messages -------------------------------------------
lib/eal/common/eal_common_options.c +2 -2
@@ -91,7 +91,7 @@ eal_long_options[] = { {OPT_SOCKET_MEM, 1, NULL, OPT_SOCKET_MEM_NUM }, {OPT_SOCKET_LIMIT, 1, NULL, OPT_SOCKET_LIMIT_NUM }, #ifndef RTE_EXEC_ENV_WINDOWS - {OPT_SYSLOG, 1, NULL, OPT_SYSLOG_NUM }, + {OPT_SYSLOG, 2, NULL, OPT_SYSLOG_NUM }, #endif {OPT_VDEV, 1, NULL, OPT_VDEV_NUM }, {OPT_VFIO_INTR, 1, NULL, OPT_VFIO_INTR_NUM },
@@ -2209,7 +2209,7 @@ eal_common_usage(void) " --"OPT_VMWARE_TSC_MAP" Use VMware TSC map instead of native RDTSC\n" " --"OPT_PROC_TYPE" Type of this process (primary|secondary|auto)\n" #ifndef RTE_EXEC_ENV_WINDOWS - " --"OPT_SYSLOG" Set syslog facility\n" + " --"OPT_SYSLOG"[=<when>] Enable use of syslog\n" #endif" --" OPT_LOG_LEVEL "=<level> Set global log level\n" " --" OPT_LOG_LEVEL "=<type-match>:<level>\n"
lib/log/log.c +20 -23
89 lines not on this page · raw message
lib/log/log_freebsd.c deleted +0 -11
@@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause -* Copyright(c) 2023 Intel Corporation -*/ - -#include <rte_common.h> -#include "log_internal.h" - -void -eal_log_init(__rte_unused const char *id) -{ -}
lib/log/log_internal.h +0 -6
@@ -16,12 +16,6 @@__rte_internal void eal_log_init(const char *id); -/* -* Determine where log data is written when no call to rte_openlog_stream. -*/ -__rte_internal -void eal_log_set_default(FILE *default_log); -/* * Save a log option for later. */
lib/log/log_private.h new file +10 -0
@@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#ifndef LOG_PRIVATE_H +#define LOG_PRIVATE_H + +#ifndef RTE_EXEC_ENV_WINDOWS +FILE *log_syslog_open (const char *id); +#endif + +#endif /* LOG_PRIVATE_H */
lib/log/log_syslog.c +8 -13
@@ -5,12 +5,16 @@#include <stdio.h> #include <string.h> #include <sys/types.h> +#include <stdbool.h> +#include <stdio.h> +#include <string.h> #include <syslog.h> #include <rte_common.h> #include <rte_log.h> #include "log_internal.h" +#include "log_private.h" static int log_facility =LOG_DAEMON ;
@@ -77,20 +81,11 @@ static cookie_io_functions_t log_syslog_func = { .close = log_syslog_close, }; -/* -* set the log to default function, called during eal init process, -* once memzones are available. -*/ -void -eal_log_init (const char *id) +FILE * +log_syslog_open (const char *id) { -FILE *log_stream; -openlog (id,LOG_NDELAY |LOG_PID |LOG_PERROR , log_facility); - log_stream =fopencookie (NULL ,"w+" , log_syslog_func); -if (log_stream !=NULL ) -eal_log_set_default (log_stream); -else -eal_log_set_default (stderr); +/* redirect other log messages to syslog as well */ +return fopencookie (NULL ,"w" , log_syslog_func); }
lib/log/log_windows.c deleted +0 -22
@@ -1,22 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause -* Copyright(c) 2017-2018 Intel Corporation -*/ - -#include <rte_common.h> -#include <rte_log.h> -#include "log_internal.h" - -int -eal_log_syslog(const char *name __rte_unused) -{ -return -1 ;/* not used */ -} - -/* set the log to default function, called during eal init process. */ -void -eal_log_init(__rte_unused const char *id) -{ -rte_openlog_stream (stderr); - -eal_log_set_default (stderr); -}
lib/log/version.map +1 -2
@@ -29,7 +29,6 @@ INTERNAL { eal_log_level2str; eal_log_save_pattern; eal_log_save_regexp; - eal_log_set_default; - eal_log_syslog; + eal_log_syslog; # WINDOWS_NO_EXPORT rte_eal_log_cleanup; };
Signature · 1 line
2.45.2
PATCH v27 11/14 log: add timestamp option
In reply to Stephen HemmingerWhen debugging driver or startup issues, it is useful to have a timestamp on each message printed. The messages in syslog already have a timestamp, but often syslog is not available during testing.
There are multiple timestamp formats similar to Linux dmesg. The default is time relative since startup (when first step of logging initialization is done by constructor). Other alternative formats are delta, ctime, reltime and iso formats.
Example:
$ dpdk-testpmd --log-timestamp -- -i [ 0.008610] EAL: Detected CPU lcores: 8 [ 0.008634] EAL: Detected NUMA nodes: 1 [ 0.008792] EAL: Detected static linkage of DPDK [ 0.010620] EAL: Multi-process socket /var/run/dpdk/rte/mp_socket [ 0.012618] EAL: Selected IOVA mode 'VA' [ 0.016675] testpmd: No probed ethernet devices Interactive-mode selected
--- app/test/test_eal_flags.c | 26 +++ doc/guides/prog_guide/log_lib.rst | 30 +++- lib/eal/common/eal_common_options.c | 14 +- lib/eal/common/eal_options.h | 2 + lib/eal/freebsd/eal.c | 6 +- lib/eal/linux/eal.c | 4 +- lib/eal/windows/eal.c | 4 +- lib/log/log.c | 5 + lib/log/log_internal.h | 9 + lib/log/log_private.h | 6 + lib/log/log_timestamp.c | 245 ++++++++++++++++++++++++++++ lib/log/meson.build | 1 + lib/log/version.map | 1 + 13 files changed, 346 insertions(+), 7 deletions(-) create mode 100644 lib/log/log_timestamp.c
app/test/test_eal_flags.c +26 -0
@@ -1055,6 +1055,19 @@ test_misc_flags(void)const char *const argv22[] = {prgname, prefix, mp_flag,"--huge-worker-stack=512" }; +/* Try running with --log-timestamp */ +const char *const argv23[] = {prgname, prefix, mp_flag, +"--log-timestamp" }; + +/* Try running with --log-timestamp=iso */ +const char *const argv24[] = {prgname, prefix, mp_flag, +"--log-timestamp=iso" }; + +/* Try running with invalid timestamp */ +const char *const argv25[] = {prgname, prefix, mp_flag, +"--log-timestamp=invalid" }; + +/* run all tests also applicable to FreeBSD first */ if (launch_proc (argv0) ==0 ) {
@@ -1162,6 +1175,19 @@ test_misc_flags(void)printf ("Error - process did not run ok with --huge-worker-stack=size parameter\n" ); goto fail; } +if (launch_proc (argv23) !=0 ) { +printf ("Error - process did not run ok with --log-timestamp parameter\n" ); + goto fail; + } +if (launch_proc (argv24) !=0 ) { +printf ("Error - process did not run ok with --log-timestamp=iso parameter\n" ); + goto fail; + } +if (launch_proc (argv25) ==0 ) { +printf ("Error - process did run ok with --log-timestamp=invalid parameter\n" ); + goto fail; + } +rmdir (hugepath_dir3);rmdir (hugepath_dir2);
doc/guides/prog_guide/log_lib.rst +29 -1
@@ -57,7 +57,6 @@ For example:: Within an application, the same result can be got using the ``rte_log_set_level_pattern()`` or ``rte_log_set_level_regex()`` APIs. - Using Logging APIs to Generate Log Messages -------------------------------------------
@@ -109,3 +108,32 @@ Throughout the cfgfile library, all logging calls are therefore of the form: CFG_LOG(ERR, "invalid comment characters %c", params->comment_character); + +Log timestamp +~~~~~~~~~~~~~ + +An optional timestamp can be added before each message +by adding the ``--log-timestamp`` option. +For example:: + + /path/to/app --log-level=lib.*:debug --log-timestamp + +Multiple timestamp alternative timestamp formats are available: + +.. csv-table:: Log time stamp format + :header: "Format", "Description", "Example" + :widths: 6, 30, 32 + + "ctime", "Unix ctime", "``[Wed Mar 20 07:26:12 2024]``" + "delta", "Offset since last", "``[< 3.162373>]``" + "reltime", "Seconds since last or time if minute changed", "``[ +3.001791]`` or ``[Mar20 07:26:12]``" + "iso", "ISO-8601", "``[2024-03-20T07:26:12−07:00]``" + +To prefix all console messages with ISO format time the syntax is:: + + /path/to/app --log-timestamp=iso + +.. note:: + + Timestamp option has no effect if using syslog because the ``syslog()`` + service already does timestamping internally.
lib/eal/common/eal_common_options.c +12 -2
@@ -74,6 +74,7 @@ eal_long_options[] = { {OPT_IOVA_MODE, 1, NULL, OPT_IOVA_MODE_NUM }, {OPT_LCORES, 1, NULL, OPT_LCORES_NUM }, {OPT_LOG_LEVEL, 1, NULL, OPT_LOG_LEVEL_NUM }, + {OPT_LOG_TIMESTAMP, 2, NULL, OPT_LOG_TIMESTAMP_NUM }, {OPT_TRACE, 1, NULL, OPT_TRACE_NUM }, {OPT_TRACE_DIR, 1, NULL, OPT_TRACE_DIR_NUM }, {OPT_TRACE_BUF_SIZE, 1, NULL, OPT_TRACE_BUF_SIZE_NUM },
@@ -1618,6 +1619,7 @@ eal_log_level_parse(int argc, char * const argv[])switch (opt) {case OPT_LOG_LEVEL_NUM :case OPT_SYSLOG_NUM : +case OPT_LOG_TIMESTAMP_NUM :if (eal_parse_common_option (opt, optarg, internal_conf) <0 )return -1 ;break ;
@@ -1840,7 +1842,7 @@ eal_parse_common_option(int opt, const char *optarg,break ;#endif -case OPT_LOG_LEVEL_NUM : { +case OPT_LOG_LEVEL_NUM :if (eal_parse_log_level (optarg) <0 ) {EAL_LOG (ERR , "invalid parameters for --"
@@ -1848,7 +1850,14 @@ eal_parse_common_option(int opt, const char *optarg,return -1 ; }break ; - } + +case OPT_LOG_TIMESTAMP_NUM : +if (eal_log_timestamp (optarg) <0 ) { +EAL_LOG (ERR ,"invalid parameters for --" +OPT_LOG_TIMESTAMP ); +return -1 ; + } +break ;#ifndef RTE_EXEC_ENV_WINDOWS case OPT_TRACE_NUM : {
@@ -2215,6 +2224,7 @@ eal_common_usage(void)" --" OPT_LOG_LEVEL "=<type-match>:<level>\n" " Set specific log level\n" " --" OPT_LOG_LEVEL "=help Show log types and levels\n" +" --" OPT_LOG_TIMESTAMP "[=<format>] Timestamp log output\n" #ifndef RTE_EXEC_ENV_WINDOWS" --" OPT_TRACE "=<regex-match>\n" " Enable trace based on regular expression trace name.\n"
lib/eal/common/eal_options.h +2 -0
@@ -35,6 +35,8 @@ enum {OPT_LCORES_NUM , #define OPT_LOG_LEVEL "log-level"OPT_LOG_LEVEL_NUM , +#define OPT_LOG_TIMESTAMP "log-timestamp" +OPT_LOG_TIMESTAMP_NUM , #define OPT_TRACE "trace"OPT_TRACE_NUM , #define OPT_TRACE_DIR "trace-dir"
lib/eal/freebsd/eal.c +4 -2
@@ -392,8 +392,10 @@ eal_parse_args(int argc, char **argv) goto out; } -/* eal_log_level_parse() already handled these */ -if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_LOG_SYSLOG_NUM ) +/* eal_log_level_parse() already handled these options */ +if (opt ==OPT_LOG_LEVEL_NUM || + opt ==OPT_SYSLOG_NUM || + opt ==OPT_LOG_TIMESTAMP_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
lib/eal/linux/eal.c +3 -1
@@ -611,7 +611,9 @@ eal_parse_args(int argc, char **argv) }/* eal_log_level_parse() already handled these options */ -if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_SYSLOG_NUM ) +if (opt ==OPT_LOG_LEVEL_NUM || + opt ==OPT_SYSLOG_NUM || + opt ==OPT_LOG_TIMESTAMP_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
lib/eal/windows/eal.c +3 -1
@@ -121,7 +121,9 @@ eal_parse_args(int argc, char **argv) }/* eal_log_level_parse() already handled these options */ -if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_SYSLOG_NUM ) +if (opt ==OPT_LOG_LEVEL_NUM || + opt ==OPT_SYSLOG_NUM || + opt ==OPT_LOG_TIMESTAMP_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
lib/log/log.c +5 -0
@@ -514,6 +514,11 @@ eal_log_init(const char *id)rte_openlog_stream (logf);#endif +if (log_timestamp_enabled ()) + rte_logs.print_func = log_print_with_timestamp; +else + rte_logs.print_func = vfprintf; +#if RTE_LOG_DP_LEVEL >=RTE_LOG_DEBUG RTE_LOG (NOTICE ,EAL ,"Debug dataplane logs available - lower performance\n" );
lib/log/log_internal.h +9 -0
@@ -5,8 +5,10 @@#ifndef LOG_INTERNAL_H #define LOG_INTERNAL_H +#include <stdbool.h> #include <stdio.h> #include <stdint.h> +#include <time.h> #include <rte_compat.h>
@@ -39,4 +41,11 @@ const char *eal_log_level2str(uint32_t level);__rte_internal void rte_eal_log_cleanup(void); +/* +* Add timestamp to console logs +*/ +__rte_internal +int eal_log_timestamp(const char *fmt); + +#endif /* LOG_INTERNAL_H */
lib/log/log_private.h +6 -0
@@ -7,4 +7,10 @@FILE *log_syslog_open (const char *id);#endif +bool log_timestamp_enabled (void ); +ssize_t log_timestamp (char *tsbuf,size_t tsbuflen); + +__rte_format_printf(2, 0) +int log_print_with_timestamp (FILE *f,const char *format,va_list ap); +#endif /* LOG_PRIVATE_H */
lib/log/log_timestamp.c new file +245 -0
245 lines not on this page · raw message
lib/log/meson.build +1 -0
@@ -4,6 +4,7 @@ includes += global_inc sources = files( 'log.c', + 'log_timestamp.c', ) if not is_windows
lib/log/version.map +1 -0
@@ -30,5 +30,6 @@ INTERNAL { eal_log_save_pattern; eal_log_save_regexp; eal_log_syslog; # WINDOWS_NO_EXPORT + eal_log_timestamp; rte_eal_log_cleanup; };
Signature · 1 line
2.45.2
PATCH v27 12/14 log: add support for systemd journal
In reply to Stephen HemmingerIf DPDK application is being run as a systemd service, then it can use the journal protocol which allows putting more information in the log such as priority and other information.
The use of journal protocol is automatically detected and handled. Rather than having a dependency on libsystemd, just use the protocol directly as defined in:
https://systemd.io/JOURNAL_NATIVE_PROTOCOL/
--- lib/log/log.c | 13 ++-- lib/log/log_internal.h | 3 + lib/log/log_journal.c | 154 +++++++++++++++++++++++++++++++++++++++++ lib/log/log_private.h | 14 +++- lib/log/log_syslog.c | 17 ++++- lib/log/meson.build | 4 ++ lib/log/version.map | 1 + 7 files changed, 198 insertions(+), 8 deletions(-) create mode 100644 lib/log/log_journal.c
lib/log/log.c +7 -6
@@ -506,15 +506,16 @@ rte_log(uint32_t level, uint32_t logtype, const char *format, ...)void eal_log_init (const char *id) { -#ifndef RTE_EXEC_ENV_WINDOWS -FILE *logf; +FILE *logf =NULL ; + +if (log_journal_enabled ()) + logf =log_journal_open (id); +else if (log_syslog_enabled ()) + logf =log_syslog_open (id); - logf =log_syslog_open (id);if (logf)rte_openlog_stream (logf); -#endif - -if (log_timestamp_enabled ()) +else if (log_timestamp_enabled ()) rte_logs.print_func = log_print_with_timestamp;else rte_logs.print_func = vfprintf;
lib/log/log_internal.h +3 -0
@@ -29,6 +29,9 @@ int eal_log_save_pattern(const char *pattern, uint32_t level);__rte_internal int eal_log_syslog(const char *name); +__rte_internal +int eal_log_journal(const char *opt); +/* * Convert log level to string. */
lib/log/log_journal.c new file +154 -0
154 lines not on this page · raw message
lib/log/log_private.h +13 -1
@@ -3,10 +3,22 @@#ifndef LOG_PRIVATE_H #define LOG_PRIVATE_H -#ifndef RTE_EXEC_ENV_WINDOWS +#ifdef RTE_EXEC_ENV_WINDOWS +#define log_syslog_enabled () (false) +#define log_syslog_open (id) (NULL) +#else +bool log_syslog_enabled (void );FILE *log_syslog_open (const char *id);#endif +#ifdef RTE_EXEC_ENV_LINUX +bool log_journal_enabled (void ); +FILE *log_journal_open (const char *id); +#else +#define log_journal_enabled () (false) +#define log_journal_open (id) (NULL) +#endif /* !RTE_EXEC_ENV_LINUX */ +bool log_timestamp_enabled (void );ssize_t log_timestamp (char *tsbuf,size_t tsbuflen);
lib/log/log_syslog.c +16 -1
@@ -16,8 +16,12 @@#include "log_internal.h" #include "log_private.h" -static int log_facility =LOG_DAEMON ; +static int log_facility; +/* +* Usable list of facilities +* Skip kern, mark, and security +*/ static const struct { const char *name; int value;
@@ -48,6 +52,11 @@ eal_log_syslog(const char *name) {unsigned int i; +if (name ==NULL ) { + log_facility =LOG_DAEMON ; +return 0 ; + } +for (i =0 ; i <RTE_DIM (facilitys); i++) {if (!strcmp (name, facilitys[i].name)) { log_facility = facilitys[i].value;
@@ -57,6 +66,12 @@ eal_log_syslog(const char *name)return -1 ; } +/* syslog is enabled if facility is set */ +bool log_syslog_enabled (void ) +{ +return log_facility !=0 ;/* LOG_KERN is 0 */ +} +/* * default log function */
lib/log/meson.build +4 -0
@@ -11,4 +11,8 @@ if not is_windows sources += files('log_syslog.c') endif +if is_linux + sources += files('log_journal.c') +endif + headers = files('rte_log.h')
lib/log/version.map +1 -0
@@ -26,6 +26,7 @@ INTERNAL { global: eal_log_init; + eal_log_journal; # WINDOWS_NO_EXPORT eal_log_level2str; eal_log_save_pattern; eal_log_save_regexp;
Signature · 1 line
2.45.2
PATCH v27 13/14 log: colorize log output
In reply to Stephen HemmingerLike dmesg, colorize the log output (unless redirected to file). Timestamp is green, the subsystem is in yellow and the message is red if urgent, boldface if an error, and normal for info and debug messages.
The default is to not use color since it may disturb automatic tests and other embedded usage.
--- app/test/test_eal_flags.c | 24 ++++ doc/guides/prog_guide/log_lib.rst | 24 ++++ lib/eal/common/eal_common_options.c | 11 ++ lib/eal/common/eal_options.h | 2 + lib/log/log.c | 20 ++- lib/log/log_color.c | 216 ++++++++++++++++++++++++++++ lib/log/log_internal.h | 5 + lib/log/log_private.h | 8 ++ lib/log/meson.build | 1 + lib/log/version.map | 1 + 10 files changed, 308 insertions(+), 4 deletions(-) create mode 100644 lib/log/log_color.c
app/test/test_eal_flags.c +24 -0
@@ -1067,6 +1067,18 @@ test_misc_flags(void)const char *const argv25[] = {prgname, prefix, mp_flag,"--log-timestamp=invalid" }; +/* Try running with --log-color */ +const char *const argv26[] = {prgname, prefix, mp_flag, +"--log-color" }; + +/* Try running with --log-color=never */ +const char *const argv27[] = {prgname, prefix, mp_flag, +"--log-color=never" }; + +/* Try running with --log-color=invalid */ +const char *const argv28[] = {prgname, prefix, mp_flag, +"--log-color=invalid" }; +/* run all tests also applicable to FreeBSD first */
@@ -1187,6 +1199,18 @@ test_misc_flags(void)printf ("Error - process did run ok with --log-timestamp=invalid parameter\n" ); goto fail; } +if (launch_proc (argv26) !=0 ) { +printf ("Error - process did not run ok with --log-color parameter\n" ); + goto fail; + } +if (launch_proc (argv27) !=0 ) { +printf ("Error - process did not run ok with --log-color=none parameter\n" ); + goto fail; + } +if (launch_proc (argv28) ==0 ) { +printf ("Error - process did run ok with --log-timestamp=invalid parameter\n" ); + goto fail; + }rmdir (hugepath_dir3);
doc/guides/prog_guide/log_lib.rst +24 -0
@@ -57,6 +57,7 @@ For example:: Within an application, the same result can be got using the ``rte_log_set_level_pattern()`` or ``rte_log_set_level_regex()`` APIs. + Using Logging APIs to Generate Log Messages -------------------------------------------
@@ -137,3 +138,26 @@ To prefix all console messages with ISO format time the syntax is:: Timestamp option has no effect if using syslog because the ``syslog()`` service already does timestamping internally. + + +Color output +~~~~~~~~~~~~ + +The log library will highlight important messages. +This is controlled by the ``--log-color`` option. +The optional argument describes when color is enabled: + +:never: Do not enable color. This is the default behavior. + +:auto: Enable color only when printing to a terminal. + This is the same as ``--log-color`` with no argument + +:always: Always print color + +For example to enable color in logs if using terminal:: + + /path/to/app --log-color + +.. note:: + + Color output is never used for syslog or systemd journal logging.
lib/eal/common/eal_common_options.c +11 -0
@@ -73,6 +73,7 @@ eal_long_options[] = { {OPT_HUGE_UNLINK, 2, NULL, OPT_HUGE_UNLINK_NUM }, {OPT_IOVA_MODE, 1, NULL, OPT_IOVA_MODE_NUM }, {OPT_LCORES, 1, NULL, OPT_LCORES_NUM }, + {OPT_LOG_COLOR, 2, NULL, OPT_LOG_COLOR_NUM }, {OPT_LOG_LEVEL, 1, NULL, OPT_LOG_LEVEL_NUM }, {OPT_LOG_TIMESTAMP, 2, NULL, OPT_LOG_TIMESTAMP_NUM }, {OPT_TRACE, 1, NULL, OPT_TRACE_NUM },
@@ -1620,6 +1621,7 @@ eal_log_level_parse(int argc, char * const argv[])case OPT_LOG_LEVEL_NUM :case OPT_SYSLOG_NUM :case OPT_LOG_TIMESTAMP_NUM : +case OPT_LOG_COLOR_NUM :if (eal_parse_common_option (opt, optarg, internal_conf) <0 )return -1 ;break ;
@@ -1859,6 +1861,14 @@ eal_parse_common_option(int opt, const char *optarg, }break ; +case OPT_LOG_COLOR_NUM : +if (eal_log_color (optarg) <0 ) { +EAL_LOG (ERR ,"invalid parameters for --" +OPT_LOG_COLOR ); +return -1 ; + } +break ; +#ifndef RTE_EXEC_ENV_WINDOWS case OPT_TRACE_NUM : {if (eal_trace_args_save (optarg) <0 ) {
@@ -2225,6 +2235,7 @@ eal_common_usage(void)" Set specific log level\n" " --" OPT_LOG_LEVEL "=help Show log types and levels\n" " --" OPT_LOG_TIMESTAMP "[=<format>] Timestamp log output\n" +" --" OPT_LOG_COLOR "[=<when>] Colorize log messages\n" #ifndef RTE_EXEC_ENV_WINDOWS" --" OPT_TRACE "=<regex-match>\n" " Enable trace based on regular expression trace name.\n"
lib/eal/common/eal_options.h +2 -0
@@ -33,6 +33,8 @@ enum {OPT_HUGE_UNLINK_NUM , #define OPT_LCORES "lcores"OPT_LCORES_NUM , +#define OPT_LOG_COLOR "log-color" +OPT_LOG_COLOR_NUM , #define OPT_LOG_LEVEL "log-level"OPT_LOG_LEVEL_NUM , #define OPT_LOG_TIMESTAMP "log-timestamp"
lib/log/log.c +16 -4
@@ -515,10 +515,22 @@ eal_log_init(const char *id)if (logf)rte_openlog_stream (logf); -else if (log_timestamp_enabled ()) - rte_logs.print_func = log_print_with_timestamp; -else - rte_logs.print_func = vfprintf; +else { +bool is_terminal =isatty (fileno (stderr)); +bool use_color =log_color_enabled (is_terminal); + +if (log_timestamp_enabled ()) { +if (use_color) + rte_logs.print_func = color_print_with_timestamp; +else + rte_logs.print_func = log_print_with_timestamp; + }else { +if (use_color) + rte_logs.print_func = color_print; +else + rte_logs.print_func = vfprintf; + } + }#if RTE_LOG_DP_LEVEL >=RTE_LOG_DEBUG RTE_LOG(NOTICE, EAL,
lib/log/log_color.c new file +216 -0
216 lines not on this page · raw message
lib/log/log_internal.h +5 -0
@@ -50,5 +50,10 @@ void rte_eal_log_cleanup(void);__rte_internal int eal_log_timestamp(const char *fmt); +/* +* Enable or disable color in log messages +*/ +__rte_internal +int eal_log_color(const char *mode);#endif /* LOG_INTERNAL_H */
lib/log/log_private.h +8 -0
@@ -25,4 +25,12 @@ ssize_t log_timestamp(char *tsbuf, size_t tsbuflen); __rte_format_printf(2, 0)int log_print_with_timestamp (FILE *f,const char *format,va_list ap); +bool log_color_enabled (bool is_tty); + +__rte_format_printf(2, 0) +int color_print (FILE *f,const char *format,va_list ap); + +__rte_format_printf(2, 0) +int color_print_with_timestamp (FILE *f,const char *format,va_list ap); +#endif /* LOG_PRIVATE_H */
lib/log/meson.build +1 -0
@@ -4,6 +4,7 @@ includes += global_inc sources = files( 'log.c', + 'log_color.c', 'log_timestamp.c', )
lib/log/version.map +1 -0
@@ -25,6 +25,7 @@ DPDK_25 { INTERNAL { global: + eal_log_color; eal_log_init; eal_log_journal; # WINDOWS_NO_EXPORT eal_log_level2str;
Signature · 1 line
2.45.2
Re: [PATCH v27 13/14] log: colorize log output
The code has some mentions of --log-color=none but only the never option is parsed.
Quoted 490 lines · Stephen Hemminger
Like dmesg, colorize the log output (unless redirected to file). Timestamp is green, the subsystem is in yellow and the message is red if urgent, boldface if an error, and normal for info and debug messages.
The default is to not use color since it may disturb automatic tests and other embedded usage.
Signed-off-by Stephen Hemminger <[email protected]>Acked-by Morten Brørup <[email protected]>Acked-by Bruce Richardson <[email protected]>Acked-by Chengwen Feng <[email protected]>--- app/test/test_eal_flags.c | 24 ++++ doc/guides/prog_guide/log_lib.rst | 24 ++++ lib/eal/common/eal_common_options.c | 11 ++ lib/eal/common/eal_options.h | 2 + lib/log/log.c | 20 ++- lib/log/log_color.c | 216 ++++++++++++++++++++++++++++ lib/log/log_internal.h | 5 + lib/log/log_private.h | 8 ++ lib/log/meson.build | 1 + lib/log/version.map | 1 + 10 files changed, 308 insertions(+), 4 deletions(-) create mode 100644 lib/log/log_color.capp/test/test_eal_flags.c +24
-3@@ -1067,6 +1067,18 @@ test_misc_flags(void)const char *const argv25[] = {prgname, prefix, mp_flag,"--log-timestamp=invalid" }; +/* Try running with --log-color */ +const char *const argv26[] = {prgname, prefix, mp_flag, +"--log-color" }; + +/* Try running with --log-color=never */ +const char *const argv27[] = {prgname, prefix, mp_flag, +"--log-color=never" }; + +/* Try running with --log-color=invalid */ +const char *const argv28[] = {prgname, prefix, mp_flag, +"--log-color=invalid" }; +/* run all tests also applicable to FreeBSD first */ @@ -1187,6 +1199,18 @@ test_misc_flags(void) printf("Error - process did run ok with --log-timestamp=invalid parameter\n"); goto fail; } +if (launch_proc (argv26) !=0 ) { +printf ("Error - process did not run ok with --log-color parameter\n"); + goto fail; + } +if (launch_proc (argv27) !=0 ) { + printf("Error - process did not run ok with --log-color=none parameter\n"); + goto fail; + } +if (launch_proc (argv28) ==0 ) { + printf("Error - process did run ok with --log-timestamp=invalid parameter\n"); + goto fail; + }rmdir (hugepath_dir3);doc/guides/prog_guide/log_lib.rst +0
-0@@ -57,6 +57,7 @@ For example:: Within an application, the same result can be got using the``rte_log_set_level_pattern()`` or ``rte_log_set_level_regex()`` APIs.
doc/guides/prog_guide/log_lib.rst +1
-0+ Using Logging APIs to Generate Log Messages -------------------------------------------@@ -137,3 +138,26 @@ To prefix all console messages with ISO format timethe syntax is::
Timestamp option has no effect if using syslog because the ``syslog()`` service already does timestamping internally.
doc/guides/prog_guide/log_lib.rst +23
-0+ + +Color output +~~~~~~~~~~~~ + +The log library will highlight important messages. +This is controlled by the ``--log-color`` option. +The optional argument describes when color is enabled: + +:never: Do not enable color. This is the default behavior. + +:auto: Enable color only when printing to a terminal. + This is the same as ``--log-color`` with no argument + +:always: Always print color + +For example to enable color in logs if using terminal:: + + /path/to/app --log-color + +.. note:: + + Color output is never used for syslog or systemd journal logging.lib/eal/common/eal_common_options.c +2
-0@@ -73,6 +73,7 @@ eal_long_options[] = { {OPT_HUGE_UNLINK, 2, NULL, OPT_HUGE_UNLINK_NUM }, {OPT_IOVA_MODE, 1, NULL, OPT_IOVA_MODE_NUM }, {OPT_LCORES, 1, NULL, OPT_LCORES_NUM }, + {OPT_LOG_COLOR, 2, NULL, OPT_LOG_COLOR_NUM }, {OPT_LOG_LEVEL, 1, NULL, OPT_LOG_LEVEL_NUM }, {OPT_LOG_TIMESTAMP, 2, NULL, OPT_LOG_TIMESTAMP_NUM }, {OPT_TRACE, 1, NULL, OPT_TRACE_NUM },@@ -1620,6 +1621,7 @@ eal_log_level_parse(int argc, char * const argv[])case OPT_LOG_LEVEL_NUM :case OPT_SYSLOG_NUM :case OPT_LOG_TIMESTAMP_NUM : +case OPT_LOG_COLOR_NUM :if (eal_parse_common_option (opt, optarg, internal_conf) <0 )return -1 ;break;lib/eal/common/eal_common_options.c +9
-0@@ -1859,6 +1861,14 @@ eal_parse_common_option(int opt, const char *optarg, }break ; +case OPT_LOG_COLOR_NUM : +if (eal_log_color (optarg) <0 ) { +EAL_LOG (ERR ,"invalid parameters for --" +OPT_LOG_COLOR ); +return -1 ; + } +break ; +#ifndef RTE_EXEC_ENV_WINDOWS case OPT_TRACE_NUM : {if (eal_trace_args_save (optarg) <0 ) {@@ -2225,6 +2235,7 @@ eal_common_usage(void)" Set specific log level\n" " --" OPT_LOG_LEVEL "=help Show log types and levels\n" " --" OPT_LOG_TIMESTAMP "[=<format>] Timestamp log output\n" +" --" OPT_LOG_COLOR "[=<when>] Colorize log messages\n" #ifndef RTE_EXEC_ENV_WINDOWS" --" OPT_TRACE "=<regex-match>\n" " Enable trace based on regularexpression trace name.\n"
lib/eal/common/eal_options.h +2
-0@@ -33,6 +33,8 @@ enum {OPT_HUGE_UNLINK_NUM , #define OPT_LCORES "lcores"OPT_LCORES_NUM , +#define OPT_LOG_COLOR "log-color" +OPT_LOG_COLOR_NUM , #define OPT_LOG_LEVEL "log-level"OPT_LOG_LEVEL_NUM , #define OPT_LOG_TIMESTAMP "log-timestamp"lib/log/log.c +16
-4@@ -515,10 +515,22 @@ eal_log_init(const char *id)if (logf)rte_openlog_stream (logf); -else if (log_timestamp_enabled ()) - rte_logs.print_func = log_print_with_timestamp; -else - rte_logs.print_func = vfprintf; +else { +bool is_terminal =isatty (fileno (stderr)); +bool use_color =log_color_enabled (is_terminal); + +if (log_timestamp_enabled ()) { +if (use_color) + rte_logs.print_func = color_print_with_timestamp; +else + rte_logs.print_func = log_print_with_timestamp; + }else { +if (use_color) + rte_logs.print_func = color_print; +else + rte_logs.print_func = vfprintf; + } + }#if
RTE_LOG_DP_LEVEL>=RTE_LOG_DEBUG
RTE_LOG(NOTICE, EAL,lib/log/log_color.c new file +122
-0@@ -0,0 +1,216 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#include <limits.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdint.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> + +#include <rte_common.h> +#include <rte_log.h> + +#ifdef RTE_EXEC_ENV_WINDOWS +#include <rte_os_shim.h> +#endif + +#include "log_internal.h" +#include "log_private.h" + +enum { +LOG_COLOR_AUTO =0 , +LOG_COLOR_NEVER , +LOG_COLOR_ALWAYS , +} log_color_mode =LOG_COLOR_NEVER ; + +enum color { +COLOR_NONE , +COLOR_RED , +COLOR_GREEN , +COLOR_YELLOW , +COLOR_BLUE , +COLOR_MAGENTA , +COLOR_CYAN , +COLOR_WHITE , +COLOR_BOLD , +COLOR_CLEAR , +}; + +enum log_field { +LOG_FIELD_SUBSYS , +LOG_FIELD_TIME , +LOG_FIELD_ALERT , +LOG_FIELD_ERROR , +LOG_FIELD_INFO , +}; + +static const enum color field_colors[] = { + [LOG_FIELD_SUBSYS ] =COLOR_YELLOW , + [LOG_FIELD_TIME ] =COLOR_GREEN , + [LOG_FIELD_ALERT ] =COLOR_RED , + [LOG_FIELD_ERROR ] =COLOR_BOLD , + [LOG_FIELD_INFO ] =COLOR_NONE , +}; + +/* If set all colors are bolder */ +static bool dark_mode; + +/* Standard terminal escape codes for colors and bold */ +static const uint8_t color_esc_code[] = { + [COLOR_RED ] =31 , + [COLOR_GREEN ] =32 , + [COLOR_YELLOW ] =33 , + [COLOR_BLUE ] =34 , + [COLOR_MAGENTA ] =35 , + [COLOR_CYAN ] =36 , + [COLOR_WHITE ] =37 , + [COLOR_BOLD ] =1 , +}; + +__rte_format_printf(4, 5) +static int +color_snprintf (char *buf,size_t len,enum log_field field, +const char *fmt, ...) +{ +enum color color = field_colors[field]; +uint8_t esc = color_esc_code[color]; +va_list args; +int ret =0 ; + +va_start (args, fmt); +if (esc ==0 ) { + ret =vsnprintf (buf, len, fmt, args); + }else { + ret =snprintf (buf, len, + dark_mode ?"\e[1;%um" :"\e[%um" , esc); + ret +=vsnprintf (buf + ret, len - ret, fmt, args); + ret +=snprintf (buf + ret, len - ret,"%s" ,"\e[0m" ); + } +va_end (args); + +return ret; +} + +/* +* Controls whether color is enabled: +* modes are: +* always - enable color output regardless +* auto - enable if stderr is a terminal +* never - color output is disabled. +*/ +int +eal_log_color (const char *mode) +{ +if (mode ==NULL ||strcmp (mode,"always" ) ==0 ) + log_color_mode =LOG_COLOR_ALWAYS ; +else if (strcmp (mode,"never" ) ==0 ) + log_color_mode =LOG_COLOR_NEVER ; +else if (strcmp (mode,"auto" ) ==0 ) + log_color_mode =LOG_COLOR_AUTO ; +else +return -1 ; + +return 0 ; +} + +bool +log_color_enabled (bool is_terminal) +{ +char *env, *sep; + +/* Set dark mode using the defacto heuristics used by other programs */
lib/log/log_color.c new file +48
-0+ env =getenv ("COLORFGBG" ); +if (env) { + sep =strrchr (env,';' ); +if (sep && + ((sep[1 ] >='0' && sep[1 ] <='6' ) || sep[1 ] =='8' ) && + sep[2 ] =='\0' ) + dark_mode = true; + } + +switch (log_color_mode) { +case LOG_COLOR_ALWAYS : +return true; +case LOG_COLOR_AUTO : +return is_terminal; +default : +return false; + + } +} + +/* Look ast the current message level to determine color of field */ +static enum log_field +color_msg_field (void ) +{ +const int level =rte_log_cur_msg_loglevel (); + +if (level <=0 || level >= (int )RTE_LOG_INFO ) +return LOG_FIELD_INFO ; +else if (level >= (int )RTE_LOG_ERR ) +return LOG_FIELD_ERROR ; +else +return LOG_FIELD_ALERT ; +} + +__rte_format_printf(3, 0) +static int +color_fmt_msg (char *out,size_t len,const char *format,va_list ap) +{ +enum log_field field =color_msg_field (); +char buf[LINE_MAX ]; +int ret =0 ; + +/* format raw message */ +vsnprintf (buf,sizeof (buf), format, ap); +const char *msg = buf; + +/* +* use convention that first part of message (up to the ':' character)
lib/log/log_color.c new file +46
-0+* is the subsystem id and should be highlighted. +*/ +const char *cp =strchr (msg,':' ); +if (cp) { +/* print first part in yellow */ + ret =color_snprintf (out, len,LOG_FIELD_SUBSYS , +"%.*s" , (int )(cp - msg +1 ), msg); + msg = cp +1 ; + } + + ret +=color_snprintf (out + ret, len - ret, field,"%s" , msg); +return ret; +} + +__rte_format_printf(2, 0) +int +color_print (FILE *f,const char *format,va_list ap) +{ +char out[LINE_MAX ]; + +/* format raw message */ +int ret =color_fmt_msg (out,sizeof (out), format, ap); +if (fputs (out, f) <0 ) +return -1 ; + +return ret; +} + +__rte_format_printf(2, 0) +int +color_print_with_timestamp (FILE *f,const char *format,va_list ap) +{ +char out[LINE_MAX ]; +char tsbuf[128 ]; +int ret =0 ; + +if (log_timestamp (tsbuf,sizeof (tsbuf)) >0 ) + ret =color_snprintf (out,sizeof (out), +LOG_FIELD_TIME ,"[%s] " , tsbuf); + + ret +=color_fmt_msg (out + ret,sizeof (out) - ret, format, ap); +if (fputs (out, f) <0 ) +return -1 ; + +return ret; +}lib/log/log_internal.h +5
-0@@ -50,5 +50,10 @@ void rte_eal_log_cleanup(void);__rte_internal int eal_log_timestamp(const char *fmt); +/* +* Enable or disable color in log messages +*/ +__rte_internal +int eal_log_color(const char *mode);#endif /* LOG_INTERNAL_H */ lib/log/log_private.h +8
-0@@ -25,4 +25,12 @@ ssize_t log_timestamp(char *tsbuf, size_t tsbuflen); __rte_format_printf(2, 0)int log_print_with_timestamp (FILE *f,const char *format,va_list ap); +bool log_color_enabled (bool is_tty); + +__rte_format_printf(2, 0) +int color_print (FILE *f,const char *format,va_list ap); + +__rte_format_printf(2, 0) +int color_print_with_timestamp (FILE *f,const char *format,va_list ap); +#endif /* LOG_PRIVATE_H */ lib/log/meson.build +1
-0@@ -4,6 +4,7 @@ includes += global_inc sources = files( 'log.c', + 'log_color.c', 'log_timestamp.c', )lib/log/version.map +1
-1@@ -25,6 +25,7 @@ DPDK_25 { INTERNAL { global: + eal_log_color; eal_log_init; eal_log_journal; # WINDOWS_NO_EXPORT eal_log_level2str; --2.45.2
Signature · 6 lines
Baruch Even Platform Technical Lead at WEKA E [email protected]* *W https://www.weka.io* * [image: App Banner Image] <https://www.weka.io/trends-in-AI-emsig?utm_campaign=signature&utm_source=WiseStamp&utm_medium=email>
PATCH v27 14/14 doc: add release note about log library
In reply to Stephen HemmingerSignificant enough to add some documentation.
--- doc/guides/rel_notes/release_24_11.rst | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
doc/guides/rel_notes/release_24_11.rst +19 -0
@@ -349,6 +349,25 @@ API Changes and replaced it with a new shared devarg ``llq_policy`` that keeps the same logic. +* **Logging library changes** + + * The log is initialized earlier in startup so all messages go through the library. + + * Added a new option to timestamp log messages, which is useful for + debugging delays in application and driver startup. + + * Syslog option change. If *--syslog* is specified, then messages + will go to syslog; if not specified then messages will only be displayed + on stderr. This option is now supported on FreeBSD (but not on Windows). + + * If the application is a systemd service and the log output is being + sent of standard error then DPDK will switch to journal native protocol. + + * Log messages can be timestamped with *--log-timestamp* option. + + * Log messages can be colorized with the *--log-color* option. + + ABI Changes -----------
Signature · 1 line
2.45.2
v28 cover Logging subsystem improvements
In reply to Stephen HemmingerImprovements and unification of logging library.
This version works on all platforms: Linux, Windows and FreeBSD.
This is update to rework patch set. It adds several new features to the console log output.
* Putting a timestamp on console output which is useful for analyzing performance of startup codes. Timestamp is optional and must be enabled on command line.
* Displaying console output with colors.
It uses the standard conventions used by many other Linux commands for colorized display. The default is to enable color if the console output is going to a terminal. But it can be always on or disabled by command line flag. This default was chosen based on what dmesg(1) command does.
Color is used by many tools (vi, iproute2, git) because it is helpful; DPDK drivers and libraries print lots of not very useful messages. And having error messages highlighted in bold face helps. This might also get users to pay more attention to error messages. Many bug reports have earlier messages that are lost because there are so many info messages.
* Add support for automatic detection of systemd journal protocol. If running as systemd service will get enhanced logging.
* Use of syslog is optional and the meaning of the --syslog flag has changed. The default is *not* to use unless requested.
Add myself as maintainer for log because by now have added more than previous authors.
v28 - fix windows build
fixup documentation around syslog
consolidate syslog patches
Stephen Hemminger (13):
maintainers: add for log library
windows: make getopt functions have const properties
windows: update os shim
eal: make eal_log_level_parse common
eal: do not duplicate rte_init_alert() messages
eal: change rte_exit() output to match rte_log()
log: rework syslog handling
eal: initialize log before everything else
log: add hook for printing log messages
log: add timestamp option
log: add support for systemd journal
log: colorize log output
doc: add release note about log library
MAINTAINERS | 1 + app/test/test_eal_flags.c | 66 ++++- .../freebsd_gsg/freebsd_eal_parameters.rst | 27 ++ .../prog_guide/env_abstraction_layer.rst | 6 +- doc/guides/prog_guide/log_lib.rst | 57 ++++- doc/guides/rel_notes/release_24_11.rst | 19 ++ lib/eal/common/eal_common_debug.c | 6 +- lib/eal/common/eal_common_options.c | 122 +++++---- lib/eal/common/eal_internal_cfg.h | 1 - lib/eal/common/eal_options.h | 5 + lib/eal/freebsd/eal.c | 65 ++--- lib/eal/linux/eal.c | 68 +---- lib/eal/windows/eal.c | 50 +--- lib/eal/windows/getopt.c | 23 +- lib/eal/windows/include/getopt.h | 8 +- lib/eal/windows/include/rte_os_shim.h | 10 + lib/log/log.c | 76 ++++-- lib/log/log_color.c | 214 ++++++++++++++++ lib/log/log_freebsd.c | 12 - lib/log/log_internal.h | 22 +- lib/log/log_journal.c | 154 +++++++++++ lib/log/log_linux.c | 61 ----- lib/log/log_private.h | 53 ++++ lib/log/log_syslog.c | 109 ++++++++ lib/log/log_timestamp.c | 240 ++++++++++++++++++ lib/log/log_windows.c | 18 -- lib/log/meson.build | 12 +- lib/log/version.map | 5 +- 28 files changed, 1158 insertions(+), 352 deletions(-) create mode 100644 lib/log/log_color.c delete mode 100644 lib/log/log_freebsd.c create mode 100644 lib/log/log_journal.c delete mode 100644 lib/log/log_linux.c create mode 100644 lib/log/log_private.h create mode 100644 lib/log/log_syslog.c create mode 100644 lib/log/log_timestamp.c delete mode 100644 lib/log/log_windows.c
Signature · 1 line
2.45.2
PATCH v28 1/13 maintainers: add for log library
"You touch it you own it"
Add myself as maintainer for log library.
--- MAINTAINERS | 1 + 1 file changed, 1 insertion(+)
MAINTAINERS +1 -0
@@ -186,6 +186,7 @@ F: app/test/test_threads.c F: app/test/test_version.c Logging +M: Stephen Hemminger <[email protected]> F: lib/log/ F: doc/guides/prog_guide/log_lib.rst F: app/test/test_logs.c
Signature · 1 line
2.45.2
PATCH v28 2/13 windows: make getopt functions have const properties
In reply to Stephen HemmingerHaving different prototypes on different platforms can lead to lots of unnecessary workarounds. Looks like the version of getopt used from windows was based on an older out of date version from FreeBSD.
This patch changes getopt, getopt_long, etc to have the same const attributes as Linux and FreeBSD. The changes are derived from the current FreeBSD version of getopt_long.
--- lib/eal/windows/getopt.c | 23 ++++++++++++----------- lib/eal/windows/include/getopt.h | 8 ++++---- 2 files changed, 16 insertions(+), 15 deletions(-)
lib/eal/windows/getopt.c +12 -11
@@ -20,7 +20,7 @@#include <string.h> #include <stdlib.h> -const char *optarg;/* argument associated with option */ +char *optarg;/* argument associated with option */ int opterr =1 ;/* if error message should be printed */ int optind =1 ;/* index into parent argv vector */ int optopt ='?' ;/* character checked for validity */
@@ -39,9 +39,9 @@ static void pass(const char *a) {(void) a; }#define BADARG ((*options == ':') ? (int)':' : (int)'?')#define INORDER 1 -#define EMSG "" +static char EMSG [] ="" ; -static const char *place =EMSG ;/* option letter processing */ +static char *place =EMSG ;/* option letter processing */ /* XXX: set optreset to 1 rather than these two */ static int nonopt_start =-1 ;/* first non option argument (for permute) */
@@ -80,7 +80,7 @@ gcd(int a, int b)*/ static void permute_args (int panonopt_start,int panonopt_end,int opt_end, -char **nargv) +char *const *nargv) {int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;char *swap;
@@ -101,11 +101,12 @@ permute_args(int panonopt_start, int panonopt_end, int opt_end, pos -= nnonopts; else pos += nopts; + swap = nargv[pos];/* LINTED const cast */ - ((char **) nargv)[pos] = nargv[cstart]; + ((char **)(uintptr_t )nargv)[pos] = nargv[cstart];/* LINTED const cast */ - ((char **)nargv)[cstart] = swap; + ((char **)(uintptr_t )nargv)[cstart] = swap; } } }
@@ -116,7 +117,7 @@ permute_args(int panonopt_start, int panonopt_end, int opt_end,* Returns -1 if short_too is set and the option does not match long_options. */ static int -parse_long_options (char **nargv,const char *options, +parse_long_options (char *const *nargv,const char *options,const struct option *long_options,int *idx,int short_too) {const char *current_argv;
@@ -236,7 +237,7 @@ parse_long_options(char **nargv, const char *options,* Parse argc/argv argument vector. Called by user level routines. */ static int -getopt_internal (int nargc,char **nargv,const char *options, +getopt_internal (int nargc,char *const nargv[],const char *options,const struct option *long_options,int *idx,int flags) {char *oli;/* option letter list index */
@@ -434,7 +435,7 @@ getopt_internal(int nargc, char **nargv, const char *options,* Parse argc/argv argument vector. */ int -getopt (int nargc,char *nargv[],const char *options) +getopt (int nargc,char *const nargv[],const char *options) {return getopt_internal (nargc, nargv, options,NULL ,NULL ,FLAG_PERMUTE );
@@ -445,7 +446,7 @@ getopt(int nargc, char *nargv[], const char *options)* Parse argc/argv argument vector. */ int -getopt_long (int nargc,char *nargv[],const char *options, +getopt_long (int nargc,char *const nargv[],const char *options,const struct option *long_options,int *idx) {
@@ -458,7 +459,7 @@ getopt_long(int nargc, char *nargv[], const char *options,* Parse argc/argv argument vector. */ int -getopt_long_only (int nargc,char *nargv[],const char *options, +getopt_long_only (int nargc,char *const nargv[],const char *options,const struct option *long_options,int *idx) {
lib/eal/windows/include/getopt.h +4 -4
@@ -44,7 +44,7 @@/** argument to current option, or NULL if it has none */ -extern const char *optarg; +extern char *optarg;/** Current position in arg string. Starts from 1. * Setting to 0 resets state. */
@@ -80,14 +80,14 @@ struct option { };/** Compat: getopt */ -int getopt (int argc,char *argv[],const char *options); +int getopt (int argc,char *const argv[],const char *options);/** Compat: getopt_long */ -int getopt_long (int argc,char *argv[],const char *options, +int getopt_long (int argc,char *const argv[],const char *options,const struct option *longopts,int *longindex);/** Compat: getopt_long_only */ -int getopt_long_only (int nargc,char *argv[],const char *options, +int getopt_long_only (int nargc,char *const argv[],const char *options,const struct option *long_options,int *idx);
Signature · 1 line
2.45.2
PATCH v28 3/13 windows: update os shim
In reply to Stephen HemmingerWindows does not have localtime_r but it does have a similar function that can be used instead.
Use rte_os_shim.h in lib/log instead of redefine of strdup.
--- lib/eal/windows/include/rte_os_shim.h | 10 ++++++++++ lib/log/log.c | 7 +++---- 2 files changed, 13 insertions(+), 4 deletions(-)
lib/eal/windows/include/rte_os_shim.h +10 -0
@@ -110,4 +110,14 @@ rte_clock_gettime(clockid_t clock_id, struct timespec *tp) }#define clock_gettime (clock_id, tp) rte_clock_gettime(clock_id, tp) +static inline struct tm * +rte_localtime_r (const time_t *timep,struct tm *result) +{ +if (localtime_s (result, timep) ==0 ) +return result; +else +return NULL ; +} +#define localtime_r (timep, result) rte_localtime_r(timep, result) +#endif /* _RTE_OS_SHIM_ */
lib/log/log.c +3 -4
@@ -14,13 +14,12 @@#include <rte_log.h> #include <rte_per_lcore.h> - -#include "log_internal.h" -#ifdef RTE_EXEC_ENV_WINDOWS -#define strdup _strdup +#include <rte_os_shim.h> #endif +#include "log_internal.h" +struct rte_log_dynamic_type {const char *name;uint32_t loglevel;
Signature · 1 line
2.45.2
PATCH v28 4/13 eal: make eal_log_level_parse common
In reply to Stephen HemmingerThe code to parse for log-level option should be same on all OS variants.
--- lib/eal/common/eal_common_options.c | 40 +++++++++++++++++++++++++++ lib/eal/common/eal_options.h | 1 + lib/eal/freebsd/eal.c | 42 ----------------------------- lib/eal/linux/eal.c | 39 --------------------------- lib/eal/windows/eal.c | 35 ------------------------ 5 files changed, 41 insertions(+), 116 deletions(-)
lib/eal/common/eal_common_options.c +40 -0
@@ -1640,6 +1640,46 @@ eal_parse_huge_unlink(const char *arg, struct hugepage_file_discipline *out)return -1 ; } +/* Parse the all arguments looking for log related ones */ +int +eal_log_level_parse (int argc,char *const argv[]) +{ +struct internal_config *internal_conf =eal_get_internal_configuration (); +int option_index, opt; +const int old_optind = optind; +const int old_optopt = optopt; +const int old_opterr = opterr; +char *old_optarg = optarg; +#ifdef RTE_EXEC_ENV_FREEBSD +const int old_optreset = optreset; + optreset =1 ; +#endif + + optind =1 ; + opterr =0 ; + +while ((opt =getopt_long (argc, argv, eal_short_options, + eal_long_options, &option_index)) !=EOF ) { + +switch (opt) { +case OPT_LOG_LEVEL_NUM : +if (eal_parse_common_option (opt, optarg, internal_conf) <0 ) +return -1 ; +break ; + } + } + +/* restore getopt lib */ + optind = old_optind; + optopt = old_optopt; + optarg = old_optarg; + opterr = old_opterr; +#ifdef RTE_EXEC_ENV_FREEBSD + optreset = old_optreset; +#endif +return 0 ; +} +int eal_parse_common_option (int opt,const char *optarg,struct internal_config *conf)
lib/eal/common/eal_options.h +1 -0
@@ -96,6 +96,7 @@ enum {extern const char eal_short_options[];extern const struct option eal_long_options[]; +int eal_log_level_parse (int argc,char *const argv[]);int eal_parse_common_option (int opt,const char *argv,struct internal_config *conf);int eal_option_device_parse (void );
lib/eal/freebsd/eal.c +0 -42
48 lines not on this page · raw message
lib/eal/linux/eal.c +0 -39
@@ -546,45 +546,6 @@ eal_parse_vfio_vf_token(const char *vf_token)return -1 ; } -/* Parse the arguments for --log-level only */ -static void -eal_log_level_parse (int argc,char **argv) -{ -int opt; -char **argvopt; -int option_index; -const int old_optind = optind; -const int old_optopt = optopt; -char *const old_optarg = optarg; -struct internal_config *internal_conf = -eal_get_internal_configuration (); - - argvopt = argv; - optind =1 ; - -while ((opt =getopt_long (argc, argvopt, eal_short_options, - eal_long_options, &option_index)) !=EOF ) { - -int ret; - -/* getopt is not happy, stop right now */ -if (opt =='?' ) -break ; - - ret = (opt ==OPT_LOG_LEVEL_NUM ) ? -eal_parse_common_option (opt, optarg, internal_conf) :0 ; - -/* common parser is not happy */ -if (ret <0 ) -break ; - } - -/* restore getopt lib */ - optind = old_optind; - optopt = old_optopt; - optarg = old_optarg; -} -static int eal_parse_huge_worker_stack (const char *arg) {
lib/eal/windows/eal.c +0 -35
@@ -96,41 +96,6 @@ eal_usage(const char *prgname) } } -/* Parse the arguments for --log-level only */ -static void -eal_log_level_parse (int argc,char **argv) -{ -int opt; -char **argvopt; -int option_index; -struct internal_config *internal_conf = -eal_get_internal_configuration (); - - argvopt = argv; - -eal_reset_internal_config (internal_conf); - -while ((opt =getopt_long (argc, argvopt, eal_short_options, - eal_long_options, &option_index)) !=EOF ) { - -int ret; - -/* getopt is not happy, stop right now */ -if (opt =='?' ) -break ; - - ret = (opt ==OPT_LOG_LEVEL_NUM ) ? -eal_parse_common_option (opt, optarg, - internal_conf) :0 ; - -/* common parser is not happy */ -if (ret <0 ) -break ; - } - - optind =0 ;/* reset getopt lib */ -} -/* Parse the argument given in the command line of the application */ static int eal_parse_args (int argc,char **argv)
Signature · 1 line
2.45.2
PATCH v28 5/13 eal: do not duplicate rte_init_alert() messages
In reply to Stephen HemmingerThe message already goes through logging, and does not need to be printed on stderr. Message level should be ALERT to match function name.
--- lib/eal/freebsd/eal.c | 3 +-- lib/eal/linux/eal.c | 3 +-- lib/eal/windows/eal.c | 1 - 3 files changed, 2 insertions(+), 5 deletions(-)
lib/eal/freebsd/eal.c +1 -2
@@ -529,8 +529,7 @@ rte_eal_iopl_init(void)static void rte_eal_init_alert (const char *msg) { -fprintf (stderr,"EAL: FATAL: %s\n" , msg); -EAL_LOG (ERR ,"%s" , msg); +EAL_LOG (ALERT ,"%s" , msg); }/* Launch threads, called at application init(). */
lib/eal/linux/eal.c +1 -2
@@ -830,8 +830,7 @@ rte_eal_iopl_init(void)static void rte_eal_init_alert (const char *msg) { -fprintf (stderr,"EAL: FATAL: %s\n" , msg); -EAL_LOG (ERR ,"%s" , msg); +EAL_LOG (ALERT ,"%s" , msg); }/*
lib/eal/windows/eal.c +0 -1
@@ -181,7 +181,6 @@ sync_func(void *arg __rte_unused)static void rte_eal_init_alert (const char *msg) { -fprintf (stderr,"EAL: FATAL: %s\n" , msg);EAL_LOG (ERR ,"%s" , msg); }
Signature · 1 line
2.45.2
PATCH v28 6/13 eal: change rte_exit() output to match rte_log()
In reply to Stephen HemmingerThe rte_exit() output format confuses the timestamp and coloring options. Change it to use be a single line with proper prefix.
Before:
[ 0.006481] EAL: Error - exiting with code: 1 Cause: [ 0.006489] Cannot init EAL: Permission denied
After:
[ 0.006238] EAL: Error - exiting with code: 1 [ 0.006250] EAL: Cannot init EAL: Permission denied
--- lib/eal/common/eal_common_debug.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
lib/eal/common/eal_common_debug.c +2 -4
@@ -36,15 +36,13 @@ rte_exit(int exit_code, const char *format, ...)va_list ap;if (exit_code !=0 ) -RTE_LOG (CRIT ,EAL ,"Error - exiting with code: %d\n" -" Cause: " , exit_code); +EAL_LOG (CRIT ,"Error - exiting with code: %d" , exit_code);va_start (ap, format);rte_vlog (RTE_LOG_CRIT ,RTE_LOGTYPE_EAL , format, ap);va_end (ap);if (rte_eal_cleanup () !=0 && rte_errno !=EALREADY ) -EAL_LOG (CRIT , -"EAL could not release all resources" ); +EAL_LOG (CRIT ,"EAL could not release all resources" );exit (exit_code); }
Signature · 1 line
2.45.2
PATCH v28 7/13 log: rework syslog handling
In reply to Stephen HemmingerRefactor how syslog is handled, make it common to Linux and FreeBSD The syslog facility property is better handled in lib/log rather than in eal. This also add syslog support to FreeBSD.
Log to syslog only if option is specified.
If no --syslog is given then use console only.
--- app/test/test_eal_flags.c | 16 +-- .../freebsd_gsg/freebsd_eal_parameters.rst | 27 +++++ .../prog_guide/env_abstraction_layer.rst | 6 +- doc/guides/prog_guide/log_lib.rst | 5 +- lib/eal/common/eal_common_options.c | 57 ++-------- lib/eal/common/eal_internal_cfg.h | 1 - lib/eal/freebsd/eal.c | 5 +- lib/eal/linux/eal.c | 12 +-- lib/eal/windows/eal.c | 6 +- lib/log/log.c | 45 ++++---- lib/log/log_freebsd.c | 12 --- lib/log/log_internal.h | 11 +- lib/log/log_linux.c | 61 ----------- lib/log/log_private.h | 25 +++++ lib/log/log_syslog.c | 100 ++++++++++++++++++ lib/log/log_windows.c | 18 ---- lib/log/meson.build | 6 +- lib/log/version.map | 2 +- 18 files changed, 211 insertions(+), 204 deletions(-) delete mode 100644 lib/log/log_freebsd.c delete mode 100644 lib/log/log_linux.c create mode 100644 lib/log/log_private.h create mode 100644 lib/log/log_syslog.c delete mode 100644 lib/log/log_windows.c
app/test/test_eal_flags.c +8 -8
@@ -985,12 +985,12 @@ test_misc_flags(void)/* With -v */ const char *argv2[] = {prgname, prefix, mp_flag,"-v" };/* With valid --syslog */ -const char *argv3[] = {prgname, prefix, mp_flag, -"--syslog" ,"syslog" }; -/* With empty --syslog (should fail) */ +const char *argv3[] = {prgname, prefix, mp_flag,"--syslog=user" }; +/* With empty --syslog (now defaults) */ const char *argv4[] = {prgname, prefix, mp_flag,"--syslog" };/* With invalid --syslog */ -const char *argv5[] = {prgname, prefix, mp_flag,"--syslog" ,"error" }; +const char *argv5[] = {prgname, prefix, mp_flag,"--syslog=invalid" }; +/* With no-sh-conf, also use no-huge to ensure this test runs on BSD */ const char *argv6[] = {prgname,"-m" ,DEFAULT_MEM_SIZE , no_shconf, nosh_prefix, no_huge};
@@ -1080,15 +1080,15 @@ test_misc_flags(void)#endif if (launch_proc (argv3) !=0 ) { -printf ("Error - process did not run ok with --syslog flag\n" ); +printf ("Error - process did not run ok with --syslog=user flag\n" ); goto fail; } -if (launch_proc (argv4) ==0 ) { -printf ("Error - process run ok with empty --syslog flag\n" ); +if (launch_proc (argv4) !=0 ) { +printf ("Error - process did not run ok with --syslog flag\n" ); goto fail; }if (launch_proc (argv5) ==0 ) { -printf ("Error - process run ok with invalid --syslog flag\n" ); +printf ("Error - process run ok with --syslog=invalid flag\n" ); goto fail; }if (launch_proc (argv7) !=0 ) {
doc/guides/freebsd_gsg/freebsd_eal_parameters.rst +27 -0
@@ -18,3 +18,30 @@ FreeBSD-specific EAL parameters ------------------------------- There are currently no FreeBSD-specific EAL command-line parameters available. + +Other options +~~~~~~~~~~~~~ + +* ``--syslog <syslog facility>`` + + Set syslog facility. Valid syslog facilities are:: + + auth + cron + daemon + ftp + kern + lpr + mail + news + syslog + user + uucp + local0 + local1 + local2 + local3 + local4 + local5 + local6 + local7
doc/guides/prog_guide/env_abstraction_layer.rst +3 -3
@@ -851,9 +851,9 @@ Signal Safety Other functions are not signal safe because they use one or more library routines that are not themselves signal safe. For example, calling ``rte_panic()`` is not safe in a signal handler - because it uses ``rte_log()`` and ``rte_log()`` calls the - ``syslog()`` library function which is in the list of - signal safe functions in + because it uses ``rte_log()`` and ``rte_log()`` may call ``vfprintf()`` or + ``syslog()`` library functions which are not in the list of + signal safe functions `Signal-Safety manual page <https://man7.org/linux/man-pages/man7/signal-safety.7.html>`_. The set of functions that are expected to be async-signal-safe in DPDK
doc/guides/prog_guide/log_lib.rst +2 -3
@@ -5,9 +5,7 @@ Log Library =========== The DPDK Log library provides the logging functionality for other DPDK libraries and drivers. -By default, in a Linux application, logs are sent to syslog and also to the console. -On FreeBSD and Windows applications, logs are sent only to the console. -However, the log function can be overridden by the user to use a different logging mechanism. +The messages can be sent to one or more sources controlled by the EAL command line options. Log Levels ----------
@@ -59,6 +57,7 @@ For example:: Within an application, the same result can be got using the ``rte_log_set_level_pattern()`` or ``rte_log_set_level_regex()`` APIs. + Using Logging APIs to Generate Log Messages -------------------------------------------
lib/eal/common/eal_common_options.c +6 -51
99 lines not on this page · raw message
lib/eal/common/eal_internal_cfg.h +0 -1
@@ -84,7 +84,6 @@ struct internal_config {/**< true if storing all pages within single files (per-page-size, * per-node) non-legacy mode only. */ -volatile int syslog_facility;/**< facility passed to openlog() */ /** default interrupt mode for VFIO */ volatile enum rte_intr_mode vfio_intr_mode;/** the shared VF token for VFIO-PCI bound PF and VFs devices */
lib/eal/freebsd/eal.c +2 -3
@@ -11,7 +11,6 @@#include <stdarg.h> #include <unistd.h> #include <pthread.h> -#include <syslog.h> #include <getopt.h> #include <sys/file.h> #include <stddef.h>
@@ -392,8 +391,8 @@ eal_parse_args(int argc, char **argv) goto out; } -/* eal_log_level_parse() already handled this option */ -if (opt ==OPT_LOG_LEVEL_NUM ) +/* eal_log_level_parse() already handled these */ +if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_LOG_SYSLOG_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
lib/eal/linux/eal.c +3 -9
@@ -610,8 +610,8 @@ eal_parse_args(int argc, char **argv) goto out; } -/* eal_log_level_parse() already handled this option */ -if (opt ==OPT_LOG_LEVEL_NUM ) +/* eal_log_level_parse() already handled these options */ +if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_SYSLOG_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
@@ -1103,13 +1103,7 @@ rte_eal_init(int argc, char **argv)#endif } -if (eal_log_init (program_invocation_short_name, - internal_conf->syslog_facility) <0 ) { -rte_eal_init_alert ("Cannot init logging." ); - rte_errno =ENOMEM ; -rte_atomic_store_explicit (&run_once,0 , rte_memory_order_relaxed); -return -1 ; - } +eal_log_init (program_invocation_short_name);#ifdef VFIO_PRESENT if (rte_vfio_enable ("vfio" )) {
lib/eal/windows/eal.c +3 -3
@@ -120,8 +120,8 @@ eal_parse_args(int argc, char **argv)return -1 ; } -/* eal_log_level_parse() already handled this option */ -if (opt ==OPT_LOG_LEVEL_NUM ) +/* eal_log_level_parse() already handled these options */ +if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_SYSLOG_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
@@ -249,7 +249,7 @@ rte_eal_init(int argc, char **argv)char cpuset[RTE_CPU_AFFINITY_STR_LEN ];char thread_name[RTE_THREAD_NAME_SIZE ]; -eal_log_init (NULL ,0 ); +eal_log_init (NULL );eal_log_level_parse (argc, argv);
lib/log/log.c +22 -23
96 lines not on this page · raw message
lib/log/log_freebsd.c deleted +0 -12
@@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause -* Copyright(c) 2023 Intel Corporation -*/ - -#include <rte_common.h> -#include "log_internal.h" - -int -eal_log_init(__rte_unused const char *id, __rte_unused int facility) -{ -return 0 ; -}
lib/log/log_internal.h +4 -7
@@ -14,13 +14,7 @@* Initialize the default log stream. */ __rte_internal -int eal_log_init(const char *id, int facility); - -/* -* Determine where log data is written when no call to rte_openlog_stream. -*/ -__rte_internal -void eal_log_set_default(FILE *default_log); +void eal_log_init(const char *id);/* * Save a log option for later.
@@ -30,6 +24,9 @@ int eal_log_save_regexp(const char *regexp, uint32_t level);__rte_internal int eal_log_save_pattern(const char *pattern, uint32_t level); +__rte_internal +int eal_log_syslog(const char *name); +/* * Convert log level to string. */
lib/log/log_linux.c deleted +0 -61
61 lines not on this page · raw message
lib/log/log_private.h new file +25 -0
@@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#ifndef LOG_PRIVATE_H +#define LOG_PRIVATE_H + +/* Defined in limits.h on Linux */ +#ifndef LINE_MAX +#define LINE_MAX 2048/* _POSIX2_LINE_MAX */ +#endif + +#ifdef RTE_EXEC_ENV_WINDOWS +static inline bool log_syslog_enabled (void ) +{ +return false; +} +static inline FILE *log_syslog_open(const char *id __rte_unused) +{ +return NULL ; +} +#else +bool log_syslog_enabled (void ); +FILE *log_syslog_open (const char *id); +#endif + +#endif /* LOG_PRIVATE_H */
lib/log/log_syslog.c new file +100 -0
100 lines not on this page · raw message
lib/log/log_windows.c deleted +0 -18
@@ -1,18 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause -* Copyright(c) 2017-2018 Intel Corporation -*/ - -#include <rte_common.h> -#include <rte_log.h> -#include "log_internal.h" - -/* set the log to default function, called during eal init process. */ -int -eal_log_init(__rte_unused const char *id, __rte_unused int facility) -{ -rte_openlog_stream (stderr); - -eal_log_set_default (stderr); - -return 0 ; -}
lib/log/meson.build +5 -1
@@ -4,6 +4,10 @@ includes += global_inc sources = files( 'log.c', - 'log_' + exec_env + '.c', ) + +if not is_windows + sources += files('log_syslog.c') +endif + headers = files('rte_log.h')
lib/log/version.map +1 -1
@@ -29,6 +29,6 @@ INTERNAL { eal_log_level2str; eal_log_save_pattern; eal_log_save_regexp; - eal_log_set_default; + eal_log_syslog; # WINDOWS_NO_EXPORT rte_eal_log_cleanup; };
Signature · 1 line
2.45.2
PATCH v28 8/13 eal: initialize log before everything else
In reply to Stephen HemmingerIn order for all log messages (including CPU mismatch) to come out through the logging library, it must be initialized as early in rte_eal_init() as possible on all platforms.
Where it was done before was likely historical based on the support of non-OS isolated CPU's which required a shared memory buffer; that support was dropped before DPDK was publicly released.
--- lib/eal/freebsd/eal.c | 13 ++++++++++--- lib/eal/linux/eal.c | 14 +++++++++----- lib/eal/windows/eal.c | 8 ++++++-- lib/log/log_internal.h | 6 ++++++ 4 files changed, 31 insertions(+), 10 deletions(-)
lib/eal/freebsd/eal.c +10 -3
@@ -52,6 +52,7 @@#include "eal_options.h" #include "eal_memcfg.h" #include "eal_trace.h" +#include "log_internal.h" #define MEMSIZE_IF_NO_HUGE_PAGE (64ULL * 1024ULL * 1024ULL)
@@ -546,6 +547,15 @@ rte_eal_init(int argc, char **argv)bool has_phys_addr;enum rte_iova_mode iova_mode; +/* setup log as early as possible */ +if (eal_log_level_parse (argc, argv) <0 ) { +rte_eal_init_alert ("invalid log arguments." ); + rte_errno =EINVAL ; +return -1 ; + } + +eal_log_init (getprogname ()); +/* checks if the machine is adequate */ if (!rte_cpu_is_supported ()) {rte_eal_init_alert ("unsupported cpu type." );
@@ -572,9 +582,6 @@ rte_eal_init(int argc, char **argv)/* clone argv to report out later in telemetry */ eal_save_args (argc, argv); -/* set log level as early as possible */ -eal_log_level_parse (argc, argv); -if (rte_eal_cpu_init () <0 ) {rte_eal_init_alert ("Cannot detect lcores." ); rte_errno =ENOTSUP ;
lib/eal/linux/eal.c +9 -5
@@ -926,6 +926,15 @@ rte_eal_init(int argc, char **argv)struct internal_config *internal_conf =eal_get_internal_configuration (); +/* setup log as early as possible */ +if (eal_log_level_parse (argc, argv) <0 ) { +rte_eal_init_alert ("invalid log arguments." ); + rte_errno =EINVAL ; +return -1 ; + } + +eal_log_init (program_invocation_short_name); +/* checks if the machine is adequate */ if (!rte_cpu_is_supported ()) {rte_eal_init_alert ("unsupported cpu type." );
@@ -949,9 +958,6 @@ rte_eal_init(int argc, char **argv)eal_reset_internal_config (internal_conf); -/* set log level as early as possible */ -eal_log_level_parse (argc, argv); -/* clone argv to report out later in telemetry */ eal_save_args (argc, argv);
@@ -1103,8 +1109,6 @@ rte_eal_init(int argc, char **argv)#endif } -eal_log_init (program_invocation_short_name); -#ifdef VFIO_PRESENT if (rte_vfio_enable ("vfio" )) {rte_eal_init_alert ("Cannot init VFIO" );
lib/eal/windows/eal.c +6 -2
@@ -249,9 +249,13 @@ rte_eal_init(int argc, char **argv)char cpuset[RTE_CPU_AFFINITY_STR_LEN ];char thread_name[RTE_THREAD_NAME_SIZE ]; -eal_log_init (NULL ); +if (eal_log_level_parse (argc, argv) <0 ) { +rte_eal_init_alert ("invalid log arguments." ); + rte_errno =EINVAL ; +return -1 ; + } -eal_log_level_parse (argc, argv); +eal_log_init (NULL );if (eal_create_cpu_map () <0 ) {rte_eal_init_alert ("Cannot discover CPU and NUMA." );
lib/log/log_internal.h +6 -0
@@ -16,6 +16,12 @@__rte_internal void eal_log_init(const char *id); +/* +* Determine where log data is written when no call to rte_openlog_stream. +*/ +__rte_internal +void eal_log_set_default(FILE *default_log); +/* * Save a log option for later. */
Signature · 1 line
2.45.2