diff --git a/src/core/dprint.c b/src/core/dprint.c index 1b180474c1a..8d2053e0ae3 100644 --- a/src/core/dprint.c +++ b/src/core/dprint.c @@ -1,5 +1,5 @@ /* - * debug print + * debug print * * Copyright (C) 2001-2003 FhG Fokus * @@ -15,8 +15,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /*! @@ -27,11 +27,11 @@ */ - + #include "globals.h" #include "dprint.h" #include "pvar.h" - + #include #include #include @@ -51,7 +51,7 @@ void km_log_func_set(km_log_f f) #ifndef NO_SIG_DEBUG /* signal protection: !=0 when LOG/DBG/... are printing */ -volatile int dprint_crit = 0; +volatile int dprint_crit = 0; #endif static char* str_fac[]={"LOG_AUTH","LOG_CRON","LOG_DAEMON", @@ -63,7 +63,7 @@ static char* str_fac[]={"LOG_AUTH","LOG_CRON","LOG_DAEMON", "LOG_AUTHPRIV","LOG_FTP","LOG_SYSLOG", #endif 0}; - + static int int_fac[]={LOG_AUTH , LOG_CRON , LOG_DAEMON , LOG_KERN , LOG_LOCAL0 , LOG_LOCAL1 , LOG_LOCAL2 , LOG_LOCAL3 , LOG_LOCAL4 , LOG_LOCAL5 , @@ -479,3 +479,39 @@ void log_prefix_set(sip_msg_t *msg) return; log_prefix_val = &log_prefix_str; } + +/* structured logging */ + +ksr_slog_f _ksr_slog_func = NULL; + +void ksr_slog_json(ksr_logdata_t *kld, const char *format, ...) +{ + va_list arglist; +#define KSR_SLOG_MAX_SIZE 32*1024 + char obuf[KSR_SLOG_MAX_SIZE]; + int n; + + n = 0; + va_start(arglist, format); + n += vsnprintf(obuf + n, KSR_SLOG_MAX_SIZE - n, format, arglist); + va_end(arglist); + + if (unlikely(log_stderr)) { + if (unlikely(log_color)) dprint_color(kld->v_level); + fprintf(stderr, + "{ \"level\": \"%s\", \"module\": \"%s\", \"file\": \"%s\", \"line\": %d, \"function\": \"%s\", \"message\": \"%.*s\" }\n", + kld->v_lname, kld->v_mname, kld->v_fname, kld->v_fline, kld->v_func, n, obuf); + if (unlikely(log_color)) dprint_color_reset(); + } else { + _km_log_func(kld->v_facility, + "{ \"level\": \"%s\", \"module\": \"%s\", \"file\": \"%s\", \"line\": %d, \"function\": \"%s\", \"message\": \"%.*s\" }\n", + kld->v_lname, kld->v_mname, kld->v_fname, kld->v_fline, kld->v_func, n, obuf); + } +} + +void ksr_slog_init(char *ename) +{ + if(ename && (strlen(ename)==4) && (strcasecmp(ename, "json")==0)) { + _ksr_slog_func = &ksr_slog_json; + } +} diff --git a/src/core/dprint.h b/src/core/dprint.h index 1ac684c9b67..bab44c12750 100644 --- a/src/core/dprint.h +++ b/src/core/dprint.h @@ -13,8 +13,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -106,6 +106,28 @@ #define LOG2SYSLOG_LEVEL(level) \ (log_level_info[(level) - (L_ALERT)].syslog_level) +/** + * data fileds used for structured logging + */ +typedef struct ksr_logdata { + /* next field are automatically set by log macro */ + int v_facility; + int v_level; + char *v_lname; + const char *v_fname; + int v_fline; + const char *v_mname; + const char *v_func; + const char *v_locinfo; + /* next field are __not__ automatically set by log macro */ + int v_pid; + int v_pidx; +} ksr_logdata_t; + +typedef void (*ksr_slog_f)(ksr_logdata_t*, const char*, ...); +void ksr_slog_init(char *ename); + +extern ksr_slog_f _ksr_slog_func; /** @brief my_pid(), process_no are from pt.h but we cannot \#include it here because of circular dependencies */ @@ -259,23 +281,39 @@ void log_prefix_init(void); int __llevel; \ __llevel = ((level)L_DBG)?L_DBG:level); \ DPRINT_CRIT_ENTER; \ - if (unlikely(log_stderr)) { \ - if (unlikely(log_color)) dprint_color(__llevel); \ - fprintf(stderr, "%2d(%d) %s: %.*s%s" _FUNC_FMT_ fmt, \ + if (_ksr_slog_func) { /* structured logging */ \ + ksr_logdata_t __kld = {0}; \ + __kld.v_facility = LOG2SYSLOG_LEVEL(__llevel) | \ + (((facility) != DEFAULT_FACILITY) ? \ + (facility) : \ + get_debug_facility(LOG_MNAME, LOG_MNAME_LEN)); \ + __kld.v_level = __llevel; \ + __kld.v_lname = (lname)?(lname):LOG_LEVEL2NAME(__llevel); \ + __kld.v_fname = __FILE__; \ + __kld.v_fline = __LINE__; \ + __kld.v_mname = LOG_MNAME; \ + __kld.v_func = _FUNC_NAME_; \ + __kld.v_locinfo = prefix; \ + _ksr_slog_func(&__kld, fmt, ## args); \ + } else { /* classic logging */ \ + if (unlikely(log_stderr)) { \ + if (unlikely(log_color)) dprint_color(__llevel); \ + fprintf(stderr, "%2d(%d) %s: %.*s%s" _FUNC_FMT_ fmt, \ process_no, my_pid(), \ (lname)?(lname):LOG_LEVEL2NAME(__llevel), \ LOGV_PREFIX_LEN, LOGV_PREFIX_STR, \ - (prefix), _FUNC_NAME_, ## args);\ - if (unlikely(log_color)) dprint_color_reset(); \ - } else { \ - _km_log_func(LOG2SYSLOG_LEVEL(__llevel) |\ + (prefix), _FUNC_NAME_, ## args); \ + if (unlikely(log_color)) dprint_color_reset(); \ + } else { \ + _km_log_func(LOG2SYSLOG_LEVEL(__llevel) | \ (((facility) != DEFAULT_FACILITY) ? \ (facility) : \ get_debug_facility(LOG_MNAME, LOG_MNAME_LEN)), \ - "%s: %.*s%s" _FUNC_FMT_ fmt,\ - (lname)?(lname):LOG_LEVEL2NAME(__llevel),\ + "%s: %.*s%s" _FUNC_FMT_ fmt, \ + (lname)?(lname):LOG_LEVEL2NAME(__llevel), \ LOGV_PREFIX_LEN, LOGV_PREFIX_STR, \ (prefix), _FUNC_NAME_, ## args); \ + } \ } \ DPRINT_CRIT_EXIT; \ } \