From 31e34cfd72712c76c127509d14d50eb008743fd5 Mon Sep 17 00:00:00 2001 From: ShyamsundarR Date: Fri, 20 Dec 2013 13:19:00 +0530 Subject: log: enhance gluster log format with message ID and standardize errno reporting Currently there are quite a slew of logs in Gluster that do not lend themselves to trivial analysis by various tools that help collect and monitor logs, due to the textual nature of the logs. This FEAT is to make this better by giving logs message IDs so that the tools do not have to do complex log parsing to break it down to problem areas and suggest troubleshooting options. With this patch, a new set of logging APIs are introduced that take additionally a message ID and an error number, so as to print the message ID and the descriptive string for the error. New APIs: - gf_msg, gf_msg_debug/trace, gf_msg_nomem, gf_msg_callingfn These APIs follow the functionality of the previous gf_log* counterparts, and hence are 1:1 replacements, with the delta that, gf_msg, gf_msg_callingfn take additional parameters as specified above. Defining the log messages: Each invocation of gf_msg/gf_msg_callingfn, should provide an ID and an errnum (if available). Towards this, a common message id file is provided, which contains defines to various messages and their respective strings. As other messages are changed to the new infrastructure APIs, it is intended that this file is edited to add these messages as well. Framework enhanced: The logging framework is also enhanced to be able to support different logging backends in the future. Hence new configuration options for logging framework and logging formats are introduced. Backward compatibility: Currently the framework supports logging in the traditional format, with the inclusion of an error string based on the errnum passed in. Hence the shift to these new APIs would retain the log file names, locations, and format with the exception of an additional error string where applicable. Testing done: Tested the new APIs with different messages in normal code paths Tested with configurations set to gluster logs (syslog pending) Tested nomem variants, inducing the message in normal code paths Tested ident generation for normal code paths (other paths pending) Tested with sample gfapi program for gfapi messages Test code is stripped from the commit Pending work (not to be addressed in this patch (future)): - Logging framework should be configurable - Logging format should be configurable - Once all messages move to the new APIs deprecate/delete older APIs to prevent misuse/abuse using the same - Repeated log messages should be suppressed (as a configurable option) - Logging framework assumes that only one init is possible, but there is no protection around the same (in existing code) - gf_log_fini is not invoked anywhere and does very little cleanup (in existing code) - DOxygen comments to message id headers for each message Change-Id: Ia043fda99a1c6cf7817517ef9e279bfcf35dcc24 BUG: 1075611 Signed-off-by: ShyamsundarR Reviewed-on: http://review.gluster.org/6547 Reviewed-by: Krutika Dhananjay Tested-by: Gluster Build System Reviewed-by: Raghavendra G Reviewed-by: Pranith Kumar Karampuri Reviewed-by: Vijay Bellur --- libglusterfs/src/logging.h | 129 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 114 insertions(+), 15 deletions(-) (limited to 'libglusterfs/src/logging.h') diff --git a/libglusterfs/src/logging.h b/libglusterfs/src/logging.h index e2b7e664d..b6b13fbd0 100644 --- a/libglusterfs/src/logging.h +++ b/libglusterfs/src/logging.h @@ -61,6 +61,20 @@ typedef enum { GF_LOG_TRACE, /* full trace of operation */ } gf_loglevel_t; +/* format for the logs */ +typedef enum { + gf_logformat_traditional = 0, /* Format as in gluster 3.5 */ + gf_logformat_withmsgid, /* Format enhanced with MsgID, ident, errstr */ + gf_logformat_cee /* log enhanced format in cee */ +} gf_log_format_t; + +/* log infrastructure to log to */ +typedef enum { + gf_logger_glusterlog = 0, /* locations and files as in gluster 3.5 */ + gf_logger_syslog /* log to (r)syslog, based on (r)syslog conf */ + /* NOTE: In the future journald, lumberjack, next new thing here */ +} gf_log_logger_t; + #define DEFAULT_LOG_FILE_DIRECTORY DATADIR "/log/glusterfs" #define DEFAULT_LOG_LEVEL GF_LOG_INFO @@ -76,11 +90,10 @@ typedef struct gf_log_handle_ { FILE *gf_log_logfile; char *cmd_log_filename; FILE *cmdlogfile; -#ifdef GF_USE_SYSLOG - int log_control_file_found; + gf_log_logger_t logger; + gf_log_format_t logformat; char *ident; -#endif /* GF_USE_SYSLOG */ - + int log_control_file_found; } gf_log_handle_t; void gf_log_globals_init (void *ctx); @@ -90,25 +103,117 @@ void gf_log_logrotate (int signum); void gf_log_cleanup (void); +/* Internal interfaces to log messages with message IDs */ +int _gf_msg (const char *domain, const char *file, + const char *function, int32_t line, gf_loglevel_t level, + int errnum, int trace, uint64_t msgid, const char *fmt, ...) + __attribute__ ((__format__ (__printf__, 9, 10))); + +void _gf_msg_backtrace_nomem (gf_loglevel_t level, int stacksize); + +int _gf_msg_plain (gf_loglevel_t level, const char *fmt, ...) + __attribute__ ((__format__ (__printf__, 2, 3))); + +int _gf_msg_plain_nomem (gf_loglevel_t level, const char *msg); + +int _gf_msg_vplain (gf_loglevel_t level, const char *fmt, va_list ap); + +int _gf_msg_nomem (const char *domain, const char *file, + const char *function, int line, gf_loglevel_t level, + size_t size); + int _gf_log (const char *domain, const char *file, const char *function, int32_t line, gf_loglevel_t level, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 6, 7))); + int _gf_log_callingfn (const char *domain, const char *file, const char *function, int32_t line, gf_loglevel_t level, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 6, 7))); -int _gf_log_nomem (const char *domain, const char *file, - const char *function, int line, gf_loglevel_t level, - size_t size); - int _gf_log_eh (const char *function, const char *fmt, ...); +/* treat GF_LOG_TRACE and GF_LOG_NONE as LOG_DEBUG and + * other level as is */ +#define SET_LOG_PRIO(level, priority) do { \ + if (GF_LOG_TRACE == (level) || GF_LOG_NONE == (level)) { \ + priority = LOG_DEBUG; \ + } else { \ + priority = (level) - 1; \ + } \ + } while (0) + +/* extract just the file name from the path */ +#define GET_FILE_NAME_TO_LOG(file, basename) do { \ + basename = strrchr ((file), '/'); \ + if (basename) \ + basename++; \ + else \ + basename = (file); \ + } while (0) + +#define PRINT_SIZE_CHECK(ret, label, strsize) do { \ + if (ret < 0) \ + goto label; \ + if ((strsize - ret) > 0) { \ + strsize -= ret; \ + } else { \ + ret = 0; \ + goto label; \ + } \ + } while (0) + #define FMT_WARN(fmt...) do { if (0) printf (fmt); } while (0) +/* Interface to log messages with message IDs */ +#define gf_msg(dom, levl, errnum, msgid, fmt...) do { \ + _gf_msg (dom, __FILE__, __FUNCTION__, __LINE__, \ + levl, errnum, 0, msgid, ##fmt); \ + } while (0) + +/* no frills, no thrills, just a vanilla message, used to print the graph */ +#define gf_msg_plain(levl, fmt...) do { \ + _gf_msg_plain (levl, ##fmt); \ + } while (0) + +#define gf_msg_plain_nomem(levl, msg) do { \ + _gf_msg_plain_nomem (levl, msg); \ + } while (0) + +#define gf_msg_vplain(levl, fmt, va) do { \ + _gf_msg_vplain (levl, fmt, va); \ + } while (0) + +#define gf_msg_backtrace_nomem(level, stacksize) do { \ + _gf_msg_backtrace_nomem (level, stacksize); \ + } while (0) + +#define gf_msg_callingfn(dom, levl, errnum, msgid, fmt...) do { \ + _gf_msg (dom, __FILE__, __FUNCTION__, __LINE__, \ + levl, errnum, 1, msgid, ##fmt); \ + } while (0) + +/* No malloc or calloc should be called in this function */ +#define gf_msg_nomem(dom, levl, size) do { \ + _gf_msg_nomem (dom, __FILE__, __FUNCTION__, __LINE__, \ + levl, size); \ + } while (0) + +/* Debug or trace messages do not need message IDs as these are more developer + * related. Hence, the following abstractions are provided for the same */ +#define gf_msg_debug(dom, errnum, fmt...) do { \ + _gf_msg (dom, __FILE__, __FUNCTION__, __LINE__, \ + GF_LOG_DEBUG, errnum, 0, 0, ##fmt); \ + } while (0) + +#define gf_msg_trace(dom, errnum, fmt...) do { \ + _gf_msg (dom, __FILE__, __FUNCTION__, __LINE__, \ + GF_LOG_TRACE, errnum, 0, 0, ##fmt); \ + } while (0) + #define gf_log(dom, levl, fmt...) do { \ FMT_WARN (fmt); \ _gf_log (dom, __FILE__, __FUNCTION__, __LINE__, \ @@ -127,13 +232,6 @@ int _gf_log_eh (const char *function, const char *fmt, ...); } while (0) -/* No malloc or calloc should be called in this function */ -#define gf_log_nomem(dom, levl, size) do { \ - _gf_log_nomem (dom, __FILE__, __FUNCTION__, __LINE__, \ - levl, size); \ - } while (0) - - /* Log once in GF_UNIVERSAL_ANSWER times */ #define GF_LOG_OCCASIONALLY(var, args...) if (!(var++%GF_UNIVERSAL_ANSWER)) { \ gf_log (args); \ @@ -143,6 +241,7 @@ void gf_log_disable_syslog (void); void gf_log_enable_syslog (void); gf_loglevel_t gf_log_get_loglevel (void); void gf_log_set_loglevel (gf_loglevel_t level); +void gf_log_flush (void); gf_loglevel_t gf_log_get_xl_loglevel (void *xl); void gf_log_set_xl_loglevel (void *xl, gf_loglevel_t level); -- cgit From 712541cdefcc9614e5a79f628358f205ceda6e55 Mon Sep 17 00:00:00 2001 From: Krutika Dhananjay Date: Tue, 11 Mar 2014 15:05:44 +0530 Subject: logging: Make logger and log format configurable through cli Change-Id: Ic4b701a6621578848ff67ae4ecb5a10b5f32f93b BUG: 1075611 Signed-off-by: Krutika Dhananjay Reviewed-on: http://review.gluster.org/7372 Tested-by: Gluster Build System Reviewed-by: Krishnan Parthasarathi Reviewed-by: Vijay Bellur --- libglusterfs/src/logging.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'libglusterfs/src/logging.h') diff --git a/libglusterfs/src/logging.h b/libglusterfs/src/logging.h index b6b13fbd0..210602c32 100644 --- a/libglusterfs/src/logging.h +++ b/libglusterfs/src/logging.h @@ -48,6 +48,12 @@ #define LOG_DEBUG 7 /* debug-level messages */ #endif +#define GF_LOG_FORMAT_NO_MSG_ID "no-msg-id" +#define GF_LOG_FORMAT_WITH_MSG_ID "with-msg-id" + +#define GF_LOGGER_GLUSTER_LOG "gluster-log" +#define GF_LOGGER_SYSLOG "syslog" + typedef enum { GF_LOG_NONE, GF_LOG_EMERG, @@ -254,6 +260,12 @@ void set_sys_log_level (gf_loglevel_t level); int gf_log_fini(void *data); +void +gf_log_set_logger (gf_log_logger_t logger); + +void +gf_log_set_logformat (gf_log_format_t format); + #define GF_DEBUG(xl, format, args...) \ gf_log ((xl)->name, GF_LOG_DEBUG, format, ##args) #define GF_INFO(xl, format, args...) \ -- cgit