From b355a2a65511c32aaaddf289d70395f872bd4b26 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Bollo?= Date: Mon, 4 Sep 2017 14:40:14 +0200 Subject: [PATCH] Improve handling of verbosity MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The macros VERBOSE_NO_DATA and VERBOSE_NO_DETAILS can be used to tune what verbose parts are to be emitted: If VERBOSE_NO_DATA is defined then the macro will only report the file and the line that emitted the message. This mode is intended to reduce the count of static data in the binary. If VERBOSE_NO_DATA is not defined and VERBOSE_NO_DETAILS is defined, this is the opposite: the messages are emitted but not the file, line and function. When none of these 2 are difened, everything is emitted: the message and the details (file, line and function). At the same time the emission of the details (file, line, function) is not done for levels NOTICE, INFO, DEBUG on the console Change-Id: Ibb83cd435797fadf90626cb06bbda77f0f8b3cde Signed-off-by: José Bollo --- src/afb-hook.c | 2 +- src/verbose.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++------- src/verbose.h | 13 +++++++++- 3 files changed, 82 insertions(+), 11 deletions(-) diff --git a/src/afb-hook.c b/src/afb-hook.c index c2baf472..7dd81cba 100644 --- a/src/afb-hook.c +++ b/src/afb-hook.c @@ -1415,7 +1415,7 @@ static struct afb_hook_global_itf hook_global_default_itf = { static void afb_hook_global_vverbose(int level, const char *file, int line, const char *func, const char *fmt, va_list args) { - _HOOK_GLOBAL_(vverbose, level, file ?: "?", line, func ?: "?", fmt, args); + _HOOK_GLOBAL_(vverbose, level, file ?: "?", line, func ?: "?", fmt ?: "", args); } /****************************************************************************** diff --git a/src/verbose.c b/src/verbose.c index e0e38248..b8751069 100644 --- a/src/verbose.c +++ b/src/verbose.c @@ -83,6 +83,8 @@ void verbose_set_name(const char *name, int authority) #include #include +#include +#include static const char *appname; @@ -99,18 +101,76 @@ static const char *prefixes[] = { "<7> DEBUG" }; +static int tty; + +static const char chars[] = { '\n', '?', ':', ' ', '[', ',', ']' }; + static void _vverbose_(int loglevel, const char *file, int line, const char *function, const char *fmt, va_list args) { - int saverr = errno; - int tty = isatty(fileno(stderr)); - errno = saverr; + char buffer[4000]; + char lino[40]; + int saverr, n, rc; + struct iovec iov[20]; + + saverr = errno; + + if (!tty) + tty = 1 + isatty(STDERR_FILENO); + + iov[0].iov_base = (void*)prefixes[CROP_LOGLEVEL(loglevel)] + (tty - 1 ? 4 : 0); + iov[0].iov_len = strlen(iov[0].iov_base); + + iov[1].iov_base = (void*)&chars[2]; + iov[1].iov_len = 2; + + n = 2; + if (fmt) { + iov[n].iov_base = buffer; + rc = vsnprintf(buffer, sizeof buffer, fmt, args); + if (rc < 0) + rc = 0; + else if ((size_t)rc > sizeof buffer) { + rc = (int)sizeof buffer; + buffer[rc - 1] = buffer[rc - 2] = buffer[rc - 3] = '.'; + } + iov[n++].iov_len = (size_t)rc; + } + if (file && (!fmt || tty == 1 || loglevel <= Log_Level_Warning)) { + iov[n].iov_base = (void*)&chars[3 + !fmt]; + iov[n++].iov_len = 2 - !fmt; + iov[n].iov_base = (void*)file; + iov[n++].iov_len = strlen(file); + iov[n].iov_base = (void*)&chars[2]; + iov[n++].iov_len = 1; + if (line) { + iov[n].iov_base = lino; + iov[n++].iov_len = snprintf(lino, sizeof lino, "%d", line); + } else { + iov[n].iov_base = (void*)&chars[1]; + iov[n++].iov_len = 1; + } + iov[n].iov_base = (void*)&chars[5]; + iov[n++].iov_len = 1; + if (function) { + iov[n].iov_base = (void*)function; + iov[n++].iov_len = strlen(function); + } else { + iov[n].iov_base = (void*)&chars[1]; + iov[n++].iov_len = 1; + } + iov[n].iov_base = (void*)&chars[6]; + iov[n++].iov_len = 1; + } + if (n == 2) { + iov[n].iov_base = (void*)&chars[1]; + iov[n++].iov_len = 1; + } + iov[n].iov_base = (void*)&chars[0]; + iov[n++].iov_len = 1; - fprintf(stderr, "%s: ", prefixes[CROP_LOGLEVEL(loglevel)] + (tty ? 4 : 0)); - vfprintf(stderr, fmt, args); - if (file != NULL && (!tty || verbosity > 2)) - fprintf(stderr, " [%s:%d,%s]\n", file, line, function); - else - fprintf(stderr, "\n"); + writev(STDERR_FILENO, iov, n); + + errno = saverr; } void verbose_set_name(const char *name, int authority) diff --git a/src/verbose.h b/src/verbose.h index 4b103ca8..402da404 100644 --- a/src/verbose.h +++ b/src/verbose.h @@ -73,12 +73,23 @@ enum log_levels extern void verbose(int loglevel, const char *file, int line, const char *function, const char *fmt, ...) __attribute__((format(printf, 5, 6))); extern void vverbose(int loglevel, const char *file, int line, const char *function, const char *fmt, va_list args); -# define _VERBOSE_(vlvl,llvl,...) do{ if (verbosity >= vlvl) verbose(llvl, __FILE__, __LINE__, __func__, __VA_ARGS__); } while(0) +#if defined(VERBOSE_NO_DATA) +# define __VERBOSE__(lvl,...) do{if((lvl)<=Log_Level_Error) verbose(lvl, __FILE__, __LINE__, __func__, __VA_ARGS__)\ + else verbose(lvl, __FILE__, __LINE__, __func__, NULL);}while(0) +#elif defined(VERBOSE_NO_DETAILS) +# define __VERBOSE__(lvl,...) verbose(lvl, NULL, 0, NULL, __VA_ARGS__) +#else +# define __VERBOSE__(lvl,...) verbose(lvl, __FILE__, __LINE__, __func__, __VA_ARGS__) +#endif + +# define _VERBOSE_(vlvl,llvl,...) do{ if (verbosity >= vlvl) __VERBOSE__(llvl, __VA_ARGS__); } while(0) + # define ERROR(...) _VERBOSE_(Verbosity_Level_Error, Log_Level_Error, __VA_ARGS__) # define WARNING(...) _VERBOSE_(Verbosity_Level_Warning, Log_Level_Warning, __VA_ARGS__) # define NOTICE(...) _VERBOSE_(Verbosity_Level_Notice, Log_Level_Notice, __VA_ARGS__) # define INFO(...) _VERBOSE_(Verbosity_Level_Info, Log_Level_Info, __VA_ARGS__) # define DEBUG(...) _VERBOSE_(Verbosity_Level_Debug, Log_Level_Debug, __VA_ARGS__) + # define LOGUSER(app) verbose_set_name(app,0) # define LOGAUTH(app) verbose_set_name(app,1) -- 2.16.6