From: "Montorsi, Francesco" <fmontorsi@empirix.com>
To: Olivier Matz <olivier.matz@6wind.com>, "dev@dpdk.org" <dev@dpdk.org>
Subject: Re: [dpdk-dev] Proposal: enable redirection of DPDK logs from the user app
Date: Tue, 4 Oct 2016 12:28:25 +0000 [thread overview]
Message-ID: <4b3ed268f2584b4aaf251ba39f8c90bf@bilemail1.empirix.com> (raw)
In-Reply-To: <d84074d2-e6c3-2a29-679f-f0e97c34b698@6wind.com>
Hi Olivier,
> It seems the mailing list stripped your patch sent as attachment.
> Can you please resend it again in the body of the mail?
You're right sorry. It's attached at the end of this mail.
> I think we can already redirect logs to a file by using fopencookie() +
> rte_openlog_stream(). Did you already check these functions?
Yes, but to be honest, that seems a troublesome solution for something as easy as logging a string; e.g. by using fopencookie() approach, you don't have the concept of "log message", you just provide a function that must write a block of bytes somewhere. Typically instead, you need to know where a log message starts and ends, to e.g., add prefixes/postfixes to it.
Indeed, most of the C/C++ (open source) libraries have some simple hook that allows the user to have more control on logging... I think DPDK should be no exception... :)
Thanks,
Francesco
>From 52d4fdccee4de3787e85589ff8f666028ad9ea7b Mon Sep 17 00:00:00 2001
From: Francesco Montorsi <fmontorsi@empirix.com>
Date: Tue, 4 Oct 2016 12:08:34 +0200
Subject: [PATCH] Enable custom log sink implementations
---
lib/librte_eal/common/eal_common_log.c | 23 ++++++++++++++++++++---
lib/librte_eal/common/include/rte_log.h | 8 ++++++--
lib/librte_eal/linuxapp/eal/eal_debug.c | 16 ++++++++++++++--
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 2 +-
4 files changed, 41 insertions(+), 8 deletions(-)
diff --git a/lib/librte_eal/common/eal_common_log.c b/lib/librte_eal/common/eal_common_log.c
index 967991a..5e86309 100644
--- a/lib/librte_eal/common/eal_common_log.c
+++ b/lib/librte_eal/common/eal_common_log.c
@@ -41,15 +41,25 @@
#include "eal_private.h"
+
+/* forward declaration */
+int
+rte_vlog_to_FILE(uint32_t level, uint32_t logtype, const char *formattedstr);
+
/* global log structure */
struct rte_logs rte_logs = {
.type = ~0,
.level = RTE_LOG_DEBUG,
.file = NULL,
+ .log_callback = rte_vlog_to_FILE
};
static FILE *default_log_stream;
+#define LOG_BUFFER_SIZE 4095
+static char log_buffer[LOG_BUFFER_SIZE+1];
+
+
/**
* This global structure stores some informations about the message
* that is currently beeing processed by one lcore
@@ -123,7 +133,7 @@ int rte_log_cur_msg_logtype(void)
* defined by the previous call to rte_openlog_stream().
*/
int
-rte_vlog(uint32_t level, uint32_t logtype, const char *format, va_list ap)
+rte_vlog_to_FILE(uint32_t level, uint32_t logtype, const char *formattedstr)
{
int ret;
FILE *f = rte_logs.file;
@@ -135,11 +145,16 @@ 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 = fprintf(f, "%s", formattedstr);
fflush(f);
return ret;
}
+void rte_set_custom_vlog(rte_vlog_func_t callback)
+{
+ rte_logs.log_callback = callback;
+}
+
/*
* Generates a log message The message will be sent in the stream
* defined by the previous call to rte_openlog_stream().
@@ -152,8 +167,10 @@ rte_log(uint32_t level, uint32_t logtype, const char *format, ...)
int ret;
va_start(ap, format);
- ret = rte_vlog(level, logtype, format, ap);
+ vsnprintf(log_buffer, LOG_BUFFER_SIZE, format, ap);
va_end(ap);
+
+ ret = rte_logs.log_callback(level, logtype, log_buffer);
return ret;
}
diff --git a/lib/librte_eal/common/include/rte_log.h b/lib/librte_eal/common/include/rte_log.h
index 919563c..3dcb135 100644
--- a/lib/librte_eal/common/include/rte_log.h
+++ b/lib/librte_eal/common/include/rte_log.h
@@ -50,11 +50,15 @@ extern "C" {
#include <stdio.h>
#include <stdarg.h>
+/** The backend used for logging. Can be user-defined. */
+typedef int (*rte_vlog_func_t)(uint32_t level, uint32_t logtype, const char *formattedstr);
+
/** The rte_log structure. */
struct rte_logs {
uint32_t type; /**< Bitfield with enabled logs. */
uint32_t level; /**< Log level. */
FILE *file; /**< Pointer to current FILE* for logs. */
+ rte_vlog_func_t log_callback;
};
/** Global log informations */
@@ -236,8 +240,8 @@ int rte_log(uint32_t level, uint32_t logtype, const char *format, ...)
* - 0: Success.
* - Negative on error.
*/
-int rte_vlog(uint32_t level, uint32_t logtype, const char *format, va_list ap)
- __attribute__((format(printf,3,0)));
+void rte_set_custom_vlog(rte_vlog_func_t callback);
+
/**
* Generates a log message.
diff --git a/lib/librte_eal/linuxapp/eal/eal_debug.c b/lib/librte_eal/linuxapp/eal/eal_debug.c
index 5fbc17c..f411d96 100644
--- a/lib/librte_eal/linuxapp/eal/eal_debug.c
+++ b/lib/librte_eal/linuxapp/eal/eal_debug.c
@@ -78,9 +78,16 @@ void __rte_panic(const char *funcname, const char *format, ...)
va_list ap;
rte_log(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, "PANIC in %s():\n", funcname);
+
+#define LOG_BUFFER_SIZE 4095
+static char log_buffer[LOG_BUFFER_SIZE+1];
+
va_start(ap, format);
- rte_vlog(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, format, ap);
+ vsnprintf(log_buffer, LOG_BUFFER_SIZE, format, ap);
va_end(ap);
+
+ rte_logs.log_callback(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, log_buffer);
+
rte_dump_stack();
rte_dump_registers();
abort();
@@ -99,10 +106,15 @@ rte_exit(int exit_code, const char *format, ...)
RTE_LOG(CRIT, EAL, "Error - exiting with code: %d\n"
" Cause: ", exit_code);
+#define LOG_BUFFER_SIZE 4095
+static char log_buffer[LOG_BUFFER_SIZE+1];
+
va_start(ap, format);
- rte_vlog(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, format, ap);
+ vsnprintf(log_buffer, LOG_BUFFER_SIZE, format, ap);
va_end(ap);
+ rte_logs.log_callback(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, log_buffer);
+
#ifndef RTE_EAL_ALWAYS_PANIC_ON_ERROR
exit(exit_code);
#else
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 83721ba..b35c8c3 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -94,6 +94,7 @@ DPDK_2.0 {
rte_openlog_stream;
rte_realloc;
rte_set_application_usage_hook;
+ rte_set_custom_vlog;
rte_set_log_level;
rte_set_log_type;
rte_socket_id;
@@ -102,7 +103,6 @@ DPDK_2.0 {
rte_sys_gettid;
rte_thread_get_affinity;
rte_thread_set_affinity;
- rte_vlog;
rte_xen_dom0_memory_attach;
rte_xen_dom0_memory_init;
rte_zmalloc;
--
2.7.4
next prev parent reply other threads:[~2016-10-04 12:28 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-10-04 10:24 Montorsi, Francesco
2016-10-04 11:26 ` Olivier Matz
2016-10-04 12:28 ` Montorsi, Francesco [this message]
2016-10-05 12:18 ` Olivier Matz
2016-10-05 13:26 ` Montorsi, Francesco
2016-10-05 14:03 ` Olivier Matz
2016-10-05 21:22 ` Matthew Hall
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4b3ed268f2584b4aaf251ba39f8c90bf@bilemail1.empirix.com \
--to=fmontorsi@empirix.com \
--cc=dev@dpdk.org \
--cc=olivier.matz@6wind.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).