From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from bilemail1.empirix.com (bilemail1.empirix.com [208.67.76.245]) by dpdk.org (Postfix) with ESMTP id 8F997532E for ; Tue, 4 Oct 2016 14:28:27 +0200 (CEST) Received: from BILEMAIL1.empirix.com (10.17.8.30) by bilemail1.empirix.com (10.17.8.30) with Microsoft SMTP Server (TLS) id 15.0.1178.4; Tue, 4 Oct 2016 08:28:26 -0400 Received: from BILEMAIL1.empirix.com ([fe80::f9e0:9293:2523:f021]) by bilemail1.empirix.com ([fe80::f9e0:9293:2523:f021%22]) with mapi id 15.00.1178.000; Tue, 4 Oct 2016 08:28:26 -0400 From: "Montorsi, Francesco" To: Olivier Matz , "dev@dpdk.org" Thread-Topic: [dpdk-dev] Proposal: enable redirection of DPDK logs from the user app Thread-Index: AdIeKK66V/qdjvS8QiaE91re7uFfpgAKvhEAAAaSYsA= Date: Tue, 4 Oct 2016 12:28:25 +0000 Message-ID: <4b3ed268f2584b4aaf251ba39f8c90bf@bilemail1.empirix.com> References: <32054c5dd466431ebf99d84641c6313a@bilemail1.empirix.com> In-Reply-To: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-transport-fromentityheader: Hosted x-originating-ip: [10.12.50.52] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [dpdk-dev] Proposal: enable redirection of DPDK logs from the user app X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 04 Oct 2016 12:28:28 -0000 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 e= asy as logging a string; e.g. by using fopencookie() approach, you don't ha= ve the concept of "log message", you just provide a function that must writ= e 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 tha= t 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 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 @@ =20 #include "eal_private.h" =20 + +/* forward declaration */ +int +rte_vlog_to_FILE(uint32_t level, uint32_t logtype, const char *formattedst= r); + /* global log structure */ struct rte_logs rte_logs =3D { .type =3D ~0, .level =3D RTE_LOG_DEBUG, .file =3D NULL, + .log_callback =3D rte_vlog_to_FILE }; =20 static FILE *default_log_stream; =20 +#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 *formattedst= r) { int ret; FILE *f =3D 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 =3D level; RTE_PER_LCORE(log_cur_msg).logtype =3D logtype; =20 - ret =3D vfprintf(f, format, ap); + ret =3D fprintf(f, "%s", formattedstr); fflush(f); return ret; } =20 +void rte_set_custom_vlog(rte_vlog_func_t callback) +{ + rte_logs.log_callback =3D 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; =20 va_start(ap, format); - ret =3D rte_vlog(level, logtype, format, ap); + vsnprintf(log_buffer, LOG_BUFFER_SIZE, format, ap); va_end(ap); + + ret =3D rte_logs.log_callback(level, logtype, log_buffer); return ret; } =20 diff --git a/lib/librte_eal/common/include/rte_log.h b/lib/librte_eal/commo= n/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 #include =20 +/** The backend used for logging. Can be user-defined. */ +typedef int (*rte_vlog_func_t)(uint32_t level, uint32_t logtype, const cha= r *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; }; =20 /** Global log informations */ @@ -236,8 +240,8 @@ int rte_log(uint32_t level, uint32_t logtype, const cha= r *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); + =20 /** * Generates a log message. diff --git a/lib/librte_eal/linuxapp/eal/eal_debug.c b/lib/librte_eal/linux= app/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 *forma= t, ...) va_list ap; =20 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); =20 +#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); =20 + 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_e= al/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; --=20 2.7.4