Skip to content

Commit c05cb75

Browse files
Add a new core event triggered for every log message
1 parent f89b21b commit c05cb75

File tree

12 files changed

+210
-2
lines changed

12 files changed

+210
-2
lines changed

cfg.lex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ LOGSTDOUT log_stdout
212212
LOGSTDERROR log_stderror
213213
STDERROR_ENABLED stderror_enabled
214214
SYSLOG_ENABLED syslog_enabled
215+
LOG_EVENT_ENABLED log_event_enabled
215216
STDERROR_LEVEL_FILTER stderror_level_filter
216217
SYSLOG_LEVEL_FILTER syslog_level_filter
217218
STDERROR_FORMAT stderror_log_format
@@ -431,6 +432,7 @@ SPACE [ ]
431432
<INITIAL>{LOGSTDERROR} { yylval.strval=yytext; return LOGSTDERROR; }
432433
<INITIAL>{STDERROR_ENABLED} { yylval.strval=yytext; return STDERROR_ENABLED; }
433434
<INITIAL>{SYSLOG_ENABLED} { yylval.strval=yytext; return SYSLOG_ENABLED; }
435+
<INITIAL>{LOG_EVENT_ENABLED} { yylval.strval=yytext; return LOG_EVENT_ENABLED; }
434436
<INITIAL>{STDERROR_LEVEL_FILTER} { count(); yylval.strval=yytext; return STDERROR_LEVEL_FILTER; }
435437
<INITIAL>{SYSLOG_LEVEL_FILTER} { count(); yylval.strval=yytext; return SYSLOG_LEVEL_FILTER; }
436438
<INITIAL>{STDERROR_FORMAT} { count(); yylval.strval=yytext; return STDERROR_FORMAT; }

