From 4e68e3b4bc974d46382ee95ce4f2a971aab4f070 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Wed, 22 Apr 2020 06:32:15 +0100 Subject: [PATCH] logs: allow giving log bitfields from cmake to force build or exclusion By default this doesn't change any existing logging behaviour at all. But it allows you to define cmake options to force or force-disable the build of individual log levels using new cmake option bitfields LWS_LOGGING_BITFIELD_SET and LWS_LOGGING_BITFIELD_CLEAR. Eg, -DLWS_LOGGING_BITFIELD_SET="(LLL_INFO)" can force INFO log level built even in release mode. -DLWS_LOGGING_BITFIELD_CLEAR="(LLL_NOTICE)" will likewise remove NOTICE logging from the build regardless of DEBUG or RELEASE mode. --- CMakeLists.txt | 4 +- cmake/lws_config.h.in | 2 + include/libwebsockets/lws-logs.h | 173 ++++++++++++++++++++++--------- lib/core-net/pollfd.c | 2 +- lib/core-net/state.c | 16 +-- lib/core-net/wsi.c | 4 +- lib/core/lws_dll2.c | 2 + lib/misc/lwsac/lwsac.c | 2 +- lib/tls/openssl/openssl-client.c | 6 +- 9 files changed, 145 insertions(+), 66 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a41a9c747..519bb1604 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -139,7 +139,9 @@ else() option(LWS_WITH_DIR "Directory scanning api support" ON) option(LWS_WITH_LEJP_CONF "With LEJP configuration parser as used by lwsws" ON) endif() -option(LWS_WITH_NO_LOGS "Disable all logging from being compiled in" OFF) +option(LWS_WITH_NO_LOGS "Disable all logging other than _err and _user from being compiled in" OFF) +set(LWS_LOGGING_BITFIELD_SET 0 CACHE STRING "Bitfield describing which log levels to force included into the build") +set(LWS_LOGGING_BITFIELD_CLEAR 0 CACHE STRING "Bitfield describing which log levels to force removed from the build") option(LWS_LOGS_TIMESTAMP "Timestamp at start of logs" ON) option(LWS_AVOID_SIGPIPE_IGN "Android 7+ reportedly needs this" OFF) option(LWS_WITH_STATS "Keep statistics of lws internal operations" OFF) diff --git a/cmake/lws_config.h.in b/cmake/lws_config.h.in index 131648f67..db956d465 100644 --- a/cmake/lws_config.h.in +++ b/cmake/lws_config.h.in @@ -80,6 +80,8 @@ #cmakedefine LWS_HAVE_X509_get_key_usage #cmakedefine LWS_HAVE_X509_VERIFY_PARAM_set1_host #cmakedefine LWS_LIBRARY_VERSION "${LWS_LIBRARY_VERSION}" +#define LWS_LOGGING_BITFIELD_CLEAR ${LWS_LOGGING_BITFIELD_CLEAR} +#define LWS_LOGGING_BITFIELD_SET ${LWS_LOGGING_BITFIELD_SET} #cmakedefine LWS_MINGW_SUPPORT #cmakedefine LWS_NO_CLIENT #cmakedefine LWS_NO_DAEMONIZE diff --git a/include/libwebsockets/lws-logs.h b/include/libwebsockets/lws-logs.h index dc29b349e..c08384e62 100644 --- a/include/libwebsockets/lws-logs.h +++ b/include/libwebsockets/lws-logs.h @@ -34,22 +34,20 @@ */ ///@{ -enum lws_log_levels { - LLL_ERR = 1 << 0, - LLL_WARN = 1 << 1, - LLL_NOTICE = 1 << 2, - LLL_INFO = 1 << 3, - LLL_DEBUG = 1 << 4, - LLL_PARSER = 1 << 5, - LLL_HEADER = 1 << 6, - LLL_EXT = 1 << 7, - LLL_CLIENT = 1 << 8, - LLL_LATENCY = 1 << 9, - LLL_USER = 1 << 10, - LLL_THREAD = 1 << 11, +#define LLL_ERR (1 << 0) +#define LLL_WARN (1 << 1) +#define LLL_NOTICE (1 << 2) +#define LLL_INFO (1 << 3) +#define LLL_DEBUG (1 << 4) +#define LLL_PARSER (1 << 5) +#define LLL_HEADER (1 << 6) +#define LLL_EXT (1 << 7) +#define LLL_CLIENT (1 << 8) +#define LLL_LATENCY (1 << 9) +#define LLL_USER (1 << 10) +#define LLL_THREAD (1 << 11) - LLL_COUNT = 12 /* set to count of valid flags */ -}; +#define LLL_COUNT (12) /* set to count of valid flags */ /** * lwsl_timestamp: generate logging timestamp string @@ -70,51 +68,124 @@ LWS_VISIBLE LWS_EXTERN void _lws_log(int filter, const char *format, ...) LWS_FO LWS_VISIBLE LWS_EXTERN void _lws_logv(int filter, const char *format, va_list vl); #endif -/* these guys are unconditionally included */ - -#define lwsl_err(...) _lws_log(LLL_ERR, __VA_ARGS__) -#define lwsl_user(...) _lws_log(LLL_USER, __VA_ARGS__) - -#if !defined(LWS_WITH_NO_LOGS) -/* notice and warn are usually included by being compiled in */ -#define lwsl_warn(...) _lws_log(LLL_WARN, __VA_ARGS__) -#define lwsl_notice(...) _lws_log(LLL_NOTICE, __VA_ARGS__) -#endif /* - * weaker logging can be deselected by telling CMake to build in RELEASE mode - * that gets rid of the overhead of checking while keeping _warn and _err - * active + * Figure out which logs to build in or not */ #if defined(_DEBUG) -#if defined(LWS_WITH_NO_LOGS) -/* notice, warn and log are always compiled in */ -#define lwsl_warn(...) _lws_log(LLL_WARN, __VA_ARGS__) -#define lwsl_notice(...) _lws_log(LLL_NOTICE, __VA_ARGS__) -#endif -#define lwsl_info(...) _lws_log(LLL_INFO, __VA_ARGS__) -#define lwsl_debug(...) _lws_log(LLL_DEBUG, __VA_ARGS__) -#define lwsl_parser(...) _lws_log(LLL_PARSER, __VA_ARGS__) -#define lwsl_header(...) _lws_log(LLL_HEADER, __VA_ARGS__) -#define lwsl_ext(...) _lws_log(LLL_EXT, __VA_ARGS__) -#define lwsl_client(...) _lws_log(LLL_CLIENT, __VA_ARGS__) -#define lwsl_latency(...) _lws_log(LLL_LATENCY, __VA_ARGS__) -#define lwsl_thread(...) _lws_log(LLL_THREAD, __VA_ARGS__) + /* + * In DEBUG build, select all logs unless NO_LOGS + */ + #if defined(LWS_WITH_NO_LOGS) + #define _LWS_LINIT (LLL_ERR | LLL_USER) + #else + #define _LWS_LINIT ((1 << LLL_COUNT) - 1) + #endif +#else /* not _DEBUG */ + #define _LWS_LINIT (LLL_ERR | LLL_USER | LLL_WARN | LLL_NOTICE) +#endif /* _DEBUG */ -#else /* no debug */ -#if defined(LWS_WITH_NO_LOGS) +/* + * Create either empty overrides or the ones forced at build-time. + * These overrides have the final say... any bits set in + * LWS_LOGGING_BITFIELD_SET force the build of those logs, any bits + * set in LWS_LOGGING_BITFIELD_CLEAR disable the build of those logs. + * + * If not defined lws decides based on CMAKE_BUILD_TYPE=DEBUG or not + */ + +#if defined(LWS_LOGGING_BITFIELD_SET) + #define _LWS_LBS (LWS_LOGGING_BITFIELD_SET) +#else + #define _LWS_LBS 0 +#endif + +#if defined(LWS_LOGGING_BITFIELD_CLEAR) + #define _LWS_LBC (LWS_LOGGING_BITFIELD_CLEAR) +#else + #define _LWS_LBC 0 +#endif + +/* + * Compute the final active logging bitfield for build + */ +#define _LWS_ENABLED_LOGS (((_LWS_LINIT) | (_LWS_LBS)) & ~(_LWS_LBC)) + +/* + * Individually enable or disable log levels for build + * depending on what was computed + */ + +#if (_LWS_ENABLED_LOGS & LLL_ERR) +#define lwsl_err(...) _lws_log(LLL_ERR, __VA_ARGS__) +#else +#define lwsl_err(...) do {} while(0) +#endif + +#if (_LWS_ENABLED_LOGS & LLL_WARN) +#define lwsl_warn(...) _lws_log(LLL_WARN, __VA_ARGS__) +#else #define lwsl_warn(...) do {} while(0) +#endif + +#if (_LWS_ENABLED_LOGS & LLL_NOTICE) +#define lwsl_notice(...) _lws_log(LLL_NOTICE, __VA_ARGS__) +#else #define lwsl_notice(...) do {} while(0) #endif -#define lwsl_info(...) do {} while(0) -#define lwsl_debug(...) do {} while(0) -#define lwsl_parser(...) do {} while(0) -#define lwsl_header(...) do {} while(0) -#define lwsl_ext(...) do {} while(0) -#define lwsl_client(...) do {} while(0) -#define lwsl_latency(...) do {} while(0) -#define lwsl_thread(...) do {} while(0) +#if (_LWS_ENABLED_LOGS & LLL_INFO) +#define lwsl_info(...) _lws_log(LLL_INFO, __VA_ARGS__) +#else +#define lwsl_info(...) do {} while(0) +#endif + +#if (_LWS_ENABLED_LOGS & LLL_DEBUG) +#define lwsl_debug(...) _lws_log(LLL_DEBUG, __VA_ARGS__) +#else +#define lwsl_debug(...) do {} while(0) +#endif + +#if (_LWS_ENABLED_LOGS & LLL_PARSER) +#define lwsl_parser(...) _lws_log(LLL_PARSER, __VA_ARGS__) +#else +#define lwsl_parser(...) do {} while(0) +#endif + +#if (_LWS_ENABLED_LOGS & LLL_HEADER) +#define lwsl_header(...) _lws_log(LLL_HEADER, __VA_ARGS__) +#else +#define lwsl_header(...) do {} while(0) +#endif + +#if (_LWS_ENABLED_LOGS & LLL_EXT) +#define lwsl_ext(...) _lws_log(LLL_EXT, __VA_ARGS__) +#else +#define lwsl_ext(...) do {} while(0) +#endif + +#if (_LWS_ENABLED_LOGS & LLL_CLIENT) +#define lwsl_client(...) _lws_log(LLL_CLIENT, __VA_ARGS__) +#else +#define lwsl_client(...) do {} while(0) +#endif + +#if (_LWS_ENABLED_LOGS & LLL_LATENCY) +#define lwsl_latency(...) _lws_log(LLL_LATENCY, __VA_ARGS__) +#else +#define lwsl_latency(...) do {} while(0) +#endif + +#if (_LWS_ENABLED_LOGS & LLL_THREAD) +#define lwsl_thread(...) _lws_log(LLL_THREAD, __VA_ARGS__) +#else +#define lwsl_thread(...) do {} while(0) +#endif + +#if (_LWS_ENABLED_LOGS & LLL_USER) +#define lwsl_user(...) _lws_log(LLL_USER, __VA_ARGS__) +#else +#define lwsl_user(...) do {} while(0) #endif diff --git a/lib/core-net/pollfd.c b/lib/core-net/pollfd.c index a8d8759d4..cdf366fde 100644 --- a/lib/core-net/pollfd.c +++ b/lib/core-net/pollfd.c @@ -242,7 +242,7 @@ lws_accept_modulation(struct lws_context *context, } #endif -#if defined(_DEBUG) +#if _LWS_ENABLED_LOGS & LLL_WARN void __dump_fds(struct lws_context_per_thread *pt, const char *s) { diff --git a/lib/core-net/state.c b/lib/core-net/state.c index fd9242929..a8c904f2b 100644 --- a/lib/core-net/state.c +++ b/lib/core-net/state.c @@ -46,7 +46,7 @@ lws_state_reg_notifier_list(lws_state_manager_t *mgr, lws_state_reg_notifier(mgr, *notify_link_array++); } -#if defined(_DEBUG) +#if (_LWS_ENABLED_LOGS & (LLL_INFO | LLL_DEBUG)) static const char * _systnm(lws_state_manager_t *mgr, int state, char *temp8) { @@ -62,7 +62,7 @@ _systnm(lws_state_manager_t *mgr, int state, char *temp8) static int _report(lws_state_manager_t *mgr, int a, int b) { -#if defined(_DEBUG) +#if (_LWS_ENABLED_LOGS & LLL_INFO) char temp8[8]; #endif @@ -72,12 +72,14 @@ _report(lws_state_manager_t *mgr, int a, int b) if (l->notify_cb(mgr, l, a, b)) { /* a dependency took responsibility for retry */ -#if defined(_DEBUG) + +#if (_LWS_ENABLED_LOGS & LLL_INFO) lwsl_info("%s: %s: %s: rejected '%s' -> '%s'\n", __func__, mgr->name, l->name, _systnm(mgr, a, temp8), _systnm(mgr, b, temp8)); #endif + return 1; } @@ -89,14 +91,14 @@ _report(lws_state_manager_t *mgr, int a, int b) static int _lws_state_transition(lws_state_manager_t *mgr, int target) { -#if defined(_DEBUG) +#if (_LWS_ENABLED_LOGS & LLL_DEBUG) char temp8[8]; #endif if (_report(mgr, mgr->state, target)) return 1; -#if defined(_DEBUG) +#if (_LWS_ENABLED_LOGS & LLL_DEBUG) lwsl_debug("%s: %s: changed %d '%s' -> %d '%s'\n", __func__, mgr->name, mgr->state, _systnm(mgr, mgr->state, temp8), target, _systnm(mgr, target, temp8)); @@ -114,7 +116,7 @@ int lws_state_transition_steps(lws_state_manager_t *mgr, int target) { int n = 0; -#if defined(_DEBUG) +#if (_LWS_ENABLED_LOGS & LLL_INFO) int i = mgr->state; char temp8[8]; #endif @@ -122,7 +124,7 @@ lws_state_transition_steps(lws_state_manager_t *mgr, int target) while (!n && mgr->state != target) n = _lws_state_transition(mgr, mgr->state + 1); -#if defined(_DEBUG) +#if (_LWS_ENABLED_LOGS & LLL_INFO) lwsl_info("%s: %s -> %s\n", __func__, _systnm(mgr, i, temp8), _systnm(mgr, mgr->state, temp8)); #endif diff --git a/lib/core-net/wsi.c b/lib/core-net/wsi.c index db77be39f..78a83fc33 100644 --- a/lib/core-net/wsi.c +++ b/lib/core-net/wsi.c @@ -445,13 +445,13 @@ void lws_role_transition(struct lws *wsi, enum lwsi_role role, enum lwsi_state state, const struct lws_role_ops *ops) { -#if defined(_DEBUG) +#if (_LWS_ENABLED_LOGS & LLL_DEBUG) const char *name = "(unset)"; #endif wsi->wsistate = role | state; if (ops) wsi->role_ops = ops; -#if defined(_DEBUG) +#if (_LWS_ENABLED_LOGS & LLL_DEBUG) if (wsi->role_ops) name = wsi->role_ops->name; lwsl_debug("%s: %p: wsistate 0x%lx, ops %s\n", __func__, wsi, diff --git a/lib/core/lws_dll2.c b/lib/core/lws_dll2.c index 2b3218fc1..7556695db 100644 --- a/lib/core/lws_dll2.c +++ b/lib/core/lws_dll2.c @@ -214,6 +214,7 @@ lws_dll2_add_sorted(lws_dll2_t *d, lws_dll2_owner_t *own, void lws_dll2_describe(lws_dll2_owner_t *owner, const char *desc) { +#if _LWS_ENABLED_LOGS & LLL_INFO int n = 1; lwsl_info("%s: %s: owner %p: count %d, head %p, tail %p\n", @@ -224,6 +225,7 @@ lws_dll2_describe(lws_dll2_owner_t *owner, const char *desc) lwsl_info("%s: %d: %p: owner %p, prev %p, next %p\n", __func__, n++, p, p->owner, p->prev, p->next); } lws_end_foreach_dll_safe(p, tp); +#endif } #endif diff --git a/lib/misc/lwsac/lwsac.c b/lib/misc/lwsac/lwsac.c index 596b08215..cde97ef3c 100644 --- a/lib/misc/lwsac/lwsac.c +++ b/lib/misc/lwsac/lwsac.c @@ -277,7 +277,7 @@ lwsac_free(struct lwsac **head) void lwsac_info(struct lwsac *head) { -#if defined(_DEBUG) +#if _LWS_ENABLED_LOGS & LLL_DEBUG struct lwsac_head *lachead; if (!head) { diff --git a/lib/tls/openssl/openssl-client.c b/lib/tls/openssl/openssl-client.c index 9a258b10e..2a4e73632 100644 --- a/lib/tls/openssl/openssl-client.c +++ b/lib/tls/openssl/openssl-client.c @@ -383,14 +383,14 @@ lws_tls_client_connect(struct lws *wsi) unsigned int len; #endif int m, n; -#if defined(WIN32) || defined(_DEBUG) +#if defined(WIN32) || (_LWS_ENABLED_LOGS & LLL_INFO) int en; #endif errno = 0; ERR_clear_error(); n = SSL_connect(wsi->tls.ssl); -#if defined(WIN32) || defined(_DEBUG) +#if defined(WIN32) || (_LWS_ENABLED_LOGS & LLL_INFO) en = errno; #endif m = lws_ssl_get_error(wsi, n); @@ -400,7 +400,7 @@ lws_tls_client_connect(struct lws *wsi) && en #endif ) { -#if defined(WIN32) || defined(_DEBUG) +#if defined(WIN32) || (_LWS_ENABLED_LOGS & LLL_INFO) lwsl_info("%s: n %d, m %d, errno %d\n", __func__, n, m, en); #endif return LWS_SSL_CAPABLE_ERROR;