/* helper: tell how many messages we lost due to linux-like ratelimiting */ static void tellLostCnt(ratelimit_t *ratelimit) { uchar msgbuf[1024]; if(ratelimit->missed) { snprintf((char*)msgbuf, sizeof(msgbuf), "%s: %u messages lost due to rate-limiting", ratelimit->name, ratelimit->missed); ratelimit->missed = 0; logmsgInternal(RS_RET_RATE_LIMITED, LOG_SYSLOG|LOG_INFO, msgbuf, 0); } }
/* log an imkmsg-internal message * rgerhards, 2008-04-14 */ rsRetVal imkmsgLogIntMsg(syslog_pri_t priority, char *fmt, ...) { DEFiRet; va_list ap; uchar msgBuf[2048]; /* we use the same size as sysklogd to remain compatible */ va_start(ap, fmt); vsnprintf((char*)msgBuf, sizeof(msgBuf), fmt, ap); va_end(ap); logmsgInternal(NO_ERRCODE, priority, msgBuf, 0); RETiRet; }
/* Read journal log while data are available, each read() reads one * record of printk buffer. */ static rsRetVal readjournal() { DEFiRet; struct timeval tv; uint64_t timestamp; struct json_object *json = NULL; int r; /* Information from messages */ char *message; char *sys_pid; char *sys_iden; char *sys_iden_help; const void *get; const void *pidget; char *parse; char *get2; size_t length; size_t pidlength; const void *equal_sign; struct json_object *jval; char *data; char *name; size_t l; long prefixlen = 0; int priority = 0; int facility = 0; /* Get message text */ if (sd_journal_get_data(j, "MESSAGE", &get, &length) < 0) { logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar *)"log message from journal doesn't have MESSAGE", 0); iRet = RS_RET_OK; goto ret; } message = strndup(get+8, length-8); if (message == NULL) { iRet = RS_RET_OUT_OF_MEMORY; goto ret; } /* Get message priority */ if (sd_journal_get_data(j, "PRIORITY", &get, &length) >= 0) { get2 = strndup(get, length); priority = ((char *)get2)[9] - '0'; free (get2); } /* Get syslog facility */ if (sd_journal_get_data(j, "SYSLOG_FACILITY", &get, &length) >= 0) { get2 = strndup(get, length); char f = ((char *)get2)[16]; if (f >= '0' && f <= '9') { facility += f - '0'; } f = ((char *)get2)[17]; if (f >= '0' && f <= '9') { facility *= 10; facility += (f - '0'); } free (get2); } else { /* message is missing facility -> internal systemd journal msg, drop */ iRet = RS_RET_OK; goto free_message; } /* Get message identifier, client pid and add ':' */ if (sd_journal_get_data(j, "SYSLOG_IDENTIFIER", &get, &length) >= 0) { sys_iden = strndup(get+18, length-18); } else { sys_iden = strdup("journal"); } if (sys_iden == NULL) { iRet = RS_RET_OUT_OF_MEMORY; goto free_message; } if (sd_journal_get_data(j, "SYSLOG_PID", &pidget, &pidlength) >= 0) { sys_pid = strndup(pidget+11, pidlength-11); if (sys_pid == NULL) { iRet = RS_RET_OUT_OF_MEMORY; free (sys_iden); goto free_message; } } else { sys_pid = NULL; } if (sys_pid) { r = asprintf(&sys_iden_help, "%s[%s]:", sys_iden, sys_pid); } else { r = asprintf(&sys_iden_help, "%s:", sys_iden); } free (sys_iden); free (sys_pid); if (-1 == r) { iRet = RS_RET_OUT_OF_MEMORY; goto finalize_it; } json = json_object_new_object(); SD_JOURNAL_FOREACH_DATA(j, get, l) { /* locate equal sign, this is always present */ equal_sign = memchr(get, '=', l); /* ... but we know better than to trust the specs */ if (equal_sign == NULL) { errmsg.LogError(0, RS_RET_ERR, "SD_JOURNAL_FOREACH_DATA()" "returned a malformed field (has no '='): '%s'", get); continue; /* skip the entry */ } /* get length of journal data prefix */ prefixlen = ((char *)equal_sign - (char *)get); /* translate name fields to lumberjack names */ parse = (char *)get; switch (*parse) { case '_': ++parse; if (*parse == 'P') { if (!strncmp(parse+1, "ID=", 4)) { name = strdup("pid"); } else { name = strndup(get, prefixlen); } } else if (*parse == 'G') { if (!strncmp(parse+1, "ID=", 4)) { name = strdup("gid"); } else { name = strndup(get, prefixlen); } } else if (*parse == 'U') { if (!strncmp(parse+1, "ID=", 4)) { name = strdup("uid"); } else { name = strndup(get, prefixlen); } } else if (*parse == 'E') { if (!strncmp(parse+1, "XE=", 4)) { name = strdup("exe"); } else { name = strndup(get, prefixlen); } } else if (*parse == 'C') { parse++; if (*parse == 'O') { if (!strncmp(parse+1, "MM=", 4)) { name = strdup("appname"); } else { name = strndup(get, prefixlen); } } else if (*parse == 'M') { if (!strncmp(parse+1, "DLINE=", 7)) { name = strdup("cmd"); } else { name = strndup(get, prefixlen); } } else { name = strndup(get, prefixlen); } } else { name = strndup(get, prefixlen); } break; default: name = strndup(get, prefixlen); break; } if (name == NULL) { iRet = RS_RET_OUT_OF_MEMORY; goto ret; } prefixlen++; /* remove '=' */ data = strndup(get + prefixlen, l - prefixlen); if (data == NULL) { iRet = RS_RET_OUT_OF_MEMORY; free (name); goto ret; } /* and save them to json object */ jval = json_object_new_string((char *)data); json_object_object_add(json, name, jval); free (data); free (name); }