cfg.y

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ extern int cfg_parse_only_routes;
291291
%token LOGSTDERROR
292292
%token STDERROR_ENABLED
293293
%token SYSLOG_ENABLED
294+
%token LOG_EVENT_ENABLED
294295
%token STDERROR_LEVEL_FILTER
295296
%token SYSLOG_LEVEL_FILTER
296297
%token STDERROR_FORMAT
@@ -919,6 +920,16 @@ assign_stm: LOGLEVEL EQUAL snumber { IFOR();
919920
}
920921
}
921922
| SYSLOG_ENABLED EQUAL error { yyerror("boolean value expected"); }
923+
| LOG_EVENT_ENABLED EQUAL NUMBER {
924+
IFOR();
925+
if ($3) {
926+
if (init_log_msg_buf(0) < 0) {
927+
yyerror("failed to allocate msg log buffer");
928+
YYABORT;
929+
}
930+
}
931+
log_event_enabled=$3; }
932+
| LOG_EVENT_ENABLED EQUAL error { yyerror("boolean value expected"); }
922933
| STDERROR_LEVEL_FILTER EQUAL snumber {
923934
IFOR();
924935
s_tmp.s=STDERR_CONSUMER_NAME;

dprint.c

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ static struct log_consumer_t default_log_consumers[2] ={
8686
struct log_consumer_t *log_consumers = default_log_consumers;
8787
int log_consumers_no = 2;
8888

89+
int log_event_enabled = 0;
90+
static str evi_log_name = str_init("E_CORE_LOG");
91+
static event_id_t evi_log_id;
92+
8993
static char* str_fac[]={"LOG_AUTH","LOG_CRON","LOG_DAEMON",
9094
"LOG_KERN","LOG_LOCAL0","LOG_LOCAL1",
9195
"LOG_LOCAL2","LOG_LOCAL3","LOG_LOCAL4","LOG_LOCAL5",
@@ -456,6 +460,110 @@ static void syslog_dprint(int log_level, int facility, char *module, const char
456460
}
457461
}
458462

463+
static str evi_time_str = str_init("time");
464+
static str evi_pid_str = str_init("pid");
465+
static str evi_level_str = str_init("level");
466+
static str evi_module_str = str_init("module");
467+
static str evi_func_str = str_init("function");
468+
static str evi_prefix_str = str_init("prefix");
469+
static str evi_msg_str = str_init("message");
470+
471+
static void event_dprint(int log_level, int facility, char *module, const char *func,
472+
char *format, va_list ap)
473+
{
474+
evi_params_p list = NULL;
475+
str s;
476+
int n;
477+
static char in_progress = 0;
478+
479+
/* prevent reentry from the same process */
480+
if (in_progress)
481+
return;
482+
483+
in_progress = 1;
484+
485+
if (!evi_probe_event(evi_log_id)) {
486+
in_progress = 0;
487+
return;
488+
}
489+
490+
if (!(list = evi_get_params())) {
491+
in_progress = 0;
492+
return;
493+
}
494+
495+
init_str(&s, dp_time());
496+
if (evi_param_add_str(list, &evi_time_str, &s)) {
497+
stderr_dprint_tmp("error: unable to add event parameter\n");
498+
goto end_free;
499+
}
500+
n = dp_my_pid();
501+
if (evi_param_add_int(list, &evi_pid_str, &n)) {
502+
stderr_dprint_tmp("error: unable to add event parameter\n");
503+
goto end_free;
504+
}
505+
init_str(&s, dp_log_level_str(log_level));
506+
if (evi_param_add_str(list, &evi_level_str, &s)) {
507+
stderr_dprint_tmp("error: unable to add event parameter\n");
508+
goto end_free;
509+
}
510+
511+
if (module && func) {
512+
init_str(&s, module);
513+
if (evi_param_add_str(list, &evi_module_str, &s)) {
514+
stderr_dprint_tmp("error: unable to add event parameter\n");
515+
goto end_free;
516+
}
517+
init_str(&s, func);
518+
if (evi_param_add_str(list, &evi_func_str, &s)) {
519+
stderr_dprint_tmp("error: unable to add event parameter\n");
520+
goto end_free;
521+
}
522+
}
523+
524+
init_str(&s, log_prefix);
525+
if (s.len) {
526+
if (evi_param_add_str(list, &evi_prefix_str, &s)) {
527+
stderr_dprint_tmp("error: unable to add event parameter\n");
528+
goto end_free;
529+
}
530+
}
531+
532+
s.len = vsnprintf(log_msg_buf, log_msg_buf_size, format, ap);
533+
if (s.len < 0) {
534+
stderr_dprint_tmp("error: vsnprintf() failed!\n");
535+
goto end_free;
536+
}
537+
if (s.len>=log_msg_buf_size) {
538+
stderr_dprint_tmp("warning: log message truncated\n");
539+
s.len = log_msg_buf_size;
540+
}
541+
542+
/* try to strip \n from the end of the "message" param */
543+
if (log_msg_buf[s.len-1] == '\n') {
544+
log_msg_buf[s.len-1] = '\0';
545+
s.len--;
546+
}
547+
548+
s.s = log_msg_buf;
549+
if (evi_param_add_str(list, &evi_msg_str, &s)) {
550+
stderr_dprint_tmp("error: unable to add event parameter\n");
551+
goto end_free;
552+
}
553+
554+
if (evi_raise_event(evi_log_id, list)) {
555+
stderr_dprint_tmp("error: unable to raise '%.*s' event\n",
556+
evi_log_name.len, evi_log_name.s);
557+
}
558+
559+
in_progress = 0;
560+
561+
return;
562+
end_free:
563+
evi_free_params(list);
564+
in_progress = 0;
565+
}
566+
459567
/* generic consumer that registers to the log interface */
460568
static void gen_consumer_pre_fmt_func(log_print_f gen_print_func, int log_level,
461569
int facility, char *module, const char *func,
@@ -587,6 +695,29 @@ int init_log_cons_shm_table(void)
587695
return 0;
588696
}
589697

698+
int init_log_event_cons(void)
699+
{
700+
evi_log_id = evi_publish_event(evi_log_name);
701+
if (evi_log_id == EVI_ERROR) {
702+
LM_ERR("cannot register '%.*s' event\n",
703+
evi_log_name.len, evi_log_name.s);
704+
return -1;
705+
}
706+
707+
log_msg_buf = pkg_malloc(log_msg_buf_size+1);
708+
if (!log_msg_buf) {
709+
LM_ERR("no pkg memory left\n");
710+
return -1;
711+
}
712+
713+
if (register_log_consumer(EVENT_CONSUMER_NAME, event_dprint, 0, 1) < 0) {
714+
LM_ERR("Failed to register 'event' log consumer\n");
715+
return -1;
716+
}
717+
718+
return 0;
719+
}
720+
590721
static struct log_consumer_t *get_log_consumer_by_name(str *name)
591722
{
592723
int i;
@@ -658,6 +789,22 @@ int get_log_consumer_mute_state(str *name, int *state)
658789
return 0;
659790
}
660791

792+
int set_log_event_cons_cfg_state(void)
793+
{
794+
if (set_log_consumer_mute_state(&str_init(EVENT_CONSUMER_NAME),
795+
!log_event_enabled) < 0) {
796+
LM_ERR("Failed to set mute state for event consumer\n");
797+
return -1;
798+
}
799+
800+
return 0;
801+
}
802+
803+
void distroy_log_event_cons(void)
804+
{
805+
set_log_consumer_mute_state(&str_init(EVENT_CONSUMER_NAME), 1);
806+
}
807+
661808
int init_log_level(void)
662809
{
663810
log_level = &pt[process_no].log_level;

dprint.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,11 @@
105105
#undef NO_LOG
106106
#endif
107107

108-
#define MAX_LOG_CONS_NO 2
108+
#define MAX_LOG_CONS_NO 3
109109

110110
#define STDERR_CONSUMER_NAME "stderror"
111111
#define SYSLOG_CONSUMER_NAME "syslog"
112+
#define EVENT_CONSUMER_NAME "event"
112113

113114
#define LOG_PLAIN_NAME "plain_text"
114115
#define LOG_JSON_NAME "json"
@@ -126,6 +127,7 @@ extern int *log_level;
126127
extern char *log_prefix;
127128
extern int log_stdout;
128129
extern int stderr_enabled, syslog_enabled;
130+
extern int log_event_enabled;
129131
extern int log_facility;
130132
extern char* log_name;
131133
extern char ctime_buf[];
@@ -147,14 +149,17 @@ int init_log_cons_shm_table(void);
147149
int init_log_json_buf(int realloc);
148150
int init_log_msg_buf(int realloc);
149151

152+
int init_log_event_cons();
153+
int set_log_event_cons_cfg_state(void);
154+
void distroy_log_event_cons();
155+
150156
int set_log_consumer_mute_state(str *name, int state);
151157
int get_log_consumer_mute_state(str *name, int *state);
152158

153159
int set_log_consumer_level_filter(str *name, int level);
154160
int get_log_consumer_level_filter(str *name, int *level_filter);
155161

156162
int parse_log_format(str *format);
157-
158163
int dp_my_pid(void);
159164

160165
void stderr_dprint_tmp(char *format, ...);

ipc.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,12 @@ void ipc_handle_job(int fd)
289289
return;
290290
}
291291

292+
/* we shouldn't print any logs, in case we are handling
293+
* an event_route IPC job for the E_CORE_LOG event */
294+
/*
292295
LM_DBG("received job type %d[%s] from process %d\n",
293296
job.handler_type, ipc_handlers[job.handler_type].name, job.snd_proc);
297+
*/
294298

295299
/* custom handling for RPC type */
296300
if (job.handler_type==ipc_rpc_type) {

main.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,11 @@ static int main_loop(void)
302302
last_check = get_uticks();
303303
}
304304

305+
if (set_log_event_cons_cfg_state() < 0) {
306+
LM_ERR("Failed to set the config state for event consumer\n");
307+
goto error;
308+
}
309+
305310
if (_ProfilerStart(0, "attendant") != 0) {
306311
LM_ERR("failed to start profiling\n");
307312
goto error;
@@ -936,6 +941,11 @@ int main(int argc, char** argv)
936941
goto error;
937942
}
938943

944+
if (init_log_event_cons() < 0) {
945+
LM_ERR("Failed to initialize log event consumer\n");
946+
goto error;
947+
}
948+
939949
if (trans_init_all_listeners()<0) {
940950
LM_ERR("failed to init all SIP listeners, aborting\n");
941951
goto error;

modules/event_kafka/kafka_producer.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,14 +632,20 @@ static int handle_io(struct fd_map *fm, int idx, int event_type)
632632

633633
switch (fm->type) {
634634
case F_KAFKA_JOB:
635+
/* supppress any logs, in case we are handling the E_CORE_LOG event */
636+
set_proc_log_level(L_ALERT-1);
637+
635638
job = kafka_receive_job();
636639
if (!job) {
637640
LM_ERR("Cannot receive job\n");
641+
reset_proc_log_level();
638642
return 0;
639643
}
640644

641645
if (kafka_handle_job(job) != 0)
642646
shm_free(job);
647+
648+
reset_proc_log_level();
643649
break;
644650
case F_KAFKA_EVENT:
645651
prod = (kafka_producer_t *)fm->data;

modules/event_rabbitmq/rabbitmq_send.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,9 @@ void rmq_process(int rank)
541541
rmq_init_reader();
542542
rmq_send_t * rmqs;
543543

544+
/* supppress any logs, in case we are handling the E_CORE_LOG event */
545+
set_proc_log_level(L_ALERT-1);
546+
544547
/* waiting for commands */
545548
for (;;) {
546549
rmqs = rmq_receive();
@@ -576,4 +579,6 @@ void rmq_process(int rank)
576579
if (rmqs)
577580
shm_free(rmqs);
578581
}
582+
583+
reset_proc_log_level();
579584
}

modules/event_route/route_send.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ static void route_received(int sender, void *param)
125125
struct sip_msg* req;
126126
route_send_t *route_s = (route_send_t *)param;
127127

128+
/* supppress any logs, in case we are handling the E_CORE_LOG event */
129+
set_proc_log_level(L_ALERT-1);
130+
128131
if (!ref_script_route_check_and_update(route_s->ev_route)){
129132
LM_ERR("event route [%.s] no longer available in script\n",
130133
route_s->ev_route->name.s);
@@ -149,6 +152,8 @@ static void route_received(int sender, void *param)
149152
if (route_s->ev_route)
150153
shm_free(route_s->ev_route);
151154
shm_free(route_s);
155+
156+
reset_proc_log_level();
152157
}
153158

154159

modules/event_stream/stream_send.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,13 +661,19 @@ static int handle_io(struct fd_map *fm, int idx, int event_type)
661661

662662
switch (fm->type) {
663663
case F_EV_JSONRPC_CMD:
664+
/* supppress any logs, in case we are handling the E_CORE_LOG event */
665+
set_proc_log_level(L_ALERT-1);
666+
664667
jsonrpcs = stream_receive();
665668
if (!jsonrpcs) {
666669
LM_ERR("invalid receive jsonrpc command\n");
670+
reset_proc_log_level();
667671
return -1;
668672
}
669673

670674
handle_new_stream(jsonrpcs);
675+
676+
reset_proc_log_level();
671677
break;
672678
case F_EV_JSONRPC_RPL:
673679
con = (struct stream_con *)fm->data;

0 commit comments

Comments
 (0)