Skip to content

Commit

Permalink
core: dprint - support for structured logging
Browse files Browse the repository at this point in the history
- enable formatting the logging output with different functions
  • Loading branch information
miconda committed Jan 20, 2020
1 parent 85fcffa commit 452635c
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 18 deletions.
50 changes: 43 additions & 7 deletions src/core/dprint.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* debug print
* debug print
*
* Copyright (C) 2001-2003 FhG Fokus
*
Expand All @@ -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
*/
/*!
Expand All @@ -27,11 +27,11 @@
*/



#include "globals.h"
#include "dprint.h"
#include "pvar.h"

#include <stdarg.h>
#include <stdio.h>
#include <strings.h>
Expand All @@ -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",
Expand All @@ -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 ,
Expand Down Expand Up @@ -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;
}
}
60 changes: 49 additions & 11 deletions src/core/dprint.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/

Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -259,23 +281,39 @@ void log_prefix_init(void);
int __llevel; \
__llevel = ((level)<L_ALERT)?L_ALERT:(((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; \
} \
Expand Down

0 comments on commit 452635c

Please sign in to comment.