eal: add option to put timestamp on console output
PATCH v19 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.43.0
PATCH v19 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 *timer,struct tm *buf) +{ +if (localtime_s (buf, timer) ==0 ) +return buf; +else +return NULL ; +} +#define localtime_r (timer, buf) rte_localtime_r(timer, buf) +#endif /* _RTE_OS_SHIM_ */
Signature · 1 line
2.43.0
PATCH v19 4/15 windows: common wrapper for vasprintf and asprintf
In reply to Stephen HemmingerReplace the windows version of asprintf() that was only usable in eal. With a more generic one that supports both vasprintf() and asprintf(). This also eliminates duplicate code.
--- drivers/bus/pci/pci_common.c | 32 ------------------ lib/eal/common/eal_private.h | 10 ------ lib/eal/windows/eal.c | 28 ---------------- lib/eal/windows/include/rte_os_shim.h | 48 +++++++++++++++++++++++++++ 4 files changed, 48 insertions(+), 70 deletions(-)
drivers/bus/pci/pci_common.c +0 -32
@@ -45,38 +45,6 @@ const char *rte_pci_get_sysfs_path(void)return path; } -#ifdef RTE_EXEC_ENV_WINDOWS -#define asprintf pci_asprintf - -static int -__rte_format_printf(2, 3) -pci_asprintf(char **buffer, const char *format, ...) -{ - int size, ret; -va_list arg; - - va_start(arg, format); - size =vsnprintf (NULL ,0 , format, arg); -va_end (arg); - if (size < 0) - return -1; - size++; - - *buffer =malloc (size); - if (*buffer == NULL) - return -1; - - va_start(arg, format); - ret =vsnprintf (*buffer, size, format, arg); -va_end (arg); - if (ret != size - 1) { -free (*buffer); -return -1 ; - } -return ret; -} -#endif /* RTE_EXEC_ENV_WINDOWS */ -static struct rte_devargs *pci_devargs_lookup (const struct rte_pci_addr *pci_addr) {
lib/eal/common/eal_private.h +0 -10
@@ -737,16 +737,6 @@ void __rte_thread_init(unsigned int lcore_id, rte_cpuset_t *cpuset);*/ void __rte_thread_uninit (void ); -/** -* asprintf(3) replacement for Windows. -*/ -#ifdef RTE_EXEC_ENV_WINDOWS -__rte_format_printf(2, 3) -int eal_asprintf (char **buffer,const char *format, ...); - -#define asprintf (buffer, format, ...) \ - eal_asprintf(buffer, format, ##__VA_ARGS__) -#endif #define EAL_LOG (level, ...) \ RTE_LOG_LINE(level, EAL, "" __VA_ARGS__)
lib/eal/windows/eal.c +0 -28
@@ -503,34 +503,6 @@ rte_eal_init(int argc, char **argv)return fctret; } -/* Don't use MinGW asprintf() to have identical code with all toolchains. */ -int -eal_asprintf (char **buffer,const char *format, ...) -{ -int size, ret; -va_list arg; - -va_start (arg, format); - size =vsnprintf (NULL ,0 , format, arg); -va_end (arg); -if (size <0 ) -return -1 ; - size++; - - *buffer =malloc (size); -if (*buffer ==NULL ) -return -1 ; - -va_start (arg, format); - ret =vsnprintf (*buffer, size, format, arg); -va_end (arg); -if (ret != size -1 ) { -free (*buffer); -return -1 ; - } -return ret; -} - int rte_vfio_container_dma_map(__rte_unused int container_fd, __rte_unused uint64_t vaddr,
lib/eal/windows/include/rte_os_shim.h +48 -0
58 lines not on this page · raw message
Signature · 1 line
2.43.0
PATCH v19 5/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 | 46 +++++++++++++++++++++++++++++ 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, 47 insertions(+), 116 deletions(-)
lib/eal/common/eal_common_options.c +46 -0
@@ -1640,6 +1640,51 @@ 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 ; +case '?' : +/* getopt is not happy, stop right now */ + goto out; +default : +continue ; + } + } +out: +/* 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)
@@ -2173,6 +2218,7 @@ rte_vect_set_max_simd_bitwidth(uint16_t bitwidth)return 0 ; } +void eal_common_usage (void ) {
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.43.0
PATCH v19 6/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.43.0
PATCH v19 7/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: Cause - Cannot init EAL: Permission denied
--- lib/eal/common/eal_common_debug.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
lib/eal/common/eal_common_debug.c +6 -5
@@ -34,17 +34,18 @@ void rte_exit(int exit_code, const char *format, ...) { va_list ap; +char msg[256 ];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); +vsnprintf (msg,sizeof (msg), format, ap);va_end (ap); +rte_log (RTE_LOG_CRIT ,RTE_LOGTYPE_EAL ,"EAL: Cause - %s" , msg); +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.43.0
PATCH v19 8/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 ;
@@ -1882,7 +1835,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);
@@ -1106,8 +1106,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.43.0
PATCH v19 9/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." );
@@ -565,9 +574,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." );
@@ -952,9 +961,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);
@@ -1106,13 +1112,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.43.0
PATCH v19 10/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
@@ -2212,9 +2212,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.43.0
PATCH v19 11/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 | 14 +++++++++++++- lib/log/log_private.h | 11 +++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 lib/log/log_private.h
lib/log/log.c +13 -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
@@ -28,16 +29,19 @@ struct rte_log_dynamic_type {uint32_t loglevel; }; +/** 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 = log_print, };struct rte_eal_opt_loglevel {
@@ -74,6 +78,7 @@ int rte_openlog_stream(FILE *f) { rte_logs.file = f; + rte_logs.print_func = log_print;return 0 ; }
@@ -470,7 +475,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, level, format, ap);fflush (f);return ret; }
@@ -499,6 +504,13 @@ eal_log_syslog(const char *mode __rte_unused)return -1 ; } +/* default log print function */ +int +log_print(FILE *f, uint32_t level __rte_unused, const char *format, va_list ap) +{ +return vfprintf (f, format, ap); +} +/* * Called by rte_eal_init */
lib/log/log_private.h new file +11 -0
@@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#ifndef LOG_PRIVATE_H +#define LOG_PRIVATE_H + +typedef int (*log_print_t )(FILE *f,uint32_t level,const char *fmt,va_list ap); + +__rte_format_printf(3, 0) +int log_print (FILE *f,uint32_t level,const char *format,va_list ap); + +#endif /* LOG_PRIVATE_H */
Signature · 1 line
2.43.0
PATCH v19 12/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 | 10 +- lib/log/log_internal.h | 9 ++ lib/log/log_private.h | 7 + lib/log/log_timestamp.c | 204 ++++++++++++++++++++++++++++ lib/log/meson.build | 6 +- lib/log/version.map | 1 + 13 files changed, 309 insertions(+), 10 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 ;
@@ -1843,7 +1845,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 --"
@@ -1851,7 +1853,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 : {
@@ -2216,6 +2225,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 +7 -3
@@ -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 {
@@ -29,13 +29,13 @@ struct rte_log_dynamic_type {uint32_t loglevel; }; -/** 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 = {
@@ -359,7 +359,6 @@ static const struct logtype logtype_strings[] = { RTE_INIT_PRIO(log_init, LOG) {uint32_t i; -rte_log_set_global_level (RTE_LOG_DEBUG ); rte_logs.dynamic_types = calloc(RTE_LOGTYPE_FIRST_EXT_ID,
@@ -517,6 +516,11 @@ log_print(FILE *f, uint32_t level __rte_unused, const char *format, va_list ap)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 = log_print; +#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 +7 -0
@@ -8,4 +8,11 @@ typedef int (*log_print_t)(FILE *f, uint32_t level, const char *fmt, va_list ap) __rte_format_printf(3, 0)int log_print (FILE *f,uint32_t level,const char *format,va_list ap); +bool log_timestamp_enabled (void ); + +ssize_t log_timestamp (char *tsbuf,size_t tsbuflen); + +__rte_format_printf(3, 0) +int log_print_with_timestamp (FILE *f,uint32_t level,const char *format,va_list ap); +#endif /* LOG_PRIVATE_H */
lib/log/log_timestamp.c new file +204 -0
204 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.43.0
PATCH v19 13/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 | 25 +++--- lib/log/log_private.h | 4 + lib/log/log_stubs.c | 28 ++++++ lib/log/log_syslog.c | 89 +++++++++++++++++++ lib/log/meson.build | 6 ++ 9 files changed, 165 insertions(+), 41 deletions(-) create mode 100644 lib/log/log_stubs.c 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 },
@@ -2221,6 +2221,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 +14 -11
@@ -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,13 +497,6 @@ 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 ; -} -/* default log print function */ int log_print(FILE *f, uint32_t level __rte_unused, const char *format, va_list ap)
@@ -514,8 +508,17 @@ log_print(FILE *f, uint32_t level __rte_unused, const char *format, va_list ap)* Called by rte_eal_init */ void -eal_log_init(const char *id __rte_unused) +eal_log_init (const char *id) { +#ifdef RTE_EXEC_ENV_WINDOWS +RTE_SET_USED (id); +#else +bool is_terminal =isatty (STDERR_FILENO ); + +if (log_syslog_enabled (is_terminal)) +log_syslog_open (id, is_terminal); + else +#endif if (log_timestamp_enabled ()) rte_logs.print_func = log_print_with_timestamp;else
lib/log/log_private.h +4 -0
@@ -15,4 +15,8 @@ ssize_t log_timestamp(char *tsbuf, size_t tsbuflen); __rte_format_printf(3, 0)int log_print_with_timestamp (FILE *f,uint32_t level,const char *format,va_list ap); +bool log_syslog_enabled (bool is_tty); +void log_syslog_open (const char *id,bool is_terminal); + +#endif /* LOG_PRIVATE_H */
lib/log/log_stubs.c new file +28 -0
@@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(c) 2010-2014 Intel Corporation +*/ + +#include <stdio.h> +#include <stdint.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <regex.h> +#include <fnmatch.h> +#include <sys/queue.h> +#include <unistd.h> +#include <rte_os_shim.h> + +#include <rte_log.h> +#include <rte_per_lcore.h> + +#include "log_internal.h" +#include "log_private.h" + +/* Stubs for Windows */ +int +eal_log_syslog(const char *str __rte_unused) +{ +return -1 ; +}
lib/log/log_syslog.c new file +89 -0
89 lines not on this page · raw message
lib/log/meson.build +6 -0
@@ -7,4 +7,10 @@ sources = files( 'log_timestamp.c', ) +if is_windows + sources += files('log_stubs.c') +else + sources += files('log_syslog.c') +endif + headers = files('rte_log.h')
Signature · 1 line
2.43.0
PATCH v19 14/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 | 11 ++ lib/eal/common/eal_options.h | 2 + lib/log/log.c | 5 + lib/log/log_internal.h | 3 + lib/log/log_journal.c | 216 ++++++++++++++++++++++++++++ lib/log/log_private.h | 4 + lib/log/log_stubs.c | 6 + lib/log/meson.build | 5 + lib/log/version.map | 1 + 10 files changed, 267 insertions(+) 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 +11 -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 ;
@@ -1843,6 +1845,14 @@ eal_parse_common_option(int opt, const char *optarg, return -1; }break ; + +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 :
@@ -2223,6 +2233,7 @@ 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" + " --"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 +5 -0
@@ -515,6 +515,11 @@ eal_log_init(const char *id)#else bool is_terminal =isatty (STDERR_FILENO ); +#ifdef RTE_EXEC_ENV_LINUX +if (log_journal_enabled (id)) + rte_logs.print_func = journal_print; + else +#endif if (log_syslog_enabled (is_terminal))log_syslog_open (id, is_terminal);else
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 +216 -0
216 lines not on this page · raw message
lib/log/log_private.h +4 -0
@@ -18,5 +18,9 @@ int log_print_with_timestamp(FILE *f, uint32_t level, const char *format, va_lisbool log_syslog_enabled (bool is_tty);void log_syslog_open (const char *id,bool is_terminal); +bool log_journal_enabled (const char *id); + +__rte_format_printf(3, 0) +int journal_print (FILE *f,uint32_t level,const char *format,va_list ap);#endif /* LOG_PRIVATE_H */
lib/log/log_stubs.c +6 -0
@@ -26,3 +26,9 @@ eal_log_syslog(const char *str __rte_unused) {return -1 ; } + +int +eal_log_journal(const char *str __rte_unused) +{ +return -1 ; +}
lib/log/meson.build +5 -0
@@ -7,10 +7,15 @@ sources = files( 'log_timestamp.c', ) +if is_linux + sources += files('log_journal.c') +endif + if is_windows sources += files('log_stubs.c') else sources += files('log_syslog.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; eal_log_level2str; eal_log_save_pattern; eal_log_save_regexp;
Signature · 1 line
2.43.0
PATCH v19 15/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 | 16 ++- lib/eal/common/eal_common_options.c | 11 ++ lib/eal/common/eal_options.h | 6 +- lib/log/log.c | 24 +++-- lib/log/log_color.c | 160 ++++++++++++++++++++++++++++ lib/log/log_internal.h | 5 + lib/log/log_private.h | 8 ++ lib/log/meson.build | 2 +- lib/log/version.map | 1 + 10 files changed, 247 insertions(+), 10 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 -1
@@ -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 ~~~~~~~~~~~~~
@@ -115,7 +130,6 @@ There are three possible settings for this option: *always* Always try to direct messages to journal socket. - Using Logging APIs to Generate Log Messages -------------------------------------------
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 ;
@@ -1872,6 +1874,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 ) {
@@ -2240,6 +2250,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 +18 -6
@@ -510,10 +510,14 @@ log_print(FILE *f, uint32_t level __rte_unused, const char *format, va_list ap)void eal_log_init (const char *id) { +bool is_terminal; +#ifdef RTE_EXEC_ENV_WINDOWS RTE_SET_USED (id); + + is_terminal =_isatty (_fileno (stderr));#else -bool is_terminal =isatty (STDERR_FILENO ); + is_terminal =isatty (STDERR_FILENO );#ifdef RTE_EXEC_ENV_LINUX if (log_journal_enabled (id))
@@ -523,11 +527,19 @@ eal_log_init(const char *id)if (log_syslog_enabled (is_terminal))log_syslog_open (id, is_terminal); else -#endif -if (log_timestamp_enabled ()) - rte_logs.print_func = log_print_with_timestamp; -else - rte_logs.print_func = log_print; +#endif /* RTE_EXEC_ENV_WINDOWS */ + +if (log_color_enabled (is_terminal)) { +if (log_timestamp_enabled ()) + rte_logs.print_func = color_print_with_timestamp; +else + rte_logs.print_func = color_print; + }else { +if (log_timestamp_enabled ()) + rte_logs.print_func = log_print_with_timestamp; +else + rte_logs.print_func = log_print; + }#if RTE_LOG_DP_LEVEL >=RTE_LOG_DEBUG RTE_LOG(NOTICE, EAL,
lib/log/log_color.c new file +160 -0
160 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
@@ -23,4 +23,12 @@ bool log_journal_enabled(const char *id); __rte_format_printf(3, 0)int journal_print (FILE *f,uint32_t level,const char *format,va_list ap); +bool log_color_enabled (bool is_tty); + +__rte_format_printf(3, 0) +int color_print (FILE *f,uint32_t level,const char *format,va_list ap); + +__rte_format_printf(3, 0) +int color_print_with_timestamp (FILE *f,uint32_t level,const char *format,va_list ap); +#endif /* LOG_PRIVATE_H */
lib/log/meson.build +1 -1
@@ -4,6 +4,7 @@ includes += global_inc sources = files( 'log.c', + 'log_color.c', 'log_timestamp.c', )
@@ -17,5 +18,4 @@ else sources += files('log_syslog.c') endif - headers = files('rte_log.h')
lib/log/version.map +1 -0
@@ -25,6 +25,7 @@ DPDK_24 { INTERNAL { global: + eal_log_color; eal_log_init; eal_log_journal; eal_log_level2str;
Signature · 1 line
2.43.0
v20 cover Logging unification and 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.
Add myself as maintainer for log because by now have added more than previous authors.
v20 - avoid use vasprintf if possible, because it requires
extra patch for Windows, and increases risk of missed message if malloc pool is corrupted.
- fix build on FreeBSD.
Stephen Hemminger (14):
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
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 | 71 ++++++ lib/eal/common/eal_common_debug.c | 11 +- lib/eal/common/eal_common_options.c | 137 +++++++----- 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 | 80 ++++--- 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 | 34 +++ lib/log/log_stubs.c | 37 +++ lib/log/log_syslog.c | 88 ++++++++ lib/log/log_timestamp.c | 210 ++++++++++++++++++ lib/log/log_windows.c | 18 -- lib/log/meson.build | 14 +- lib/log/version.map | 5 +- 26 files changed, 1097 insertions(+), 378 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_stubs.c 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.43.0
PATCH v20 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
@@ -180,6 +180,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.43.0
PATCH v20 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.43.0
PATCH v20 3/14 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 *timer,struct tm *buf) +{ +if (localtime_s (buf, timer) ==0 ) +return buf; +else +return NULL ; +} +#define localtime_r (timer, buf) rte_localtime_r(timer, buf) +#endif /* _RTE_OS_SHIM_ */
Signature · 1 line
2.43.0
PATCH v20 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 | 46 +++++++++++++++++++++++++++++ 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, 47 insertions(+), 116 deletions(-)
lib/eal/common/eal_common_options.c +46 -0
@@ -1640,6 +1640,51 @@ 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 ; +case '?' : +/* getopt is not happy, stop right now */ + goto out; +default : +continue ; + } + } +out: +/* 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)
@@ -2173,6 +2218,7 @@ rte_vect_set_max_simd_bitwidth(uint16_t bitwidth)return 0 ; } +void eal_common_usage (void ) {
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.43.0
PATCH v20 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 +-- 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.43.0
PATCH v20 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: Cause - Cannot init EAL: Permission denied
--- lib/eal/common/eal_common_debug.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
lib/eal/common/eal_common_debug.c +6 -5
@@ -34,17 +34,18 @@ void rte_exit(int exit_code, const char *format, ...) { va_list ap; +char msg[256 ];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); +vsnprintf (msg,sizeof (msg), format, ap);va_end (ap); +rte_log (RTE_LOG_CRIT ,RTE_LOGTYPE_EAL ,"EAL: Cause - %s" , msg); +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.43.0
PATCH v20 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 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 ;
@@ -1882,7 +1835,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);
@@ -1106,8 +1106,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.43.0
PATCH v20 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_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." );
@@ -565,9 +574,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." );
@@ -952,9 +961,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);
@@ -1106,13 +1112,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.43.0
PATCH v20 9/14 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
@@ -2212,9 +2212,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.43.0
PATCH v20 10/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 | 7 ++++++- lib/log/log_private.h | 9 +++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 lib/log/log_private.h
lib/log/log.c +6 -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
@@ -28,16 +29,19 @@ struct rte_log_dynamic_type {uint32_t loglevel; }; +/** 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 {
@@ -74,6 +78,7 @@ int rte_openlog_stream(FILE *f) { rte_logs.file = f; + rte_logs.print_func = vfprintf;return 0 ; }
@@ -470,7 +475,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.43.0
PATCH v20 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 | 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 | 10 +- 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, 319 insertions(+), 10 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 ;
@@ -1843,7 +1845,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 --"
@@ -1851,7 +1853,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 : {
@@ -2216,6 +2225,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 +7 -3
@@ -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 {
@@ -29,13 +29,13 @@ struct rte_log_dynamic_type {uint32_t loglevel; }; -/** 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 = {
@@ -359,7 +359,6 @@ static const struct logtype logtype_strings[] = { RTE_INIT_PRIO(log_init, LOG) {uint32_t i; -rte_log_set_global_level (RTE_LOG_DEBUG ); rte_logs.dynamic_types = calloc(RTE_LOGTYPE_FIRST_EXT_ID,
@@ -510,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.43.0
PATCH v20 12/14 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 | 25 +++--- lib/log/log_private.h | 4 + lib/log/log_stubs.c | 28 ++++++ lib/log/log_syslog.c | 88 +++++++++++++++++++ lib/log/meson.build | 6 ++ 9 files changed, 164 insertions(+), 41 deletions(-) create mode 100644 lib/log/log_stubs.c 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 },
@@ -2221,6 +2221,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 +14 -11
@@ -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,19 +497,21 @@ 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) { +#ifdef RTE_EXEC_ENV_WINDOWS +RTE_SET_USED (id); +#else +bool is_terminal =isatty (STDERR_FILENO ); + +if (log_syslog_enabled (is_terminal)) +log_syslog_open (id, is_terminal); + else +#endif if (log_timestamp_enabled ()) rte_logs.print_func = log_print_with_timestamp;else
lib/log/log_private.h +4 -0
@@ -17,4 +17,8 @@ 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_syslog_enabled (bool is_tty); +void log_syslog_open (const char *id,bool is_terminal); + +#endif /* LOG_PRIVATE_H */
lib/log/log_stubs.c new file +28 -0
@@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(c) 2010-2014 Intel Corporation +*/ + +#include <stdio.h> +#include <stdint.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <regex.h> +#include <fnmatch.h> +#include <sys/queue.h> +#include <unistd.h> +#include <rte_os_shim.h> + +#include <rte_log.h> +#include <rte_per_lcore.h> + +#include "log_internal.h" +#include "log_private.h" + +/* Stubs for Windows */ +int +eal_log_syslog(const char *str __rte_unused) +{ +return -1 ; +}
lib/log/log_syslog.c new file +88 -0
88 lines not on this page · raw message
lib/log/meson.build +6 -0
@@ -7,4 +7,10 @@ sources = files( 'log_timestamp.c', ) +if is_windows + sources += files('log_stubs.c') +else + sources += files('log_syslog.c') +endif + headers = files('rte_log.h')
Signature · 1 line
2.43.0
PATCH v20 13/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/
--- doc/guides/prog_guide/log_lib.rst | 14 ++ lib/eal/common/eal_common_options.c | 11 ++ lib/eal/common/eal_options.h | 2 + lib/log/log.c | 5 + lib/log/log_internal.h | 3 + lib/log/log_journal.c | 200 ++++++++++++++++++++++++++++ lib/log/log_private.h | 2 + lib/log/log_stubs.c | 11 +- lib/log/meson.build | 10 +- lib/log/version.map | 1 + 10 files changed, 255 insertions(+), 4 deletions(-) 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 +11 -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 ;
@@ -1843,6 +1845,14 @@ eal_parse_common_option(int opt, const char *optarg, return -1; }break ; + +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 :
@@ -2223,6 +2233,7 @@ 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" + " --"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 +5 -0
@@ -508,6 +508,11 @@ eal_log_init(const char *id)#else bool is_terminal =isatty (STDERR_FILENO ); +#ifdef RTE_EXEC_ENV_LINUX +if (log_journal_enabled ()) +log_journal_open (id); + else +#endif if (log_syslog_enabled (is_terminal))log_syslog_open (id, is_terminal);else
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 +2 -0
@@ -20,5 +20,7 @@ int log_print_with_timestamp(FILE *f, const char *format, va_list ap);bool log_syslog_enabled (bool is_tty);void log_syslog_open (const char *id,bool is_terminal); +bool log_journal_enabled (void ); +void log_journal_open (const char *id);#endif /* LOG_PRIVATE_H */
lib/log/log_stubs.c +10 -1
@@ -20,9 +20,18 @@#include "log_internal.h" #include "log_private.h" -/* Stubs for Windows */ +#ifdef RTE_EXEC_ENV_WINDOWS int eal_log_syslog(const char *str __rte_unused) {return -1 ; } +#endif + +#ifndef RTE_EXEC_ENV_LINUX +int +eal_log_journal(const char *str __rte_unused) +{ +return -1 ; +} +#endif
lib/log/meson.build +7 -3
@@ -7,10 +7,14 @@ sources = files( 'log_timestamp.c', ) -if is_windows - sources += files('log_stubs.c') -else +if not is_windows sources += files('log_syslog.c') endif +if is_linux + sources += files('log_journal.c') +else + sources += files('log_stubs.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; eal_log_level2str; eal_log_save_pattern; eal_log_save_regexp;
Signature · 1 line
2.43.0
Re: [PATCH v20 13/14] log: add support for systemd journal
Quoted 11 lines · Stephen Hemminger
If 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/Signed-off-by Stephen Hemminger <[email protected]>
Quoted 13 lines
--- doc/guides/prog_guide/log_lib.rst | 14 ++ lib/eal/common/eal_common_options.c | 11 ++ lib/eal/common/eal_options.h | 2 + lib/log/log.c | 5 + lib/log/log_internal.h | 3 + lib/log/log_journal.c | 200 ++++++++++++++++++++++++++++ lib/log/log_private.h | 2 + lib/log/log_stubs.c | 11 +- lib/log/meson.build | 10 +- lib/log/version.map | 1 + 10 files changed, 255 insertions(+), 4 deletions(-) create mode 100644 lib/log/log_journal.c
This is very nice work, I like it a lot!
Quoted 23 lines
lib/log/log_journal.c new file +23
-0+/* +* send structured message using journal protocol +* See: https://systemd.io/JOURNAL_NATIVE_PROTOCOL/ +*/ +static int +journal_send (const char *buf,size_t len) +{ +struct iovec iov[4 ]; +unsigned int n =0 ; +int priority =rte_log_cur_msg_loglevel () -1 ; +char msg[] ="MESSAGE=" ; +char newline ='\n' ; +char pbuf[16 ];/* "PRIORITY=N\n" */ + + iov[n].iov_base = msg; + iov[n++].iov_len =strlen (msg); + + iov[n].iov_base = (char *)(uintptr_t )buf; + iov[n++].iov_len = len; + +/* if message doesn't end with newline, one will be applied. */ +if (buf[len -1 ] !='\n' ) { + iov[n].iov_base = &newline;
lib/log/log_journal.c line 75
Quoted 10 lines
lib/log/log_journal.c new file +10
-0+ iov[n++].iov_len =1 ; + } + +/* priority value between 0 ("emerg") and 7 ("debug") */ + iov[n].iov_base = pbuf; + iov[n++].iov_len =snprintf (pbuf,sizeof (pbuf), +"PRIORITY=%d\n" , priority); + +return writev (log_journal_fd, iov, n); +}
Doesn't need to be implemented immediately, but the nicest thing about talking directly to the journal is the ability to send lots of arbitrary and useful metadata together with a message, so would be nice if the logging function took an optional string vector that is appended, or some other such mechanism.
A very useful example is creating a UUID and then setting MESSAGE_ID=uuid when logging particularly important messages that are useful to filter by this type - for example, when an interface state changes to up/down. That way, one can do 'journalctl MESSAGE_ID=abc..' and get all messages about interface state changes. A project can also ship a catalog file that adds additional context to each ID, that is automatically parsed and displayed to users.
PATCH v20 14/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.
--- app/test/test_eal_flags.c | 24 +++++ doc/guides/prog_guide/log_lib.rst | 16 ++- lib/eal/common/eal_common_options.c | 11 +++ lib/eal/common/eal_options.h | 6 +- lib/log/log.c | 24 +++-- 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, 235 insertions(+), 9 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 -1
@@ -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 ~~~~~~~~~~~~~
@@ -115,7 +130,6 @@ There are three possible settings for this option: *always* Always try to direct messages to journal socket. - Using Logging APIs to Generate Log Messages -------------------------------------------
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 ;
@@ -1872,6 +1874,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 ) {
@@ -2240,6 +2250,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 +18 -6
@@ -503,10 +503,14 @@ rte_log(uint32_t level, uint32_t logtype, const char *format, ...)void eal_log_init (const char *id) { +bool is_terminal; +#ifdef RTE_EXEC_ENV_WINDOWS RTE_SET_USED (id); + + is_terminal =_isatty (_fileno (stderr));#else -bool is_terminal =isatty (STDERR_FILENO ); + is_terminal =isatty (STDERR_FILENO );#ifdef RTE_EXEC_ENV_LINUX if (log_journal_enabled ())
@@ -516,11 +520,19 @@ eal_log_init(const char *id)if (log_syslog_enabled (is_terminal))log_syslog_open (id, is_terminal); else -#endif -if (log_timestamp_enabled ()) - rte_logs.print_func = log_print_with_timestamp; -else - rte_logs.print_func = vfprintf; +#endif /* RTE_EXEC_ENV_WINDOWS */ + +if (log_color_enabled (is_terminal)) { +if (log_timestamp_enabled ()) + rte_logs.print_func = color_print_with_timestamp; +else + rte_logs.print_func = color_print; + }else { +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,
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
@@ -23,4 +23,12 @@ void log_syslog_open(const char *id, bool is_terminal);bool log_journal_enabled (void );void log_journal_open (const char *id); +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_24 { INTERNAL { global: + eal_log_color; eal_log_init; eal_log_journal; eal_log_level2str;
Signature · 1 line
2.43.0
v21 cover Log library unification ane enhancements
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.
v21 - rebase and clean up a couple of blank lines that snuck in
Stephen Hemminger (14):
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
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 ++++++ lib/eal/common/eal_common_debug.c | 11 +- lib/eal/common/eal_common_options.c | 136 +++++++----- 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 | 80 ++++--- 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 | 34 +++ lib/log/log_stubs.c | 37 +++ lib/log/log_syslog.c | 88 ++++++++ lib/log/log_timestamp.c | 210 ++++++++++++++++++ lib/log/log_windows.c | 18 -- lib/log/meson.build | 14 +- lib/log/version.map | 5 +- 26 files changed, 1097 insertions(+), 378 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_stubs.c 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.43.0
PATCH v21 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
@@ -181,6 +181,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.43.0
RE: [PATCH v21 01/14] maintainers: add for log library
Quoted 9 lines
From: Stephen Hemminger [mailto:[email protected]]
Sent: Tuesday, 4 June 2024 02.45"You touch it you own it"
Add myself as maintainer for log library.Signed-off-by Stephen Hemminger <[email protected]>Acked-by Tyler Retzlaff <[email protected]>---
For the series,
PATCH v21 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.43.0
Re: [PATCH v21 02/14] windows: make getopt functions have const properties
Quoted 5 lines · On Mon, 3 Jun 2024 17:44:50 -0700 Stephen Hemminger…
Having 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.
Quoted 7 lines
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 ofgetopt_long.Signed-off-by Stephen Hemminger <[email protected]>Acked-by Tyler Retzlaff <[email protected]>Acked-by Dmitry Kozlyuk <[email protected]>
Ignore checkpatch complaints about this file.
It is better for the code to not change from the original FreeBSD.
PATCH v21 3/14 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 *timer,struct tm *buf) +{ +if (localtime_s (buf, timer) ==0 ) +return buf; +else +return NULL ; +} +#define localtime_r (timer, buf) rte_localtime_r(timer, buf) +#endif /* _RTE_OS_SHIM_ */
Signature · 1 line
2.43.0
PATCH v21 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 | 45 +++++++++++++++++++++++++++++ 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, 46 insertions(+), 116 deletions(-)
lib/eal/common/eal_common_options.c +45 -0
@@ -1640,6 +1640,51 @@ 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 ; +case '?' : +/* getopt is not happy, stop right now */ + goto out; +default : +continue ; + } + } +out: +/* 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.43.0
PATCH v21 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 +-- 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.43.0
PATCH v21 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: Cause - Cannot init EAL: Permission denied
--- lib/eal/common/eal_common_debug.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
lib/eal/common/eal_common_debug.c +6 -5
@@ -34,17 +34,18 @@ void rte_exit(int exit_code, const char *format, ...) { va_list ap; +char msg[256 ];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); +vsnprintf (msg,sizeof (msg), format, ap);va_end (ap); +rte_log (RTE_LOG_CRIT ,RTE_LOGTYPE_EAL ,"EAL: Cause - %s" , msg); +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.43.0
PATCH v21 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 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 ;
@@ -1882,7 +1835,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);
@@ -1106,8 +1106,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.43.0
PATCH v21 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_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." );
@@ -565,9 +574,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." );
@@ -952,9 +961,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);
@@ -1106,13 +1112,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.43.0
PATCH v21 9/14 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
@@ -2211,9 +2211,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.43.0
Re: [PATCH v21 09/14] log: drop syslog support, and make code common
Quoted 5 lines · On Mon, 3 Jun 2024 17:44:57 -0700 Stephen Hemminger…
This patch makes the log setup code common across all platforms.
Drops syslog support for now, will come back in later patch.
Signed-off-by Stephen Hemminger <[email protected]>
Ignore checkpatch complaints on this patch.
It is better for the test code in test_eal_flags.c to match the existing style, rather than being different because checkpatch wants it to be static.
PATCH v21 10/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 | 7 ++++++- lib/log/log_private.h | 9 +++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 lib/log/log_private.h
lib/log/log.c +6 -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
@@ -28,16 +29,19 @@ struct rte_log_dynamic_type {uint32_t loglevel; }; +/** 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 {
@@ -74,6 +78,7 @@ int rte_openlog_stream(FILE *f) { rte_logs.file = f; + rte_logs.print_func = vfprintf;return 0 ; }
@@ -470,7 +475,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.43.0
PATCH v21 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 | 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 | 10 +- 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, 319 insertions(+), 10 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 ;
@@ -1843,7 +1845,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 --"
@@ -1851,7 +1853,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 +7 -3
@@ -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 {
@@ -29,13 +29,13 @@ struct rte_log_dynamic_type {uint32_t loglevel; }; -/** 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 = {
@@ -359,7 +359,6 @@ static const struct logtype logtype_strings[] = { RTE_INIT_PRIO(log_init, LOG) {uint32_t i; -rte_log_set_global_level (RTE_LOG_DEBUG ); rte_logs.dynamic_types = calloc(RTE_LOGTYPE_FIRST_EXT_ID,
@@ -510,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.43.0
Re: [PATCH v21 11/14] log: add timestamp option
Quoted 20 lines · On Mon, 3 Jun 2024 17:44:59 -0700 Stephen Hemminger…
When 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
Quoted 1 line
Signed-off-by Stephen Hemminger <[email protected]>
Ignore bogus checkpatch warning from this patch. Checkpatch thinks that #include <stdio.h> is a spelling error!
PATCH v21 12/14 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 | 25 +++--- lib/log/log_private.h | 4 + lib/log/log_stubs.c | 28 ++++++ lib/log/log_syslog.c | 88 +++++++++++++++++++ lib/log/meson.build | 6 ++ 9 files changed, 164 insertions(+), 41 deletions(-) create mode 100644 lib/log/log_stubs.c 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 },
@@ -2220,6 +2220,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 +14 -11
@@ -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,19 +497,21 @@ 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) { +#ifdef RTE_EXEC_ENV_WINDOWS +RTE_SET_USED (id); +#else +bool is_terminal =isatty (STDERR_FILENO ); + +if (log_syslog_enabled (is_terminal)) +log_syslog_open (id, is_terminal); + else +#endif if (log_timestamp_enabled ()) rte_logs.print_func = log_print_with_timestamp;else
lib/log/log_private.h +4 -0
@@ -17,4 +17,8 @@ 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_syslog_enabled (bool is_tty); +void log_syslog_open (const char *id,bool is_terminal); + +#endif /* LOG_PRIVATE_H */
lib/log/log_stubs.c new file +28 -0
@@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(c) 2010-2014 Intel Corporation +*/ + +#include <stdio.h> +#include <stdint.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <regex.h> +#include <fnmatch.h> +#include <sys/queue.h> +#include <unistd.h> +#include <rte_os_shim.h> + +#include <rte_log.h> +#include <rte_per_lcore.h> + +#include "log_internal.h" +#include "log_private.h" + +/* Stubs for Windows */ +int +eal_log_syslog(const char *str __rte_unused) +{ +return -1 ; +}
lib/log/log_syslog.c new file +88 -0
88 lines not on this page · raw message
lib/log/meson.build +6 -0
@@ -7,4 +7,10 @@ sources = files( 'log_timestamp.c', ) +if is_windows + sources += files('log_stubs.c') +else + sources += files('log_syslog.c') +endif + headers = files('rte_log.h')
Signature · 1 line
2.43.0
Re: [PATCH v21 12/14] log: add optional support of syslog
Quoted 6 lines · On Mon, 3 Jun 2024 17:45:00 -0700 Stephen Hemminger…
Log 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.
Signed-off-by Stephen Hemminger <[email protected]>---
Ignore checkpatch complaints.
1. The tests should use the same style as other tests.
2. Checkpatch can't figure out code indent correctly with #ifdefs.
3. Checkpatch thinks stdio.h is spelling error.
PATCH v21 13/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/
--- doc/guides/prog_guide/log_lib.rst | 14 ++ lib/eal/common/eal_common_options.c | 11 ++ lib/eal/common/eal_options.h | 2 + lib/log/log.c | 5 + lib/log/log_internal.h | 3 + lib/log/log_journal.c | 200 ++++++++++++++++++++++++++++ lib/log/log_private.h | 2 + lib/log/log_stubs.c | 11 +- lib/log/meson.build | 10 +- lib/log/version.map | 1 + 10 files changed, 255 insertions(+), 4 deletions(-) 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 +11 -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 ;
@@ -1843,6 +1845,14 @@ eal_parse_common_option(int opt, const char *optarg, return -1; }break ; + +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 :
@@ -2222,6 +2232,7 @@ 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" + " --"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 +5 -0
@@ -508,6 +508,11 @@ eal_log_init(const char *id)#else bool is_terminal =isatty (STDERR_FILENO ); +#ifdef RTE_EXEC_ENV_LINUX +if (log_journal_enabled ()) +log_journal_open (id); + else +#endif if (log_syslog_enabled (is_terminal))log_syslog_open (id, is_terminal);else
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 +2 -0
@@ -20,5 +20,7 @@ int log_print_with_timestamp(FILE *f, const char *format, va_list ap);bool log_syslog_enabled (bool is_tty);void log_syslog_open (const char *id,bool is_terminal); +bool log_journal_enabled (void ); +void log_journal_open (const char *id);#endif /* LOG_PRIVATE_H */
lib/log/log_stubs.c +10 -1
@@ -20,9 +20,18 @@#include "log_internal.h" #include "log_private.h" -/* Stubs for Windows */ +#ifdef RTE_EXEC_ENV_WINDOWS int eal_log_syslog(const char *str __rte_unused) {return -1 ; } +#endif + +#ifndef RTE_EXEC_ENV_LINUX +int +eal_log_journal(const char *str __rte_unused) +{ +return -1 ; +} +#endif
lib/log/meson.build +7 -3
@@ -7,10 +7,14 @@ sources = files( 'log_timestamp.c', ) -if is_windows - sources += files('log_stubs.c') -else +if not is_windows sources += files('log_syslog.c') endif +if is_linux + sources += files('log_journal.c') +else + sources += files('log_stubs.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; eal_log_level2str; eal_log_save_pattern; eal_log_save_regexp;
Signature · 1 line
2.43.0
Re: [PATCH v21 13/14] log: add support for systemd journal
Quoted 10 lines · On Mon, 3 Jun 2024 17:45:01 -0700 Stephen Hemminger…
If 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/Signed-off-by Stephen Hemminger <[email protected]>
Same kind of bogus checkpatch warnings:
- stdio.h is not a spelling error
- the indent is correct, just that checkpatch can't handle #ifdef's
PATCH v21 14/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.
--- 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 | 24 +++-- 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, 235 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 ;
@@ -1872,6 +1874,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 ) {
@@ -2239,6 +2249,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 +18 -6
@@ -503,10 +503,14 @@ rte_log(uint32_t level, uint32_t logtype, const char *format, ...)void eal_log_init (const char *id) { +bool is_terminal; +#ifdef RTE_EXEC_ENV_WINDOWS RTE_SET_USED (id); + + is_terminal =_isatty (_fileno (stderr));#else -bool is_terminal =isatty (STDERR_FILENO ); + is_terminal =isatty (STDERR_FILENO );#ifdef RTE_EXEC_ENV_LINUX if (log_journal_enabled ())
@@ -516,11 +520,19 @@ eal_log_init(const char *id)if (log_syslog_enabled (is_terminal))log_syslog_open (id, is_terminal); else -#endif -if (log_timestamp_enabled ()) - rte_logs.print_func = log_print_with_timestamp; -else - rte_logs.print_func = vfprintf; +#endif /* RTE_EXEC_ENV_WINDOWS */ + +if (log_color_enabled (is_terminal)) { +if (log_timestamp_enabled ()) + rte_logs.print_func = color_print_with_timestamp; +else + rte_logs.print_func = color_print; + }else { +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,
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
@@ -23,4 +23,12 @@ void log_syslog_open(const char *id, bool is_terminal);bool log_journal_enabled (void );void log_journal_open (const char *id); +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_24 { INTERNAL { global: + eal_log_color; eal_log_init; eal_log_journal; eal_log_level2str;
Signature · 1 line
2.43.0
Re: [PATCH v21 14/14] log: colorize log output
Quoted 6 lines · On Mon, 3 Jun 2024 17:45:02 -0700 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]>
Yet another valid patch that checkpatch complains about:
1. indent is correct, but it can't see #ifdefs
2. stdio is not a spelling error
3. it doesn't understand that FILE is a type, so it thinks it sees a multiply operator
v22 cover Logging 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.
v22 - rebase, rearrange some code to stifle some checkpatch complaints
and add release notes
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 | 14 ++ lib/eal/common/eal_common_debug.c | 11 +- lib/eal/common/eal_common_options.c | 136 +++++++----- 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 | 83 ++++--- 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 | 33 +++ lib/log/log_stubs.c | 37 +++ lib/log/log_syslog.c | 88 ++++++++ lib/log/log_timestamp.c | 210 ++++++++++++++++++ lib/log/log_windows.c | 18 -- lib/log/meson.build | 13 +- lib/log/version.map | 5 +- 27 files changed, 1113 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_stubs.c 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 v22 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 v22 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 v22 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 *timer,struct tm *buf) +{ +if (localtime_s (buf, timer) ==0 ) +return buf; +else +return NULL ; +} +#define localtime_r (timer, buf) rte_localtime_r(timer, buf) +#endif /* _RTE_OS_SHIM_ */
Signature · 1 line
2.45.2
PATCH v22 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 | 45 +++++++++++++++++++++++++++++ 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, 46 insertions(+), 116 deletions(-)
lib/eal/common/eal_common_options.c +45 -0
@@ -1640,6 +1640,51 @@ 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 ; +case '?' : +/* getopt is not happy, stop right now */ + goto out; +default : +continue ; + } + } +out: +/* 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 v22 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 v22 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: Cause - Cannot init EAL: Permission denied
--- lib/eal/common/eal_common_debug.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
lib/eal/common/eal_common_debug.c +6 -5
@@ -34,17 +34,18 @@ void rte_exit(int exit_code, const char *format, ...) { va_list ap; +char msg[256 ];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); +vsnprintf (msg,sizeof (msg), format, ap);va_end (ap); +rte_log (RTE_LOG_CRIT ,RTE_LOGTYPE_EAL ,"EAL: Cause - %s" , msg); +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 v22 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 ;
@@ -1882,7 +1835,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 v22 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 v22 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
@@ -2211,9 +2211,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 v22 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 v22 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 ;
@@ -1843,7 +1845,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 --"
@@ -1851,7 +1853,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 +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 v22 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 | 3 + lib/log/log_stubs.c | 28 ++++++ lib/log/log_syslog.c | 88 +++++++++++++++++++ lib/log/meson.build | 6 ++ 9 files changed, 166 insertions(+), 41 deletions(-) create mode 100644 lib/log/log_stubs.c 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 },
@@ -2220,6 +2220,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 +17 -11
@@ -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,28 +497,33 @@ 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) { +#ifdef RTE_EXEC_ENV_WINDOWS +RTE_SET_USED (id); +#else +bool is_terminal =isatty (STDERR_FILENO ); + +if (log_syslog_enabled (is_terminal)) { +log_syslog_open (id, is_terminal); + goto notice; + } +#endif if (log_timestamp_enabled ()) rte_logs.print_func = log_print_with_timestamp;else rte_logs.print_func = vfprintf; +notice:#if RTE_LOG_DP_LEVEL >=RTE_LOG_DEBUG RTE_LOG (NOTICE ,EAL ,"Debug dataplane logs available - lower performance\n" );#endif +return ;/* needed for goto target */ }/*
lib/log/log_private.h +3 -0
@@ -17,4 +17,7 @@ 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_syslog_enabled (bool is_tty); +void log_syslog_open (const char *id,bool is_terminal); +#endif /* LOG_PRIVATE_H */
lib/log/log_stubs.c new file +28 -0
@@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(c) 2010-2014 Intel Corporation +*/ + +#include <stdio.h> +#include <stdint.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <regex.h> +#include <fnmatch.h> +#include <sys/queue.h> +#include <unistd.h> +#include <rte_os_shim.h> + +#include <rte_log.h> +#include <rte_per_lcore.h> + +#include "log_internal.h" +#include "log_private.h" + +/* Stubs for Windows */ +int +eal_log_syslog(const char *str __rte_unused) +{ +return -1 ; +}
lib/log/log_syslog.c new file +88 -0
88 lines not on this page · raw message
lib/log/meson.build +6 -0
@@ -7,4 +7,10 @@ sources = files( 'log_timestamp.c', ) +if is_windows + sources += files('log_stubs.c') +else + sources += files('log_syslog.c') +endif + headers = files('rte_log.h')
Signature · 1 line
2.45.2
PATCH v22 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 | 11 ++ lib/eal/common/eal_options.h | 2 + lib/log/log.c | 6 + lib/log/log_internal.h | 3 + lib/log/log_journal.c | 200 ++++++++++++++++++++++++++++ lib/log/log_private.h | 2 + lib/log/log_stubs.c | 11 +- lib/log/meson.build | 3 + lib/log/version.map | 1 + 10 files changed, 252 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 +11 -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 ;
@@ -1843,6 +1845,14 @@ eal_parse_common_option(int opt, const char *optarg, return -1; }break ; + +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 :
@@ -2222,6 +2232,7 @@ 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" + " --"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 +6 -0
@@ -508,6 +508,12 @@ eal_log_init(const char *id)#else bool is_terminal =isatty (STDERR_FILENO ); +#ifdef RTE_EXEC_ENV_LINUX +if (log_journal_enabled ()) { +log_journal_open (id); + goto notice; + } +#endif if (log_syslog_enabled (is_terminal)) {log_syslog_open (id, is_terminal); goto notice;
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 +2 -0
@@ -19,5 +19,7 @@ int log_print_with_timestamp(FILE *f, const char *format, va_list ap);bool log_syslog_enabled (bool is_tty);void log_syslog_open (const char *id,bool is_terminal); +bool log_journal_enabled (void ); +void log_journal_open (const char *id);#endif /* LOG_PRIVATE_H */
lib/log/log_stubs.c +10 -1
@@ -20,9 +20,18 @@#include "log_internal.h" #include "log_private.h" -/* Stubs for Windows */ +#ifdef RTE_EXEC_ENV_WINDOWS int eal_log_syslog(const char *str __rte_unused) {return -1 ; } +#endif + +#ifndef RTE_EXEC_ENV_LINUX +int +eal_log_journal(const char *str __rte_unused) +{ +return -1 ; +} +#endif
lib/log/meson.build +3 -0
@@ -11,6 +11,9 @@ if is_windows sources += files('log_stubs.c') else sources += files('log_syslog.c') +if is_linux + sources += files('log_journal.c') +endif endif headers = files('rte_log.h')
lib/log/version.map +1 -0
@@ -26,6 +26,7 @@ INTERNAL { global: eal_log_init; + eal_log_journal; eal_log_level2str; eal_log_save_pattern; eal_log_save_regexp;
Signature · 1 line
2.45.2
PATCH v22 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 | 25 +++-- 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, 236 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 ;
@@ -1872,6 +1874,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 ) {
@@ -2239,6 +2249,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 +19 -6
@@ -503,10 +503,14 @@ rte_log(uint32_t level, uint32_t logtype, const char *format, ...)void eal_log_init (const char *id) { +bool is_terminal; + #ifdef RTE_EXEC_ENV_WINDOWS RTE_SET_USED(id); + + is_terminal = _isatty(_fileno(stderr)); #else - bool is_terminal = isatty(STDERR_FILENO); + is_terminal = isatty(STDERR_FILENO); #ifdef RTE_EXEC_ENV_LINUX if (log_journal_enabled()) {
@@ -518,11 +522,20 @@ eal_log_init(const char *id)log_syslog_open (id, is_terminal); goto notice; } -#endif -if (log_timestamp_enabled ()) - rte_logs.print_func = log_print_with_timestamp; -else - rte_logs.print_func = vfprintf; + +#endif /* RTE_EXEC_ENV_WINDOWS */ + +if (log_color_enabled (is_terminal)) { +if (log_timestamp_enabled ()) + rte_logs.print_func = color_print_with_timestamp; +else + rte_logs.print_func = color_print; + }else { +if (log_timestamp_enabled ()) + rte_logs.print_func = log_print_with_timestamp; +else + rte_logs.print_func = vfprintf; + } notice: #if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG
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
@@ -22,4 +22,12 @@ void log_syslog_open(const char *id, bool is_terminal);bool log_journal_enabled (void );void log_journal_open (const char *id); +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; eal_log_level2str;
Signature · 1 line
2.45.2
PATCH v22 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 | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
doc/guides/rel_notes/release_24_11.rst +14 -0
@@ -55,6 +55,20 @@ New Features Also, make sure to start the actual text at the margin. ======================================================= +* **Enhancements to logging library.** + + * Log is initialized earlier in startup so all messages go through the log library. + + * Log messages can be timestamped which is useful for debugging startup timing. + + * The log now supports color in the log if going to a terminal device + 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 DPDK is being used by 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 uses syslog the same as Linux. Removed Items -------------
Signature · 1 line
2.45.2
RE: [PATCH v22 15/15] doc: add release note about log library
v23 cover Logging 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.
v23 - simplify and fix Windows and FreeBSD builds; fix #ifdefs.
Change from defining stubs to using inline functions in log_private.h.
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 | 15 ++ lib/eal/common/eal_common_debug.c | 11 +- lib/eal/common/eal_common_options.c | 140 +++++++----- 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, 1096 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 v23 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
Re: [PATCH v23 01/15] maintainers: add for log library
Quoted 22 lines · Stephen Hemminger
"You touch it you own it"
Add myself as maintainer for log library.Signed-off-by Stephen Hemminger <[email protected]>Acked-by Tyler Retzlaff <[email protected]>Acked-by Morten Brørup <[email protected]>--- 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
PATCH v23 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
Re: [PATCH v23 02/15] windows: make getopt functions have const properties
Quoted 13 lines · Stephen Hemminger
Having 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 ofgetopt_long.Signed-off-by Stephen Hemminger <[email protected]>Acked-by Tyler Retzlaff <[email protected]>Acked-by Dmitry Kozlyuk <[email protected]>Acked-by Morten Brørup <[email protected]>
PATCH v23 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 *timer,struct tm *buf) +{ +if (localtime_s (buf, timer) ==0 ) +return buf; +else +return NULL ; +} +#define localtime_r (timer, buf) rte_localtime_r(timer, buf) +#endif /* _RTE_OS_SHIM_ */
Signature · 1 line
2.45.2
Re: [PATCH v23 03/15] windows: add os shim for localtime_r
Quoted 15 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]>--- lib/eal/windows/include/rte_os_shim.h | 10 ++++++++++ 1 file changed, 10 insertions(+)lib/eal/windows/include/rte_os_shim.h +0
-0
lib/eal/windows/include/rte_os_shim.h rte_clock_gettime(clockid_t clock_id, struct timespec *tp) · line 114
Quoted 5 lines
lib/eal/windows/include/rte_os_shim.h +2
-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 *timer,struct tm *buf)
buf always means char *, but this function return struct tm *, suggest:
struct tm *localtime_r(const time_t *timep, struct tm *result)
Quoted 9 lines
lib/eal/windows/include/rte_os_shim.h +8
-0+{ +if (localtime_s (buf, timer) ==0 ) +return buf; +else +return NULL ; +} +#define localtime_r (timer, buf) rte_localtime_r(timer, buf) +#endif /* _RTE_OS_SHIM_ */
Re: [PATCH v23 03/15] windows: add os shim for localtime_r
Quoted 15 lines · On Wed, 18 Sep 2024 15:09:25 +0800 fengchengwen <[email protected]> wrote:
lib/eal/windows/include/rte_os_shim.h rte_clock_gettime(clockid_t clock_id, struct timespec *tp) · line 114
Quoted 10 lines
lib/eal/windows/include/rte_os_shim.h +2
-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 *timer,struct tm *buf)buf always means char *, but this function return struct tm *, suggest:
struct tm *localtime_r(consttime_t*timep, struct tm *result)
Quoted 7 lines
lib/eal/windows/include/rte_os_shim.h rte_clock_gettime(clockid_t clock_id, struct timespec *tp) · line 121
Quoted 7 lines
lib/eal/windows/include/rte_os_shim.h +7
-0+{ +if (localtime_s (buf, timer) ==0 ) +return buf; +else +return NULL ; +} +#define localtime_r (timer, buf) rte_localtime_r(timer, buf)
This is a windows wrapper around the GNU extension localtime_r() so the signature needs to be the same, will change the name of the args to match man page.
struct tm *localtime_r(const time_t *restrict timep,
struct tm *restrict result);
PATCH v23 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 | 45 +++++++++++++++++++++++++++++ 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, 46 insertions(+), 116 deletions(-)
lib/eal/common/eal_common_options.c +45 -0
@@ -1640,6 +1640,51 @@ 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 ; +case '?' : +/* getopt is not happy, stop right now */ + goto out; +default : +continue ; + } + } +out: +/* 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
Re: [PATCH v23 04/15] eal: make eal_log_level_parse common
Quoted 41 lines · Stephen Hemminger
The code to parse for log-level option should be same on all OS variants.
Signed-off-by Stephen Hemminger <[email protected]>Acked-by Tyler Retzlaff <[email protected]>Acked-by Morten Brørup <[email protected]>--- lib/eal/common/eal_common_options.c | 45 +++++++++++++++++++++++++++++ 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, 46 insertions(+), 116 deletions(-)lib/eal/common/eal_common_options.c +19
-0@@ -1640,6 +1640,51 @@ 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,
lib/eal/common/eal_common_options.c eal_parse_huge_unlink(const char *arg, struct hugepage_file_discipline *out) · line 1671
Quoted 10 lines
lib/eal/common/eal_common_options.c +10
-0+ 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 ; +case '?' : +/* getopt is not happy, stop right now */ + goto out;
no need goto, could use break
Quoted 16 lines
lib/eal/common/eal_common_options.c +16
-0+default : +continue ; + } + } +out: +/* 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 ; +} +
...
Re: [PATCH v23 04/15] eal: make eal_log_level_parse common
Quoted 23 lines · On Wed, 18 Sep 2024 15:18:04 +0800 fengchengwen <[email protected]> wrote:
Quoted 23 lines
lib/eal/common/eal_common_options.c +23
-0+/* 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 :
Quoted 8 lines
lib/eal/common/eal_common_options.c eal_parse_huge_unlink(const char *arg, struct hugepage_file_discipline *out) · line 1671
Quoted 6 lines
lib/eal/common/eal_common_options.c +6
-0+if (eal_parse_common_option (opt, optarg, internal_conf) <0 ) +return -1 ; +break ; +case '?' : +/* getopt is not happy, stop right now */ + goto out;no need goto, could use break
This function is only used to pre-scan options, it should just ignore anything it doesn't care about. Can remove the ? case and default part.
PATCH v23 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
Re: [PATCH v23 05/15] eal: do not duplicate rte_init_alert() messages
Quoted 40 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]>--- 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); }/*
PATCH v23 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: Cause - Cannot init EAL: Permission denied
--- lib/eal/common/eal_common_debug.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
lib/eal/common/eal_common_debug.c +6 -5
@@ -34,17 +34,18 @@ void rte_exit(int exit_code, const char *format, ...) { va_list ap; +char msg[256 ];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); +vsnprintf (msg,sizeof (msg), format, ap);va_end (ap); +rte_log (RTE_LOG_CRIT ,RTE_LOGTYPE_EAL ,"EAL: Cause - %s" , msg); +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 v23 06/15] eal: change rte_exit() output to match rte_log()
Quoted 23 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: Cause - Cannot init EAL: Permission deniedSigned-off-by Stephen Hemminger <[email protected]>Acked-by Tyler Retzlaff <[email protected]>Acked-by Morten Brørup <[email protected]>--- lib/eal/common/eal_common_debug.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)lib/eal/common/eal_common_debug.c +0
-0
lib/eal/common/eal_common_debug.c void · line 37
Quoted 4 lines
lib/eal/common/eal_common_debug.c +1
-0@@ -34,17 +34,18 @@ void rte_exit(int exit_code, const char *format, ...) { va_list ap; +char msg[256 ];
the length maybe too short.
lib/eal/common/eal_common_debug.c void · line 43
Quoted 9 lines
lib/eal/common/eal_common_debug.c +2
-3if (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); +vsnprintf (msg,sizeof (msg), format, ap);
should handle the vsnprintf return negative value.
Quoted 10 lines
lib/eal/common/eal_common_debug.c +3
-2va_end (ap); +rte_log (RTE_LOG_CRIT ,RTE_LOGTYPE_EAL ,"EAL: Cause - %s" , msg); +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 v23 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 ;
@@ -1882,7 +1835,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
Re: [PATCH v23 07/15] log: move handling of syslog facility out of eal
Quoted 6 lines · Stephen Hemminger
The 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.
Signed-off-by Stephen Hemminger <[email protected]>Acked-by Morten Brørup <[email protected]>
PATCH v23 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
Re: [PATCH v23 08/15] eal: initialize log before everything else
Quoted 12 lines · Stephen Hemminger
In 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.
Signed-off-by Stephen Hemminger <[email protected]>Acked-by Tyler Retzlaff <[email protected]>Acked-by Morten Brørup <[email protected]>
PATCH v23 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
@@ -2211,9 +2211,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 v23 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
Re: [PATCH v23 10/15] log: add hook for printing log messages
Quoted 5 lines · Stephen Hemminger
This is useful for when decorating log output for console or journal. Provide basic version in this patch.
Signed-off-by Stephen Hemminger <[email protected]>Acked-by Morten Brørup <[email protected]>
PATCH v23 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 ;
@@ -1843,7 +1845,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 --"
@@ -1851,7 +1853,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 +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
Re: [PATCH v23 11/15] log: add timestamp option
Quoted 20 lines · Stephen Hemminger
When 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
...
lib/log/log_timestamp.c line 27
Quoted 8 lines
lib/log/log_timestamp.c new file +8
-0+ +static enum { + LOG_TIMESTAMP_NONE = 0, + LOG_TIMESTAMP_TIME, /* time since start */ + LOG_TIMESTAMP_DELTA, /* time since last message */ + LOG_TIMESTAMP_RELTIME, /* relative time since last message */ + LOG_TIMESTAMP_CTIME, /* Unix standard time format */ + LOG_TIMESTAMP_ISO, /* ISO8601 time format */
Some of the impl should consider multiple-thread safety.
And for multiple-process, how about the secondary-processes align the main-process.
Re: [PATCH v23 11/15] log: add timestamp option
Quoted 13 lines · On Wed, 18 Sep 2024 15:37:49 +0800 fengchengwen <[email protected]> wrote:
...
lib/log/log_timestamp.c line 27
Quoted 8 lines
lib/log/log_timestamp.c new file +8
-0+ +static enum { + LOG_TIMESTAMP_NONE = 0, + LOG_TIMESTAMP_TIME, /* time since start */ + LOG_TIMESTAMP_DELTA, /* time since last message */ + LOG_TIMESTAMP_RELTIME, /* relative time since last message */ + LOG_TIMESTAMP_CTIME, /* Unix standard time format */ + LOG_TIMESTAMP_ISO, /* ISO8601 time format */Some of the impl should consider multiple-thread safety.
Quoted 1 line
And for multiple-process, how about the secondary-processes align the main-process.
As much as possible, they are thread safe, that is why locatime_r is used. Of course if multiple threads are printing it is possible that time stamps could be out of order. I.e CPU A got timestamp and is formatting message, and CPU B got timestamp is formatting message. The formatting might take longer for A.
Re: [PATCH v23 11/15] log: add timestamp option
Quoted 16 lines · Stephen Hemminger
Quoted 13 lines · On Wed, 18 Sep 2024 15:37:49 +0800 fengchengwen <[email protected]> wrote:
...
lib/log/log_timestamp.c line 27
Quoted 8 lines
lib/log/log_timestamp.c new file +8
-0+ +static enum { + LOG_TIMESTAMP_NONE = 0, + LOG_TIMESTAMP_TIME, /* time since start */ + LOG_TIMESTAMP_DELTA, /* time since last message */ + LOG_TIMESTAMP_RELTIME, /* relative time since last message */ + LOG_TIMESTAMP_CTIME, /* Unix standard time format */ + LOG_TIMESTAMP_ISO, /* ISO8601 time format */Some of the impl should consider multiple-thread safety.
Quoted 7 lines
Quoted 1 line
And for multiple-process, how about the secondary-processes align the main-process.
As much as possible, they are thread safe, that is why
locatime_ris used. Of course if multiple threads are printing it is possible that time stamps could be out of order. I.e CPU A got timestamp and is formatting message, and CPU B got timestamp is formatting message. The formatting might take longer for A.
Yes, the localtime_r is thread safe, but like delta, multi thread will both read and update global variable log_time.previous with any sync, this may lead problem. static struct {
struct timespec started; /* when log was initialized */
struct timespec previous; /* when last msg was printed */
} log_time;
e.g.
1, the previous tv_sec = 1000, tv_nsec = 90000;
2, thread A invoke log, and current tv_sec = 2000, tv_nsec = 10000; it will update the previous
3, thread B also invoke log, and current tv_sec = 2000, tv_nsec = 10001, but it read previous is tv_sec = 2000, tv_nsec = 90000
and the delta will invalid.
PATCH v23 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 },
@@ -2220,6 +2220,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
Re: [PATCH v23 12/15] log: add optional support of syslog
Quoted 6 lines · Stephen Hemminger
Log 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.
Signed-off-by Stephen Hemminger <[email protected]>Acked-by Morten Brørup <[email protected]>