eal: add option to put timestamp on console output
PATCH 1/1 eal: add option to put timestamp on console output
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. The timestamp format is chosen to look like the default Linux dmesg timestamp.
Example:
[ 0.000040] EAL: Probing VFIO support...
--- doc/guides/linux_gsg/linux_eal_parameters.rst | 5 +++ lib/librte_eal/common/eal_common_options.c | 5 +++ lib/librte_eal/common/eal_internal_cfg.h | 1 + lib/librte_eal/common/eal_options.h | 2 + lib/librte_eal/linux/eal_log.c | 41 +++++++++++++++++-- 5 files changed, 51 insertions(+), 3 deletions(-)
doc/guides/linux_gsg/linux_eal_parameters.rst +5 -0
@@ -118,3 +118,8 @@ Other options local5 local6 local7 + +* ``--log-timestamp`` + + Add a timestamp of seconds and microseconds to each log message + written to standard output.
lib/librte_eal/common/eal_common_options.c +5 -0
@@ -76,6 +76,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, 0, 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 },
@@ -1626,6 +1627,9 @@ eal_parse_common_option(int opt, const char *optarg, }break ; } +case OPT_LOG_TIMESTAMP_NUM : + conf->log_timestamp =1 ; +break ;#ifndef RTE_EXEC_ENV_WINDOWS case OPT_TRACE_NUM : {
@@ -1945,6 +1949,7 @@ eal_common_usage(void) " --"OPT_PROC_TYPE" Type of this process (primary|secondary|auto)\n" #ifndef RTE_EXEC_ENV_WINDOWS " --"OPT_SYSLOG" Set syslog facility\n" + " --"OPT_LOG_TIMESTAMP" Timestamp log output\n" #endif" --" OPT_LOG_LEVEL "=<int> Set global log level\n" " --" OPT_LOG_LEVEL "=<type-match>:<int>\n"
lib/librte_eal/common/eal_internal_cfg.h +1 -0
@@ -70,6 +70,7 @@ struct internal_config {* per-node) non-legacy mode only. */ volatile int syslog_facility;/**< facility passed to openlog() */ +volatile uint8_t log_timestamp;/**< add timestamp to console output */ /** default interrupt mode for VFIO */ volatile enum rte_intr_mode vfio_intr_mode;/** the shared VF token for VFIO-PCI bound PF and VFs devices */
lib/librte_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/librte_eal/linux/eal_log.c +38 -3
70 lines not on this page · raw message
Signature · 1 line
2.27.0
Quoted 17 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. The timestamp format is chosen to look like the default Linux dmesg timestamp.
Example:
[ 0.000040] EAL: Probing VFIO support...Signed-off-by Stephen Hemminger <[email protected]>--- doc/guides/linux_gsg/linux_eal_parameters.rst | 5 +++ lib/librte_eal/common/eal_common_options.c | 5 +++ lib/librte_eal/common/eal_internal_cfg.h | 1 + lib/librte_eal/common/eal_options.h | 2 + lib/librte_eal/linux/eal_log.c | 41 +++++++++++++++++-- 5 files changed, 51 insertions(+), 3 deletions(-)
[snip]
lib/librte_eal/common/eal_common_options.c eal_common_usage(void) · line 1953
Quoted 6 lines
lib/librte_eal/common/eal_common_options.c +1
-0@@ -1945,6 +1949,7 @@ eal_common_usage(void)" --" OPT_PROC_TYPE " Type of this process (primary|secondary|auto)\n" #ifndef RTE_EXEC_ENV_WINDOWS" --" OPT_SYSLOG " Set syslog facility\n" +" --" OPT_LOG_TIMESTAMP " Timestamp log output\n" #endif
Seems like FreeBSD doesn't support this option as well.
It is clear that iovec approach saves a syscall on each write, but is it worth implementing log timestamps on each platform instead of prepending it in common code (with a second fwrite call)? For fast event stream with precise timestamps, there is tracing framework.
Quoted 29 lines · On Fri, 14 Aug 2020 21:39:29 +0300 Dmitry Kozlyuk <[email protected]>…
Quoted 17 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. The timestamp format is chosen to look like the default Linux dmesg timestamp.
Example:
[ 0.000040] EAL: Probing VFIO support...Signed-off-by Stephen Hemminger <[email protected]>--- doc/guides/linux_gsg/linux_eal_parameters.rst | 5 +++ lib/librte_eal/common/eal_common_options.c | 5 +++ lib/librte_eal/common/eal_internal_cfg.h | 1 + lib/librte_eal/common/eal_options.h | 2 + lib/librte_eal/linux/eal_log.c | 41 +++++++++++++++++-- 5 files changed, 51 insertions(+), 3 deletions(-)[snip]
lib/librte_eal/common/eal_common_options.c eal_common_usage(void) · line 1953
Quoted 6 lines
lib/librte_eal/common/eal_common_options.c +1
-0@@ -1945,6 +1949,7 @@ eal_common_usage(void)" --" OPT_PROC_TYPE " Type of this process (primary|secondary|auto)\n" #ifndef RTE_EXEC_ENV_WINDOWS" --" OPT_SYSLOG " Set syslog facility\n" +" --" OPT_LOG_TIMESTAMP " Timestamp log output\n" #endifSeems like FreeBSD doesn't support this option as well.
Quoted 4 lines
It is clear that iovec approach saves a syscall on each write, but is it worth implementing log timestamps on each platform instead of prepending it in common code (with a second fwrite call)? For fast event stream with precise timestamps, there is tracing framework.
FreeBsd doesn't go through the same log code.
Iovec is to keep timestamp and message as an atomic message. There is no good way to use fwrite to get anything atomic.
Fwrite is unnecessary here anyway saving a copy and avoid issues with library getting corrupted is good.
Quoted 2 lines · Stephen Hemminger
On Fri, 14 Aug 2020 21:39:29 +0300
Dmitry Kozlyuk <[email protected]> wrote:
[...]
Quoted 1 line
FreeBsd doesn't go through the same log code.
Then --log-timestamp shouldn't appear on FreeBSD if it's unsupported.
Quoted 4 lines
Iovec is to keep timestamp and message as an atomic message. There is no good way to use fwrite to get anything atomic.
Fwrite is unnecessary here anyway saving a copy and avoid issues with library getting corrupted is good.
Got it, thanks.
Quoted 7 lines · On Fri, 14 Aug 2020 22:09:11 +0300 Dmitry Kozlyuk <[email protected]>…
Quoted 2 lines · Stephen Hemminger
On Fri, 14 Aug 2020 21:39:29 +0300
Dmitry Kozlyuk <[email protected]> wrote:[...]
Quoted 1 line
FreeBsd doesn't go through the same log code.
Then --log-timestamp shouldn't appear on FreeBSD if it's unsupported.
Was using same ifdef that is already there. There are several options already (like syslog facility) which do nothing on FreeBSD anyway.
Quoted 7 lines
Quoted 5 lines
Iovec is to keep timestamp and message as an atomic message. There is no good way to use fwrite to get anything atomic.
Fwrite is unnecessary here anyway saving a copy and avoid issues with library getting corrupted is good.Got it, thanks.
Quoted 6 lines · Stephen Hemminger
Quoted 3 lines · On Fri, 14 Aug 2020 22:09:11 +0300 Dmitry Kozlyuk <[email protected]>…
Quoted 2 lines · Stephen Hemminger
On Fri, 14 Aug 2020 21:39:29 +0300
Dmitry Kozlyuk <[email protected]> wrote:
Quoted 8 lines
Quoted 4 lines
[...]
Quoted 1 line
FreeBsd doesn't go through the same log code.
Then --log-timestamp shouldn't appear on FreeBSD if it's unsupported.
Was using same ifdef that is already there. There are several options already (like syslog facility) which do nothing on FreeBSD anyway.
While that is correct, I think that we really should support this on FreeBSD also, since I don't think there is any technical reason we can't do so, right? Even a sub-optimal solution where the timestamp write and log write are non-atomic would be better than nothing.
/Bruce
Quoted 15 lines · On Mon, 17 Aug 2020 11:37:40 +0100 Bruce Richardson…
Quoted 6 lines · Stephen Hemminger
Quoted 3 lines · On Fri, 14 Aug 2020 22:09:11 +0300 Dmitry Kozlyuk <[email protected]>…
Quoted 2 lines · Stephen Hemminger
On Fri, 14 Aug 2020 21:39:29 +0300
Dmitry Kozlyuk <[email protected]> wrote:Quoted 8 lines
Quoted 4 lines
[...]
Quoted 1 line
FreeBsd doesn't go through the same log code.
Then --log-timestamp shouldn't appear on FreeBSD if it's unsupported.
Was using same ifdef that is already there. There are several options already (like syslog facility) which do nothing on FreeBSD anyway.
Quoted 6 lines
While that is correct, I think that we really should support this on FreeBSD also, since I don't think there is any technical reason we can't do so, right? Even a sub-optimal solution where the timestamp write and log write are non-atomic would be better than nothing.
/Bruce
FreeBSD now just uses default log stream (stdout). Linux has log stream to syslog and stdout.
There is nothing Linux specific in the old or new code.
The Linux code could just be moved to common, and both could use it.
That is a separate patch, and someone with expertise and build setup for FreeBSD needs to do it.
There was no ack or conclusion for this patch.
17/08/2020 17:11, Stephen Hemminger:
Quoted 32 lines
Quoted 15 lines · On Mon, 17 Aug 2020 11:37:40 +0100 Bruce Richardson…
Quoted 6 lines · Stephen Hemminger
Quoted 3 lines · On Fri, 14 Aug 2020 22:09:11 +0300 Dmitry Kozlyuk <[email protected]>…
Quoted 2 lines · Stephen Hemminger
On Fri, 14 Aug 2020 21:39:29 +0300
Dmitry Kozlyuk <[email protected]> wrote:Quoted 8 lines
Quoted 4 lines
[...]
Quoted 1 line
FreeBsd doesn't go through the same log code.
Then --log-timestamp shouldn't appear on FreeBSD if it's unsupported.
Was using same ifdef that is already there. There are several options already (like syslog facility) which do nothing on FreeBSD anyway.
Quoted 6 lines
While that is correct, I think that we really should support this on FreeBSD also, since I don't think there is any technical reason we can't do so, right? Even a sub-optimal solution where the timestamp write and log write are non-atomic would be better than nothing.
/Bruce
FreeBSD now just uses default log stream (stdout). Linux has log stream to syslog and stdout.
There is nothing Linux specific in the old or new code.
The Linux code could just be moved to common, and both could use it.
That is a separate patch, and someone with expertise and build setup for FreeBSD needs to do it.
Quoted 35 lines · On Mon, 19 Oct 2020 16:11:19 +0200 Thomas Monjalon <[email protected]> wrote:
There was no ack or conclusion for this patch.
17/08/2020 17:11, Stephen Hemminger:
Quoted 32 lines
Quoted 15 lines · On Mon, 17 Aug 2020 11:37:40 +0100 Bruce Richardson…
Quoted 6 lines · Stephen Hemminger
Quoted 3 lines · On Fri, 14 Aug 2020 22:09:11 +0300 Dmitry Kozlyuk <[email protected]>…
Quoted 2 lines · Stephen Hemminger
On Fri, 14 Aug 2020 21:39:29 +0300
Dmitry Kozlyuk <[email protected]> wrote:Quoted 8 lines
Quoted 4 lines
[...]
Quoted 1 line
FreeBsd doesn't go through the same log code.
Then --log-timestamp shouldn't appear on FreeBSD if it's unsupported.
Was using same ifdef that is already there. There are several options already (like syslog facility) which do nothing on FreeBSD anyway.
Quoted 6 lines
While that is correct, I think that we really should support this on FreeBSD also, since I don't think there is any technical reason we can't do so, right? Even a sub-optimal solution where the timestamp write and log write are non-atomic would be better than nothing.
/Bruce
FreeBSD now just uses default log stream (stdout). Linux has log stream to syslog and stdout.
There is nothing Linux specific in the old or new code.
The Linux code could just be moved to common, and both could use it.
That is a separate patch, and someone with expertise and build setup for FreeBSD needs to do it.
Lets fix FreeBSD to use common code for logging, then timestamp option can be added?
19/10/2020 17:25, Stephen Hemminger:
Quoted 34 lines
Quoted 31 lines · On Mon, 19 Oct 2020 16:11:19 +0200 Thomas Monjalon <[email protected]> wrote:
There was no ack or conclusion for this patch.
17/08/2020 17:11, Stephen Hemminger:
Quoted 28 lines
Quoted 15 lines · On Mon, 17 Aug 2020 11:37:40 +0100 Bruce Richardson…
Quoted 6 lines · Stephen Hemminger
Quoted 3 lines · On Fri, 14 Aug 2020 22:09:11 +0300 Dmitry Kozlyuk <[email protected]>…
Quoted 2 lines · Stephen Hemminger
On Fri, 14 Aug 2020 21:39:29 +0300
Dmitry Kozlyuk <[email protected]> wrote:Quoted 8 lines
Quoted 4 lines
[...]
Quoted 1 line
FreeBsd doesn't go through the same log code.
Then --log-timestamp shouldn't appear on FreeBSD if it's unsupported.
Was using same ifdef that is already there. There are several options already (like syslog facility) which do nothing on FreeBSD anyway.
Quoted 6 lines
While that is correct, I think that we really should support this on FreeBSD also, since I don't think there is any technical reason we can't do so, right? Even a sub-optimal solution where the timestamp write and log write are non-atomic would be better than nothing.
/Bruce
FreeBSD now just uses default log stream (stdout). Linux has log stream to syslog and stdout.
Quoted 6 lines
Quoted 4 lines
Quoted 4 lines
There is nothing Linux specific in the old or new code.
The Linux code could just be moved to common, and both could use it.
That is a separate patch, and someone with expertise and build setup for FreeBSD needs to do it.Lets fix FreeBSD to use common code for logging, then timestamp option can be added?
OK
v2 cover Add option to timestamp console log
In reply to Stephen HemmingerThis is a reprise of earlier patch to add timestamp to console messages.
Example:
# dpdk-testpmd -l 1-4 -n 4 --vdev net_null0 --log-timestamp -- -i EAL: Detected CPU lcores: 16 EAL: Detected NUMA nodes: 1 EAL: Detected static linkage of DPDK EAL: Multi-process socket /var/run/dpdk/rte/mp_socket EAL: Selected IOVA mode 'VA' Interactive-mode selected [ 0.191407] testpmd: create a new mbuf pool <mb_pool_0>: n=171456, size=2176, socket=0 [ 0.191510] testpmd: preferred mempool ops selected: ring_mp_mc
v2
- rebase to current DPDK
- make linux log code common to freebsd
Stephen Hemminger (2):
eal: unify logging code for FreeBsd and Linux
eal: add option to put timestamp on console output
.../freebsd_gsg/freebsd_eal_parameters.rst | 32 ++++++ doc/guides/linux_gsg/linux_eal_parameters.rst | 5 + lib/eal/common/eal_common_options.c | 5 + lib/eal/common/eal_internal_cfg.h | 1 + lib/eal/common/eal_options.h | 2 + lib/eal/freebsd/eal.c | 6 ++ lib/eal/linux/eal_log.c | 61 ------------ lib/eal/linux/meson.build | 1 - lib/eal/unix/eal_log.c | 97 +++++++++++++++++++ lib/eal/unix/meson.build | 1 + 10 files changed, 149 insertions(+), 62 deletions(-) delete mode 100644 lib/eal/linux/eal_log.c create mode 100644 lib/eal/unix/eal_log.c
Signature · 1 line
2.39.2
PATCH v2 1/2 eal: unify logging code for FreeBsd and Linux
FreeBSD logging code was not using syslog and did not have the same options as Linux. Move the log writing code to common tree.
---
lib/eal/freebsd/eal.c | 6 ++++++
lib/eal/linux/meson.build | 1 -
lib/eal/{linux => unix}/eal_log.c | 0
lib/eal/unix/meson.build | 1 +
4 files changed, 7 insertions(+), 1 deletion(-)
rename lib/eal/{linux => unix}/eal_log.c (100%)lib/eal/freebsd/eal.c +6 -0
@@ -744,6 +744,12 @@ rte_eal_init(int argc, char **argv)#endif } +if (eal_log_init (logid, internal_conf->syslog_facility) <0 ) { +rte_eal_init_alert ("Cannot init logging." ); + rte_errno =ENOMEM ; +return -1 ; + } +/* in secondary processes, memory init may allocate additional fbarrays * not present in primary processes, so to avoid any potential issues, * initialize memzones first.
lib/eal/linux/meson.build +0 -1
@@ -11,7 +11,6 @@ sources += files( 'eal_hugepage_info.c', 'eal_interrupts.c', 'eal_lcore.c', - 'eal_log.c', 'eal_memalloc.c', 'eal_memory.c', 'eal_thread.c',
lib/eal/unix/eal_log.c renamed from lib/eal/linux/eal_log.c +0 -0
lib/eal/unix/meson.build +1 -0
@@ -6,6 +6,7 @@ sources += files( 'eal_file.c', 'eal_filesystem.c', 'eal_firmware.c', + 'eal_log.c', 'eal_unix_memory.c', 'eal_unix_thread.c', 'eal_unix_timer.c',
Signature · 1 line
2.39.2
PATCH v2 2/2 eal: add option to put timestamp on console output
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. The timestamp format was chosen to be the same as the default Linux dmesg timestamp.
The messages are written using writev() which avoids unnecessary buffering and ensures that if multiple threads are logging at the same time that timestamp and message buffer don't get interleaved.
Example:
[ 0.000040] EAL: Probing VFIO support...
--- .../freebsd_gsg/freebsd_eal_parameters.rst | 32 ++++++++++++++ doc/guides/linux_gsg/linux_eal_parameters.rst | 5 +++ lib/eal/common/eal_common_options.c | 5 +++ lib/eal/common/eal_internal_cfg.h | 1 + lib/eal/common/eal_options.h | 2 + lib/eal/unix/eal_log.c | 42 +++++++++++++++++-- 6 files changed, 84 insertions(+), 3 deletions(-)
doc/guides/freebsd_gsg/freebsd_eal_parameters.rst +32 -0
@@ -18,3 +18,35 @@ FreeBSD-specific EAL parameters ------------------------------- There are currently no FreeBSD-specific EAL command-line parameters available. + +Other options +~~~~~~~~~~~~~ + +* ``--syslog <syslog facility>`` + + Set syslog facility. Valid syslog facilities are:: + + auth + cron + daemon + ftp + kern + lpr + mail + news + syslog + user + uucp + local0 + local1 + local2 + local3 + local4 + local5 + local6 + local7 + +* ``--log-timestamp`` + + Add a timestamp of seconds and microseconds to each log message + written to standard output.
doc/guides/linux_gsg/linux_eal_parameters.rst +5 -0
@@ -135,3 +135,8 @@ Other options local5 local6 local7 + +* ``--log-timestamp`` + + Add a timestamp of seconds and microseconds to each log message + written to standard output.
lib/eal/common/eal_common_options.c +5 -0
@@ -76,6 +76,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, 0, 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 },
@@ -1833,6 +1834,9 @@ eal_parse_common_option(int opt, const char *optarg, }break ; } +case OPT_LOG_TIMESTAMP_NUM : + conf->log_timestamp =1 ; +break ;#ifndef RTE_EXEC_ENV_WINDOWS case OPT_TRACE_NUM : {
@@ -2194,6 +2198,7 @@ eal_common_usage(void) " --"OPT_PROC_TYPE" Type of this process (primary|secondary|auto)\n" #ifndef RTE_EXEC_ENV_WINDOWS " --"OPT_SYSLOG" Set syslog facility\n" + " --"OPT_LOG_TIMESTAMP" Timestamp log output\n" #endif" --" OPT_LOG_LEVEL "=<level> Set global log level\n" " --" OPT_LOG_LEVEL "=<type-match>:<level>\n"
lib/eal/common/eal_internal_cfg.h +1 -0
@@ -85,6 +85,7 @@ struct internal_config {* per-node) non-legacy mode only. */ volatile int syslog_facility;/**< facility passed to openlog() */ +volatile uint8_t log_timestamp;/**< add timestamp to console output */ /** default interrupt mode for VFIO */ volatile enum rte_intr_mode vfio_intr_mode;/** the shared VF token for VFIO-PCI bound PF and VFs devices */
lib/eal/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/unix/eal_log.c +39 -3
67 lines not on this page · raw message
Signature · 1 line
2.39.2
Re: [PATCH v2 0/2] Add option to timestamp console log
In reply to Stephen HemmingerQuoted 15 lines · Stephen Hemminger
This is a reprise of earlier patch to add timestamp to console messages.
Example:
# dpdk-testpmd -l 1-4 -n 4 --vdev net_null0 --log-timestamp -- -i EAL: Detected CPU lcores: 16 EAL: Detected NUMA nodes: 1 EAL: Detected static linkage of DPDK EAL: Multi-process socket /var/run/dpdk/rte/mp_socket EAL: Selected IOVA mode 'VA' Interactive-mode selected [ 0.191407] testpmd: create a new mbuf pool <mb_pool_0>: n=171456, size=2176, socket=0 [ 0.191510] testpmd: preferred mempool ops selected: ring_mp_mc
Quoted 8 lines
v2
- rebase to current DPDK
- make linux log code common to freebsdStephen Hemminger (2):
eal: unify logging code for FreeBsd and Linux
eal: add option to put timestamp on console output
v3 cover Add option to timestamp console log
In reply to Stephen HemmingerThis is a reprise of earlier patch to add timestamp to console messages.
Example:
# dpdk-testpmd -l 1-4 -n 4 --vdev net_null0 --log-timestamp -- -i EAL: Detected CPU lcores: 16 EAL: Detected NUMA nodes: 1 EAL: Detected static linkage of DPDK EAL: Multi-process socket /var/run/dpdk/rte/mp_socket EAL: Selected IOVA mode 'VA' Interactive-mode selected [ 0.191407] testpmd: create a new mbuf pool <mb_pool_0>: n=171456, size=2176, socket=0 [ 0.191510] testpmd: preferred mempool ops selected: ring_mp_mc
v3 - fix log init on FreeBSD
v2
- rebase to current DPDK
- make linux log code common to freebsd
Stephen Hemminger (2):
eal: unify logging code for FreeBsd and Linux
eal: add option to put timestamp on console output
.../freebsd_gsg/freebsd_eal_parameters.rst | 32 ++++++ doc/guides/linux_gsg/linux_eal_parameters.rst | 5 + lib/eal/common/eal_common_options.c | 5 + lib/eal/common/eal_internal_cfg.h | 1 + lib/eal/common/eal_options.h | 2 + lib/eal/freebsd/eal.c | 7 ++ lib/eal/linux/eal_log.c | 61 ------------ lib/eal/linux/meson.build | 1 - lib/eal/unix/eal_log.c | 97 +++++++++++++++++++ lib/eal/unix/meson.build | 1 + 10 files changed, 150 insertions(+), 62 deletions(-) delete mode 100644 lib/eal/linux/eal_log.c create mode 100644 lib/eal/unix/eal_log.c
Signature · 1 line
2.39.2
PATCH v3 1/2 eal: unify logging code for FreeBsd and Linux
FreeBSD logging code was not using syslog and did not have the same options as Linux. Move the log writing code to common tree.
---
lib/eal/freebsd/eal.c | 7 +++++++
lib/eal/linux/meson.build | 1 -
lib/eal/{linux => unix}/eal_log.c | 0
lib/eal/unix/meson.build | 1 +
4 files changed, 8 insertions(+), 1 deletion(-)
rename lib/eal/{linux => unix}/eal_log.c (100%)lib/eal/freebsd/eal.c +7 -0
@@ -51,6 +51,7 @@#include "eal_hugepages.h" #include "eal_options.h" #include "eal_memcfg.h" +#include "eal_log.h" #include "eal_trace.h" #define MEMSIZE_IF_NO_HUGE_PAGE (64ULL * 1024ULL * 1024ULL)
@@ -744,6 +745,12 @@ rte_eal_init(int argc, char **argv)#endif } +if (eal_log_init (getprogname (), internal_conf->syslog_facility) <0 ) { +rte_eal_init_alert ("Cannot init logging." ); + rte_errno =ENOMEM ; +return -1 ; + } +/* in secondary processes, memory init may allocate additional fbarrays * not present in primary processes, so to avoid any potential issues, * initialize memzones first.
lib/eal/linux/meson.build +0 -1
@@ -11,7 +11,6 @@ sources += files( 'eal_hugepage_info.c', 'eal_interrupts.c', 'eal_lcore.c', - 'eal_log.c', 'eal_memalloc.c', 'eal_memory.c', 'eal_thread.c',
lib/eal/unix/eal_log.c renamed from lib/eal/linux/eal_log.c +0 -0
lib/eal/unix/meson.build +1 -0
@@ -6,6 +6,7 @@ sources += files( 'eal_file.c', 'eal_filesystem.c', 'eal_firmware.c', + 'eal_log.c', 'eal_unix_memory.c', 'eal_unix_thread.c', 'eal_unix_timer.c',
Signature · 1 line
2.39.2
PATCH v3 2/2 eal: add option to put timestamp on console output
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. The timestamp format is chosen to look like the default Linux dmesg timestamp.
Example:
[ 0.000040] EAL: Probing VFIO support...
--- .../freebsd_gsg/freebsd_eal_parameters.rst | 32 ++++++++++++++ doc/guides/linux_gsg/linux_eal_parameters.rst | 5 +++ lib/eal/common/eal_common_options.c | 5 +++ lib/eal/common/eal_internal_cfg.h | 1 + lib/eal/common/eal_options.h | 2 + lib/eal/unix/eal_log.c | 42 +++++++++++++++++-- 6 files changed, 84 insertions(+), 3 deletions(-)
doc/guides/freebsd_gsg/freebsd_eal_parameters.rst +32 -0
@@ -18,3 +18,35 @@ FreeBSD-specific EAL parameters ------------------------------- There are currently no FreeBSD-specific EAL command-line parameters available. + +Other options +~~~~~~~~~~~~~ + +* ``--syslog <syslog facility>`` + + Set syslog facility. Valid syslog facilities are:: + + auth + cron + daemon + ftp + kern + lpr + mail + news + syslog + user + uucp + local0 + local1 + local2 + local3 + local4 + local5 + local6 + local7 + +* ``--log-timestamp`` + + Add a timestamp of seconds and microseconds to each log message + written to standard output.
doc/guides/linux_gsg/linux_eal_parameters.rst +5 -0
@@ -135,3 +135,8 @@ Other options local5 local6 local7 + +* ``--log-timestamp`` + + Add a timestamp of seconds and microseconds to each log message + written to standard output.
lib/eal/common/eal_common_options.c +5 -0
@@ -76,6 +76,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, 0, 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 },
@@ -1833,6 +1834,9 @@ eal_parse_common_option(int opt, const char *optarg, }break ; } +case OPT_LOG_TIMESTAMP_NUM : + conf->log_timestamp =1 ; +break ;#ifndef RTE_EXEC_ENV_WINDOWS case OPT_TRACE_NUM : {
@@ -2194,6 +2198,7 @@ eal_common_usage(void) " --"OPT_PROC_TYPE" Type of this process (primary|secondary|auto)\n" #ifndef RTE_EXEC_ENV_WINDOWS " --"OPT_SYSLOG" Set syslog facility\n" + " --"OPT_LOG_TIMESTAMP" Timestamp log output\n" #endif" --" OPT_LOG_LEVEL "=<level> Set global log level\n" " --" OPT_LOG_LEVEL "=<type-match>:<level>\n"
lib/eal/common/eal_internal_cfg.h +1 -0
@@ -85,6 +85,7 @@ struct internal_config {* per-node) non-legacy mode only. */ volatile int syslog_facility;/**< facility passed to openlog() */ +volatile uint8_t log_timestamp;/**< add timestamp to console output */ /** default interrupt mode for VFIO */ volatile enum rte_intr_mode vfio_intr_mode;/** the shared VF token for VFIO-PCI bound PF and VFs devices */
lib/eal/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/unix/eal_log.c +39 -3
67 lines not on this page · raw message
Signature · 1 line
2.39.2
Quoted 44 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. The timestamp format is chosen to look like the default Linux dmesg timestamp.
Example:
[ 0.000040] EAL: Probing VFIO support...Signed-off-by Stephen Hemminger <[email protected]>--- .../freebsd_gsg/freebsd_eal_parameters.rst | 32 ++++++++++++++ doc/guides/linux_gsg/linux_eal_parameters.rst | 5 +++ lib/eal/common/eal_common_options.c | 5 +++ lib/eal/common/eal_internal_cfg.h | 1 + lib/eal/common/eal_options.h | 2 + lib/eal/unix/eal_log.c | 42 +++++++++++++++++-- 6 files changed, 84 insertions(+), 3 deletions(-)doc/guides/freebsd_gsg/freebsd_eal_parameters.rst +17
-0@@ -18,3 +18,35 @@ FreeBSD-specific EAL parameters ------------------------------- There are currently no FreeBSD-specific EAL command-line parameters available. + +Other options +~~~~~~~~~~~~~ + +* ``--syslog <syslog facility>`` + + Set syslog facility. Valid syslog facilities are:: + + auth + cron + daemon + ftp + kern + lpr + mail + news + syslog
doc/guides/freebsd_gsg/freebsd_eal_parameters.rst FreeBSD-specific EAL parameters · line 47
Quoted 10 lines
doc/guides/freebsd_gsg/freebsd_eal_parameters.rst +10
-0+ user + uucp + local0 + local1 + local2 + local3 + local4 + local5 + local6 + local7
This should add to commit 1/2 [PATCH v3 1/2] eal: unify logging code for FreeBsd and Linux
Quoted 82 lines
doc/guides/freebsd_gsg/freebsd_eal_parameters.rst +5
-0+ +* ``--log-timestamp`` + + Add a timestamp of seconds and microseconds to each log message + written to standard output.doc/guides/linux_gsg/linux_eal_parameters.rst +5
-0@@ -135,3 +135,8 @@ Other options local5 local6 local7 + +* ``--log-timestamp`` + + Add a timestamp of seconds and microseconds to each log message + written to standard output.lib/eal/common/eal_common_options.c +5
-0@@ -76,6 +76,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, 0, 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 },@@ -1833,6 +1834,9 @@ eal_parse_common_option(int opt, const char *optarg, }break ; } +case OPT_LOG_TIMESTAMP_NUM : + conf->log_timestamp =1 ; +break ;#ifndef RTE_EXEC_ENV_WINDOWS case OPT_TRACE_NUM : {@@ -2194,6 +2198,7 @@ eal_common_usage(void) " --"OPT_PROC_TYPE" Type of this process (primary|secondary|auto)\n" #ifndef RTE_EXEC_ENV_WINDOWS " --"OPT_SYSLOG" Set syslog facility\n" + " --"OPT_LOG_TIMESTAMP" Timestamp log output\n" #endif" --" OPT_LOG_LEVEL "=<level> Set global log level\n" " --" OPT_LOG_LEVEL "=<type-match>:<level>\n" lib/eal/common/eal_internal_cfg.h +1
-0@@ -85,6 +85,7 @@ struct internal_config {* per-node) non-legacy mode only. */ volatile int syslog_facility;/**< facility passed to openlog() */ +volatile uint8_t log_timestamp;/**< add timestamp to console output */ /** default interrupt mode for VFIO */ volatile enum rte_intr_mode vfio_intr_mode;/** the shared VF token for VFIO-PCI bound PF and VFs devices */ lib/eal/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/unix/eal_log.c +1
-0@@ -4,11 +4,17 @@#include <stdio.h> #include <sys/types.h> +#include <sys/uio.h>
lib/eal/unix/eal_log.c line 17
Quoted 10 lines
lib/eal/unix/eal_log.c +5
-0#include <syslog.h> +#include <time.h> +#include <unistd.h> #include <rte_log.h> #include "eal_log.h" +#include "eal_private.h" + +static struct timespec log_start_time;
This is process's private, how about support multi-process ? so that all process has the same base?
Quoted 36 lines
lib/eal/unix/eal_log.c +24
-3/* * default log function @@ -16,11 +22,39 @@static ssize_t console_log_write(__rte_unused void *c, const char *buf, size_t size) { +const struct internal_config *internal_conf = +eal_get_internal_configuration ();ssize_t ret; -/* write on stderr */ - ret =fwrite (buf,1 , size, stderr); -fflush (stderr); +/* add optional timestamp for stderr */ +if (internal_conf->log_timestamp) { +struct iovec iov[2 ]; +struct timespec ts; +char tbuf[64 ]; + +/* format up monotonic timestamp */ +clock_gettime (CLOCK_MONOTONIC , &ts); + ts.tv_sec -= log_start_time.tv_sec; + ts.tv_nsec -= log_start_time.tv_nsec; +if (ts.tv_nsec <0 ) { + --ts.tv_sec; + ts.tv_nsec +=1000000000ul ; + } + +/* use writev to put timestamp and buf in same operation */ + iov[0 ].iov_base = tbuf; + iov[0 ].iov_len =snprintf (tbuf,sizeof (tbuf),"[%8lu.%06lu] " , + ts.tv_sec, ts.tv_nsec /1000u ); + +/* casts are to unconstify the buf */ + iov[1 ].iov_base = (void *)(uintptr_t )buf;
lib/eal/unix/eal_log.c line 60
Quoted 10 lines
lib/eal/unix/eal_log.c +7
-0+ iov[1 ].iov_len = size; + ret =writev (STDERR_FILENO , iov,2 ); + }else { +/* write on stderr */ + ret =fwrite (buf,1 , size, stderr); +fflush (stderr); + }/* Syslog error levels are from 0 to 7, so subtract 1 to convert */ syslog (rte_log_cur_msg_loglevel () -1 ,"%.*s" , (int )size, buf);
The syslog will add timestamp, but the syslog backend will re-write timestamp, so in the last, you can't find the real-timestamp of this log print. sometimes it requires to get real log time.
PS: we found it in our test environment because RR schedule hang too long (similar question also found: https://bugzilla.redhat.com/show_bug.cgi?id=1855447).
So suggest add timestamp in syslog string also, and don't convert to monotonic and just print as normal format (just like syslog).
Quoted 10 lines
lib/eal/unix/eal_log.c +2
-0@@ -49,6 +83,8 @@ eal_log_init(const char *id, int facility) {FILE *log_stream; +clock_gettime (CLOCK_MONOTONIC , &log_start_time); + log_stream =fopencookie (NULL ,"w+" , console_log_func);if (log_stream ==NULL )return -1 ;
Quoted 144 lines · On Tue, 7 Mar 2023 17:35:32 +0800 fengchengwen <[email protected]> wrote:
Quoted 44 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. The timestamp format is chosen to look like the default Linux dmesg timestamp.
Example:
[ 0.000040] EAL: Probing VFIO support...Signed-off-by Stephen Hemminger <[email protected]>--- .../freebsd_gsg/freebsd_eal_parameters.rst | 32 ++++++++++++++ doc/guides/linux_gsg/linux_eal_parameters.rst | 5 +++ lib/eal/common/eal_common_options.c | 5 +++ lib/eal/common/eal_internal_cfg.h | 1 + lib/eal/common/eal_options.h | 2 + lib/eal/unix/eal_log.c | 42 +++++++++++++++++-- 6 files changed, 84 insertions(+), 3 deletions(-)doc/guides/freebsd_gsg/freebsd_eal_parameters.rst +17
-0@@ -18,3 +18,35 @@ FreeBSD-specific EAL parameters ------------------------------- There are currently no FreeBSD-specific EAL command-line parameters available. + +Other options +~~~~~~~~~~~~~ + +* ``--syslog <syslog facility>`` + + Set syslog facility. Valid syslog facilities are:: + + auth + cron + daemon + ftp + kern + lpr + mail + news + syslogdoc/guides/freebsd_gsg/freebsd_eal_parameters.rst FreeBSD-specific EAL parameters · line 47
Quoted 10 lines
doc/guides/freebsd_gsg/freebsd_eal_parameters.rst +10
-0+ user + uucp + local0 + local1 + local2 + local3 + local4 + local5 + local6 + local7This should add to commit 1/2 [PATCH v3 1/2] eal: unify logging code for FreeBsd and Linux
Quoted 86 lines
doc/guides/freebsd_gsg/freebsd_eal_parameters.rst +5
-0+ +* ``--log-timestamp`` + + Add a timestamp of seconds and microseconds to each log message + written to standard output.doc/guides/linux_gsg/linux_eal_parameters.rst +5
-0@@ -135,3 +135,8 @@ Other options local5 local6 local7 + +* ``--log-timestamp`` + + Add a timestamp of seconds and microseconds to each log message + written to standard output.lib/eal/common/eal_common_options.c +5
-0@@ -76,6 +76,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, 0, 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 },@@ -1833,6 +1834,9 @@ eal_parse_common_option(int opt, const char *optarg, }break ; } +case OPT_LOG_TIMESTAMP_NUM : + conf->log_timestamp =1 ; +break ;#ifndef RTE_EXEC_ENV_WINDOWS case OPT_TRACE_NUM : {@@ -2194,6 +2198,7 @@ eal_common_usage(void) " --"OPT_PROC_TYPE" Type of this process (primary|secondary|auto)\n" #ifndef RTE_EXEC_ENV_WINDOWS " --"OPT_SYSLOG" Set syslog facility\n" + " --"OPT_LOG_TIMESTAMP" Timestamp log output\n" #endif" --" OPT_LOG_LEVEL "=<level> Set global log level\n" " --" OPT_LOG_LEVEL "=<type-match>:<level>\n" lib/eal/common/eal_internal_cfg.h +1
-0@@ -85,6 +85,7 @@ struct internal_config {* per-node) non-legacy mode only. */ volatile int syslog_facility;/**< facility passed to openlog() */ +volatile uint8_t log_timestamp;/**< add timestamp to console output */ /** default interrupt mode for VFIO */ volatile enum rte_intr_mode vfio_intr_mode;/** the shared VF token for VFIO-PCI bound PF and VFs devices */ lib/eal/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/unix/eal_log.c +3
-0@@ -4,11 +4,17 @@#include <stdio.h> #include <sys/types.h> +#include <sys/uio.h> #include <syslog.h> +#include <time.h> +#include <unistd.h>
Quoted 8 lines
lib/eal/unix/eal_log.c line 17
Quoted 6 lines
lib/eal/unix/eal_log.c +3
-0#include <rte_log.h> #include "eal_log.h" +#include "eal_private.h" + +static struct timespec log_start_time;This is process's private, how about support multi-process ? so that all process has the same base?
If using primary/secondary, then the secondary's output would have time zero of when secondary started. Not sure if that is good or bad?
Quoted 8 lines · On Tue, 7 Mar 2023 17:35:32 +0800 fengchengwen <[email protected]> wrote:
The syslog will add timestamp, but the syslog backend will re-write timestamp, so in the last, you can't find the real-timestamp of this log print. sometimes it requires to get real log time.
PS: we found it in our test environment because RR schedule hang too long (similar question also found: https://bugzilla.redhat.com/show_bug.cgi?id=1855447).So suggest add timestamp in syslog string also, and don't convert to monotonic and just print as normal format (just like syslog).
Are you using systemd?
Never, never configure a DPDK application with real-time process priority. Polling model and RT don't mix.
Quoted 9 lines · Stephen Hemminger
Quoted 6 lines · On Tue, 7 Mar 2023 17:35:32 +0800 fengchengwen <[email protected]> wrote:
The syslog will add timestamp, but the syslog backend will re-write timestamp, so in the last, you can't find the real-timestamp of this log print. sometimes it requires to get real log time.
PS: we found it in our test environment because RR schedule hang too long (similar question also found: https://bugzilla.redhat.com/show_bug.cgi?id=1855447).
Quoted 5 lines
Quoted 2 lines
So suggest add timestamp in syslog string also, and don't convert to monotonic and just print as normal format (just like syslog).
Are you using systemd?
Yes
Quoted 3 lines
Never, never configure a DPDK application with real-time process priority. Polling model and RT don't mix.
Maybe we should document them ?
Quoted 2 lines
.
Quoted 10 lines · On Wed, 8 Mar 2023 08:36:48 +0800 fengchengwen <[email protected]> wrote:
Quoted 9 lines · Stephen Hemminger
Quoted 6 lines · On Tue, 7 Mar 2023 17:35:32 +0800 fengchengwen <[email protected]> wrote:
The syslog will add timestamp, but the syslog backend will re-write timestamp, so in the last, you can't find the real-timestamp of this log print. sometimes it requires to get real log time.
PS: we found it in our test environment because RR schedule hang too long (similar question also found: https://bugzilla.redhat.com/show_bug.cgi?id=1855447).
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
So suggest add timestamp in syslog string also, and don't convert to monotonic and just print as normal format (just like syslog).
Are you using systemd?
Yes
There is redhat bug about this:
https://bugzilla.redhat.com/show_bug.cgi?id=991678
Quoted 4 lines
Quoted 2 lines
Never, never configure a DPDK application with real-time process priority. Polling model and RT don't mix.
Maybe we should document them ?
Part of previous discussion here:
https://mails.dpdk.org/archives/dev/2021-April/203778.html
In my experience running DPDK on isolated threads (cgroup or scheduler isolation) combined with remapping interrupts gives best response without lockup.
I.e don't depend on scheduler to do the right thing. Instead ensure that each thread runs on dedicated CPU.
Quoted 29 lines · Stephen Hemminger
Quoted 10 lines · On Wed, 8 Mar 2023 08:36:48 +0800 fengchengwen <[email protected]> wrote:
Quoted 9 lines · Stephen Hemminger
Quoted 6 lines · On Tue, 7 Mar 2023 17:35:32 +0800 fengchengwen <[email protected]> wrote:
The syslog will add timestamp, but the syslog backend will re-write timestamp, so in the last, you can't find the real-timestamp of this log print. sometimes it requires to get real log time.
PS: we found it in our test environment because RR schedule hang too long (similar question also found: https://bugzilla.redhat.com/show_bug.cgi?id=1855447).Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
So suggest add timestamp in syslog string also, and don't convert to monotonic and just print as normal format (just like syslog).
Are you using systemd?
Yes
There is redhat bug about this:
https://bugzilla.redhat.com/show_bug.cgi?id=991678Quoted 4 lines
Quoted 2 lines
Never, never configure a DPDK application with real-time process priority. Polling model and RT don't mix.
Maybe we should document them ?
Quoted 8 lines
Part of previous discussion here:
https://mails.dpdk.org/archives/dev/2021-April/203778.htmlIn my experience running DPDK on isolated threads (cgroup or scheduler isolation) combined with remapping interrupts gives best response without lockup.
I.e don't depend on scheduler to do the right thing. Instead ensure that each thread runs on dedicated CPU.
Got it, thanks.
Quoted 5 lines
.
Quoted 4 lines · On Wed, 8 Mar 2023 08:36:48 +0800 fengchengwen <[email protected]> wrote:
Quoted 2 lines
Never, never configure a DPDK application with real-time process priority. Polling model and RT don't mix.
Maybe we should document them ?
LOL - ChatGPT is amusing if you ask it. The answer is pro grammatically correct, but will not work. The caveat at the end is much bigger than it understands.
Question:
Is Dataplane Development Kit (DPDK) compatible with Linux Real Time thread priority like SCH_FIFO?
Yes, Dataplane Development Kit (DPDK) is compatible with Linux Real-Time thread priority scheduling policies, such as SCHED_FIFO.
Answer:
DPDK supports setting the thread priority using the standard Linux pthread APIs, including pthread_setschedparam() and pthread_attr_setschedpolicy(). This allows the application to configure the thread scheduling policy and priority for DPDK worker threads.
To set the real-time priority of DPDK threads, you can use the pthread_setschedparam() function to set the scheduling policy to SCHED_FIFO or SCHED_RR and the priority value to a value between 1 and 99. Here is an example of how to set the real-time priority of a DPDK thread:
Quoted 4 lines
pthread_ttid;
structsched_paramsched_param;pthread_attr_tattr;
Quoted 8 lines
pthread_attr_init(&attr);pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);sched_param.sched_priority = 50;
pthread_attr_setschedparam(&attr, &sched_param);pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
pthread_create(&tid, &attr, thread_func, arg);
In this example, the SCHED_FIFO scheduling policy is used, and the priority value is set to 50. You can adjust the priority value according to your needs.
Note that using real-time scheduling policies like SCHED_FIFO or SCHED_RR requires careful consideration of system resources and may impact system performance if not used properly. It is recommended to consult the Linux documentation and to test the system thoroughly before deploying any application using real-time scheduling policies.
RE: [PATCH v3 0/2] Add option to timestamp console log
In reply to Stephen HemmingerQuoted 7 lines
From: Stephen Hemminger [mailto:[email protected]]
Sent: Monday, 6 March 2023 20.28This is a reprise of earlier patch to add timestamp to console messages.
Example:
Quoted 10 lines
# dpdk-testpmd -l 1-4 -n 4 --vdev net_null0 --log-timestamp -- -i EAL: Detected CPU lcores: 16 EAL: Detected NUMA nodes: 1 EAL: Detected static linkage of DPDK EAL: Multi-process socket /var/run/dpdk/rte/mp_socket EAL: Selected IOVA mode 'VA' Interactive-mode selected [ 0.191407] testpmd: create a new mbuf pool <mb_pool_0>: n=171456, size=2176, socket=0 [ 0.191510] testpmd: preferred mempool ops selected: ring_mp_mc
This is useful.
Here's some feature creep: Since the timestamp output is configurable, there is no need to settle on one specific timestamp format. The option could allow a choice between MONOTONIC and REALTIME, with an option for REALTIME to include the date in ISO 8601 format (YYYY-MM-DD). And REALTIME could be UTC or local time. You could consider taking a format string for strftime(), with the extension that %f expands to 6 digit microseconds like in Python [1].
[1]: https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes
With or without feature creep,
Re: [PATCH v3 0/2] Add option to timestamp console log
Quoted 20 lines · Morten Brørup
Quoted 7 lines
From: Stephen Hemminger [mailto:[email protected]]
Sent: Monday, 6 March 2023 20.28This is a reprise of earlier patch to add timestamp to console messages.
Example:
Quoted 10 lines
# dpdk-testpmd -l 1-4 -n 4 --vdev net_null0 --log-timestamp -- -i EAL: Detected CPU lcores: 16 EAL: Detected NUMA nodes: 1 EAL: Detected static linkage of DPDK EAL: Multi-process socket /var/run/dpdk/rte/mp_socket EAL: Selected IOVA mode 'VA' Interactive-mode selected [ 0.191407] testpmd: create a new mbuf pool <mb_pool_0>: n=171456, size=2176, socket=0 [ 0.191510] testpmd: preferred mempool ops selected: ring_mp_mcThis is useful.
Quoted 8 lines
Here's some feature creep: Since the timestamp output is configurable, there is no need to settle on one specific timestamp format. The option could allow a choice between MONOTONIC and REALTIME, with an option for REALTIME to include the date in ISO 8601 format (YYYY-MM-DD). And REALTIME could be UTC or local time. You could consider taking a format string for
strftime(), with the extension that %f expands to 6 digit microseconds like in Python [1].[1]: https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes
With or without feature creep,
Series-acked-by Morten Brørup <[email protected]>
Missed the fact there was already a v3 when I acked v2, so repeating here.
I'd rather not have the feature creep on it though - at least not yet!
Re: [PATCH v3 0/2] Add option to timestamp console log
In reply to Morten BrørupQuoted 1 line · On Tue, 7 Mar 2023 08:33:17 +0100 Morten Brørup <[email protected]>…
Here's some feature creep: Since the timestamp output is configurable, there is no need to settle on one specific timestamp format. The option could allow a choice between MONOTONIC and REALTIME, with an option for REALTIME to include the date in ISO 8601 format (YYYY-MM-DD). And REALTIME could be UTC or local time. You could consider taking a format string for
strftime(), with the extension that %f expands to 6 digit microseconds like in Python [1].
Does that have compiler static checking issues if you allow user to set formats?
v4 cover Logging related patchs
In reply to Stephen HemmingerThis patch set rebases and extends some earlier work on logging.
Stephen Hemminger (5):
eal: unify logging code for FreeBsd and Linux
eal: turn off getopt_long error message during eal_log_level
eal: skip stdio on console logging
eal: move logging initialization earlier
eal: add option to put timestamp on console output
.../freebsd_gsg/freebsd_eal_parameters.rst | 32 +++++++ doc/guides/linux_gsg/linux_eal_parameters.rst | 5 + lib/eal/common/eal_common_options.c | 6 ++ lib/eal/common/eal_internal_cfg.h | 3 + lib/eal/common/eal_options.h | 2 + lib/eal/freebsd/eal.c | 39 +++++--- lib/eal/linux/eal.c | 48 +++++----- lib/eal/linux/eal_log.c | 61 ------------ lib/eal/linux/meson.build | 1 - lib/eal/unix/eal_log.c | 93 +++++++++++++++++++ lib/eal/unix/meson.build | 1 + lib/eal/windows/eal.c | 3 + 12 files changed, 194 insertions(+), 100 deletions(-) delete mode 100644 lib/eal/linux/eal_log.c create mode 100644 lib/eal/unix/eal_log.c
Signature · 1 line
2.39.2
PATCH v4 1/5 eal: unify logging code for FreeBsd and Linux
FreeBSD logging code was not using syslog and did not have the same options as Linux. Move the log writing code to common source tree.
---
.../freebsd_gsg/freebsd_eal_parameters.rst | 27 +++++++++++++++++++
lib/eal/freebsd/eal.c | 7 +++++
lib/eal/linux/meson.build | 1 -
lib/eal/{linux => unix}/eal_log.c | 0
lib/eal/unix/meson.build | 1 +
5 files changed, 35 insertions(+), 1 deletion(-)
rename lib/eal/{linux => unix}/eal_log.c (100%)doc/guides/freebsd_gsg/freebsd_eal_parameters.rst +27 -0
@@ -18,3 +18,30 @@ FreeBSD-specific EAL parameters ------------------------------- There are currently no FreeBSD-specific EAL command-line parameters available. + +Other options +~~~~~~~~~~~~~ + +* ``--syslog <syslog facility>`` + + Set syslog facility. Valid syslog facilities are:: + + auth + cron + daemon + ftp + kern + lpr + mail + news + syslog + user + uucp + local0 + local1 + local2 + local3 + local4 + local5 + local6 + local7
lib/eal/freebsd/eal.c +7 -0
@@ -52,6 +52,7 @@#include "eal_hugepages.h" #include "eal_options.h" #include "eal_memcfg.h" +#include "eal_log.h" #include "eal_trace.h" #define MEMSIZE_IF_NO_HUGE_PAGE (64ULL * 1024ULL * 1024ULL)
@@ -759,6 +760,12 @@ rte_eal_init(int argc, char **argv)#endif } +if (eal_log_init (getprogname (), internal_conf->syslog_facility) <0 ) { +rte_eal_init_alert ("Cannot init logging." ); + rte_errno =ENOMEM ; +return -1 ; + } +/* in secondary processes, memory init may allocate additional fbarrays * not present in primary processes, so to avoid any potential issues, * initialize memzones first.
lib/eal/linux/meson.build +0 -1
@@ -11,7 +11,6 @@ sources += files( 'eal_hugepage_info.c', 'eal_interrupts.c', 'eal_lcore.c', - 'eal_log.c', 'eal_memalloc.c', 'eal_memory.c', 'eal_thread.c',
lib/eal/unix/eal_log.c renamed from lib/eal/linux/eal_log.c +0 -0
lib/eal/unix/meson.build +1 -0
@@ -6,6 +6,7 @@ sources += files( 'eal_file.c', 'eal_filesystem.c', 'eal_firmware.c', + 'eal_log.c', 'eal_unix_memory.c', 'eal_unix_thread.c', 'eal_unix_timer.c',
Signature · 1 line
2.39.2
PATCH v4 2/5 eal: turn off getopt_long error message during eal_log_level
In reply to Stephen HemmingerIf DPDK application is given a bogus option, the error message would get printed twice. Once during scan for log level and again during parsing of arguments.
Example:
# ./build/app/dpdk-testpmd --bogus ./build/app/dpdk-testpmd: unrecognized option '--bogus' EAL: Detected CPU lcores: 16 EAL: Detected NUMA nodes: 1 ./build/app/dpdk-testpmd: unrecognized option '--bogus'
Usage: ./build/app/dpdk-testpmd [options]
Fix by suppressing printing error message on first pass.
--- lib/eal/freebsd/eal.c | 2 ++ lib/eal/linux/eal.c | 2 ++ lib/eal/windows/eal.c | 3 +++ 3 files changed, 7 insertions(+)
lib/eal/freebsd/eal.c +2 -0
@@ -381,6 +381,7 @@ eal_log_level_parse(int argc, char **argv) argvopt = argv; optind =1 ; optreset =1 ; + opterr =0 ;while ((opt =getopt_long (argc, argvopt, eal_short_options, eal_long_options, &option_index)) !=EOF ) {
@@ -424,6 +425,7 @@ eal_parse_args(int argc, char **argv) argvopt = argv; optind =1 ; optreset =1 ; + opterr =1 ;while ((opt =getopt_long (argc, argvopt, eal_short_options, eal_long_options, &option_index)) !=EOF ) {
lib/eal/linux/eal.c +2 -0
@@ -561,6 +561,7 @@ eal_log_level_parse(int argc, char **argv) argvopt = argv; optind =1 ; + opterr =0 ;while ((opt =getopt_long (argc, argvopt, eal_short_options, eal_long_options, &option_index)) !=EOF ) {
@@ -638,6 +639,7 @@ eal_parse_args(int argc, char **argv) argvopt = argv; optind =1 ; + opterr =1 ;while ((opt =getopt_long (argc, argvopt, eal_short_options, eal_long_options, &option_index)) !=EOF ) {
lib/eal/windows/eal.c +3 -0
@@ -106,6 +106,8 @@ eal_log_level_parse(int argc, char **argv)struct internal_config *internal_conf =eal_get_internal_configuration (); + opterr =0 ; + argvopt = argv;eal_reset_internal_config (internal_conf);
@@ -143,6 +145,7 @@ eal_parse_args(int argc, char **argv)eal_get_internal_configuration (); argvopt = argv; + opterr =1 ;while ((opt =getopt_long (argc, argvopt, eal_short_options, eal_long_options, &option_index)) !=EOF ) {
Signature · 1 line
2.39.2
PATCH v4 3/5 eal: skip stdio on console logging
In reply to Stephen HemmingerThere is no need to use stdio when logging to console. Using the write system call directly avoids unnecessary copy to stdio output buffer.
--- lib/eal/unix/eal_log.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
lib/eal/unix/eal_log.c +2 -2
@@ -5,6 +5,7 @@#include <stdio.h> #include <sys/types.h> #include <syslog.h> +#include <unistd.h> #include <rte_log.h>
@@ -19,8 +20,7 @@ console_log_write(__rte_unused void *c, const char *buf, size_t size)ssize_t ret;/* write on stderr */ - ret =fwrite (buf,1 , size, stderr); -fflush (stderr); + ret =write (STDERR_FILENO , buf, size);/* Syslog error levels are from 0 to 7, so subtract 1 to convert */ syslog (rte_log_cur_msg_loglevel () -1 ,"%.*s" , (int )size, buf);
Signature · 1 line
2.39.2
PATCH v4 4/5 eal: move logging initialization earlier
In reply to Stephen HemmingerThe log stream should be setup before any messages. This ensures that any startup problems are captured on the syslog output, not only shown on the stderr.
--- lib/eal/freebsd/eal.c | 40 +++++++++++++++++++-------------------- lib/eal/linux/eal.c | 44 +++++++++++++++++++++---------------------- 2 files changed, 40 insertions(+), 44 deletions(-)
lib/eal/freebsd/eal.c +19 -21
@@ -364,7 +364,7 @@ eal_get_hugepage_mem_size(void)return (size <SIZE_MAX ) ? (size_t )(size) :SIZE_MAX ; } -/* Parse the arguments for --log-level only */ +/* Parse the arguments for --log-level and --syslog */ static void eal_log_level_parse (int argc,char **argv) {
@@ -386,20 +386,18 @@ eal_log_level_parse(int argc, char **argv)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 ) +switch (opt) { +case OPT_SYSLOG_NUM :/* fallthrough */ +case OPT_LOG_LEVEL_NUM : +if (eal_parse_common_option (opt, optarg, internal_conf) <0 ) + goto error;break ; +case '?' : +/* getopt is not happy, stop right now */ + goto error; + } } - +error:/* restore getopt lib */ optind = old_optind; optopt = old_optopt;
@@ -437,8 +435,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_SYSLOG_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
@@ -615,6 +613,12 @@ rte_eal_init(int argc, char **argv)/* set log level as early as possible */ eal_log_level_parse (argc, argv); +if (eal_log_init (getprogname (), internal_conf->syslog_facility) <0 ) { +rte_eal_init_alert ("Cannot init logging." ); + rte_errno =ENOMEM ; +return -1 ; + } +if (rte_eal_cpu_init () <0 ) {rte_eal_init_alert ("Cannot detect lcores." ); rte_errno =ENOTSUP ;
@@ -762,12 +766,6 @@ rte_eal_init(int argc, char **argv)#endif } -if (eal_log_init (getprogname (), internal_conf->syslog_facility) <0 ) { -rte_eal_init_alert ("Cannot init logging." ); - rte_errno =ENOMEM ; -return -1 ; - } -/* in secondary processes, memory init may allocate additional fbarrays * not present in primary processes, so to avoid any potential issues, * initialize memzones first.
lib/eal/linux/eal.c +21 -23
76 lines not on this page · raw message
Signature · 1 line
2.39.2
PATCH v4 5/5 eal: add option to put timestamp on console output
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. The timestamp format is chosen to look like the default Linux dmesg timestamp.
Example:
$ dpdk-testpmd --log-timestamp -- -i [ 0.007615] EAL: Detected CPU lcores: 16 [ 0.007657] EAL: Detected NUMA nodes: 1 [ 0.007878] EAL: Detected static linkage of DPDK [ 0.009469] EAL: Multi-process socket /var/run/dpdk/rte/mp_socket [ 0.012175] EAL: Selected IOVA mode 'VA' [ 0.120016] testpmd: No probed ethernet devices Interactive-mode selected [ 0.155959] testpmd: create a new mbuf pool <mb_pool_0>: n=267456, size=2176, socket=0 [ 0.155990] testpmd: preferred mempool ops selected: ring_mp_mc
--- .../freebsd_gsg/freebsd_eal_parameters.rst | 5 +++ doc/guides/linux_gsg/linux_eal_parameters.rst | 5 +++ lib/eal/common/eal_common_options.c | 6 ++++ lib/eal/common/eal_internal_cfg.h | 3 ++ lib/eal/common/eal_options.h | 2 ++ lib/eal/freebsd/eal.c | 4 ++- lib/eal/linux/eal.c | 4 ++- lib/eal/unix/eal_log.c | 36 +++++++++++++++++-- 8 files changed, 61 insertions(+), 4 deletions(-)
doc/guides/freebsd_gsg/freebsd_eal_parameters.rst +5 -0
@@ -45,3 +45,8 @@ Other options local5 local6 local7 + +* ``--log-timestamp`` + + Add a timestamp of seconds and microseconds to each log message + written to standard output.
doc/guides/linux_gsg/linux_eal_parameters.rst +5 -0
@@ -135,3 +135,8 @@ Other options local5 local6 local7 + +* ``--log-timestamp`` + + Add a timestamp of seconds and microseconds to each log message + written to standard output.
lib/eal/common/eal_common_options.c +6 -0
@@ -76,6 +76,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, 0, 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 },
@@ -1835,6 +1836,10 @@ eal_parse_common_option(int opt, const char *optarg, }#ifndef RTE_EXEC_ENV_WINDOWS +case OPT_LOG_TIMESTAMP_NUM : + conf->log_timestamp =1 ; +break ; +case OPT_TRACE_NUM : {if (eal_trace_args_save (optarg) <0 ) { RTE_LOG(ERR, EAL, "invalid parameters for --"
@@ -2194,6 +2199,7 @@ eal_common_usage(void) " --"OPT_PROC_TYPE" Type of this process (primary|secondary|auto)\n" #ifndef RTE_EXEC_ENV_WINDOWS " --"OPT_SYSLOG" Set syslog facility\n" + " --"OPT_LOG_TIMESTAMP" Timestamp log output\n" #endif" --" OPT_LOG_LEVEL "=<level> Set global log level\n" " --" OPT_LOG_LEVEL "=<type-match>:<level>\n"
lib/eal/common/eal_internal_cfg.h +3 -0
@@ -84,7 +84,10 @@ struct internal_config {/**< true if storing all pages within single files (per-page-size, * per-node) non-legacy mode only. */ +volatile uint8_t log_timestamp;/**< add timestamp to console output */ volatile int syslog_facility;/**< facility passed to openlog() */ +struct timespec log_start_time;/**< when logging was started */ +/** default interrupt mode for VFIO */ volatile enum rte_intr_mode vfio_intr_mode;/** the shared VF token for VFIO-PCI bound PF and VFs devices */
lib/eal/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 +3 -1
@@ -388,6 +388,7 @@ eal_log_level_parse(int argc, char **argv)switch (opt) {case OPT_SYSLOG_NUM :/* fallthrough */ +case OPT_LOG_TIMESTAMP_NUM :/* fallthrough */ case OPT_LOG_LEVEL_NUM :if (eal_parse_common_option (opt, optarg, internal_conf) <0 ) goto error;
@@ -436,7 +437,8 @@ eal_parse_args(int argc, char **argv) }/* eal_log_level_parse() already handled these */ -if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_SYSLOG_NUM ) +if (opt ==OPT_SYSLOG_NUM || + opt ==OPT_LOG_TIMESTAMP_NUM || opt ==OPT_LOG_LEVEL_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
lib/eal/linux/eal.c +3 -1
@@ -568,6 +568,7 @@ eal_log_level_parse(int argc, char **argv)switch (opt) {case OPT_SYSLOG_NUM :/* fallthrough */ +case OPT_LOG_TIMESTAMP_NUM :/* fallthrough */ case OPT_LOG_LEVEL_NUM :if (eal_parse_common_option (opt, optarg, internal_conf) <0 ) goto error;
@@ -650,7 +651,8 @@ eal_parse_args(int argc, char **argv) }/* eal_log_level_parse() already handled these */ -if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_SYSLOG_NUM ) +if (opt ==OPT_SYSLOG_NUM || + opt ==OPT_LOG_TIMESTAMP_NUM || opt ==OPT_LOG_LEVEL_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
lib/eal/unix/eal_log.c +34 -2
@@ -4,12 +4,15 @@#include <stdio.h> #include <sys/types.h> +#include <sys/uio.h> #include <syslog.h> +#include <time.h> #include <unistd.h> #include <rte_log.h> #include "eal_log.h" +#include "eal_private.h" /* * default log function
@@ -17,10 +20,36 @@static ssize_t console_log_write(__rte_unused void *c, const char *buf, size_t size) { +const struct internal_config *internal_conf =eal_get_internal_configuration ();ssize_t ret; -/* write on stderr */ - ret =write (STDERR_FILENO , buf, size); +/* add optional timestamp for stderr */ +if (internal_conf->log_timestamp) { +struct iovec iov[2 ]; +struct timespec ts; +char tbuf[64 ]; + +/* format up monotonic timestamp */ +clock_gettime (CLOCK_MONOTONIC , &ts); + ts.tv_sec -= internal_conf->log_start_time.tv_sec; + ts.tv_nsec -= internal_conf->log_start_time.tv_nsec; +if (ts.tv_nsec <0 ) { + --ts.tv_sec; + ts.tv_nsec +=1000000000ul ; + } + +/* use writev to put timestamp and buf in single operation */ + iov[0 ].iov_base = tbuf; + iov[0 ].iov_len =snprintf (tbuf,sizeof (tbuf),"[%8lu.%06lu] " , + ts.tv_sec, ts.tv_nsec /1000u ); + +/* casts are to unconstify the buf */ + iov[1 ].iov_base = (void *)(uintptr_t )buf; + iov[1 ].iov_len = size; + ret =writev (STDERR_FILENO , iov,2 ); + }else { + ret =write (STDERR_FILENO , buf, size); + }/* Syslog error levels are from 0 to 7, so subtract 1 to convert */ syslog (rte_log_cur_msg_loglevel () -1 ,"%.*s" , (int )size, buf);
@@ -47,8 +76,11 @@ static cookie_io_functions_t console_log_func = {int eal_log_init (const char *id,int facility) { +struct internal_config *internal_conf =eal_get_internal_configuration ();FILE *log_stream; +clock_gettime (CLOCK_MONOTONIC , &internal_conf->log_start_time); + log_stream =fopencookie (NULL ,"w+" , console_log_func);if (log_stream ==NULL )return -1 ;
Signature · 1 line
2.39.2
RE: [PATCH v4 0/5] Logging related patchs
In reply to Stephen HemmingerQuoted 6 lines
From: Stephen Hemminger [mailto:[email protected]]
Sent: Monday, 26 June 2023 20.42
To: [email protected]
Cc: Stephen Hemminger
Subject: [PATCH v4 0/5] Logging related patchs
Quoted 8 lines
This patch set rebases and extends some earlier work on logging.
Stephen Hemminger (5):
eal: unify logging code for FreeBsd and Linux
eal: turn offgetopt_longerror message duringeal_log_level
eal: skip stdio on console logging
eal: move logging initialization earlier
eal: add option to put timestamp on console output
Re: [PATCH v4 0/5] Logging related patchs
Quoted 8 lines · On Tue, 27 Jun 2023 09:40:01 +0200 Morten Brørup <[email protected]>…
Quoted 8 lines
From: Stephen Hemminger [mailto:[email protected]]
Sent: Monday, 26 June 2023 20.42
To: [email protected]
Cc: Stephen Hemminger
Subject: [PATCH v4 0/5] Logging related patchsThis patch set rebases and extends some earlier work on logging.
Quoted 9 lines
Quoted 6 lines
Stephen Hemminger (5):
eal: unify logging code for FreeBsd and Linux
eal: turn offgetopt_longerror message duringeal_log_level
eal: skip stdio on console logging
eal: move logging initialization earlier
eal: add option to put timestamp on console outputSeries-acked-by Morten Brørup <[email protected]>
There are a few bugs, still working them out.
In initial review feedback there was desire for timestamp feature to be global. I.e secondary process would show time since start of primary. But this would hard to implement due to chicken/egg issues during argument parsing during startup; so made a decision that it wasn't worth doing.
RE: [PATCH v4 0/5] Logging related patchs
Quoted 24 lines
From: Stephen Hemminger [mailto:[email protected]]
Sent: Tuesday, 27 June 2023 16.49Quoted 8 lines · On Tue, 27 Jun 2023 09:40:01 +0200 Morten Brørup <[email protected]>…
Quoted 8 lines
From: Stephen Hemminger [mailto:[email protected]]
Sent: Monday, 26 June 2023 20.42
To: [email protected]
Cc: Stephen Hemminger
Subject: [PATCH v4 0/5] Logging related patchsThis patch set rebases and extends some earlier work on logging.
Quoted 9 lines
Quoted 6 lines
Stephen Hemminger (5):
eal: unify logging code for FreeBsd and Linux
eal: turn offgetopt_longerror message duringeal_log_level
eal: skip stdio on console logging
eal: move logging initialization earlier
eal: add option to put timestamp on console outputSeries-acked-by Morten Brørup <[email protected]>
Quoted 6 lines
There are a few bugs, still working them out.
In initial review feedback there was desire for timestamp feature to be global. I.e secondary process would show time since start of primary. But this would hard to implement due to chicken/egg issues during argument parsing during startup; so made a decision that it wasn't worth doing.
I suppose it could be implemented with a piece of shared memory set by the primary process and read by secondary processes, holding the start time offset from a system global timer (e.g. CLOCK_MONOTONIC) and a tristate variable telling if timestamps are configured - which, if true or false, overrides any timestamp parameter given to the secondary process.
Anyway, secondary process support is far from perfect, so I wouldn't worry too much about getting timestamp parameters from the primary process to the secondary process either. In short: I agree with your decision.
Bruce Richardson
Tested-byRe: [PATCH v4 0/5] Logging related patchs
In reply to Morten BrørupQuoted 8 lines · Morten Brørup
Quoted 8 lines
From: Stephen Hemminger [mailto:[email protected]]
Sent: Monday, 26 June 2023 20.42
To: [email protected]
Cc: Stephen Hemminger
Subject: [PATCH v4 0/5] Logging related patchsThis patch set rebases and extends some earlier work on logging.
Quoted 9 lines
Quoted 6 lines
Stephen Hemminger (5):
eal: unify logging code for FreeBsd and Linux
eal: turn offgetopt_longerror message duringeal_log_level
eal: skip stdio on console logging
eal: move logging initialization earlier
eal: add option to put timestamp on console outputSeries-acked-by Morten Brørup <[email protected]>
Gave it a quick sanity-test run on FreeBSD and all looks ok to me.
v5 cover Logging related patches
In reply to Stephen HemmingerThis patch set rebases and extends some earlier work on logging.
Stephen Hemminger (6):
eal: unify logging code for FreeBsd and Linux
eal: turn off getopt_long error message during eal_log_level
eal: fix handling of syslog facility
eal: skip stdio on console logging
eal: allow user to set default log stream before init
eal: add option to put timestamp on console output
v6
- make more of the log arg parsing common
- handle --syslog argument better
- drop the early logging initialization (need shmem to be setup)
- base timestamp on start of primary process (in shmem)
.../freebsd_gsg/freebsd_eal_parameters.rst | 32 ++++ doc/guides/linux_gsg/linux_eal_parameters.rst | 5 + lib/eal/common/eal_common_log.c | 6 + lib/eal/common/eal_common_options.c | 8 +- lib/eal/common/eal_internal_cfg.h | 3 + lib/eal/common/eal_log.h | 6 + lib/eal/common/eal_options.h | 2 + lib/eal/freebsd/eal.c | 59 ++----- lib/eal/linux/eal.c | 52 ++---- lib/eal/linux/eal_log.c | 61 ------- lib/eal/linux/meson.build | 1 - lib/eal/unix/eal_log.c | 165 ++++++++++++++++++ lib/eal/unix/meson.build | 1 + lib/eal/windows/eal.c | 3 + 14 files changed, 255 insertions(+), 149 deletions(-) delete mode 100644 lib/eal/linux/eal_log.c create mode 100644 lib/eal/unix/eal_log.c
Signature · 1 line
2.39.2
PATCH v5 1/6 eal: unify logging code for FreeBsd and Linux
FreeBSD logging code was not using syslog and did not have the same options as Linux. Move the log writing code to common source tree.
Also fix a number of argument parsing bugs:
1. If application is given a bogus option, the error message would get printed twice. Once during scan for log level and again during parsing of arguments.
2. A bad argument give to --log-level option was given the code would keep going.
3. The syslog facility argument was parsed too late to all log to be initialized before other errors.
--- .../freebsd_gsg/freebsd_eal_parameters.rst | 27 ++++ lib/eal/common/eal_log.h | 5 + lib/eal/freebsd/eal.c | 55 ++------ lib/eal/linux/eal.c | 48 +------ lib/eal/linux/eal_log.c | 61 --------- lib/eal/linux/meson.build | 1 - lib/eal/unix/eal_log.c | 121 ++++++++++++++++++ lib/eal/unix/meson.build | 1 + 8 files changed, 173 insertions(+), 146 deletions(-) delete mode 100644 lib/eal/linux/eal_log.c create mode 100644 lib/eal/unix/eal_log.c
doc/guides/freebsd_gsg/freebsd_eal_parameters.rst +27 -0
@@ -18,3 +18,30 @@ FreeBSD-specific EAL parameters ------------------------------- There are currently no FreeBSD-specific EAL command-line parameters available. + +Other options +~~~~~~~~~~~~~ + +* ``--syslog <syslog facility>`` + + Set syslog facility. Valid syslog facilities are:: + + auth + cron + daemon + ftp + kern + lpr + mail + news + syslog + user + uucp + local0 + local1 + local2 + local3 + local4 + local5 + local6 + local7
lib/eal/common/eal_log.h +5 -0
@@ -13,6 +13,11 @@*/ int eal_log_init (const char *id,int facility); +/* +* Scan command line args for log settings. +*/ +int eal_log_level_parse (int argc,char *const argv[]); +/* * Determine where log data is written when no call to rte_openlog_stream. */
lib/eal/freebsd/eal.c +12 -43
79 lines not on this page · raw message
lib/eal/linux/eal.c +7 -41
66 lines not on this page · raw message
lib/eal/linux/eal_log.c deleted +0 -61
61 lines not on this page · raw message
lib/eal/linux/meson.build +0 -1
@@ -11,7 +11,6 @@ sources += files( 'eal_hugepage_info.c', 'eal_interrupts.c', 'eal_lcore.c', - 'eal_log.c', 'eal_memalloc.c', 'eal_memory.c', 'eal_thread.c',
lib/eal/unix/eal_log.c new file +121 -0
121 lines not on this page · raw message
lib/eal/unix/meson.build +1 -0
@@ -6,6 +6,7 @@ sources += files( 'eal_file.c', 'eal_filesystem.c', 'eal_firmware.c', + 'eal_log.c', 'eal_unix_memory.c', 'eal_unix_thread.c', 'eal_unix_timer.c',
Signature · 1 line
2.39.2
PATCH v5 2/6 eal: turn off getopt_long error message during eal_log_level
In reply to Stephen HemmingerIf DPDK application is given a bogus option, the error message would get printed twice. Once during scan for log level and again during parsing of arguments.
Example:
# ./build/app/dpdk-testpmd --bogus ./build/app/dpdk-testpmd: unrecognized option '--bogus' EAL: Detected CPU lcores: 16 EAL: Detected NUMA nodes: 1 ./build/app/dpdk-testpmd: unrecognized option '--bogus'
Usage: ./build/app/dpdk-testpmd [options]
Fix by suppressing printing error message on first pass.
--- lib/eal/unix/eal_log.c | 3 +++ lib/eal/windows/eal.c | 3 +++ 2 files changed, 6 insertions(+)
lib/eal/unix/eal_log.c +3 -0
@@ -64,12 +64,14 @@ eal_log_level_parse(int argc, char *const argv[])int option_index, opt;const int old_optind = optind;const int old_optopt = optopt; +const int old_opterr = opterr;char *const old_optarg = optarg;#ifdef RTE_EXEC_ENV_FREEBSD const int old_optrset = optreset;#endif optind =1 ; + opterr =0 ;#ifdef RTE_EXEC_ENV_FREEBSD optreset =1 ;#endif
@@ -94,6 +96,7 @@ eal_log_level_parse(int argc, char *const argv[]) optind = old_optind; optopt = old_optopt; optarg = old_optarg; + opterr = old_opterr;#ifdef RTE_EXEC_ENV_FREEBSD optreset = old_optreset;#endif
lib/eal/windows/eal.c +3 -0
@@ -106,6 +106,8 @@ eal_log_level_parse(int argc, char **argv)struct internal_config *internal_conf =eal_get_internal_configuration (); + opterr =0 ; + argvopt = argv;eal_reset_internal_config (internal_conf);
@@ -143,6 +145,7 @@ eal_parse_args(int argc, char **argv)eal_get_internal_configuration (); argvopt = argv; + opterr =1 ;while ((opt =getopt_long (argc, argvopt, eal_short_options, eal_long_options, &option_index)) !=EOF ) {
Signature · 1 line
2.39.2
PATCH v5 3/6 eal: fix handling of syslog facility
In reply to Stephen HemmingerThe syslog facility option needs to be parsed before log_init is called. Also help message whas missing the required argument.
--- lib/eal/common/eal_common_options.c | 2 +- lib/eal/freebsd/eal.c | 2 +- lib/eal/linux/eal.c | 2 +- lib/eal/unix/eal_log.c | 1 + 4 files changed, 4 insertions(+), 3 deletions(-)
lib/eal/common/eal_common_options.c +1 -1
@@ -2193,7 +2193,7 @@ eal_common_usage(void) " --"OPT_VMWARE_TSC_MAP" Use VMware TSC map instead of native RDTSC\n" " --"OPT_PROC_TYPE" Type of this process (primary|secondary|auto)\n" #ifndef RTE_EXEC_ENV_WINDOWS - " --"OPT_SYSLOG" Set syslog facility\n" + " --"OPT_SYSLOG"=<facility> Set syslog facility\n" #endif" --" OPT_LOG_LEVEL "=<level> Set global log level\n" " --" OPT_LOG_LEVEL "=<type-match>:<level>\n"
lib/eal/freebsd/eal.c +1 -1
@@ -394,7 +394,7 @@ eal_parse_args(int argc, char **argv) }/* eal_log_level_parse() already handled this option */ -if (opt ==OPT_LOG_LEVEL_NUM ) +if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_SYSLOG_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
lib/eal/linux/eal.c +1 -1
@@ -611,7 +611,7 @@ eal_parse_args(int argc, char **argv) }/* eal_log_level_parse() already handled these */ -if (opt ==OPT_LOG_LEVEL_NUM ) +if (opt ==OPT_LOG_LEVEL_NUM || opt ==OPT_SYSLOG_NUM )continue ; ret =eal_parse_common_option (opt, optarg, internal_conf);
lib/eal/unix/eal_log.c +1 -0
@@ -80,6 +80,7 @@ eal_log_level_parse(int argc, char *const argv[]) eal_long_options, &option_index)) != EOF) {switch (opt) { +case OPT_SYSLOG_NUM :case OPT_LOG_LEVEL_NUM :if (eal_parse_common_option (opt, optarg, internal_conf) <0 )return -1 ;
Signature · 1 line
2.39.2
PATCH v5 4/6 eal: skip stdio on console logging
In reply to Stephen HemmingerThere is no need to use stdio when logging to console. Using the write system call directly avoids unnecessary copy to stdio output buffer.
--- lib/eal/unix/eal_log.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
lib/eal/unix/eal_log.c +2 -2
@@ -6,6 +6,7 @@#include <stdio.h> #include <sys/types.h> #include <syslog.h> +#include <unistd.h> #include <rte_log.h>
@@ -23,8 +24,7 @@ console_log_write(__rte_unused void *c, const char *buf, size_t size)ssize_t ret;/* write on stderr */ - ret =fwrite (buf,1 , size, stderr); -fflush (stderr); + ret =write (STDERR_FILENO , buf, size);/* Syslog error levels are from 0 to 7, so subtract 1 to convert */ syslog (rte_log_cur_msg_loglevel () -1 ,"%.*s" , (int )size, buf);
Signature · 1 line
2.39.2
PATCH v5 5/6 eal: allow user to set default log stream before init
In reply to Stephen HemmingerIt is useful for application to be able to set the default log stream before call rte_eal_init(). This makes all messages go to the new default.
For example, to skip using syslog; just doing
rte_log_set_default(stderr);
--- lib/eal/common/eal_common_log.c | 6 ++++++ lib/eal/common/eal_log.h | 1 + lib/eal/unix/eal_log.c | 4 ++++ 3 files changed, 11 insertions(+)
lib/eal/common/eal_common_log.c +6 -0
@@ -535,6 +535,12 @@ eal_log_set_default(FILE *default_log)#endif } +FILE * +eal_log_get_default (void ) +{ +return default_log_stream; +} +/* * Called by eal_cleanup */
lib/eal/common/eal_log.h +1 -0
@@ -22,6 +22,7 @@ int eal_log_level_parse(int argc, char * const argv[]);* Determine where log data is written when no call to rte_openlog_stream. */ void eal_log_set_default (FILE *default_log); +FILE *eal_log_get_default (void );/* * Save a log option for later.
lib/eal/unix/eal_log.c +4 -0
@@ -113,6 +113,10 @@ eal_log_init(const char *id, int facility) {FILE *log_stream; +/* has user has already setup a log stream */ +if (eal_log_get_default ()) +return 0 ; + log_stream =fopencookie (NULL ,"w+" , console_log_func);if (log_stream ==NULL )return -1 ;
Signature · 1 line
2.39.2
PATCH v5 6/6 eal: add option to put timestamp on console output
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. The timestamp format is chosen to look like the default Linux dmesg timestamp.
The first few lines are not timestamped because the flag is stored in internal configuration which is stored in shared memory which is not setup up until a little later in startup process.
Example:
$ dpdk-testpmd --log-timestamp -- -i EAL: Detected CPU lcores: 16 EAL: Detected NUMA nodes: 1 EAL: Detected static linkage of DPDK EAL: Multi-process socket /var/run/dpdk/rte/mp_socket EAL: Selected IOVA mode 'VA' [ 0.112264] testpmd: No probed ethernet devices Interactive-mode selected [ 0.184573] testpmd: create a new mbuf pool <mb_pool_0>: n=163456, size=2176, socket=0 [ 0.184612] testpmd: preferred mempool ops selected: ring_mp_mc
--- .../freebsd_gsg/freebsd_eal_parameters.rst | 5 +++ doc/guides/linux_gsg/linux_eal_parameters.rst | 5 +++ lib/eal/common/eal_common_options.c | 6 +++ lib/eal/common/eal_internal_cfg.h | 3 ++ lib/eal/common/eal_options.h | 2 + lib/eal/freebsd/eal.c | 4 +- lib/eal/linux/eal.c | 4 +- lib/eal/unix/eal_log.c | 44 +++++++++++++++++-- 8 files changed, 67 insertions(+), 6 deletions(-)
doc/guides/freebsd_gsg/freebsd_eal_parameters.rst +5 -0
@@ -45,3 +45,8 @@ Other options local5 local6 local7 + +* ``--log-timestamp`` + + Add a timestamp of seconds and microseconds to each log message + written to standard output.
doc/guides/linux_gsg/linux_eal_parameters.rst +5 -0
@@ -135,3 +135,8 @@ Other options local5 local6 local7 + +* ``--log-timestamp`` + + Add a timestamp of seconds and microseconds to each log message + written to standard output.
lib/eal/common/eal_common_options.c +6 -0
@@ -76,6 +76,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, 0, 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 },
@@ -1835,6 +1836,10 @@ eal_parse_common_option(int opt, const char *optarg, }#ifndef RTE_EXEC_ENV_WINDOWS +case OPT_LOG_TIMESTAMP_NUM : + conf->log_timestamp =1 ; +break ; +case OPT_TRACE_NUM : {if (eal_trace_args_save (optarg) <0 ) { RTE_LOG(ERR, EAL, "invalid parameters for --"
@@ -2194,6 +2199,7 @@ eal_common_usage(void) " --"OPT_PROC_TYPE" Type of this process (primary|secondary|auto)\n" #ifndef RTE_EXEC_ENV_WINDOWS " --"OPT_SYSLOG"=<facility> Set syslog facility\n" + " --"OPT_LOG_TIMESTAMP" Timestamp log output\n" #endif" --" OPT_LOG_LEVEL "=<level> Set global log level\n" " --" OPT_LOG_LEVEL "=<type-match>:<level>\n"
lib/eal/common/eal_internal_cfg.h +3 -0
@@ -84,7 +84,10 @@ struct internal_config {/**< true if storing all pages within single files (per-page-size, * per-node) non-legacy mode only. */ +uint8_t log_timestamp;/**< add timestamp to console output */ +struct timespec log_start_time;/**< monotonic clock when started */ volatile int syslog_facility;/**< facility passed to openlog() */ +/** default interrupt mode for VFIO */ volatile enum rte_intr_mode vfio_intr_mode;/** the shared VF token for VFIO-PCI bound PF and VFs devices */
lib/eal/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 +3 -1
@@ -394,7 +394,9 @@ eal_parse_args(int argc, char **argv) }/* eal_log_level_parse() already handled this option */ -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/linux/eal.c +3 -1
@@ -611,7 +611,9 @@ eal_parse_args(int argc, char **argv) }/* eal_log_level_parse() already handled these */ -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/unix/eal_log.c +40 -4
78 lines not on this page · raw message
Signature · 1 line
2.39.2
v6 cover Logging related patches
In reply to Stephen HemmingerPatchset that includes:
- unified code for more of log argument handling
- fix for duplicate option errors
- timestamp option for logging
v6
- fix build on freebsd and windows
- add test for log timestamp
Stephen Hemminger (6):
eal: unify logging code
eal: turn off getopt_long error message during eal_log_level
eal: fix help message for syslog option
eal: skip stdio on console logging
eal: allow user to set default log stream before init
eal: add option to put timestamp on console output
app/dumpcap/main.c | 3 + app/pdump/main.c | 3 + app/proc-info/main.c | 3 + app/test/test_eal_flags.c | 9 ++ .../freebsd_gsg/freebsd_eal_parameters.rst | 32 +++++ doc/guides/linux_gsg/linux_eal_parameters.rst | 5 + lib/eal/common/eal_common_log.c | 55 +++++++++ lib/eal/common/eal_common_options.c | 8 +- lib/eal/common/eal_internal_cfg.h | 3 + lib/eal/common/eal_log.h | 6 + lib/eal/common/eal_options.h | 2 + lib/eal/freebsd/eal.c | 55 ++------- lib/eal/linux/eal.c | 46 +------- lib/eal/linux/eal_log.c | 61 ---------- lib/eal/linux/meson.build | 1 - lib/eal/unix/eal_log.c | 111 ++++++++++++++++++ lib/eal/unix/meson.build | 1 + lib/eal/windows/eal.c | 36 +----- 18 files changed, 259 insertions(+), 181 deletions(-) delete mode 100644 lib/eal/linux/eal_log.c create mode 100644 lib/eal/unix/eal_log.c
Signature · 1 line
2.39.2
PATCH v6 1/6 eal: unify logging code
FreeBSD logging code was not using syslog and did not have the same options as Linux. Use a common set of functions for that.
Pre-parsing for log level is common to all OS's.
Now the pre-scan can return an error.
A bad argument give to --log-level option was given the code would keep going.
make log_parse common to windows
---
.../freebsd_gsg/freebsd_eal_parameters.rst | 27 +++++++++
lib/eal/common/eal_common_log.c | 46 ++++++++++++++++
lib/eal/common/eal_log.h | 5 ++
lib/eal/freebsd/eal.c | 55 ++++---------------
lib/eal/linux/eal.c | 46 ++--------------
lib/eal/linux/meson.build | 1 -
lib/eal/{linux => unix}/eal_log.c | 11 ++++
lib/eal/unix/meson.build | 1 +
lib/eal/windows/eal.c | 35 ------------
9 files changed, 108 insertions(+), 119 deletions(-)
rename lib/eal/{linux => unix}/eal_log.c (76%)doc/guides/freebsd_gsg/freebsd_eal_parameters.rst +27 -0
@@ -18,3 +18,30 @@ FreeBSD-specific EAL parameters ------------------------------- There are currently no FreeBSD-specific EAL command-line parameters available. + +Other options +~~~~~~~~~~~~~ + +* ``--syslog <syslog facility>`` + + Set syslog facility. Valid syslog facilities are:: + + auth + cron + daemon + ftp + kern + lpr + mail + news + syslog + user + uucp + local0 + local1 + local2 + local3 + local4 + local5 + local6 + local7
lib/eal/common/eal_common_log.c +46 -0
64 lines not on this page · raw message
lib/eal/common/eal_log.h +5 -0
@@ -13,6 +13,11 @@*/ int eal_log_init (const char *id,int facility); +/* +* Scan command line args for log settings. +*/ +int eal_log_level_parse (int argc,char *const argv[]); +/* * Determine where log data is written when no call to rte_openlog_stream. */
lib/eal/freebsd/eal.c +12 -43
79 lines not on this page · raw message
lib/eal/linux/eal.c +6 -40
58 lines not on this page · raw message
lib/eal/linux/meson.build +0 -1
@@ -11,7 +11,6 @@ sources += files( 'eal_hugepage_info.c', 'eal_interrupts.c', 'eal_lcore.c', - 'eal_log.c', 'eal_memalloc.c', 'eal_memory.c', 'eal_thread.c',
lib/eal/unix/eal_log.c renamed from lib/eal/linux/eal_log.c +11 -0
@@ -9,6 +9,8 @@#include <rte_log.h> #include "eal_log.h" +#include "eal_internal_cfg.h" +#include "eal_private.h" /* * default log function
@@ -25,6 +27,15 @@ console_log_write(__rte_unused void *c, const char *buf, size_t size)/* Syslog error levels are from 0 to 7, so subtract 1 to convert */ syslog (rte_log_cur_msg_loglevel () -1 ,"%.*s" , (int )size, buf); +#ifdef RTE_EXEC_ENV_LINUX +/* Handle glibc quirk: write function should return the number of bytes +* copied from buf, or 0 on error. (The function must not return a negative value.) +* FreeBSD expects that write function behaves like write(2). +*/ +if (ret <0 ) + ret =0 ; +#endif +return ret; }
lib/eal/unix/meson.build +1 -0
@@ -6,6 +6,7 @@ sources += files( 'eal_file.c', 'eal_filesystem.c', 'eal_firmware.c', + 'eal_log.c', 'eal_unix_memory.c', 'eal_unix_thread.c', 'eal_unix_timer.c',
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.39.2
PATCH v6 2/6 eal: turn off getopt_long error message during eal_log_level
In reply to Stephen HemmingerIf DPDK application is given a bogus option, the error message would get printed twice. Once during scan for log level and again during parsing of arguments.
Example:
# ./build/app/dpdk-testpmd --bogus ./build/app/dpdk-testpmd: unrecognized option '--bogus' EAL: Detected CPU lcores: 16 EAL: Detected NUMA nodes: 1 ./build/app/dpdk-testpmd: unrecognized option '--bogus'
Usage: ./build/app/dpdk-testpmd [options]
Fix by suppressing printing error message on first pass.
--- lib/eal/common/eal_common_log.c | 3 +++ lib/eal/windows/eal.c | 1 + 2 files changed, 4 insertions(+)
lib/eal/common/eal_common_log.c +3 -0
@@ -235,6 +235,7 @@ eal_log_level_parse(int argc, char *const argv[])int option_index, opt;const int old_optind = optind;const int old_optopt = optopt; +const int old_opterr = opterr;char *const old_optarg = optarg;#ifdef RTE_EXEC_ENV_FREEBSD const int old_optreset = optreset;
@@ -242,6 +243,7 @@ eal_log_level_parse(int argc, char *const argv[])#endif optind =1 ; + opterr =0 ;while ((opt =getopt_long (argc, argv, eal_short_options, eal_long_options, &option_index)) !=EOF ) {
@@ -263,6 +265,7 @@ eal_log_level_parse(int argc, char *const argv[]) optind = old_optind; optopt = old_optopt; optarg = old_optarg; + opterr = old_opterr;#ifdef RTE_EXEC_ENV_FREEBSD optreset = old_optreset;#endif
lib/eal/windows/eal.c +1 -0
@@ -108,6 +108,7 @@ eal_parse_args(int argc, char **argv)eal_get_internal_configuration (); argvopt = argv; + opterr =1 ;while ((opt =getopt_long (argc, argvopt, eal_short_options, eal_long_options, &option_index)) !=EOF ) {
Signature · 1 line
2.39.2
PATCH v6 3/6 eal: fix help message for syslog option
In reply to Stephen HemmingerThe --syslog flag takes facility argument.
--- lib/eal/common/eal_common_options.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
lib/eal/common/eal_common_options.c +1 -1
@@ -2193,7 +2193,7 @@ eal_common_usage(void) " --"OPT_VMWARE_TSC_MAP" Use VMware TSC map instead of native RDTSC\n" " --"OPT_PROC_TYPE" Type of this process (primary|secondary|auto)\n" #ifndef RTE_EXEC_ENV_WINDOWS - " --"OPT_SYSLOG" Set syslog facility\n" + " --"OPT_SYSLOG"=<facility> Set syslog facility\n" #endif" --" OPT_LOG_LEVEL "=<level> Set global log level\n" " --" OPT_LOG_LEVEL "=<type-match>:<level>\n"
Signature · 1 line
2.39.2
PATCH v6 4/6 eal: skip stdio on console logging
In reply to Stephen HemmingerThere is no need to use stdio when logging to console. Using the write system call directly avoids unnecessary copy to stdio output buffer.
--- lib/eal/unix/eal_log.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
lib/eal/unix/eal_log.c +2 -2
@@ -5,6 +5,7 @@#include <stdio.h> #include <sys/types.h> #include <syslog.h> +#include <unistd.h> #include <rte_log.h>
@@ -21,8 +22,7 @@ console_log_write(__rte_unused void *c, const char *buf, size_t size)ssize_t ret;/* write on stderr */ - ret =fwrite (buf,1 , size, stderr); -fflush (stderr); + ret =write (STDERR_FILENO , buf, size);/* Syslog error levels are from 0 to 7, so subtract 1 to convert */ syslog (rte_log_cur_msg_loglevel () -1 ,"%.*s" , (int )size, buf);
Signature · 1 line
2.39.2
PATCH v6 5/6 eal: allow user to set default log stream before init
In reply to Stephen HemmingerIt is useful for application to be able to set the default log stream before call rte_eal_init(). This makes all messages go to the new default.
For example, to skip using syslog; just doing
rte_openlog_stream(stderr);
There is no reason for helper command line applications to clutter syslog with messages.
--- app/dumpcap/main.c | 3 +++ app/pdump/main.c | 3 +++ app/proc-info/main.c | 3 +++ lib/eal/common/eal_common_log.c | 6 ++++++ lib/eal/common/eal_log.h | 1 + lib/eal/unix/eal_log.c | 4 ++++ 6 files changed, 20 insertions(+)
app/dumpcap/main.c +3 -0
@@ -639,6 +639,9 @@ static void dpdk_init(void) eal_argv[i++] =strdup (file_prefix); } +/* keep any logging away from syslog. */ +rte_openlog_stream (stderr); +if (rte_eal_init (eal_argc, eal_argv) <0 )rte_exit (EXIT_FAILURE ,"EAL init failed: is primary process running?\n" ); }
app/pdump/main.c +3 -0
@@ -989,6 +989,9 @@ main(int argc, char **argv) argc +=2 ; +/* keep any logging away from syslog. */ +rte_openlog_stream (stderr); + diag =rte_eal_init (argc, argp);if (diag <0 )rte_panic ("Cannot init EAL\n" );
app/proc-info/main.c +3 -0
@@ -1774,6 +1774,9 @@ main(int argc, char **argv) argc +=4 ; +/* keep any logging away from syslog. */ +rte_openlog_stream (stderr); + ret =rte_eal_init (argc, argp);if (ret <0 )rte_panic ("Cannot init EAL\n" );
lib/eal/common/eal_common_log.c +6 -0
@@ -584,6 +584,12 @@ eal_log_set_default(FILE *default_log)#endif } +FILE * +eal_log_get_default (void ) +{ +return default_log_stream; +} +/* * Called by eal_cleanup */
lib/eal/common/eal_log.h +1 -0
@@ -22,6 +22,7 @@ int eal_log_level_parse(int argc, char * const argv[]);* Determine where log data is written when no call to rte_openlog_stream. */ void eal_log_set_default (FILE *default_log); +FILE *eal_log_get_default (void );/* * Save a log option for later.
lib/eal/unix/eal_log.c +4 -0
@@ -60,6 +60,10 @@ eal_log_init(const char *id, int facility) {FILE *log_stream; +/* has user has already setup a log stream */ +if (eal_log_get_default ()) +return 0 ; + log_stream =fopencookie (NULL ,"w+" , console_log_func);if (log_stream ==NULL )return -1 ;
Signature · 1 line
2.39.2
PATCH v6 6/6 eal: add option to put timestamp on console output
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. The timestamp format is chosen to look like the default Linux dmesg timestamp.
The first few lines are not timestamped because the flag is stored in internal configuration which is stored in shared memory which is not setup up until a little later in startup process.
Example:
$ dpdk-testpmd --log-timestamp -- -i EAL: Detected CPU lcores: 16 EAL: Detected NUMA nodes: 1 EAL: Detected static linkage of DPDK EAL: Multi-process socket /var/run/dpdk/rte/mp_socket EAL: Selected IOVA mode 'VA' [ 0.112264] testpmd: No probed ethernet devices Interactive-mode selected [ 0.184573] testpmd: create a new mbuf pool <mb_pool_0>: n=163456, size=2176, socket=0 [ 0.184612] testpmd: preferred mempool ops selected: ring_mp_mc
--- app/test/test_eal_flags.c | 9 ++++ .../freebsd_gsg/freebsd_eal_parameters.rst | 5 +++ doc/guides/linux_gsg/linux_eal_parameters.rst | 5 +++ lib/eal/common/eal_common_options.c | 6 +++ lib/eal/common/eal_internal_cfg.h | 3 ++ lib/eal/common/eal_options.h | 2 + lib/eal/unix/eal_log.c | 43 +++++++++++++++++-- 7 files changed, 69 insertions(+), 4 deletions(-)
app/test/test_eal_flags.c +9 -0
@@ -1055,6 +1055,10 @@ 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" }; +/* run all tests also applicable to FreeBSD first */ if (launch_proc (argv0) ==0 ) {
@@ -1162,6 +1166,11 @@ 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; + } +rmdir (hugepath_dir3);rmdir (hugepath_dir2);
doc/guides/freebsd_gsg/freebsd_eal_parameters.rst +5 -0
@@ -45,3 +45,8 @@ Other options local5 local6 local7 + +* ``--log-timestamp`` + + Add a timestamp of seconds and microseconds to each log message + written to standard output.
doc/guides/linux_gsg/linux_eal_parameters.rst +5 -0
@@ -135,3 +135,8 @@ Other options local5 local6 local7 + +* ``--log-timestamp`` + + Add a timestamp of seconds and microseconds to each log message + written to standard output.
lib/eal/common/eal_common_options.c +6 -0
@@ -76,6 +76,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, 0, 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 },
@@ -1835,6 +1836,10 @@ eal_parse_common_option(int opt, const char *optarg, }#ifndef RTE_EXEC_ENV_WINDOWS +case OPT_LOG_TIMESTAMP_NUM : + conf->log_timestamp =1 ; +break ; +case OPT_TRACE_NUM : {if (eal_trace_args_save (optarg) <0 ) { RTE_LOG(ERR, EAL, "invalid parameters for --"
@@ -2194,6 +2199,7 @@ eal_common_usage(void) " --"OPT_PROC_TYPE" Type of this process (primary|secondary|auto)\n" #ifndef RTE_EXEC_ENV_WINDOWS " --"OPT_SYSLOG"=<facility> Set syslog facility\n" + " --"OPT_LOG_TIMESTAMP" Timestamp log output\n" #endif" --" OPT_LOG_LEVEL "=<level> Set global log level\n" " --" OPT_LOG_LEVEL "=<type-match>:<level>\n"
lib/eal/common/eal_internal_cfg.h +3 -0
@@ -84,7 +84,10 @@ struct internal_config {/**< true if storing all pages within single files (per-page-size, * per-node) non-legacy mode only. */ +uint8_t log_timestamp;/**< add timestamp to console output */ +struct timespec log_start_time;/**< monotonic clock when started */ volatile int syslog_facility;/**< facility passed to openlog() */ +/** default interrupt mode for VFIO */ volatile enum rte_intr_mode vfio_intr_mode;/** the shared VF token for VFIO-PCI bound PF and VFs devices */
lib/eal/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/unix/eal_log.c +39 -4
71 lines not on this page · raw message
Signature · 1 line
2.39.2
v7 cover Logging timetamp and related patches
In reply to Stephen HemmingerPatchset that includes:
- unified code for more of log argument handling
- fix for duplicate option errors
- timestamp option for logging
v7
- consolidate patches
- fix windows to have same getopt args as Linux and FreeBSD
Stephen Hemminger (5):
windows: make getopt functions have const properties
eal: fix help message for syslog option
eal: unify logging code
eal: allow user to set default log stream before init
eal: add option to put timestamp on console output
app/dumpcap/main.c | 3 + app/pdump/main.c | 3 + app/proc-info/main.c | 3 + app/test/test_eal_flags.c | 9 ++ .../freebsd_gsg/freebsd_eal_parameters.rst | 32 +++++ doc/guides/linux_gsg/linux_eal_parameters.rst | 5 + lib/eal/common/eal_common_log.c | 55 +++++++++ lib/eal/common/eal_common_options.c | 8 +- lib/eal/common/eal_internal_cfg.h | 3 + lib/eal/common/eal_log.h | 6 + lib/eal/common/eal_options.h | 2 + lib/eal/freebsd/eal.c | 55 ++------- lib/eal/linux/eal.c | 46 +------- lib/eal/linux/eal_log.c | 61 ---------- lib/eal/linux/meson.build | 1 - lib/eal/unix/eal_log.c | 111 ++++++++++++++++++ lib/eal/unix/meson.build | 1 + lib/eal/windows/eal.c | 36 +----- lib/eal/windows/getopt.c | 23 ++-- lib/eal/windows/include/getopt.h | 8 +- 20 files changed, 275 insertions(+), 196 deletions(-) delete mode 100644 lib/eal/linux/eal_log.c create mode 100644 lib/eal/unix/eal_log.c
Signature · 1 line
2.39.2
PATCH v7 1/5 windows: make getopt functions have const properties
This aligns getopt, getopt_long, etc to have the same const attributes as Linux and FreeBSD. The changes are derived from the 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.39.2
Re: [PATCH v7 1/5] windows: make getopt functions have const properties
Quoted 6 lines · Stephen Hemminger
This aligns getopt,
getopt_long, etc to have the same const attributes as Linux and FreeBSD. The changes are derived from the FreeBSD version ofgetopt_long.Signed-off-by Stephen Hemminger <[email protected]>---
PATCH v7 2/5 eal: fix help message for syslog option
In reply to Stephen HemmingerThe --syslog flag takes facility argument.
--- lib/eal/common/eal_common_options.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
lib/eal/common/eal_common_options.c +1 -1
@@ -2193,7 +2193,7 @@ eal_common_usage(void) " --"OPT_VMWARE_TSC_MAP" Use VMware TSC map instead of native RDTSC\n" " --"OPT_PROC_TYPE" Type of this process (primary|secondary|auto)\n" #ifndef RTE_EXEC_ENV_WINDOWS - " --"OPT_SYSLOG" Set syslog facility\n" + " --"OPT_SYSLOG"=<facility> Set syslog facility\n" #endif" --" OPT_LOG_LEVEL "=<level> Set global log level\n" " --" OPT_LOG_LEVEL "=<type-match>:<level>\n"
Signature · 1 line
2.39.2
PATCH v7 3/5 eal: unify logging code
In reply to Stephen HemmingerFreeBSD logging code was not using syslog and did not have the same options as Linux. Use a common set of functions for that.
Pre-parsing for log level is common to all OS's.
Now the pre-scan can return an error.
A bad argument give to --log-level option was given the code would keep going.
Use opterr to fix duplicate error message on bad option.
---
.../freebsd_gsg/freebsd_eal_parameters.rst | 27 +++++++++
lib/eal/common/eal_common_log.c | 49 +++++++++++++++++
lib/eal/common/eal_log.h | 5 ++
lib/eal/freebsd/eal.c | 55 ++++---------------
lib/eal/linux/eal.c | 46 ++--------------
lib/eal/linux/meson.build | 1 -
lib/eal/{linux => unix}/eal_log.c | 11 ++++
lib/eal/unix/meson.build | 1 +
lib/eal/windows/eal.c | 36 +-----------
9 files changed, 112 insertions(+), 119 deletions(-)
rename lib/eal/{linux => unix}/eal_log.c (76%)doc/guides/freebsd_gsg/freebsd_eal_parameters.rst +27 -0
@@ -18,3 +18,30 @@ FreeBSD-specific EAL parameters ------------------------------- There are currently no FreeBSD-specific EAL command-line parameters available. + +Other options +~~~~~~~~~~~~~ + +* ``--syslog <syslog facility>`` + + Set syslog facility. Valid syslog facilities are:: + + auth + cron + daemon + ftp + kern + lpr + mail + news + syslog + user + uucp + local0 + local1 + local2 + local3 + local4 + local5 + local6 + local7
lib/eal/common/eal_common_log.c +49 -0
67 lines not on this page · raw message
lib/eal/common/eal_log.h +5 -0
@@ -13,6 +13,11 @@*/ int eal_log_init (const char *id,int facility); +/* +* Scan command line args for log settings. +*/ +int eal_log_level_parse (int argc,char *const argv[]); +/* * Determine where log data is written when no call to rte_openlog_stream. */
lib/eal/freebsd/eal.c +12 -43
79 lines not on this page · raw message
lib/eal/linux/eal.c +6 -40
58 lines not on this page · raw message
lib/eal/linux/meson.build +0 -1
@@ -11,7 +11,6 @@ sources += files( 'eal_hugepage_info.c', 'eal_interrupts.c', 'eal_lcore.c', - 'eal_log.c', 'eal_memalloc.c', 'eal_memory.c', 'eal_thread.c',
lib/eal/unix/eal_log.c renamed from lib/eal/linux/eal_log.c +11 -0
@@ -9,6 +9,8 @@#include <rte_log.h> #include "eal_log.h" +#include "eal_internal_cfg.h" +#include "eal_private.h" /* * default log function
@@ -25,6 +27,15 @@ console_log_write(__rte_unused void *c, const char *buf, size_t size)/* Syslog error levels are from 0 to 7, so subtract 1 to convert */ syslog (rte_log_cur_msg_loglevel () -1 ,"%.*s" , (int )size, buf); +#ifdef RTE_EXEC_ENV_LINUX +/* Handle glibc quirk: write function should return the number of bytes +* copied from buf, or 0 on error. (The function must not return a negative value.) +* FreeBSD expects that write function behaves like write(2). +*/ +if (ret <0 ) + ret =0 ; +#endif +return ret; }
lib/eal/unix/meson.build +1 -0
@@ -6,6 +6,7 @@ sources += files( 'eal_file.c', 'eal_filesystem.c', 'eal_firmware.c', + 'eal_log.c', 'eal_unix_memory.c', 'eal_unix_thread.c', 'eal_unix_timer.c',
lib/eal/windows/eal.c +1 -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)
@@ -143,6 +108,7 @@ eal_parse_args(int argc, char **argv)eal_get_internal_configuration (); argvopt = argv; + opterr =1 ;while ((opt =getopt_long (argc, argvopt, eal_short_options, eal_long_options, &option_index)) !=EOF ) {
Signature · 1 line
2.39.2
PATCH v7 4/5 eal: allow user to set default log stream before init
In reply to Stephen HemmingerIt is useful for application to be able to set the default log stream before call rte_eal_init(). This makes all messages go to the new default.
For example, to skip using syslog; just doing
rte_openlog_stream(stderr);
There is no reason for helper command line applications to clutter syslog with messages.
--- app/dumpcap/main.c | 3 +++ app/pdump/main.c | 3 +++ app/proc-info/main.c | 3 +++ lib/eal/common/eal_common_log.c | 6 ++++++ lib/eal/common/eal_log.h | 1 + lib/eal/unix/eal_log.c | 4 ++++ 6 files changed, 20 insertions(+)
app/dumpcap/main.c +3 -0
@@ -639,6 +639,9 @@ static void dpdk_init(void) eal_argv[i++] =strdup (file_prefix); } +/* keep any logging away from syslog. */ +rte_openlog_stream (stderr); +if (rte_eal_init (eal_argc, eal_argv) <0 )rte_exit (EXIT_FAILURE ,"EAL init failed: is primary process running?\n" ); }
app/pdump/main.c +3 -0
@@ -989,6 +989,9 @@ main(int argc, char **argv) argc +=2 ; +/* keep any logging away from syslog. */ +rte_openlog_stream (stderr); + diag =rte_eal_init (argc, argp);if (diag <0 )rte_panic ("Cannot init EAL\n" );
app/proc-info/main.c +3 -0
@@ -1774,6 +1774,9 @@ main(int argc, char **argv) argc +=4 ; +/* keep any logging away from syslog. */ +rte_openlog_stream (stderr); + ret =rte_eal_init (argc, argp);if (ret <0 )rte_panic ("Cannot init EAL\n" );
lib/eal/common/eal_common_log.c +6 -0
@@ -584,6 +584,12 @@ eal_log_set_default(FILE *default_log)#endif } +FILE * +eal_log_get_default (void ) +{ +return default_log_stream; +} +/* * Called by eal_cleanup */
lib/eal/common/eal_log.h +1 -0
@@ -22,6 +22,7 @@ int eal_log_level_parse(int argc, char * const argv[]);* Determine where log data is written when no call to rte_openlog_stream. */ void eal_log_set_default (FILE *default_log); +FILE *eal_log_get_default (void );/* * Save a log option for later.
lib/eal/unix/eal_log.c +4 -0
@@ -60,6 +60,10 @@ eal_log_init(const char *id, int facility) {FILE *log_stream; +/* has user has already setup a log stream */ +if (eal_log_get_default ()) +return 0 ; + log_stream =fopencookie (NULL ,"w+" , console_log_func);if (log_stream ==NULL )return -1 ;
Signature · 1 line
2.39.2
PATCH v7 5/5 eal: add option to put timestamp on console output
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. The timestamp format is chosen to look like the default Linux dmesg timestamp.
The first few lines are not timestamped because the flag is stored in internal configuration which is stored in shared memory which is not setup up until a little later in startup process.
This logging skips the unnecessary step of going through stdio, which makes it more robust against being called in interrupt handlers etc.
Example:
$ dpdk-testpmd --log-timestamp -- -i EAL: Detected CPU lcores: 16 EAL: Detected NUMA nodes: 1 EAL: Detected static linkage of DPDK EAL: Multi-process socket /var/run/dpdk/rte/mp_socket EAL: Selected IOVA mode 'VA' [ 0.112264] testpmd: No probed ethernet devices Interactive-mode selected [ 0.184573] testpmd: create a new mbuf pool <mb_pool_0>: n=163456, size=2176, socket=0 [ 0.184612] testpmd: preferred mempool ops selected: ring_mp_mc
--- app/test/test_eal_flags.c | 9 ++++ .../freebsd_gsg/freebsd_eal_parameters.rst | 5 +++ doc/guides/linux_gsg/linux_eal_parameters.rst | 5 +++ lib/eal/common/eal_common_options.c | 6 +++ lib/eal/common/eal_internal_cfg.h | 3 ++ lib/eal/common/eal_options.h | 2 + lib/eal/unix/eal_log.c | 45 ++++++++++++++++--- 7 files changed, 70 insertions(+), 5 deletions(-)
app/test/test_eal_flags.c +9 -0
@@ -1055,6 +1055,10 @@ 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" }; +/* run all tests also applicable to FreeBSD first */ if (launch_proc (argv0) ==0 ) {
@@ -1162,6 +1166,11 @@ 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; + } +rmdir (hugepath_dir3);rmdir (hugepath_dir2);
doc/guides/freebsd_gsg/freebsd_eal_parameters.rst +5 -0
@@ -45,3 +45,8 @@ Other options local5 local6 local7 + +* ``--log-timestamp`` + + Add a timestamp of seconds and microseconds to each log message + written to standard output.
doc/guides/linux_gsg/linux_eal_parameters.rst +5 -0
@@ -135,3 +135,8 @@ Other options local5 local6 local7 + +* ``--log-timestamp`` + + Add a timestamp of seconds and microseconds to each log message + written to standard output.
lib/eal/common/eal_common_options.c +6 -0
@@ -76,6 +76,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, 0, 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 },
@@ -1835,6 +1836,10 @@ eal_parse_common_option(int opt, const char *optarg, }#ifndef RTE_EXEC_ENV_WINDOWS +case OPT_LOG_TIMESTAMP_NUM : + conf->log_timestamp =1 ; +break ; +case OPT_TRACE_NUM : {if (eal_trace_args_save (optarg) <0 ) { RTE_LOG(ERR, EAL, "invalid parameters for --"
@@ -2194,6 +2199,7 @@ eal_common_usage(void) " --"OPT_PROC_TYPE" Type of this process (primary|secondary|auto)\n" #ifndef RTE_EXEC_ENV_WINDOWS " --"OPT_SYSLOG"=<facility> Set syslog facility\n" + " --"OPT_LOG_TIMESTAMP" Timestamp log output\n" #endif" --" OPT_LOG_LEVEL "=<level> Set global log level\n" " --" OPT_LOG_LEVEL "=<type-match>:<level>\n"
lib/eal/common/eal_internal_cfg.h +3 -0
@@ -84,7 +84,10 @@ struct internal_config {/**< true if storing all pages within single files (per-page-size, * per-node) non-legacy mode only. */ +uint8_t log_timestamp;/**< add timestamp to console output */ +struct timespec log_start_time;/**< monotonic clock when started */ volatile int syslog_facility;/**< facility passed to openlog() */ +/** default interrupt mode for VFIO */ volatile enum rte_intr_mode vfio_intr_mode;/** the shared VF token for VFIO-PCI bound PF and VFs devices */
lib/eal/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/unix/eal_log.c +40 -5
73 lines not on this page · raw message
Signature · 1 line
2.39.2
v8 cover Logging timestamp and related patches
In reply to Stephen HemmingerImprovements and unification of logging library (for 24.07 release). This is update to earlier patch set.
v8 - rebase to current code base where logging in in lib/log
use stdio for log timestamp
initialization changes (setup log earlier)
Stephen Hemminger (5):
log: unify logging code
eal: make eal_log_level_parse common
eal: allow user to set default log stream before init
eal: add option to put timestamp on console output
eal: initialize logging before plugins
app/dumpcap/main.c | 3 +
app/pdump/main.c | 3 +
app/proc-info/main.c | 3 +
app/test/test_eal_flags.c | 9 +++
doc/guides/linux_gsg/linux_eal_parameters.rst | 27 ---------
doc/guides/prog_guide/log_lib.rst | 28 +++++++++-
lib/eal/common/eal_common_options.c | 56 ++++++++++++++++++-
lib/eal/common/eal_options.h | 3 +
lib/eal/freebsd/eal.c | 50 +++--------------
lib/eal/linux/eal.c | 55 +++---------------
lib/eal/unix/eal_unix_log.c | 0
lib/eal/windows/eal.c | 35 ------------
lib/log/log.c | 6 ++
lib/log/log_freebsd.c | 12 ----
lib/log/log_internal.h | 11 ++++
lib/log/{log_linux.c => log_unix.c} | 36 +++++++++++-
lib/log/log_windows.c | 6 ++
lib/log/meson.build | 12 ++--
lib/log/version.map | 2 +
19 files changed, 184 insertions(+), 173 deletions(-)
create mode 100644 lib/eal/unix/eal_unix_log.c
delete mode 100644 lib/log/log_freebsd.c
rename lib/log/{log_linux.c => log_unix.c} (58%)Signature · 1 line
2.43.0
PATCH v8 1/5 log: unify logging code
FreeBSD and Linux logging code can use common code. This also fixes FreeBSD not using syslog.
---
doc/guides/linux_gsg/linux_eal_parameters.rst | 27 -------------------
doc/guides/prog_guide/log_lib.rst | 18 +++++++++++--
lib/eal/freebsd/eal.c | 8 ++++++
lib/log/log_freebsd.c | 12 ---------
lib/log/{log_linux.c => log_unix.c} | 0
lib/log/meson.build | 12 ++++++---
6 files changed, 32 insertions(+), 45 deletions(-)
delete mode 100644 lib/log/log_freebsd.c
rename lib/log/{log_linux.c => log_unix.c} (100%)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 +16 -2
@@ -5,8 +5,8 @@ Log Library =========== The DPDK Log library provides the logging functionality for other DPDK libraries and drivers. -By default, in a Linux application, logs are sent to syslog and also to the console. -On FreeBSD and Windows applications, logs are sent only to the console. +By default, in a Linux (or FreeBSD) application, logs are sent to syslog and also to the console. +In Windows applications, logs are sent only to the console. However, the log function can be overridden by the user to use a different logging mechanism. Log Levels
@@ -29,6 +29,7 @@ will be emitted by the application to the log output. That level can be configured either by the application calling the relevant APIs from the logging library, or by the user passing the ``--log-level`` parameter to the EAL via the application. + Setting Global Log Level ~~~~~~~~~~~~~~~~~~~~~~~~
@@ -59,6 +60,19 @@ 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. + +Setting syslog facility +~~~~~~~~~~~~~~~~~~~~~~~ + +On Linux and FreeBSD, where syslog is used a ``facility`` argument can be +used to specify what type of program is logging. +The default facility is ``daemon`` but it can be overridden +by the ``--syslog`` EAL parameter. See ``syslog.3`` man page for full values. +For example:: + + /path/to/app --syslog local0 + + Using Logging APIs to Generate Log Messages -------------------------------------------
lib/eal/freebsd/eal.c +8 -0
@@ -760,6 +760,14 @@ rte_eal_init(int argc, char **argv)#endif } +if (eal_log_init (program_invocation_short_name, + internal_conf->syslog_facility) <0 ) { +rte_eal_init_alert ("Cannot init logging." ); + rte_errno =ENOMEM ; +rte_atomic_store_explicit (&run_once,0 , rte_memory_order_relaxed); +return -1 ; + } +/* in secondary processes, memory init may allocate additional fbarrays * not present in primary processes, so to avoid any potential issues, * initialize memzones first.
lib/log/log_freebsd.c deleted +0 -12
@@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause -* Copyright(c) 2023 Intel Corporation -*/ - -#include <rte_common.h> -#include "log_internal.h" - -int -eal_log_init(__rte_unused const char *id, __rte_unused int facility) -{ -return 0 ; -}
lib/log/log_unix.c renamed from lib/log/log_linux.c +0 -0
lib/log/meson.build +8 -4
@@ -2,8 +2,12 @@ # Copyright(c) 2023 Intel Corporation includes += global_inc -sources = files( - 'log.c', - 'log_' + exec_env + '.c', -) +sources = files('log.c') + +if is_windows + sources += files('log_windows.c') +else + sources += files('log_unix.c') +endif + headers = files('rte_log.h')
Signature · 1 line
2.43.0
PATCH v8 2/5 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-level */ +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 v8 3/5 eal: allow user to set default log stream before init
In reply to Stephen HemmingerIt is useful for application to be able to set the default log stream before call rte_eal_init(). This makes all messages go to the new default.
For example, to skip using syslog; just doing
rte_openlog_stream(stderr);
There is no reason for helper command line applications to clutter syslog with messages.
--- app/dumpcap/main.c | 3 +++ app/pdump/main.c | 3 +++ app/proc-info/main.c | 3 +++ lib/log/log.c | 6 ++++++ lib/log/log_internal.h | 2 ++ lib/log/log_unix.c | 4 ++++ lib/log/version.map | 1 + 7 files changed, 22 insertions(+)
app/dumpcap/main.c +3 -0
@@ -633,6 +633,9 @@ static void dpdk_init(void)rte_panic ("No memory\n" ); } +/* keep any logging away from syslog. */ +rte_openlog_stream (stderr); +if (rte_eal_init (eal_argc, eal_argv) <0 )rte_exit (EXIT_FAILURE ,"EAL init failed: is primary process running?\n" ); }
app/pdump/main.c +3 -0
@@ -995,6 +995,9 @@ main(int argc, char **argv) argc +=2 ; +/* keep any logging away from syslog. */ +rte_openlog_stream (stderr); + diag =rte_eal_init (argc, argp);if (diag <0 )rte_panic ("Cannot init EAL\n" );
app/proc-info/main.c +3 -0
@@ -2149,6 +2149,9 @@ main(int argc, char **argv) argc +=4 ; +/* keep any logging away from syslog. */ +rte_openlog_stream (stderr); + ret =rte_eal_init (argc, argp);if (ret <0 )rte_panic ("Cannot init EAL\n" );
lib/log/log.c +6 -0
@@ -519,6 +519,12 @@ eal_log_set_default(FILE *default_log)#endif } +FILE * +eal_log_get_default (void ) +{ +return default_log_stream; +} +/* * Called by eal_cleanup */
lib/log/log_internal.h +2 -0
@@ -21,6 +21,8 @@ int eal_log_init(const char *id, int facility);*/ __rte_internal void eal_log_set_default(FILE *default_log); +__rte_internal +FILE *eal_log_get_default(void);/* * Save a log option for later.
lib/log/log_unix.c +4 -0
@@ -49,6 +49,10 @@ eal_log_init(const char *id, int facility) {FILE *log_stream; +/* skip if user has already setup a log stream */ +if (eal_log_get_default ()) +return 0 ; + log_stream =fopencookie (NULL ,"w+" , console_log_func);if (log_stream ==NULL )return -1 ;
lib/log/version.map +1 -0
@@ -25,6 +25,7 @@ DPDK_24 { INTERNAL { global: + eal_log_get_default; eal_log_init; eal_log_level2str; eal_log_save_pattern;
Signature · 1 line
2.43.0
PATCH v8 4/5 eal: add option to put timestamp on console output
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. The timestamp format is chosen to look like the default Linux dmesg timestamp.
The first few lines are not timestamped because the flag is stored in internal configuration which is stored in shared memory which is not setup up until a little later in startup process.
This logging skips the unnecessary step of going through stdio, which makes it more robust against being called in interrupt handlers etc.
Example:
$ dpdk-testpmd --log-timestamp -- -i EAL: Detected CPU lcores: 16 EAL: Detected NUMA nodes: 1 EAL: Detected static linkage of DPDK EAL: Multi-process socket /var/run/dpdk/rte/mp_socket EAL: Selected IOVA mode 'VA' [ 0.112264] testpmd: No probed ethernet devices Interactive-mode selected [ 0.184573] testpmd: create a new mbuf pool <mb_pool_0>: n=163456, size=2176, socket=0 [ 0.184612] testpmd: preferred mempool ops selected: ring_mp_mc
--- app/test/test_eal_flags.c | 9 ++++++++ doc/guides/prog_guide/log_lib.rst | 10 +++++++++ lib/eal/common/eal_common_options.c | 10 +++++++-- lib/eal/common/eal_options.h | 2 ++ lib/log/log_internal.h | 9 ++++++++ lib/log/log_unix.c | 32 +++++++++++++++++++++++++++-- lib/log/log_windows.c | 6 ++++++ lib/log/version.map | 1 + 8 files changed, 75 insertions(+), 4 deletions(-)
app/test/test_eal_flags.c +9 -0
@@ -1055,6 +1055,10 @@ 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" }; +/* run all tests also applicable to FreeBSD first */ if (launch_proc (argv0) ==0 ) {
@@ -1162,6 +1166,11 @@ 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; + } +rmdir (hugepath_dir3);rmdir (hugepath_dir2);
doc/guides/prog_guide/log_lib.rst +10 -0
@@ -73,6 +73,16 @@ For example:: /path/to/app --syslog local0 +Console timestamp +~~~~~~~~~~~~~~~~~ + +On Linux and FreeBSD, 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 + + Using Logging APIs to Generate Log Messages -------------------------------------------
lib/eal/common/eal_common_options.c +8 -2
@@ -77,6 +77,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, 0, 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 },
@@ -1663,6 +1664,7 @@ eal_log_level_parse(int argc, char * const argv[])switch (opt) {case OPT_LOG_LEVEL_NUM : +case OPT_LOG_TIMESTAMP_NUM :if (eal_parse_common_option (opt, optarg, internal_conf) <0 )return -1 ;break ;
@@ -1890,7 +1892,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 --"
@@ -1898,7 +1900,10 @@ eal_parse_common_option(int opt, const char *optarg,return -1 ; }break ; - } + +case OPT_LOG_TIMESTAMP_NUM : +eal_log_enable_timestamp (); +break ;#ifndef RTE_EXEC_ENV_WINDOWS case OPT_TRACE_NUM : {
@@ -2261,6 +2266,7 @@ eal_common_usage(void) " --"OPT_PROC_TYPE" Type of this process (primary|secondary|auto)\n" #ifndef RTE_EXEC_ENV_WINDOWS " --"OPT_SYSLOG" Set syslog facility\n" + " --"OPT_LOG_TIMESTAMP" Timestamp log output\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_TIMESTAMP "log-timestamp" +OPT_LOG_TIMESTAMP_NUM , #define OPT_TRACE "trace"OPT_TRACE_NUM , #define OPT_TRACE_DIR "trace-dir"
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>
@@ -44,4 +46,11 @@ const char *eal_log_level2str(uint32_t level);__rte_internal void rte_eal_log_cleanup(void); +/* +* Add timestamp to console logs +*/ +__rte_internal +void eal_log_enable_timestamp(void); + +#endif /* LOG_INTERNAL_H */
lib/log/log_unix.c +30 -2
@@ -2,24 +2,52 @@* Copyright(c) 2010-2014 Intel Corporation */ +#include <stdbool.h> #include <stdio.h> #include <sys/types.h> +#include <sys/uio.h> #include <syslog.h> +#include <time.h> +#include <unistd.h> #include <rte_log.h> #include "log_internal.h" +static bool timestamp_enabled; +static struct timespec log_started; + +void +eal_log_enable_timestamp (void ) +{ + timestamp_enabled = true; +clock_gettime (CLOCK_MONOTONIC , &log_started); +} +/* * default log function */ static ssize_t console_log_write(__rte_unused void *c, const char *buf, size_t size) { +struct timespec ts;ssize_t ret; -/* write on stderr */ - ret =fwrite (buf,1 , size, stderr); +if (timestamp_enabled) { +clock_gettime (CLOCK_MONOTONIC , &ts); + ts.tv_sec -= log_started.tv_sec; + ts.tv_nsec -= log_started.tv_nsec; +if (ts.tv_nsec <0 ) { + --ts.tv_sec; + ts.tv_nsec +=1000000000ul ; + } + + ret =fprintf (stderr,"[%8lu.%06lu] %.*s" , + ts.tv_sec, ts.tv_nsec /1000u , + (int ) size, buf); + }else { + ret =fwrite (buf,1 , size, stderr); + }fflush (stderr);/* Syslog error levels are from 0 to 7, so subtract 1 to convert */
lib/log/log_windows.c +6 -0
@@ -6,6 +6,12 @@#include <rte_log.h> #include "log_internal.h" +void +eal_log_enable_timestamp (void ) +{ +/* not implemented */ +} +/* set the log to default function, called during eal init process. */ int eal_log_init(__rte_unused const char *id, __rte_unused int facility)
lib/log/version.map +1 -0
@@ -25,6 +25,7 @@ DPDK_24 { INTERNAL { global: + eal_log_enable_timestamp; eal_log_get_default; eal_log_init; eal_log_level2str;
Signature · 1 line
2.43.0
PATCH v8 5/5 eal: initialize logging before plugins
In reply to Stephen HemmingerWant to make sure that as many log messages as possible get added with the real log stream.
--- lib/eal/freebsd/eal.c | 16 ++++++++-------- lib/eal/linux/eal.c | 16 ++++++++-------- lib/eal/unix/eal_unix_log.c | 0 3 files changed, 16 insertions(+), 16 deletions(-) create mode 100644 lib/eal/unix/eal_unix_log.c
lib/eal/freebsd/eal.c +8 -8
@@ -592,6 +592,14 @@ rte_eal_init(int argc, char **argv) internal_conf->in_memory = false; } +if (eal_log_init (program_invocation_short_name, + internal_conf->syslog_facility) <0 ) { +rte_eal_init_alert ("Cannot init logging." ); + rte_errno =ENOMEM ; +rte_atomic_store_explicit (&run_once,0 , rte_memory_order_relaxed); +return -1 ; + } +if (eal_plugins_init () <0 ) {rte_eal_init_alert ("Cannot init plugins" ); rte_errno =EINVAL ;
@@ -718,14 +726,6 @@ rte_eal_init(int argc, char **argv)#endif } -if (eal_log_init (program_invocation_short_name, - internal_conf->syslog_facility) <0 ) { -rte_eal_init_alert ("Cannot init logging." ); - rte_errno =ENOMEM ; -rte_atomic_store_explicit (&run_once,0 , rte_memory_order_relaxed); -return -1 ; - } -/* in secondary processes, memory init may allocate additional fbarrays * not present in primary processes, so to avoid any potential issues, * initialize memzones first.
lib/eal/linux/eal.c +8 -8
@@ -973,6 +973,14 @@ rte_eal_init(int argc, char **argv)return -1 ; } +if (eal_log_init (program_invocation_short_name, + internal_conf->syslog_facility) <0 ) { +rte_eal_init_alert ("Cannot init logging." ); + rte_errno =ENOMEM ; +rte_atomic_store_explicit (&run_once,0 , rte_memory_order_relaxed); +return -1 ; + } +if (eal_plugins_init () <0 ) {rte_eal_init_alert ("Cannot init plugins" ); rte_errno =EINVAL ;
@@ -1107,14 +1115,6 @@ rte_eal_init(int argc, char **argv)#endif } -if (eal_log_init (program_invocation_short_name, - internal_conf->syslog_facility) <0 ) { -rte_eal_init_alert ("Cannot init logging." ); - rte_errno =ENOMEM ; -rte_atomic_store_explicit (&run_once,0 , rte_memory_order_relaxed); -return -1 ; - } -#ifdef VFIO_PRESENT if (rte_eal_vfio_setup () <0 ) {rte_eal_init_alert ("Cannot init VFIO" );
lib/eal/unix/eal_unix_log.c new file +0 -0
Signature · 1 line
2.43.0
v9 cover Logging unification and timestamp
In reply to Stephen HemmingerImprovements and unification of logging library (for 24.07 release). This is update to earlier patch set.
v9 - reorder patches and fix FreeBSD build
v8 - rebase to current code base where logging in in lib/log
use stdio for log timestamp
initialization changes (setup log earlier)
Stephen Hemminger (5):
log: unify logging code
eal: make eal_log_level_parse common
eal: initialize logging before plugins
eal: allow user to set default log stream before init
eal: add option to put timestamp on console output
app/dumpcap/main.c | 3 +
app/pdump/main.c | 3 +
app/proc-info/main.c | 3 +
app/test/test_eal_flags.c | 9 +++
doc/guides/linux_gsg/linux_eal_parameters.rst | 27 ---------
doc/guides/prog_guide/log_lib.rst | 28 +++++++++-
lib/eal/common/eal_common_options.c | 56 ++++++++++++++++++-
lib/eal/common/eal_options.h | 3 +
lib/eal/freebsd/eal.c | 50 +++--------------
lib/eal/linux/eal.c | 55 +++---------------
lib/eal/unix/eal_unix_log.c | 0
lib/eal/windows/eal.c | 35 ------------
lib/log/log.c | 6 ++
lib/log/log_freebsd.c | 12 ----
lib/log/log_internal.h | 11 ++++
lib/log/{log_linux.c => log_unix.c} | 36 +++++++++++-
lib/log/log_windows.c | 6 ++
lib/log/meson.build | 12 ++--
lib/log/version.map | 2 +
19 files changed, 184 insertions(+), 173 deletions(-)
create mode 100644 lib/eal/unix/eal_unix_log.c
delete mode 100644 lib/log/log_freebsd.c
rename lib/log/{log_linux.c => log_unix.c} (58%)Signature · 1 line
2.43.0
PATCH v9 1/5 log: unify logging code
FreeBSD and Linux logging code can use common code. This also fixes FreeBSD not using syslog.
---
doc/guides/linux_gsg/linux_eal_parameters.rst | 27 -------------------
doc/guides/prog_guide/log_lib.rst | 18 +++++++++++--
lib/eal/freebsd/eal.c | 8 ++++++
lib/log/log_freebsd.c | 12 ---------
lib/log/{log_linux.c => log_unix.c} | 0
lib/log/meson.build | 12 ++++++---
6 files changed, 32 insertions(+), 45 deletions(-)
delete mode 100644 lib/log/log_freebsd.c
rename lib/log/{log_linux.c => log_unix.c} (100%)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 +16 -2
@@ -5,8 +5,8 @@ Log Library =========== The DPDK Log library provides the logging functionality for other DPDK libraries and drivers. -By default, in a Linux application, logs are sent to syslog and also to the console. -On FreeBSD and Windows applications, logs are sent only to the console. +By default, in a Linux (or FreeBSD) application, logs are sent to syslog and also to the console. +In Windows applications, logs are sent only to the console. However, the log function can be overridden by the user to use a different logging mechanism. Log Levels
@@ -29,6 +29,7 @@ will be emitted by the application to the log output. That level can be configured either by the application calling the relevant APIs from the logging library, or by the user passing the ``--log-level`` parameter to the EAL via the application. + Setting Global Log Level ~~~~~~~~~~~~~~~~~~~~~~~~
@@ -59,6 +60,19 @@ 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. + +Setting syslog facility +~~~~~~~~~~~~~~~~~~~~~~~ + +On Linux and FreeBSD, where syslog is used a ``facility`` argument can be +used to specify what type of program is logging. +The default facility is ``daemon`` but it can be overridden +by the ``--syslog`` EAL parameter. See ``syslog.3`` man page for full values. +For example:: + + /path/to/app --syslog local0 + + Using Logging APIs to Generate Log Messages -------------------------------------------
lib/eal/freebsd/eal.c +8 -0
@@ -53,6 +53,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)
@@ -760,6 +761,13 @@ rte_eal_init(int argc, char **argv)#endif } +if (eal_log_init (getprogname (), internal_conf->syslog_facility) <0 ) { +rte_eal_init_alert ("Cannot init logging." ); + rte_errno =ENOMEM ; +rte_atomic_store_explicit (&run_once,0 , rte_memory_order_relaxed); +return -1 ; + } +/* in secondary processes, memory init may allocate additional fbarrays * not present in primary processes, so to avoid any potential issues, * initialize memzones first.
lib/log/log_freebsd.c deleted +0 -12
@@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause -* Copyright(c) 2023 Intel Corporation -*/ - -#include <rte_common.h> -#include "log_internal.h" - -int -eal_log_init(__rte_unused const char *id, __rte_unused int facility) -{ -return 0 ; -}
lib/log/log_unix.c renamed from lib/log/log_linux.c +0 -0
lib/log/meson.build +8 -4
@@ -2,8 +2,12 @@ # Copyright(c) 2023 Intel Corporation includes += global_inc -sources = files( - 'log.c', - 'log_' + exec_env + '.c', -) +sources = files('log.c') + +if is_windows + sources += files('log_windows.c') +else + sources += files('log_unix.c') +endif + headers = files('rte_log.h')
Signature · 1 line
2.43.0
PATCH v9 2/5 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-level */ +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 v9 3/5 eal: initialize logging before plugins
In reply to Stephen HemmingerWant to make sure that as many log messages as possible get added with the real log stream.
--- lib/eal/freebsd/eal.c | 14 +++++++------- lib/eal/linux/eal.c | 16 ++++++++-------- lib/eal/unix/eal_unix_log.c | 0 3 files changed, 15 insertions(+), 15 deletions(-) create mode 100644 lib/eal/unix/eal_unix_log.c
lib/eal/freebsd/eal.c +7 -7
@@ -593,6 +593,13 @@ rte_eal_init(int argc, char **argv) internal_conf->in_memory = false; } +if (eal_log_init (getprogname (), internal_conf->syslog_facility) <0 ) { +rte_eal_init_alert ("Cannot init logging." ); + rte_errno =ENOMEM ; +rte_atomic_store_explicit (&run_once,0 , rte_memory_order_relaxed); +return -1 ; + } +if (eal_plugins_init () <0 ) {rte_eal_init_alert ("Cannot init plugins" ); rte_errno =EINVAL ;
@@ -719,13 +726,6 @@ rte_eal_init(int argc, char **argv)#endif } -if (eal_log_init (getprogname (), internal_conf->syslog_facility) <0 ) { -rte_eal_init_alert ("Cannot init logging." ); - rte_errno =ENOMEM ; -rte_atomic_store_explicit (&run_once,0 , rte_memory_order_relaxed); -return -1 ; - } -/* in secondary processes, memory init may allocate additional fbarrays * not present in primary processes, so to avoid any potential issues, * initialize memzones first.
lib/eal/linux/eal.c +8 -8
@@ -973,6 +973,14 @@ rte_eal_init(int argc, char **argv)return -1 ; } +if (eal_log_init (program_invocation_short_name, + internal_conf->syslog_facility) <0 ) { +rte_eal_init_alert ("Cannot init logging." ); + rte_errno =ENOMEM ; +rte_atomic_store_explicit (&run_once,0 , rte_memory_order_relaxed); +return -1 ; + } +if (eal_plugins_init () <0 ) {rte_eal_init_alert ("Cannot init plugins" ); rte_errno =EINVAL ;
@@ -1107,14 +1115,6 @@ rte_eal_init(int argc, char **argv)#endif } -if (eal_log_init (program_invocation_short_name, - internal_conf->syslog_facility) <0 ) { -rte_eal_init_alert ("Cannot init logging." ); - rte_errno =ENOMEM ; -rte_atomic_store_explicit (&run_once,0 , rte_memory_order_relaxed); -return -1 ; - } -#ifdef VFIO_PRESENT if (rte_eal_vfio_setup () <0 ) {rte_eal_init_alert ("Cannot init VFIO" );
lib/eal/unix/eal_unix_log.c new file +0 -0
Signature · 1 line
2.43.0
PATCH v9 4/5 eal: allow user to set default log stream before init
In reply to Stephen HemmingerIt is useful for application to be able to set the default log stream before call rte_eal_init(). This makes all messages go to the new default.
For example, to skip using syslog; just doing
rte_openlog_stream(stderr);
There is no reason for helper command line applications to clutter syslog with messages.
--- app/dumpcap/main.c | 3 +++ app/pdump/main.c | 3 +++ app/proc-info/main.c | 3 +++ lib/log/log.c | 6 ++++++ lib/log/log_internal.h | 2 ++ lib/log/log_unix.c | 4 ++++ lib/log/version.map | 1 + 7 files changed, 22 insertions(+)
app/dumpcap/main.c +3 -0
@@ -633,6 +633,9 @@ static void dpdk_init(void)rte_panic ("No memory\n" ); } +/* keep any logging away from syslog. */ +rte_openlog_stream (stderr); +if (rte_eal_init (eal_argc, eal_argv) <0 )rte_exit (EXIT_FAILURE ,"EAL init failed: is primary process running?\n" ); }
app/pdump/main.c +3 -0
@@ -995,6 +995,9 @@ main(int argc, char **argv) argc +=2 ; +/* keep any logging away from syslog. */ +rte_openlog_stream (stderr); + diag =rte_eal_init (argc, argp);if (diag <0 )rte_panic ("Cannot init EAL\n" );
app/proc-info/main.c +3 -0
@@ -2149,6 +2149,9 @@ main(int argc, char **argv) argc +=4 ; +/* keep any logging away from syslog. */ +rte_openlog_stream (stderr); + ret =rte_eal_init (argc, argp);if (ret <0 )rte_panic ("Cannot init EAL\n" );
lib/log/log.c +6 -0
@@ -519,6 +519,12 @@ eal_log_set_default(FILE *default_log)#endif } +FILE * +eal_log_get_default (void ) +{ +return default_log_stream; +} +/* * Called by eal_cleanup */
lib/log/log_internal.h +2 -0
@@ -21,6 +21,8 @@ int eal_log_init(const char *id, int facility);*/ __rte_internal void eal_log_set_default(FILE *default_log); +__rte_internal +FILE *eal_log_get_default(void);/* * Save a log option for later.
lib/log/log_unix.c +4 -0
@@ -49,6 +49,10 @@ eal_log_init(const char *id, int facility) {FILE *log_stream; +/* skip if user has already setup a log stream */ +if (eal_log_get_default ()) +return 0 ; + log_stream =fopencookie (NULL ,"w+" , console_log_func);if (log_stream ==NULL )return -1 ;
lib/log/version.map +1 -0
@@ -25,6 +25,7 @@ DPDK_24 { INTERNAL { global: + eal_log_get_default; eal_log_init; eal_log_level2str; eal_log_save_pattern;
Signature · 1 line
2.43.0
PATCH v9 5/5 eal: add option to put timestamp on console output
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. The timestamp format is chosen to look like the default Linux dmesg timestamp.
The first few lines are not timestamped because the flag is stored in internal configuration which is stored in shared memory which is not setup up until a little later in startup process.
This logging skips the unnecessary step of going through stdio, which makes it more robust against being called in interrupt handlers etc.
Example:
$ dpdk-testpmd --log-timestamp -- -i EAL: Detected CPU lcores: 16 EAL: Detected NUMA nodes: 1 EAL: Detected static linkage of DPDK EAL: Multi-process socket /var/run/dpdk/rte/mp_socket EAL: Selected IOVA mode 'VA' [ 0.112264] testpmd: No probed ethernet devices Interactive-mode selected [ 0.184573] testpmd: create a new mbuf pool <mb_pool_0>: n=163456, size=2176, socket=0 [ 0.184612] testpmd: preferred mempool ops selected: ring_mp_mc
--- app/test/test_eal_flags.c | 9 ++++++++ doc/guides/prog_guide/log_lib.rst | 10 +++++++++ lib/eal/common/eal_common_options.c | 10 +++++++-- lib/eal/common/eal_options.h | 2 ++ lib/log/log_internal.h | 9 ++++++++ lib/log/log_unix.c | 32 +++++++++++++++++++++++++++-- lib/log/log_windows.c | 6 ++++++ lib/log/version.map | 1 + 8 files changed, 75 insertions(+), 4 deletions(-)
app/test/test_eal_flags.c +9 -0
@@ -1055,6 +1055,10 @@ 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" }; +/* run all tests also applicable to FreeBSD first */ if (launch_proc (argv0) ==0 ) {
@@ -1162,6 +1166,11 @@ 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; + } +rmdir (hugepath_dir3);rmdir (hugepath_dir2);
doc/guides/prog_guide/log_lib.rst +10 -0
@@ -73,6 +73,16 @@ For example:: /path/to/app --syslog local0 +Console timestamp +~~~~~~~~~~~~~~~~~ + +On Linux and FreeBSD, 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 + + Using Logging APIs to Generate Log Messages -------------------------------------------
lib/eal/common/eal_common_options.c +8 -2
@@ -77,6 +77,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, 0, 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 },
@@ -1663,6 +1664,7 @@ eal_log_level_parse(int argc, char * const argv[])switch (opt) {case OPT_LOG_LEVEL_NUM : +case OPT_LOG_TIMESTAMP_NUM :if (eal_parse_common_option (opt, optarg, internal_conf) <0 )return -1 ;break ;
@@ -1890,7 +1892,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 --"
@@ -1898,7 +1900,10 @@ eal_parse_common_option(int opt, const char *optarg,return -1 ; }break ; - } + +case OPT_LOG_TIMESTAMP_NUM : +eal_log_enable_timestamp (); +break ;#ifndef RTE_EXEC_ENV_WINDOWS case OPT_TRACE_NUM : {
@@ -2261,6 +2266,7 @@ eal_common_usage(void) " --"OPT_PROC_TYPE" Type of this process (primary|secondary|auto)\n" #ifndef RTE_EXEC_ENV_WINDOWS " --"OPT_SYSLOG" Set syslog facility\n" + " --"OPT_LOG_TIMESTAMP" Timestamp log output\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_TIMESTAMP "log-timestamp" +OPT_LOG_TIMESTAMP_NUM , #define OPT_TRACE "trace"OPT_TRACE_NUM , #define OPT_TRACE_DIR "trace-dir"
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>
@@ -44,4 +46,11 @@ const char *eal_log_level2str(uint32_t level);__rte_internal void rte_eal_log_cleanup(void); +/* +* Add timestamp to console logs +*/ +__rte_internal +void eal_log_enable_timestamp(void); + +#endif /* LOG_INTERNAL_H */
lib/log/log_unix.c +30 -2
@@ -2,24 +2,52 @@* Copyright(c) 2010-2014 Intel Corporation */ +#include <stdbool.h> #include <stdio.h> #include <sys/types.h> +#include <sys/uio.h> #include <syslog.h> +#include <time.h> +#include <unistd.h> #include <rte_log.h> #include "log_internal.h" +static bool timestamp_enabled; +static struct timespec log_started; + +void +eal_log_enable_timestamp (void ) +{ + timestamp_enabled = true; +clock_gettime (CLOCK_MONOTONIC , &log_started); +} +/* * default log function */ static ssize_t console_log_write(__rte_unused void *c, const char *buf, size_t size) { +struct timespec ts;ssize_t ret; -/* write on stderr */ - ret =fwrite (buf,1 , size, stderr); +if (timestamp_enabled) { +clock_gettime (CLOCK_MONOTONIC , &ts); + ts.tv_sec -= log_started.tv_sec; + ts.tv_nsec -= log_started.tv_nsec; +if (ts.tv_nsec <0 ) { + --ts.tv_sec; + ts.tv_nsec +=1000000000ul ; + } + + ret =fprintf (stderr,"[%8lu.%06lu] %.*s" , + ts.tv_sec, ts.tv_nsec /1000u , + (int ) size, buf); + }else { + ret =fwrite (buf,1 , size, stderr); + }fflush (stderr);/* Syslog error levels are from 0 to 7, so subtract 1 to convert */
lib/log/log_windows.c +6 -0
@@ -6,6 +6,12 @@#include <rte_log.h> #include "log_internal.h" +void +eal_log_enable_timestamp (void ) +{ +/* not implemented */ +} +/* set the log to default function, called during eal init process. */ int eal_log_init(__rte_unused const char *id, __rte_unused int facility)
lib/log/version.map +1 -0
@@ -25,6 +25,7 @@ DPDK_24 { INTERNAL { global: + eal_log_enable_timestamp; eal_log_get_default; eal_log_init; eal_log_level2str;
Signature · 1 line
2.43.0
Quoted 32 lines
From: Stephen Hemminger [mailto:[email protected]]
Sent: Monday, 18 March 2024 23.03When 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. The timestamp format is chosen to look like the default Linux dmesg timestamp.
The first few lines are not timestamped because the flag is stored in internal configuration which is stored in shared memory which is not setup up until a little later in startup process.
This logging skips the unnecessary step of going through stdio, which makes it more robust against being called in interrupt handlers etc.
Example:
$ dpdk-testpmd --log-timestamp -- -i EAL: Detected CPU lcores: 16 EAL: Detected NUMA nodes: 1 EAL: Detected static linkage of DPDK EAL: Multi-process socket /var/run/dpdk/rte/mp_socket EAL: Selected IOVA mode 'VA' [ 0.112264] testpmd: No probed ethernet devices Interactive-mode selected [ 0.184573] testpmd: create a new mbuf pool <mb_pool_0>: n=163456, size=2176, socket=0 [ 0.184612] testpmd: preferred mempool ops selected: ring_mp_mcSigned-off-by Stephen Hemminger <[email protected]>---
[...]
lib/log/log_unix.c line 39
Quoted 12 lines
static
ssize_t
console_log_write(__rte_unused void *c, const char *buf, size_t size){lib/log/log_unix.c +5
-2+struct timespec ts;ssize_t ret; -/* write on stderr */ - ret =fwrite (buf,1 , size, stderr); +if (timestamp_enabled) { +clock_gettime (CLOCK_MONOTONIC , &ts); + ts.tv_sec -= log_started.tv_sec; + ts.tv_nsec -= log_started.tv_nsec;
Please log the absolute CLOCK_MONOTONIC instead of subtracting log_started, so timestamps can be easily compared with timestamps from other processes.
lib/log/log_unix.c line 47
Quoted 8 lines
lib/log/log_unix.c +8
-0+if (ts.tv_nsec <0 ) { + --ts.tv_sec; + ts.tv_nsec +=1000000000ul ; + } + + ret =fprintf (stderr,"[%8lu.%06lu] %.*s" , + ts.tv_sec, ts.tv_nsec /1000u , + (int ) size, buf);
With the above change,
For the series,
Quoted 6 lines · On Tue, 19 Mar 2024 08:37:30 +0100 Morten Brørup <[email protected]>…
Quoted 6 lines
static
ssize_t
console_log_write(__rte_unused void *c, const char *buf, size_t size){lib/log/log_unix.c +1
-0+struct timespec ts;ssize_t ret;
Quoted 8 lines
lib/log/log_unix.c line 39
Quoted 6 lines
lib/log/log_unix.c +4
-2-/* write on stderr */ - ret =fwrite (buf,1 , size, stderr); +if (timestamp_enabled) { +clock_gettime (CLOCK_MONOTONIC , &ts); + ts.tv_sec -= log_started.tv_sec; + ts.tv_nsec -= log_started.tv_nsec;Please log the absolute
CLOCK_MONOTONICinstead of subtractinglog_started, so timestamps can be easily compared with timestamps from other processes.
No, was trying to do what kernel dmesg does.
Quoted 21 lines
From: Stephen Hemminger [mailto:[email protected]]
Sent: Tuesday, 19 March 2024 16.52Quoted 2 lines · On Tue, 19 Mar 2024 08:37:30 +0100 Morten Brørup <[email protected]>…
Quoted 2 lines
static
ssize_t
console_log_write(__rte_unused void *c, const char *buf,size_tsize)
Quoted 4 lines
Quoted 4 lines
{
lib/log/log_unix.c +1
-0+struct timespec ts;ssize_t ret;Quoted 8 lines
lib/log/log_unix.c line 39
Quoted 6 lines
lib/log/log_unix.c +4
-2-/* write on stderr */ - ret =fwrite (buf,1 , size, stderr); +if (timestamp_enabled) { +clock_gettime (CLOCK_MONOTONIC , &ts); + ts.tv_sec -= log_started.tv_sec; + ts.tv_nsec -= log_started.tv_nsec;Please log the absolute
CLOCK_MONOTONICinstead of subtracting
Quoted 5 lines
log_started, so timestamps can be easily compared with timestamps from other processes.No, was trying to do what kernel dmesg does.
What do you mean? Doesn't the kernel output CLOCK_MONOTONIC timestamps (without offset)?
And by "timestamps from other processes" I also mean timestamps in log messages from the kernel itself.
Quoted 25 lines · On Tue, 19 Mar 2024 17:13:35 +0100 Morten Brørup <[email protected]>…
Quoted 25 lines
From: Stephen Hemminger [mailto:[email protected]]
Sent: Tuesday, 19 March 2024 16.52Quoted 2 lines · On Tue, 19 Mar 2024 08:37:30 +0100 Morten Brørup <[email protected]>…
Quoted 2 lines
static
ssize_t
console_log_write(__rte_unused void *c, const char *buf,size_tsize)
Quoted 4 lines
Quoted 4 lines
{
lib/log/log_unix.c +1
-0+struct timespec ts;ssize_t ret;Quoted 8 lines
lib/log/log_unix.c line 39
Quoted 6 lines
lib/log/log_unix.c +4
-2-/* write on stderr */ - ret =fwrite (buf,1 , size, stderr); +if (timestamp_enabled) { +clock_gettime (CLOCK_MONOTONIC , &ts); + ts.tv_sec -= log_started.tv_sec; + ts.tv_nsec -= log_started.tv_nsec;Please log the absolute
CLOCK_MONOTONICinstead of subtracting
log_started, so timestamps can be easily compared with timestamps from other processes.
Quoted 6 lines
Quoted 1 line
No, was trying to do what kernel dmesg does.
What do you mean? Doesn't the kernel output
CLOCK_MONOTONICtimestamps (without offset)?And by "timestamps from other processes" I also mean timestamps in log messages from the kernel itself.
If you look at dmesg command that formats the messages, it has lots of timestamp options. Next version will support more of these.
--time-format format
Print timestamps using the given format, which can be ctime, reltime, delta or iso. The first three formats are aliases of the time-format-specific options. The iso format is a dmesg implementation of the ISO-8601 timestamp format. The purpose of this format is to make the comparing of timestamps between two systems, and any other parsing, easy. The definition of the iso timestamp is:
YYYY-MM-DD<T>HH:MM:SS,<microseconds>←+><timezone offset from UTC>.
Quoted 44 lines
From: Stephen Hemminger [mailto:[email protected]]
Sent: Wednesday, 20 March 2024 04.34Quoted 21 lines · On Tue, 19 Mar 2024 17:13:35 +0100 Morten Brørup <[email protected]>…
Quoted 21 lines
From: Stephen Hemminger [mailto:[email protected]]
Sent: Tuesday, 19 March 2024 16.52Quoted 2 lines · On Tue, 19 Mar 2024 08:37:30 +0100 Morten Brørup <[email protected]>…
Quoted 2 lines
static
ssize_t
console_log_write(__rte_unused void *c, const char *buf,size_tsize)
Quoted 12 lines
lib/log/log_unix.c line 39
Quoted 10 lines
{
lib/log/log_unix.c +5
-2+struct timespec ts;ssize_t ret; -/* write on stderr */ - ret =fwrite (buf,1 , size, stderr); +if (timestamp_enabled) { +clock_gettime (CLOCK_MONOTONIC , &ts); + ts.tv_sec -= log_started.tv_sec; + ts.tv_nsec -= log_started.tv_nsec;Please log the absolute
CLOCK_MONOTONICinstead of subtractingQuoted 7 lines
Quoted 5 lines
log_started, so timestamps can be easily compared with timestamps from other processes.No, was trying to do what kernel dmesg does.
What do you mean? Doesn't the kernel output
CLOCK_MONOTONICtimestamps(without offset)?
Quoted 2 lines
And by "timestamps from other processes" I also mean timestamps in log
messages from the kernel itself.
Quoted 1 line
If you look at dmesg command that formats the messages, it has lots of timestamp options.
Next version will support more of these.
Quoted 10 lines
--time-format format
Print timestamps using the given format, which can be ctime, reltime, delta or iso. The first three formats are aliases of the time-format-specific options. The iso format is a dmesg implementation of the ISO-8601 timestamp format. The purpose of this format is to make the comparing of timestamps between two systems, and any other parsing, easy. The definition of the iso timestamp is:
YYYY-MM-DD<T>HH:MM:SS,<microseconds>←+><timezone offset from UTC>.
That's formatting.
I'm talking about the initial offset.
The kernel's "log start time" is set to system start timestamp.
Your "log start time" is set to application start timestamp:
+void
+eal_log_enable_timestamp(void)
+{
+ timestamp_enabled = true;
+ clock_gettime(CLOCK_MONOTONIC, &log_started);
+}
So, different offset. I prefer using the same offset.
Quoted 70 lines · On Wed, 20 Mar 2024 09:34:21 +0100 Morten Brørup <[email protected]>…
Quoted 44 lines
From: Stephen Hemminger [mailto:[email protected]]
Sent: Wednesday, 20 March 2024 04.34Quoted 21 lines · On Tue, 19 Mar 2024 17:13:35 +0100 Morten Brørup <[email protected]>…
Quoted 21 lines
From: Stephen Hemminger [mailto:[email protected]]
Sent: Tuesday, 19 March 2024 16.52Quoted 2 lines · On Tue, 19 Mar 2024 08:37:30 +0100 Morten Brørup <[email protected]>…
Quoted 2 lines
static
ssize_t
console_log_write(__rte_unused void *c, const char *buf,size_tsize)
Quoted 12 lines
lib/log/log_unix.c line 39
Quoted 10 lines
{
lib/log/log_unix.c +5
-2+struct timespec ts;ssize_t ret; -/* write on stderr */ - ret =fwrite (buf,1 , size, stderr); +if (timestamp_enabled) { +clock_gettime (CLOCK_MONOTONIC , &ts); + ts.tv_sec -= log_started.tv_sec; + ts.tv_nsec -= log_started.tv_nsec;Please log the absolute
CLOCK_MONOTONICinstead of subtractingQuoted 7 lines
Quoted 5 lines
log_started, so timestamps can be easily compared with timestamps from other processes.No, was trying to do what kernel dmesg does.
What do you mean? Doesn't the kernel output
CLOCK_MONOTONICtimestamps(without offset)?
Quoted 2 lines
And by "timestamps from other processes" I also mean timestamps in log
messages from the kernel itself.
Quoted 1 line
If you look at dmesg command that formats the messages, it has lots of timestamp options.
Next version will support more of these.Quoted 10 lines
--time-format format
Print timestamps using the given format, which can be ctime, reltime, delta or iso. The first three formats are aliases of the time-format-specific options. The iso format is a dmesg implementation of the ISO-8601 timestamp format. The purpose of this format is to make the comparing of timestamps between two systems, and any other parsing, easy. The definition of the iso timestamp is:
YYYY-MM-DD<T>HH:MM:SS,<microseconds>←+><timezone offset from UTC>.That's formatting.
I'm talking about the initial offset.
The kernel's "log start time" is set to system start timestamp.
Your "log start time" is set to application start timestamp:
lib/log/log_unix.c +6
-0+void +eal_log_enable_timestamp (void ) +{ + timestamp_enabled = true; +clock_gettime (CLOCK_MONOTONIC , &log_started); +}
Quoted 1 line
So, different offset. I prefer using the same offset.
Monotonic has no absolute zero time and can be quite large so offsetting seemed most logical. Also, the kernel does not make boot time monotonic clock value available. Other options are REALTIME or BOOTTIME. But both of these get quite large.
Quoted 88 lines
From: Stephen Hemminger [mailto:[email protected]]
Sent: Wednesday, 20 March 2024 15.39Quoted 6 lines · On Wed, 20 Mar 2024 09:34:21 +0100 Morten Brørup <[email protected]>…
Quoted 6 lines
From: Stephen Hemminger [mailto:[email protected]]
Sent: Wednesday, 20 March 2024 04.34On Tue, 19 Mar 2024 17:13:35 +0100
Morten Brørup <[email protected]> wrote:Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
From: Stephen Hemminger [mailto:[email protected]]
Sent: Tuesday, 19 March 2024 16.52Quoted 2 lines · On Tue, 19 Mar 2024 08:37:30 +0100 Morten Brørup <[email protected]>…
Quoted 2 lines
static
ssize_t
console_log_write(__rte_unused void *c, const char *buf,
size_tQuoted 13 lines
Quoted 13 lines
Quoted 13 lines
Quoted 13 lines
size)
Quoted 12 lines
Review
Quoted 10 lines
{
(quoted diff) +5
-2+ struct timespec ts; ssize_t ret; - /* write on stderr */ - ret = fwrite(buf, 1, size, stderr); + if (timestamp_enabled) { + clock_gettime(CLOCK_MONOTONIC, &ts); + ts.tv_sec -= log_started.tv_sec; + ts.tv_nsec -= log_started.tv_nsec;Please log the absolute
CLOCK_MONOTONICinstead of subtractingQuoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
log_started, so timestamps can be easily compared withtimestamps from
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 4 lines
other processes.
No, was trying to do what kernel dmesg does.
What do you mean? Doesn't the kernel output
CLOCK_MONOTONICtimestamps
Quoted 3 lines
Quoted 3 lines
(without offset)?
Quoted 2 lines
And by "timestamps from other processes" I also mean timestamps in
log
Quoted 4 lines
Quoted 4 lines
messages from the kernel itself.
Quoted 1 line
If you look at dmesg command that formats the messages, it has lots
of
Quoted 5 lines
Quoted 5 lines
timestamp options.
Next version will support more of these.--time-format format
Print timestamps using the given format, which can bectime,
Quoted 1 line
Quoted 1 line
reltime, delta or iso. The first three formats are
aliases of
Quoted 1 line
Quoted 1 line
the time-format-specific options. The iso format is a
dmesg
Quoted 1 line
Quoted 1 line
implementation of the ISO-8601 timestamp format. The
purpose
Quoted 1 line
Quoted 1 line
of this format is to make the comparing of timestamps
between
Quoted 1 line
Quoted 1 line
two systems, and any other parsing, easy. The definition
of
Quoted 2 lines
Quoted 2 lines
the iso timestamp is:
YYYY-MM-DD<T>HH:MM:SS,<microseconds>←+><timezone offsetfrom
Quoted 17 lines
Quoted 1 line
UTC>.That's formatting.
I'm talking about the initial offset.
The kernel's "log start time" is set to system start timestamp.
Your "log start time" is set to application start timestamp:
(quoted diff) +6
-0+void +eal_log_enable_timestamp(void) +{ + timestamp_enabled = true; + clock_gettime(CLOCK_MONOTONIC, &log_started); +}
Quoted 7 lines
Quoted 1 line
So, different offset. I prefer using the same offset.
Monotonic has no absolute zero time and can be quite large so offsetting seemed most logical. Also, the kernel does not make boot time monotonic clock value available. Other options are REALTIME or BOOTTIME. But both of these get quite large.
I don't think that having a large tv_sec is a problem.
I think the ability to correlate log timestamps with other applications is more important.
If we choose one of the standard clocks, applications might choose the same clock. If we subtract the start time of this specific application, it's not in sync with anything else.
The question really is: Which clock is most popular for debug logging to the console? We should use that clock.
v10 cover Logging enhancements.
In reply to Stephen HemmingerImprovements and unification of logging library (for 24.07 release). This is update to earlier patch set. It adds two 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. The message going into syslog is already timestamped (by syslog) so no additional timestamp is needed.
* 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.
I find color helpful because 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.
Note: neither of these are possible on Windows because the fopencookie() function is a GNU libc and not Posix feature.
Will add a release note in next release (after this is merged).
v10 - put windows getopt patch in series since otherwise windows build fails.
- support multiple timestamp formats
- support colorized output
- fix up rte_init_alert() and rte_exit() to match format expected by the timestamp and color modes
- initialize logging much earlier in startup
- add documentation about logging options
Stephen Hemminger (10):
windows: make getopt functions have const properties
log: unify logging code
eal: make eal_log_level_parse common
eal: initialize log earlier in startup
eal: do not duplicate rte_init_alert() messages
eal: change rte_exit() output to match rte_log()
eal: allow user to set default log stream before init
eal: add option to put timestamp on console output
log: colorize log output
doc: add documentation of logging options
app/dumpcap/main.c | 3 + app/pdump/main.c | 3 + app/proc-info/main.c | 3 + app/test/test_eal_flags.c | 17 + doc/guides/linux_gsg/eal_args.include.rst | 54 ++- doc/guides/linux_gsg/linux_eal_parameters.rst | 27 -- doc/guides/prog_guide/log_lib.rst | 28 +- lib/eal/common/eal_common_debug.c | 11 +- lib/eal/common/eal_common_options.c | 70 +++- lib/eal/common/eal_options.h | 5 + lib/eal/freebsd/eal.c | 53 +-- lib/eal/linux/eal.c | 58 +--- lib/eal/unix/eal_unix_log.c | 0 lib/eal/windows/eal.c | 35 -- lib/eal/windows/getopt.c | 23 +- lib/eal/windows/include/getopt.h | 8 +- lib/log/log.c | 6 + lib/log/log_freebsd.c | 12 - lib/log/log_internal.h | 16 + lib/log/log_linux.c | 61 ---- lib/log/log_unix.c | 321 ++++++++++++++++++ lib/log/log_windows.c | 12 + lib/log/meson.build | 12 +- lib/log/version.map | 3 + 24 files changed, 577 insertions(+), 264 deletions(-) create mode 100644 lib/eal/unix/eal_unix_log.c delete mode 100644 lib/log/log_freebsd.c delete mode 100644 lib/log/log_linux.c create mode 100644 lib/log/log_unix.c
Signature · 1 line
2.43.0
PATCH v10 1/10 windows: make getopt functions have const properties
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 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 v10 2/10 log: unify logging code
In reply to Stephen HemmingerFreeBSD and Linux logging code can use common code. This also fixes FreeBSD not using syslog.
---
doc/guides/linux_gsg/linux_eal_parameters.rst | 27 -------------------
doc/guides/prog_guide/log_lib.rst | 18 +++++++++++--
lib/eal/freebsd/eal.c | 8 ++++++
lib/log/log_freebsd.c | 12 ---------
lib/log/{log_linux.c => log_unix.c} | 0
lib/log/meson.build | 12 ++++++---
6 files changed, 32 insertions(+), 45 deletions(-)
delete mode 100644 lib/log/log_freebsd.c
rename lib/log/{log_linux.c => log_unix.c} (100%)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 +16 -2
@@ -5,8 +5,8 @@ Log Library =========== The DPDK Log library provides the logging functionality for other DPDK libraries and drivers. -By default, in a Linux application, logs are sent to syslog and also to the console. -On FreeBSD and Windows applications, logs are sent only to the console. +By default, in a Linux (or FreeBSD) application, logs are sent to syslog and also to the console. +In Windows applications, logs are sent only to the console. However, the log function can be overridden by the user to use a different logging mechanism. Log Levels
@@ -29,6 +29,7 @@ will be emitted by the application to the log output. That level can be configured either by the application calling the relevant APIs from the logging library, or by the user passing the ``--log-level`` parameter to the EAL via the application. + Setting Global Log Level ~~~~~~~~~~~~~~~~~~~~~~~~
@@ -59,6 +60,19 @@ 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. + +Setting syslog facility +~~~~~~~~~~~~~~~~~~~~~~~ + +On Linux and FreeBSD, where syslog is used a ``facility`` argument can be +used to specify what type of program is logging. +The default facility is ``daemon`` but it can be overridden +by the ``--syslog`` EAL parameter. See ``syslog.3`` man page for full values. +For example:: + + /path/to/app --syslog local0 + + Using Logging APIs to Generate Log Messages -------------------------------------------
lib/eal/freebsd/eal.c +8 -0
@@ -53,6 +53,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)
@@ -760,6 +761,13 @@ rte_eal_init(int argc, char **argv)#endif } +if (eal_log_init (getprogname (), internal_conf->syslog_facility) <0 ) { +rte_eal_init_alert ("Cannot init logging." ); + rte_errno =ENOMEM ; +rte_atomic_store_explicit (&run_once,0 , rte_memory_order_relaxed); +return -1 ; + } +/* in secondary processes, memory init may allocate additional fbarrays * not present in primary processes, so to avoid any potential issues, * initialize memzones first.
lib/log/log_freebsd.c deleted +0 -12
@@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause -* Copyright(c) 2023 Intel Corporation -*/ - -#include <rte_common.h> -#include "log_internal.h" - -int -eal_log_init(__rte_unused const char *id, __rte_unused int facility) -{ -return 0 ; -}
lib/log/log_unix.c renamed from lib/log/log_linux.c +0 -0
lib/log/meson.build +8 -4
@@ -2,8 +2,12 @@ # Copyright(c) 2023 Intel Corporation includes += global_inc -sources = files( - 'log.c', - 'log_' + exec_env + '.c', -) +sources = files('log.c') + +if is_windows + sources += files('log_windows.c') +else + sources += files('log_unix.c') +endif + headers = files('rte_log.h')
Signature · 1 line
2.43.0
PATCH v10 3/10 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-level */ +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
Re: [PATCH v10 03/10] eal: make eal_log_level_parse common
Quoted 5 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]>---
PATCH v10 4/10 eal: initialize log earlier in startup
In reply to Stephen HemmingerWant to make sure that as many log messages as possible get added with the real log stream. Despite the comment, there is no dependency on memzones in current code.
--- lib/eal/freebsd/eal.c | 14 +++++++------- lib/eal/linux/eal.c | 16 ++++++++-------- lib/eal/unix/eal_unix_log.c | 0 lib/log/log_unix.c | 4 ++-- 4 files changed, 17 insertions(+), 17 deletions(-) create mode 100644 lib/eal/unix/eal_unix_log.c
lib/eal/freebsd/eal.c +7 -7
@@ -571,6 +571,13 @@ rte_eal_init(int argc, char **argv)/* set log level as early as possible */ eal_log_level_parse (argc, argv); +if (eal_log_init (getprogname (), internal_conf->syslog_facility) <0 ) { +rte_eal_init_alert ("Cannot init logging." ); + rte_errno =ENOMEM ; +rte_atomic_store_explicit (&run_once,0 , rte_memory_order_relaxed); +return -1 ; + } +if (rte_eal_cpu_init () <0 ) {rte_eal_init_alert ("Cannot detect lcores." ); rte_errno =ENOTSUP ;
@@ -719,13 +726,6 @@ rte_eal_init(int argc, char **argv)#endif } -if (eal_log_init (getprogname (), internal_conf->syslog_facility) <0 ) { -rte_eal_init_alert ("Cannot init logging." ); - rte_errno =ENOMEM ; -rte_atomic_store_explicit (&run_once,0 , rte_memory_order_relaxed); -return -1 ; - } -/* in secondary processes, memory init may allocate additional fbarrays * not present in primary processes, so to avoid any potential issues, * initialize memzones first.
lib/eal/linux/eal.c +8 -8
@@ -959,6 +959,14 @@ rte_eal_init(int argc, char **argv)/* clone argv to report out later in telemetry */ eal_save_args (argc, argv); +if (eal_log_init (program_invocation_short_name, + internal_conf->syslog_facility) <0 ) { +rte_eal_init_alert ("Cannot init logging." ); + rte_errno =ENOMEM ; +rte_atomic_store_explicit (&run_once,0 , rte_memory_order_relaxed); +return -1 ; + } +if (rte_eal_cpu_init () <0 ) {rte_eal_init_alert ("Cannot detect lcores." ); rte_errno =ENOTSUP ;
@@ -1107,14 +1115,6 @@ rte_eal_init(int argc, char **argv)#endif } -if (eal_log_init (program_invocation_short_name, - internal_conf->syslog_facility) <0 ) { -rte_eal_init_alert ("Cannot init logging." ); - rte_errno =ENOMEM ; -rte_atomic_store_explicit (&run_once,0 , rte_memory_order_relaxed); -return -1 ; - } -#ifdef VFIO_PRESENT if (rte_eal_vfio_setup () <0 ) {rte_eal_init_alert ("Cannot init VFIO" );
lib/eal/unix/eal_unix_log.c new file +0 -0
lib/log/log_unix.c +2 -2
@@ -41,8 +41,8 @@ static cookie_io_functions_t console_log_func = { };/* -* set the log to default function, called during eal init process, -* once memzones are available. +* set the log to default function, called early in eal init process; +* before lcore's and memzones are setup. */ int eal_log_init (const char *id,int facility)
Signature · 1 line
2.43.0
PATCH v10 5/10 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
@@ -530,8 +530,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 v10 6/10 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 =NULL ;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); +vasprintf (&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
Re: [PATCH v10 06/10] eal: change rte_exit() output to match rte_log()
Quoted 10 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 denied
it is better but maybe : -> - for Cause?
[ 0.006238] EAL: Error - exiting with code: 1 [ 0.006250] EAL: Cause - Cannot init EAL: Permission denied
Quoted 3 lines
Signed-off-by Stephen Hemminger <[email protected]>---
Quoted 33 lines
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 =NULL ;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); +vasprintf (&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 v10 7/10 eal: allow user to set default log stream before init
In reply to Stephen HemmingerIt is useful for application to be able to set the default log stream before call rte_eal_init(). This makes all messages go to the new default.
For example, to skip using syslog; just doing
rte_openlog_stream(stderr);
There is no reason for helper command line applications to clutter syslog with messages.
--- app/dumpcap/main.c | 3 +++ app/pdump/main.c | 3 +++ app/proc-info/main.c | 3 +++ lib/log/log.c | 6 ++++++ lib/log/log_internal.h | 2 ++ lib/log/log_unix.c | 4 ++++ lib/log/version.map | 1 + 7 files changed, 22 insertions(+)
app/dumpcap/main.c +3 -0
@@ -633,6 +633,9 @@ static void dpdk_init(void)rte_panic ("No memory\n" ); } +/* keep any logging away from syslog. */ +rte_openlog_stream (stderr); +if (rte_eal_init (eal_argc, eal_argv) <0 )rte_exit (EXIT_FAILURE ,"EAL init failed: is primary process running?\n" ); }
app/pdump/main.c +3 -0
@@ -995,6 +995,9 @@ main(int argc, char **argv) argc +=2 ; +/* keep any logging away from syslog. */ +rte_openlog_stream (stderr); + diag =rte_eal_init (argc, argp);if (diag <0 )rte_panic ("Cannot init EAL\n" );
app/proc-info/main.c +3 -0
@@ -2149,6 +2149,9 @@ main(int argc, char **argv) argc +=4 ; +/* keep any logging away from syslog. */ +rte_openlog_stream (stderr); + ret =rte_eal_init (argc, argp);if (ret <0 )rte_panic ("Cannot init EAL\n" );
lib/log/log.c +6 -0
@@ -519,6 +519,12 @@ eal_log_set_default(FILE *default_log)#endif } +FILE * +eal_log_get_default (void ) +{ +return default_log_stream; +} +/* * Called by eal_cleanup */
lib/log/log_internal.h +2 -0
@@ -21,6 +21,8 @@ int eal_log_init(const char *id, int facility);*/ __rte_internal void eal_log_set_default(FILE *default_log); +__rte_internal +FILE *eal_log_get_default(void);/* * Save a log option for later.
lib/log/log_unix.c +4 -0
@@ -49,6 +49,10 @@ eal_log_init(const char *id, int facility) {FILE *log_stream; +/* skip if user has already setup a log stream */ +if (eal_log_get_default ()) +return 0 ; + log_stream =fopencookie (NULL ,"w+" , console_log_func);if (log_stream ==NULL )return -1 ;
lib/log/version.map +1 -0
@@ -25,6 +25,7 @@ DPDK_24 { INTERNAL { global: + eal_log_get_default; eal_log_init; eal_log_level2str; eal_log_save_pattern;
Signature · 1 line
2.43.0
Re: [PATCH v10 07/10] eal: allow user to set default log stream before init
Quoted 4 lines · Stephen Hemminger
It is useful for application to be able to set the default log stream before call
rte_eal_init(). This makes all messages go to the new default.
Quoted 8 lines
For example, to skip using syslog; just doing
rte_openlog_stream(stderr);There is no reason for helper command line applications to clutter syslog with messages.
Signed-off-by Stephen Hemminger <[email protected]>---
PATCH v10 8/10 eal: add option to put timestamp on console output
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. Other alternatives are delta, ctime, reltime and iso formats.
Example:
$ dpdk-testpmd --log-timestamp -- -i EAL: Detected CPU lcores: 8 EAL: Detected NUMA nodes: 1 [ 0.000083] EAL: Detected static linkage of DPDK [ 0.002000] EAL: Multi-process socket /var/run/dpdk/rte/mp_socket [ 0.003507] EAL: Selected IOVA mode 'VA' [ 0.006272] testpmd: No probed ethernet devices Interactive-mode selected [ 0.029567] testpmd: create a new mbuf pool <mb_pool_0>: n=203456, size=2176, socket=0 [ 0.029588] testpmd: preferred mempool ops selected: ring_mp_mc
--- app/test/test_eal_flags.c | 17 ++++ doc/guides/prog_guide/log_lib.rst | 10 ++ lib/eal/common/eal_common_options.c | 14 ++- lib/eal/common/eal_options.h | 2 + lib/log/log_internal.h | 9 ++ lib/log/log_unix.c | 152 +++++++++++++++++++++++++++- lib/log/log_windows.c | 6 ++ lib/log/version.map | 1 + 8 files changed, 205 insertions(+), 6 deletions(-)
app/test/test_eal_flags.c +17 -0
@@ -1055,6 +1055,14 @@ 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" }; +/* run all tests also applicable to FreeBSD first */ if (launch_proc (argv0) ==0 ) {
@@ -1162,6 +1170,15 @@ 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; + } +rmdir (hugepath_dir3);rmdir (hugepath_dir2);
doc/guides/prog_guide/log_lib.rst +10 -0
@@ -73,6 +73,16 @@ For example:: /path/to/app --syslog local0 +Console timestamp +~~~~~~~~~~~~~~~~~ + +On Linux and FreeBSD, 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 + + Using Logging APIs to Generate Log Messages -------------------------------------------
lib/eal/common/eal_common_options.c +12 -2
@@ -77,6 +77,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 },
@@ -1663,6 +1664,7 @@ eal_log_level_parse(int argc, char * const argv[])switch (opt) {case OPT_LOG_LEVEL_NUM : +case OPT_LOG_TIMESTAMP_NUM :if (eal_parse_common_option (opt, optarg, internal_conf) <0 )return -1 ;break ;
@@ -1890,7 +1892,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 --"
@@ -1898,9 +1900,16 @@ eal_parse_common_option(int opt, const char *optarg,return -1 ; }break ; - }#ifndef RTE_EXEC_ENV_WINDOWS +case OPT_LOG_TIMESTAMP_NUM : +if (eal_log_timestamp (optarg) <0 ) { +EAL_LOG (ERR ,"invalid parameters for --" +OPT_LOG_TIMESTAMP ); +return -1 ; + } +break ; +case OPT_TRACE_NUM : {if (eal_trace_args_save (optarg) <0 ) { EAL_LOG(ERR, "invalid parameters for --"
@@ -2261,6 +2270,7 @@ eal_common_usage(void) " --"OPT_PROC_TYPE" Type of this process (primary|secondary|auto)\n" #ifndef RTE_EXEC_ENV_WINDOWS " --"OPT_SYSLOG" Set syslog facility\n" + " --"OPT_LOG_TIMESTAMP" Timestamp log output\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_TIMESTAMP "log-timestamp" +OPT_LOG_TIMESTAMP_NUM , #define OPT_TRACE "trace"OPT_TRACE_NUM , #define OPT_TRACE_DIR "trace-dir"
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>
@@ -44,4 +46,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_unix.c +148 -4
182 lines not on this page · raw message
lib/log/log_windows.c +6 -0
@@ -6,6 +6,12 @@#include <rte_log.h> #include "log_internal.h" +int +eal_log_timestamp(__rte_unused const char *fmt) +{ +return -1 ;/* not implemented */ +} +/* set the log to default function, called during eal init process. */ int eal_log_init(__rte_unused const char *id, __rte_unused int facility)
lib/log/version.map +1 -0
@@ -31,5 +31,6 @@ INTERNAL { eal_log_save_pattern; eal_log_save_regexp; eal_log_set_default; + eal_log_timestamp; rte_eal_log_cleanup; };
Signature · 1 line
2.43.0
Quoted 73 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. Other alternatives are delta, ctime, reltime and iso formats.
Example:
$ dpdk-testpmd --log-timestamp -- -i EAL: Detected CPU lcores: 8 EAL: Detected NUMA nodes: 1 [ 0.000083] EAL: Detected static linkage of DPDK [ 0.002000] EAL: Multi-process socket /var/run/dpdk/rte/mp_socket [ 0.003507] EAL: Selected IOVA mode 'VA' [ 0.006272] testpmd: No probed ethernet devices Interactive-mode selected [ 0.029567] testpmd: create a new mbuf pool <mb_pool_0>: n=203456, size=2176, socket=0 [ 0.029588] testpmd: preferred mempool ops selected: ring_mp_mcSigned-off-by Stephen Hemminger <[email protected]>--- app/test/test_eal_flags.c | 17 ++++ doc/guides/prog_guide/log_lib.rst | 10 ++ lib/eal/common/eal_common_options.c | 14 ++- lib/eal/common/eal_options.h | 2 + lib/log/log_internal.h | 9 ++ lib/log/log_unix.c | 152 +++++++++++++++++++++++++++- lib/log/log_windows.c | 6 ++ lib/log/version.map | 1 + 8 files changed, 205 insertions(+), 6 deletions(-)app/test/test_eal_flags.c +17
-0@@ -1055,6 +1055,14 @@ 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" }; +/* run all tests also applicable to FreeBSD first */ if (launch_proc (argv0) ==0 ) {@@ -1162,6 +1170,15 @@ 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; + } +rmdir (hugepath_dir3);rmdir (hugepath_dir2);doc/guides/prog_guide/log_lib.rst +0
-0
doc/guides/prog_guide/log_lib.rst For example:: · line 80
Quoted 8 lines
doc/guides/prog_guide/log_lib.rst +5
-0@@ -73,6 +73,16 @@ For example:: /path/to/app --syslog local0 +Console timestamp +~~~~~~~~~~~~~~~~~ + +On Linux and FreeBSD, an optional timestamp can be added before each +message by adding the ``--log-timestamp`` option.
i don't think Windows should be excluded from the feature, in general core libraries that get features should cover all platforms.
Quoted 10 lines · On Thu, 21 Mar 2024 10:11:31 -0700 Tyler Retzlaff…
doc/guides/prog_guide/log_lib.rst For example:: · line 80
Quoted 7 lines
doc/guides/prog_guide/log_lib.rst +5
-0+Console timestamp +~~~~~~~~~~~~~~~~~ + +On Linux and FreeBSD, an optional timestamp can be added before each +message by adding the ``--log-timestamp`` option.i don't think Windows should be excluded from the feature, in general core libraries that get features should cover all platforms.
The problem is that current Linux/FreeBSD log code depends on fopencookie() to work. I could not find a way to do that on Windows.
Quoted 14 lines · Stephen Hemminger
Quoted 10 lines · On Thu, 21 Mar 2024 10:11:31 -0700 Tyler Retzlaff…
doc/guides/prog_guide/log_lib.rst For example:: · line 80
Quoted 7 lines
doc/guides/prog_guide/log_lib.rst +5
-0+Console timestamp +~~~~~~~~~~~~~~~~~ + +On Linux and FreeBSD, an optional timestamp can be added before each +message by adding the ``--log-timestamp`` option.i don't think Windows should be excluded from the feature, in general core libraries that get features should cover all platforms.
Quoted 2 lines
The problem is that current Linux/FreeBSD log code depends on
fopencookie()to work. I could not find a way to do that on Windows.
but that looks like it is part of general log initialization. surely when we are talking about logging a timestamp to a console we're just talking about a standard stream and a format string for Windows?
i'll try to study more to gain a better understanding.
thanks
Quoted 18 lines · On Thu, 21 Mar 2024 10:49:06 -0700 Tyler Retzlaff…
Quoted 14 lines · Stephen Hemminger
Quoted 10 lines · On Thu, 21 Mar 2024 10:11:31 -0700 Tyler Retzlaff…
doc/guides/prog_guide/log_lib.rst For example:: · line 80
Quoted 7 lines
doc/guides/prog_guide/log_lib.rst +5
-0+Console timestamp +~~~~~~~~~~~~~~~~~ + +On Linux and FreeBSD, an optional timestamp can be added before each +message by adding the ``--log-timestamp`` option.i don't think Windows should be excluded from the feature, in general core libraries that get features should cover all platforms.
Quoted 2 lines
The problem is that current Linux/FreeBSD log code depends on
fopencookie()to work. I could not find a way to do that on Windows.
Quoted 7 lines
but that looks like it is part of general log initialization. surely when we are talking about logging a timestamp to a console we're just talking about a standard stream and a format string for Windows?
i'll try to study more to gain a better understanding.
thanks
What the code does is take what rte_log created and add more data before actual printing it. The other option is doing this at rte_log() but that will break the syslog side.
I am not sure that having log go directly to syslog makes sense anyway on a modern Linux system. If DPDK is being used by a daemon, that daemon will be a systemd service. And systemd has simple way to make stderr go to syslog. So if we drop the syslog support, then the whole thing gets more generic and simpler.
PATCH v10 9/10 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.
--- lib/eal/common/eal_common_options.c | 10 +++ lib/eal/common/eal_options.h | 2 + lib/log/log_internal.h | 5 ++ lib/log/log_unix.c | 132 +++++++++++++++++++++++++--- lib/log/log_windows.c | 6 ++ lib/log/version.map | 1 + 6 files changed, 146 insertions(+), 10 deletions(-)
lib/eal/common/eal_common_options.c +10 -0
@@ -78,6 +78,7 @@ eal_long_options[] = { {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_LOG_COLOR, 1, NULL, OPT_LOG_COLOR_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 },
@@ -1910,6 +1911,15 @@ 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 ; +case OPT_TRACE_NUM : {if (eal_trace_args_save (optarg) <0 ) { EAL_LOG(ERR, "invalid parameters for --"
lib/eal/common/eal_options.h +2 -0
@@ -37,6 +37,8 @@ enum {OPT_LOG_LEVEL_NUM , #define OPT_LOG_TIMESTAMP "log-timestamp"OPT_LOG_TIMESTAMP_NUM , +#define OPT_LOG_COLOR "log-color" +OPT_LOG_COLOR_NUM , #define OPT_TRACE "trace"OPT_TRACE_NUM , #define OPT_TRACE_DIR "trace-dir"
lib/log/log_internal.h +5 -0
@@ -52,5 +52,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_unix.c +122 -10
174 lines not on this page · raw message
lib/log/log_windows.c +6 -0
@@ -12,6 +12,12 @@ eal_log_timestamp(__rte_unused const char *fmt)return -1 ;/* not implemented */ } +int +eal_log_color(__rte_unused const char *mode) +{ +return -1 ;/* not implemented */ +} +/* set the log to default function, called during eal init process. */ int eal_log_init(__rte_unused const char *id, __rte_unused int facility)
lib/log/version.map +1 -0
@@ -25,6 +25,7 @@ DPDK_24 { INTERNAL { global: + eal_log_color; eal_log_get_default; eal_log_init; eal_log_level2str;
Signature · 1 line
2.43.0
PATCH v10 10/10 doc: add documentation of logging options
In reply to Stephen HemmingerAdd documentation of new log-timestamp and log-color options.
--- doc/guides/linux_gsg/eal_args.include.rst | 54 +++++++++++++++++++---- 1 file changed, 46 insertions(+), 8 deletions(-)
doc/guides/linux_gsg/eal_args.include.rst +46 -8
@@ -122,6 +122,52 @@ Memory-related options to system pthread stack size unless the optional size (in kbytes) is specified. +Logging options +~~~~~~~~~~~~~~~ + +* ``--log-level <type:val>`` + + Specify log level for a specific component. For example:: + + --log-level lib.eal:debug + + Can be specified multiple times. + +* ``--log-facility=facility`` + + Specifies the ``syslog`` facility passed to ``openlog``. + The facility can be: ``auth``, ``cron``, ``daemon``, ``ftp``, + ``lpr``, ``mail``, ``news``, ``user``, ``uucp``, + ``local0``, ``local1``, ``local2``, ``local3``, ``local4``, + ``local5``, ``local6``, or ``local7``. The default if + no facility is specified is ``daemon``. + +* ``--log-timestamp[=format]`` + + Add a time stamp to log messages that are sent to the console (stderr). + When format argument is omitted the time stamp is elapsed + seconds since the start of the DPDK application. + Other formats are: + +.. 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]``" + +* ``--log-color[=when]`` + + Colorize the console output. + The optional argument ``when`` can be ``auto``, ``never`` or ``always``. + If the when argument is omitted, it defaults to ``auto``. + To disable use of color:: + + --log-color=none + + Debugging options ~~~~~~~~~~~~~~~~~
@@ -134,14 +180,6 @@ Debugging options Use anonymous memory instead of hugepages (implies no secondary process support). -* ``--log-level <type:val>`` - - Specify log level for a specific component. For example:: - - --log-level lib.eal:debug - - Can be specified multiple times. - * ``--trace=<regex-match>`` Enable trace based on regular expression trace name. By default, the trace is
Signature · 1 line
2.43.0
v11 cover Logging unification and enhancements
In reply to Stephen HemmingerImprovements and unification of logging library (for 24.07 release). 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.
I find color helpful because 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.
* Use of syslog on Linux is replaced by using journal API (over unix domain socket). This replaces legacy syslog; (almost) all Linux distros have switched to journal.
Will add a release note in next release (after this is merged)
v11 - rework to be portable to Windows
drop syslog support and support journal instead
Stephen Hemminger (9):
windows: make getopt functions have const properties
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: drop syslog support, and make code common
log: add hook for printing log messages
log: add timestamp option
log: add support for systemd journal
log: colorize log output
app/test/test_eal_flags.c | 38 +- doc/guides/linux_gsg/linux_eal_parameters.rst | 27 - .../prog_guide/env_abstraction_layer.rst | 5 +- doc/guides/prog_guide/log_lib.rst | 41 +- lib/eal/common/eal_common_debug.c | 11 +- lib/eal/common/eal_common_options.c | 123 ++--- lib/eal/common/eal_internal_cfg.h | 2 +- lib/eal/common/eal_options.h | 7 +- lib/eal/freebsd/eal.c | 54 +- lib/eal/linux/eal.c | 52 +- lib/eal/unix/eal_debug.c | 3 +- lib/eal/windows/eal.c | 39 +- lib/eal/windows/getopt.c | 23 +- lib/eal/windows/include/getopt.h | 8 +- lib/log/log.c | 513 ++++++++++++++++-- lib/log/log_freebsd.c | 12 - lib/log/log_internal.h | 16 +- lib/log/log_linux.c | 61 --- lib/log/log_windows.c | 18 - lib/log/meson.build | 5 +- lib/log/version.map | 2 + 21 files changed, 656 insertions(+), 404 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
Signature · 1 line
2.43.0
PATCH v11 1/9 windows: make getopt functions have const properties
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 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 v11 2/9 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 v11 3/9 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 v11 4/9 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 =NULL ;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); +vasprintf (&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 v11 5/9 log: drop syslog support, and make code common
In reply to Stephen HemmingerThis patch removes syslog support from logging. Which allows the logging code to all be common across Linux, Windows and FreeBSD. It also initializes log subsystem much earlier in the init process so that all messages get processed.
It drops syslog was only used on Linux. Modern Linux systems have systemd and journal support. A later patch will add direct native journal support. Removing syslog means lots of other parts of the log system can be simplified and made portable. Remove the syslog tests and documentation as well.
--- app/test/test_eal_flags.c | 21 +------ doc/guides/linux_gsg/linux_eal_parameters.rst | 27 -------- .../prog_guide/env_abstraction_layer.rst | 5 +- doc/guides/prog_guide/log_lib.rst | 3 +- lib/eal/common/eal_common_options.c | 62 ------------------- lib/eal/common/eal_internal_cfg.h | 2 +- lib/eal/common/eal_options.h | 2 - lib/eal/freebsd/eal.c | 9 +-- lib/eal/linux/eal.c | 10 +-- lib/eal/unix/eal_debug.c | 3 +- lib/eal/windows/eal.c | 4 +- lib/log/log.c | 46 +++++--------- lib/log/log_freebsd.c | 12 ---- lib/log/log_internal.h | 2 +- lib/log/log_linux.c | 61 ------------------ lib/log/log_windows.c | 18 ------ lib/log/meson.build | 5 +- 17 files changed, 34 insertions(+), 258 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 +1 -20
@@ -984,17 +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 valid --syslog */ -const char *argv3[] = {prgname, prefix, mp_flag, -"--syslog" ,"syslog" }; -/* With empty --syslog (should fail) */ -const char *argv4[] = {prgname, prefix, mp_flag,"--syslog" }; -/* 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 */ const char *argv6[] = {prgname,"-m" ,DEFAULT_MEM_SIZE , no_shconf, nosh_prefix, no_huge}; -/* With --huge-dir */ const char *argv7[] = {prgname,"-m" ,DEFAULT_MEM_SIZE ,"--file-prefix=hugedir" ,"--huge-dir" , hugepath};
@@ -1079,18 +1072,6 @@ test_misc_flags(void)return 0 ;#endif -if (launch_proc (argv3) !=0 ) { -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" ); - goto fail; - } -if (launch_proc (argv5) ==0 ) { -printf ("Error - process run ok with invalid --syslog flag\n" ); - goto fail; - }if (launch_proc (argv7) !=0 ) {printf ("Error - process did not run ok with --huge-dir flag\n" ); goto fail;
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/env_abstraction_layer.rst +2 -3
@@ -855,9 +855,8 @@ Signal Safety Other functions are not signal safe because they use one or more library routines that are not themselves signal safe. For example, calling ``rte_panic()`` is not safe in a signal handler - because it uses ``rte_log()`` and ``rte_log()`` calls the - ``syslog()`` library function which is in the list of - signal safe functions in + because it uses ``rte_log()`` and ``rte_log()`` calls library functions + that are not all signal safe. `Signal-Safety manual page <https://man7.org/linux/man-pages/man7/signal-safety.7.html>`_. The set of functions that are expected to be async-signal-safe in DPDK
doc/guides/prog_guide/log_lib.rst +1 -2
@@ -5,8 +5,7 @@ Log Library =========== The DPDK Log library provides the logging functionality for other DPDK libraries and drivers. -By default, in a Linux application, logs are sent to syslog and also to the console. -On FreeBSD and Windows applications, logs are sent only to the console. +By default, log messages are sent to the stderr. However, the log function can be overridden by the user to use a different logging mechanism. Log Levels
lib/eal/common/eal_common_options.c +0 -62
98 lines not on this page · raw message
lib/eal/common/eal_internal_cfg.h +1 -1
@@ -84,7 +84,7 @@ struct internal_config {/**< true if storing all pages within single files (per-page-size, * per-node) non-legacy mode only. */ -volatile int syslog_facility;/**< facility passed to openlog() */ +/** default interrupt mode for VFIO */ volatile enum rte_intr_mode vfio_intr_mode;/** the shared VF token for VFIO-PCI bound PF and VFs devices */
lib/eal/common/eal_options.h +0 -2
@@ -63,8 +63,6 @@ enum {OPT_SOCKET_MEM_NUM , #define OPT_SOCKET_LIMIT "socket-limit"OPT_SOCKET_LIMIT_NUM , -#define OPT_SYSLOG "syslog" -OPT_SYSLOG_NUM , #define OPT_VDEV "vdev"OPT_VDEV_NUM , #define OPT_VFIO_INTR "vfio-intr"
lib/eal/freebsd/eal.c +5 -4
@@ -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>
@@ -563,12 +562,14 @@ rte_eal_init(int argc, char **argv)eal_reset_internal_config (internal_conf); -/* 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); +eal_log_init (getprogname ()); + +/* clone argv to report out later in telemetry */ +eal_save_args (argc, argv); +if (rte_eal_cpu_init () <0 ) {rte_eal_init_alert ("Cannot detect lcores." ); rte_errno =ENOTSUP ;
lib/eal/linux/eal.c +2 -8
@@ -955,6 +955,8 @@ rte_eal_init(int argc, char **argv)/* set log level as early as possible */ eal_log_level_parse (argc, argv); +eal_log_init (program_invocation_short_name); +/* clone argv to report out later in telemetry */ eal_save_args (argc, argv);
@@ -1106,14 +1108,6 @@ rte_eal_init(int argc, char **argv)#endif } -if (eal_log_init (program_invocation_short_name, - internal_conf->syslog_facility) <0 ) { -rte_eal_init_alert ("Cannot init logging." ); - rte_errno =ENOMEM ; -rte_atomic_store_explicit (&run_once,0 , rte_memory_order_relaxed); -return -1 ; - } -#ifdef VFIO_PRESENT if (rte_eal_vfio_setup () <0 ) {rte_eal_init_alert ("Cannot init VFIO" );
lib/eal/unix/eal_debug.c +1 -2
@@ -43,8 +43,7 @@ static char *safe_itoa(long val, char *buf, size_t len, unsigned int radix)* used in this code since may be called from inside libc or * when malloc poll is corrupt. * -* Most of libc is therefore not safe, include RTE_LOG (calls syslog); -* backtrace_symbols (calls malloc), etc. +* Most of libc is therefore not safe including backtrace_symbols (calls malloc), etc. */ void rte_dump_stack (void ) {
lib/eal/windows/eal.c +2 -2
@@ -250,10 +250,10 @@ 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_level_parse (argc, argv); +eal_log_init (NULL ); +if (eal_create_cpu_map () <0 ) {rte_eal_init_alert ("Cannot discover CPU and NUMA." );/* rte_errno is set */
lib/log/log.c +17 -29
76 lines not on this page · raw message
lib/log/log_freebsd.c deleted +0 -12
@@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause -* Copyright(c) 2023 Intel Corporation -*/ - -#include <rte_common.h> -#include "log_internal.h" - -int -eal_log_init(__rte_unused const char *id, __rte_unused int facility) -{ -return 0 ; -}
lib/log/log_internal.h +1 -1
@@ -14,7 +14,7 @@* Initialize the default log stream. */ __rte_internal -int eal_log_init(const char *id, int facility); +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 deleted +0 -61
61 lines not on this page · raw message
lib/log/log_windows.c deleted +0 -18
@@ -1,18 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause -* Copyright(c) 2017-2018 Intel Corporation -*/ - -#include <rte_common.h> -#include <rte_log.h> -#include "log_internal.h" - -/* set the log to default function, called during eal init process. */ -int -eal_log_init(__rte_unused const char *id, __rte_unused int facility) -{ -rte_openlog_stream (stderr); - -eal_log_set_default (stderr); - -return 0 ; -}
lib/log/meson.build +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')
Signature · 1 line
2.43.0
PATCH v11 6/9 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.
No functional changes in this patch, just infrastructure addition.
--- lib/log/log.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-)
lib/log/log.c +16 -3
@@ -26,16 +26,21 @@ struct rte_log_dynamic_type {uint32_t loglevel; }; +typedef int (*log_print_t )(FILE *f,uint32_t level,const char *fmt,va_list ap); +static int log_print (FILE *f,uint32_t level,const char *format,va_list ap); +/** The rte_log structure. */ static struct rte_logs {uint32_t type;/**< Bitfield with enabled logs. */ uint32_t level;/**< Log level. */ FILE *file;/**< Output file set by rte_openlog_stream, or NULL. */ +log_print_t print_func;size_t dynamic_types_len;struct rte_log_dynamic_type *dynamic_types; } rte_logs = { .type =UINT32_MAX , .level =RTE_LOG_DEBUG , + .print_func = log_print, };struct rte_eal_opt_loglevel {
@@ -67,8 +72,6 @@ struct log_cur_msg {/* per core log */ static RTE_DEFINE_PER_LCORE(struct log_cur_msg, log_cur_msg); -/* default logs */ -/* Change the stream that will be used by logging system */ int rte_openlog_stream (FILE *f)
@@ -77,6 +80,7 @@ rte_openlog_stream(FILE *f)fclose (rte_logs.file); rte_logs.file = f; + rte_logs.print_func = log_print;return 0 ; }
@@ -473,7 +477,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; }
@@ -509,6 +513,15 @@ rte_eal_log_cleanup(void) } } +/* default log print function */ +__rte_format_printf(3, 0) +static int +log_print(FILE *f, uint32_t level __rte_unused, +const char *format,va_list ap) +{ +return vfprintf (f, format, ap); +} +/* initialize logging */ void eal_log_init(const char *id __rte_unused)
Signature · 1 line
2.43.0
PATCH v11 7/9 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 | 17 +++ doc/guides/prog_guide/log_lib.rst | 26 +++++ lib/eal/common/eal_common_options.c | 14 ++- lib/eal/common/eal_options.h | 2 + lib/log/log.c | 168 +++++++++++++++++++++++++++- lib/log/log_internal.h | 9 ++ lib/log/version.map | 1 + 7 files changed, 234 insertions(+), 3 deletions(-)
app/test/test_eal_flags.c +17 -0
@@ -1048,6 +1048,14 @@ 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" }; +/* run all tests also applicable to FreeBSD first */ if (launch_proc (argv0) ==0 ) {
@@ -1143,6 +1151,15 @@ 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; + } +rmdir (hugepath_dir3);rmdir (hugepath_dir2);
doc/guides/prog_guide/log_lib.rst +26 -0
@@ -58,6 +58,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. +Console timestamp +~~~~~~~~~~~~~~~~~ + +An optional timestamp can be added before each message when printing on the console +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 },
@@ -1614,6 +1615,7 @@ eal_log_level_parse(int argc, char * const argv[])switch (opt) {case OPT_LOG_LEVEL_NUM : +case OPT_LOG_TIMESTAMP_NUM :if (eal_parse_common_option (opt, optarg, internal_conf) <0 )return -1 ;break ;
@@ -1831,7 +1833,7 @@ eal_parse_common_option(int opt, const char *optarg, }break ; -case OPT_LOG_LEVEL_NUM : { +case OPT_LOG_LEVEL_NUM :if (eal_parse_log_level (optarg) <0 ) {EAL_LOG (ERR , "invalid parameters for --"
@@ -1839,7 +1841,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 : {
@@ -2204,6 +2213,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 " 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/log/log.c +167 -1
214 lines not on this page · raw message
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>
@@ -42,4 +44,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/version.map +1 -0
@@ -30,5 +30,6 @@ INTERNAL { eal_log_save_pattern; eal_log_save_regexp; eal_log_set_default; + eal_log_timestamp; rte_eal_log_cleanup; };
Signature · 1 line
2.43.0
PATCH v11 8/9 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/
The journal protocol supports more information that could be added later.
--- lib/log/log.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 136 insertions(+), 5 deletions(-)
lib/log/log.c +136 -5
@@ -13,15 +13,20 @@#include <sys/queue.h> #include <unistd.h> +#ifdef RTE_EXEC_ENV_WINDOWS +#include <rte_os_shim.h> +#else +#include <sys/uio.h> +#include <sys/stat.h> +#include <sys/socket.h> +#include <sys/un.h> +#endif +#include <rte_log.h> #include <rte_per_lcore.h> #include "log_internal.h" -#ifdef RTE_EXEC_ENV_WINDOWS -#include <rte_os_shim.h> -#endif -struct rte_log_dynamic_type {const char *name;uint32_t loglevel;
@@ -39,11 +44,13 @@ enum eal_log_time_format {typedef int (*log_print_t )(FILE *f,uint32_t level,const char *fmt,va_list ap);static int log_print (FILE *f,uint32_t level,const char *format,va_list ap); +/** The rte_log structure. */ static struct rte_logs { uint32_t type; /**< Bitfield with enabled logs. */ uint32_t level; /**< Log level. */ FILE *file; /**< Output file set by rte_openlog_stream, or NULL. */ + int journal_fd; /**< Journal file descriptor if using */ log_print_t print_func; enum eal_log_time_format time_format;
@@ -681,6 +688,116 @@ log_print_with_timestamp(FILE *f, uint32_t level,return log_print (f, level, format, ap); } +#ifdef RTE_EXEC_ENV_LINUX +/* +* send message using journal protocol to journald +*/ +__rte_format_printf(3, 0) +static int +journal_print(FILE *f __rte_unused, uint32_t level, const char *format, va_list ap) +{ +struct iovec iov[3 ]; +char *buf =NULL ; +size_t len; +char msg[] ="MESSAGE=" ; +char *prio; + + iov[0 ].iov_base = msg; + iov[0 ].iov_len =strlen (msg); + + len =vasprintf (&buf, format, ap); +if (len ==0 ) +return 0 ; + +/* check that message ends with newline */ +if (buf[len -1 ] !='\n' ) { +char *clone =alloca (len +1 ); +if (clone ==NULL ) +return 0 ; +memcpy (clone, buf, len); + clone[len++] ='\n' ; + buf = clone; + } + + iov[1 ].iov_base = buf; + iov[1 ].iov_len = len; + +/* priority value between 0 ("emerg") and 7 ("debug") */ + len =asprintf (&prio,"PRIORITY=%i\n" , level -1 ); + iov[2 ].iov_base = prio; + iov[2 ].iov_len = len; + +return writev (rte_logs.journal_fd, iov,3 ); +} + +static void +journal_send_id (int fd,const char *id) +{ +char *syslog_id =NULL ; +size_t len; + + len =asprintf (&syslog_id,"SYSLOG_IDENTIFIER=%s\n" , id); +if (len >0 ) +write (fd, syslog_id, len); + +} + +/* +* Check if stderr is going to system journal. +* This is the documented way to handle systemd journal +* +* See: https://systemd.io/JOURNAL_NATIVE_PROTOCOL/ +* +*/ +static bool +using_journal (void ) +{ +char *jenv, *endp =NULL ; +struct stat st; +unsigned long dev, ino; + + jenv =getenv ("JOURNAL_STREAM" ); +if (jenv ==NULL ) +return false; + +if (fstat (STDERR_FILENO , &st) <0 ) +return false; + +/* systemd sets colon-separated list of device and inode number */ + dev =strtoul (jenv, &endp,10 ); +if (endp ==NULL || *endp !=':' ) +return false;/* missing colon */ + + ino =strtoul (endp +1 ,NULL ,10 ); + +return dev == st.st_dev && ino == st.st_ino; +} + +/* +* If we are being run as systemd service and stderr is going to journal +* then upgrade to use journal protocol. +*/ +static int +open_journal (void ) +{ +struct sockaddr_un sun = { + .sun_family =AF_UNIX , + .sun_path ="/run/systemd/journal/socket" , + }; +int s; + + s =socket (AF_UNIX ,SOCK_DGRAM ,0 ); +if (s <0 ) +return -1 ; + +if (connect (s, (struct sockaddr *)&sun,sizeof (sun)) <0 ) { +close (s); +return -1 ; + } +return s; +} +#endif +/* initialize logging */ void eal_log_init(const char *id __rte_unused)
@@ -689,8 +806,22 @@ eal_log_init(const char *id __rte_unused)if (rte_logs.file !=NULL )return ; -if (rte_logs.time_format !=EAL_LOG_TIMESTAMP_NONE ) +#ifdef RTE_EXEC_ENV_LINUX +if (using_journal ()) { +int jfd =open_journal (); + +if (jfd <0 ) { +RTE_LOG_LINE (NOTICE ,EAL ,"Cannot connect to journal" ); + }else { + rte_logs.journal_fd = jfd; + rte_logs.print_func = journal_print; +journal_send_id (jfd, id); + } + } else +#endif +if (rte_logs.time_format !=EAL_LOG_TIMESTAMP_NONE ) { rte_logs.print_func = log_print_with_timestamp; + }#if RTE_LOG_DP_LEVEL >=RTE_LOG_DEBUG RTE_LOG(NOTICE, EAL,
Signature · 1 line
2.43.0
PATCH v11 9/9 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.
--- doc/guides/prog_guide/log_lib.rst | 14 ++- lib/eal/common/eal_common_options.c | 1 + lib/eal/common/eal_options.h | 2 + lib/log/log.c | 153 +++++++++++++++++++++++++++- lib/log/log_internal.h | 5 + lib/log/version.map | 1 + 6 files changed, 173 insertions(+), 3 deletions(-)
doc/guides/prog_guide/log_lib.rst +13 -1
@@ -58,6 +58,19 @@ 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 +~~~~~~~~~~~~ + +It is useful ot be able see important messages highlighted. This is controlled by the +``--log-color`` option. The 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 + + Console timestamp ~~~~~~~~~~~~~~~~~
@@ -83,7 +96,6 @@ 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 +1 -0
@@ -75,6 +75,7 @@ eal_long_options[] = { {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_LOG_COLOR, 1, NULL, OPT_LOG_COLOR_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 },
lib/eal/common/eal_options.h +2 -0
@@ -37,6 +37,8 @@ enum {OPT_LOG_LEVEL_NUM , #define OPT_LOG_TIMESTAMP "log-timestamp"OPT_LOG_TIMESTAMP_NUM , +#define OPT_LOG_COLOR "log-color" +OPT_LOG_COLOR_NUM , #define OPT_TRACE "trace"OPT_TRACE_NUM , #define OPT_TRACE_DIR "trace-dir"
lib/log/log.c +151 -2
191 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/version.map +1 -0
@@ -25,6 +25,7 @@ DPDK_24 { INTERNAL { global: + eal_log_color; eal_log_init; eal_log_level2str; eal_log_save_pattern;
Signature · 1 line
2.43.0
Re: [PATCH v11 0/9] Logging unification and enhancements
In reply to Stephen HemmingerQuoted 24 lines · Stephen Hemminger
Improvements and unification of logging library (for 24.07 release). 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.I find color helpful because 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.
Quoted 4 lines
* Use of syslog on Linux is replaced by using journal API (over unix domain socket). This replaces legacy syslog; (almost) all Linux distros have switched to journal.
Is "switched to journal" the same as "switched to systemd", or are there non-systemd journal API implementations?
I'm guessing there are quite a few Linux-based embedded systems that doesn't use systemd.
Ideally, you would like to have journal as the Linux default, and then syslog as a build-time option.
Quoted 42 lines
Will add a release note in next release (after this is merged)
v11 - rework to be portable to Windows
drop syslog support and support journal insteadStephen Hemminger (9):
windows: make getopt functions have const properties
eal: makeeal_log_level_parsecommon
eal: do not duplicaterte_init_alert()messages
eal: changerte_exit()output to matchrte_log()
log: drop syslog support, and make code common
log: add hook for printing log messages
log: add timestamp option
log: add support for systemd journal
log: colorize log outputapp/test/test_eal_flags.c | 38 +- doc/guides/linux_gsg/linux_eal_parameters.rst | 27 - .../prog_guide/env_abstraction_layer.rst | 5 +- doc/guides/prog_guide/log_lib.rst | 41 +- lib/eal/common/eal_common_debug.c | 11 +- lib/eal/common/eal_common_options.c | 123 ++--- lib/eal/common/eal_internal_cfg.h | 2 +- lib/eal/common/eal_options.h | 7 +- lib/eal/freebsd/eal.c | 54 +- lib/eal/linux/eal.c | 52 +- lib/eal/unix/eal_debug.c | 3 +- lib/eal/windows/eal.c | 39 +- lib/eal/windows/getopt.c | 23 +- lib/eal/windows/include/getopt.h | 8 +- lib/log/log.c | 513 ++++++++++++++++-- lib/log/log_freebsd.c | 12 - lib/log/log_internal.h | 16 +- lib/log/log_linux.c | 61 --- lib/log/log_windows.c | 18 - lib/log/meson.build | 5 +- lib/log/version.map | 2 + 21 files changed, 656 insertions(+), 404 deletions(-)delete mode 100644
lib/log/log_freebsd.c
delete mode 100644lib/log/log_linux.c
delete mode 100644lib/log/log_windows.c
v12 cover Logging unification and enhancements
In reply to Stephen HemmingerImprovements and unification of logging library (for 24.07 release). 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.
I find color helpful because 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...
Will add a release note in next release (after this is merged)
v12 - add back syslog but make it optional.
better shims for windows (thread safe)
split out more of the eal core bits
fix build warnings on FreeBSD and Ubuntu
Stephen Hemminger (14):
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: add for log library
MAINTAINERS | 1 + app/test/test_eal_flags.c | 17 + doc/guides/linux_gsg/linux_eal_parameters.rst | 27 - doc/guides/prog_guide/log_lib.rst | 57 ++ lib/eal/common/eal_common_debug.c | 11 +- lib/eal/common/eal_common_options.c | 114 ++-- lib/eal/common/eal_options.h | 5 + lib/eal/freebsd/eal.c | 60 +- lib/eal/linux/eal.c | 64 +- lib/eal/windows/eal.c | 44 +- 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 | 594 +++++++++++++++++- lib/log/log_freebsd.c | 5 +- lib/log/log_internal.h | 25 +- lib/log/log_linux.c | 61 -- lib/log/log_windows.c | 18 - lib/log/meson.build | 5 +- lib/log/version.map | 4 +- 20 files changed, 803 insertions(+), 350 deletions(-) delete mode 100644 lib/log/log_linux.c delete mode 100644 lib/log/log_windows.c
Signature · 1 line
2.43.0
PATCH v12 1/14 windows: make getopt functions have const properties
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 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 v12 2/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 v12 3/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 v12 4/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 v12 5/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 =NULL ;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); +vasprintf (&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
Re: [PATCH v12 05/14] eal: change rte_exit() output to match rte_log()
Quoted 7 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 denied
Quoted 6 lines
After:
[ 0.006238] EAL: Error - exiting with code: 1 [ 0.006250] EAL: Cause - Cannot init EAL: Permission deniedSigned-off-by Stephen Hemminger <[email protected]>---
PATCH v12 6/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_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 + 9 files changed, 68 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_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 v12 7/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 | 8 +++++--- lib/eal/linux/eal.c | 15 +++++---------- lib/eal/windows/eal.c | 3 +-- 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, 20 insertions(+), 29 deletions(-)
lib/eal/freebsd/eal.c +5 -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,10 @@ rte_eal_init(int argc, char **argv)bool has_phys_addr;enum rte_iova_mode iova_mode; +/* setup log as early as possible */ +eal_log_level_parse (argc, argv); +eal_log_init (getprogname ()); +/* checks if the machine is adequate */ if (!rte_cpu_is_supported ()) {rte_eal_init_alert ("unsupported cpu type." );
@@ -565,9 +570,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 +5 -10
@@ -936,6 +936,11 @@ rte_eal_init(int argc, char **argv)struct internal_config *internal_conf =eal_get_internal_configuration (); + +/* setup log as early as possible */ +eal_log_level_parse (argc, argv); +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 +957,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 +1108,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 +1 -2
@@ -250,9 +250,8 @@ 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 ); -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 v12 8/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.
--- lib/log/log.c | 29 ++++++++---- 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 - 6 files changed, 21 insertions(+), 144 deletions(-) delete mode 100644 lib/log/log_linux.c delete mode 100644 lib/log/log_windows.c
lib/log/log.c +20 -9
@@ -70,12 +70,13 @@ struct log_cur_msg {/* per core log */ static RTE_DEFINE_PER_LCORE(struct log_cur_msg, log_cur_msg); -/* default logs */ -/* Change the stream that will be used by logging system */ int rte_openlog_stream (FILE *f) { +if (rte_logs.file !=NULL ) +fclose (rte_logs.file); + rte_logs.file = f;return 0 ; }
@@ -505,13 +506,20 @@ 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 environment-specific initialization functions. +* Called by rte_eal_init */ void -eal_log_set_default (FILE *default_log) +eal_log_init(const char *id __rte_unused) { - default_log_stream = default_log; + default_log_stream = stderr;#if RTE_LOG_DP_LEVEL >=RTE_LOG_DEBUG RTE_LOG(NOTICE, EAL,
@@ -525,8 +533,11 @@ eal_log_set_default(FILE *default_log)void rte_eal_log_cleanup (void ) { -if (default_log_stream) { -fclose (default_log_stream); - default_log_stream =NULL ; - } +FILE *log_stream =rte_log_get_stream (); + +/* don't close stderr on the application */ +if (log_stream != stderr) +fclose (log_stream); + + rte_logs.file =NULL ; }
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 v12 9/14 log: add hook for printing log messages
In reply to Stephen HemmingerThis is useful for when decorating log output for console or journal. Provide basic version in this patch.
--- lib/log/log.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
lib/log/log.c +16 -1
@@ -26,16 +26,21 @@ struct rte_log_dynamic_type {uint32_t loglevel; }; +typedef int (*log_print_t )(FILE *f,uint32_t level,const char *fmt,va_list ap); +static int log_print (FILE *f,uint32_t level,const char *format,va_list ap); +/** The rte_log structure. */ static struct rte_logs {uint32_t type;/**< Bitfield with enabled logs. */ uint32_t level;/**< Log level. */ FILE *file;/**< Output file set by rte_openlog_stream, or NULL. */ +log_print_t print_func;size_t dynamic_types_len;struct rte_log_dynamic_type *dynamic_types; } rte_logs = { .type =UINT32_MAX , .level =RTE_LOG_DEBUG , + .print_func = log_print, };struct rte_eal_opt_loglevel {
@@ -78,6 +83,7 @@ rte_openlog_stream(FILE *f)fclose (rte_logs.file); rte_logs.file = f; + rte_logs.print_func = log_print;return 0 ; }
@@ -484,7 +490,7 @@ rte_vlog(uint32_t level, uint32_t logtype, const char *format, va_list ap)RTE_PER_LCORE (log_cur_msg).loglevel = level;RTE_PER_LCORE (log_cur_msg).logtype = logtype; - ret =vfprintf (f, format, ap); + ret = (*rte_logs.print_func)(f, level, format, ap);fflush (f);return ret; }
@@ -513,6 +519,15 @@ eal_log_syslog(const char *mode __rte_unused)return -1 ; } +/* default log print function */ +__rte_format_printf(3, 0) +static 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 */
Signature · 1 line
2.43.0
PATCH v12 10/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 | 17 +++ 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 | 183 +++++++++++++++++++++++++++- lib/log/log_internal.h | 9 ++ lib/log/version.map | 1 + 10 files changed, 259 insertions(+), 7 deletions(-)
app/test/test_eal_flags.c +17 -0
@@ -1055,6 +1055,14 @@ 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" }; +/* run all tests also applicable to FreeBSD first */ if (launch_proc (argv0) ==0 ) {
@@ -1162,6 +1170,15 @@ 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; + } +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 : {
@@ -2219,6 +2228,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 " 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 +182 -1
231 lines not on this page · raw message
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/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 v12 11/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.
--- doc/guides/linux_gsg/linux_eal_parameters.rst | 27 ----- doc/guides/prog_guide/log_lib.rst | 17 +++ lib/eal/common/eal_common_options.c | 2 +- lib/log/log.c | 101 ++++++++++++++++-- 4 files changed, 111 insertions(+), 36 deletions(-)
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 +1 -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 },
lib/log/log.c +93 -8
148 lines not on this page · raw message
Signature · 1 line
2.43.0
PATCH v12 12/14 log: add support for systemd journal
In reply to Stephen HemmingerIf DPDK application is being run as a systemd service, then it can use the journal protocol which allows putting more information in the log such as priority and other information.
The use of journal protocol is automatically detected and handled. Rather than having a dependency on libsystemd, just use the protocol directly as defined in:
https://systemd.io/JOURNAL_NATIVE_PROTOCOL/
--- lib/log/log.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 2 deletions(-)
lib/log/log.c +126 -2
@@ -17,6 +17,10 @@#include <rte_os_shim.h> #else #include <syslog.h> +#include <sys/uio.h> +#include <sys/stat.h> +#include <sys/socket.h> +#include <sys/un.h> #endif #include <rte_log.h>
@@ -56,6 +60,7 @@ static struct rte_logs {FILE *file;/**< Output file set by rte_openlog_stream, or NULL. */ #ifndef RTE_EXEC_ENV_WINDOWS enum eal_log_syslog syslog_opt; +int journal_fd;#endif log_print_t print_func;
@@ -758,6 +763,112 @@ static cookie_io_functions_t syslog_log_func = { .write = syslog_log_write, .close = syslog_log_close, }; + + +/* + * send message using journal protocol to journald + */ +__rte_format_printf(3, 0) +static int +journal_print(FILE *f __rte_unused, uint32_t level, const char *format, va_list ap) +{ +struct iovec iov[3 ]; +char *buf =NULL ; +size_t len; +char msg[] ="MESSAGE=" ; +char *prio; + + iov[0 ].iov_base = msg; + iov[0 ].iov_len =strlen (msg); + + len =vasprintf (&buf, format, ap); +if (len ==0 ) +return 0 ; + +/* check that message ends with newline, if not add one */ +if (buf[len -1 ] !='\n' ) { +char *clone =alloca (len +1 ); +if (clone ==NULL ) +return 0 ; +memcpy (clone, buf, len); + clone[len++] ='\n' ; + buf = clone; + } + + iov[1 ].iov_base = buf; + iov[1 ].iov_len = len; + +/* priority value between 0 ("emerg") and 7 ("debug") */ + len =asprintf (&prio,"PRIORITY=%i\n" , level -1 ); + iov[2 ].iov_base = prio; + iov[2 ].iov_len = len; + +return writev (rte_logs.journal_fd, iov,3 ); +} + +/* +* Check if stderr is going to system journal. +* This is the documented way to handle systemd journal +* +* See: https://systemd.io/JOURNAL_NATIVE_PROTOCOL/ +* +*/ +static bool +using_journal (void ) +{ +char *jenv, *endp =NULL ; +struct stat st; +unsigned long dev, ino; + + jenv =getenv ("JOURNAL_STREAM" ); +if (jenv ==NULL ) +return false; + +if (fstat (STDERR_FILENO , &st) <0 ) +return false; + +/* systemd sets colon-separated list of device and inode number */ + dev =strtoul (jenv, &endp,10 ); +if (endp ==NULL || *endp !=':' ) +return false;/* missing colon */ + + ino =strtoul (endp +1 ,NULL ,10 ); + +return dev == st.st_dev && ino == st.st_ino; +} + +/* Connect to systemd's journal service */ +static int +open_journal (const char *id) +{ +char *syslog_id =NULL ; +struct sockaddr_un sun = { + .sun_family =AF_UNIX , + .sun_path ="/run/systemd/journal/socket" , + }; +ssize_t len; +int s; + + s =socket (AF_UNIX ,SOCK_DGRAM ,0 ); +if (s <0 ) +return -1 ; + +if (connect (s, (struct sockaddr *)&sun,sizeof (sun)) <0 ) + goto error; + +/* Send syslog identifier as first message */ + len =asprintf (&syslog_id,"SYSLOG_IDENTIFIER=%s\n" , id); +if (len ==0 ) + goto error; + +if (write (s, syslog_id, len) != len) + goto error; + +return s; +error: +close (s); +return -1 ; +}#endif
@@ -765,11 +876,24 @@ static cookie_io_functions_t syslog_log_func = {static void log_output_selection (const char *id) { +#ifdef RTE_EXEC_ENV_WINDOWS RTE_SET_USED (id); - -#ifndef RTE_EXEC_ENV_WINDOWS +#else bool is_terminal =isatty (STDERR_FILENO ); +/* If stderr is redirected to systemd journal then upgrade */ +if (using_journal ()) { +int jfd =open_journal (id); + +if (jfd <0 ) { +RTE_LOG_LINE (NOTICE ,EAL ,"Cannot connect to journal: %s" , +strerror (errno)); + }else { + rte_logs.print_func = journal_print; +return ; + } + } +if (!(rte_logs.syslog_opt ==EAL_LOG_SYSLOG_NONE || (rte_logs.syslog_opt ==EAL_LOG_SYSLOG_AUTO && is_terminal))) {int flags =LOG_NDELAY |LOG_PID ;
Signature · 1 line
2.43.0
PATCH v12 13/14 log: colorize log output
In reply to Stephen HemmingerLike dmesg, colorize the log output (unless redirected to file). Timestamp is green, the subsystem is in yellow and the message is red if urgent, boldface if an error, and normal for info and debug messages.
--- doc/guides/prog_guide/log_lib.rst | 16 ++- lib/eal/common/eal_common_options.c | 1 + lib/eal/common/eal_options.h | 2 + lib/log/log.c | 158 +++++++++++++++++++++++++++- lib/log/log_internal.h | 5 + lib/log/version.map | 1 + 6 files changed, 178 insertions(+), 5 deletions(-)
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 ~~~~~~~~~~~~~
@@ -101,7 +116,6 @@ option. There are three possible settings for this option: 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 +1 -0
@@ -75,6 +75,7 @@ eal_long_options[] = { {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_LOG_COLOR, 1, NULL, OPT_LOG_COLOR_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 },
lib/eal/common/eal_options.h +2 -0
@@ -37,6 +37,8 @@ enum {OPT_LOG_LEVEL_NUM , #define OPT_LOG_TIMESTAMP "log-timestamp"OPT_LOG_TIMESTAMP_NUM , +#define OPT_LOG_COLOR "log-color" +OPT_LOG_COLOR_NUM , #define OPT_TRACE "trace"OPT_TRACE_NUM , #define OPT_TRACE_DIR "trace-dir"
lib/log/log.c +154 -4
202 lines not on this page · raw message
lib/log/log_internal.h +5 -0
@@ -47,5 +47,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/version.map +1 -0
@@ -25,6 +25,7 @@ DPDK_24 { INTERNAL { global: + eal_log_color; eal_log_init; eal_log_level2str; eal_log_save_pattern;
Signature · 1 line
2.43.0
PATCH v12 14/14 maintainers: add for log library
In reply to Stephen Hemminger"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
v13 cover Logging unification and improvements
In reply to Stephen HemmingerImprovements and unification of logging library (for 24.07 release). 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.
I find color helpful because 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...
Will add a release note in next release (after this is merged)
v13 - fix functional tests and warnings about unused result
v12 - add back syslog but make it optional.
better shims for windows (thread safe)
split out more of the eal core bits
fix build warnings on FreeBSD and Ubuntu
Stephen Hemminger (11):
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
app/test/test_eal_flags.c | 40 ++- doc/guides/linux_gsg/linux_eal_parameters.rst | 27 -- doc/guides/prog_guide/log_lib.rst | 43 +++ lib/eal/common/eal_common_debug.c | 10 +- lib/eal/common/eal_common_options.c | 116 ++++--- lib/eal/common/eal_options.h | 3 + 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 | 320 +++++++++++++++++- lib/log/log_freebsd.c | 5 +- lib/log/log_internal.h | 20 +- lib/log/log_linux.c | 61 ---- lib/log/log_windows.c | 18 - lib/log/meson.build | 5 +- lib/log/version.map | 3 +- 19 files changed, 533 insertions(+), 360 deletions(-) delete mode 100644 lib/log/log_linux.c delete mode 100644 lib/log/log_windows.c
Signature · 1 line
2.43.0
PATCH v13 1/11 windows: make getopt functions have const properties
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 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 v13 01/11] windows: make getopt functions have const properties
Quoted 8 lines
From: Stephen Hemminger [mailto:[email protected]]
Sent: Tuesday, 26 March 2024 02.57Having 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 8 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]>---
For the series,
PATCH v13 2/11 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 v13 3/11 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 v13 4/11 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 v13 5/11 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 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
lib/eal/common/eal_common_debug.c +5 -5
@@ -34,17 +34,17 @@ void rte_exit(int exit_code, const char *format, ...) { va_list ap; +char *msg =NULL ;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); +if (vasprintf (&msg, format, ap) >0 ) +rte_log (RTE_LOG_CRIT ,RTE_LOGTYPE_EAL ,"EAL: Cause - %s" , msg);va_end (ap);if (rte_eal_cleanup () !=0 && rte_errno !=EALREADY ) -EAL_LOG (CRIT , -"EAL could not release all resources" ); +EAL_LOG (CRIT ,"EAL could not release all resources" );exit (exit_code); }
Signature · 1 line
2.43.0