/
githubmirror
/
rsyslog
Обзор
Документация
Войти
/
githubmirror
/
rsyslog
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
rger-test1
runtime/errmsg.c
268 строк
9 KB
Rainer Gerhards
core: add doxygen comments to errmsg object
13 сен 2025, 11:27
Не верифицирован
13 сен 2025, 11:27
10a728e
Код
Авторство
О чём код?
/* The errmsg object. * * Module begun 2008-03-05 by Rainer Gerhards, based on some code * from syslogd.c. I converted this module to lgpl and have checked that * all contributors agreed to that step. * Now moving to ASL 2.0, and contributor checks tell that there is no need * to take further case, as the code now boils to be either my own or, a few lines, * of the original BSD-licenses sysklogd code. rgerhards, 2012-01-16 * * Copyright 2008-2018 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <errno.h> #include <assert.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <unistd.h> #include "rsyslog.h" #include "obj.h" #include "msg.h" #include "errmsg.h" #include "operatingstate.h" #include "srUtils.h" #include "stringbuf.h" #include "rsconf.h" /* static data */ #ifndef O_LARGEFILE #define O_LARGEFILE 0 #endif static int bHadErrMsgs; /* indicates if we had error messages since reset of this flag * This is used to abort a run if the config is unclean. */ static int fdOversizeMsgLog = -1; static pthread_mutex_t oversizeMsgLogMut = PTHREAD_MUTEX_INITIALIZER; /* ------------------------------ methods ------------------------------ */ /* Resets the error message flag. Must be done before processing config * files. */ void resetErrMsgsFlag(void) { bHadErrMsgs = 0; } int hadErrMsgs(void) { return bHadErrMsgs; } /** @internal * Build and emit a single diagnostic line. * * - If iErrno != 0, append strerror(iErrno). * - If iErrCode is neither NO_ERRCODE nor RS_RET_ERR, append a help URL. * - Truncate to the configured max line length. * - Set the "had error" flag for LOG_ERR. */ static void doLogMsg(const int iErrno, const int iErrCode, const int severity, const char *msg) { char buf[2048]; char errStr[1024]; dbgprintf("Called LogMsg, msg: %s\n", msg); osf_write(OSF_TAG_MSG, msg); if (iErrno != 0) { rs_strerror_r(iErrno, errStr, sizeof(errStr)); if (iErrCode == NO_ERRCODE || iErrCode == RS_RET_ERR) { snprintf(buf, sizeof(buf), "%s: %s [v%s]", msg, errStr, VERSION); } else { snprintf(buf, sizeof(buf), "%s: %s [v%s try https://www.rsyslog.com/e/%d ]", msg, errStr, VERSION, iErrCode * -1); } } else { if (iErrCode == NO_ERRCODE || iErrCode == RS_RET_ERR) { snprintf(buf, sizeof(buf), "%s [v%s]", msg, VERSION); } else { snprintf(buf, sizeof(buf), "%s [v%s try https://www.rsyslog.com/e/%d ]", msg, VERSION, iErrCode * -1); } } buf[sizeof(buf) - 1] = '\0'; /* just to be on the safe side... */ errno = 0; const int msglen = (int)strlen(buf); if (msglen > glblGetMaxLine(ourConf)) { /* in extreme cases, our error messages may be longer than the configured * max message size. If so, we just truncate without further indication, as * anything else would probably lead to a death loop on error messages. * Note that we do not split, as we really do not anticipate there is * much value in supporting extremely short max message sizes - we assume * it's just a testbench thing. -- rgerhards, 2018-05-11 */ buf[glblGetMaxLine(ourConf)] = '\0'; /* space must be available! */ } glblErrLogger(severity, iErrCode, (uchar *)buf); if (severity == LOG_ERR) bHadErrMsgs = 1; } /* We now receive three parameters: one is the internal error code * which will also become the error message number, the second is * errno - if it is non-zero, the corresponding error message is included * in the text and finally the message text itself. Note that it is not * 100% clean to use the internal errcode, as it may be reached from * multiple actual error causes. However, it is much better than having * no error code at all (and in most cases, a single internal error code * maps to a specific error event). * rgerhards, 2008-06-27 */ void __attribute__((format(printf, 3, 4))) LogError(const int iErrno, const int iErrCode, const char *fmt, ...) { va_list ap; char buf[2048]; int lenBuf; va_start(ap, fmt); lenBuf = vsnprintf(buf, sizeof(buf), fmt, ap); if (lenBuf < 0) { strncpy(buf, "error message lost due to problem with vsnprintf", sizeof(buf)); } va_end(ap); buf[sizeof(buf) - 1] = '\0'; /* just to be on the safe side... */ doLogMsg(iErrno, iErrCode, LOG_ERR, buf); } /* We now receive three parameters: one is the internal error code * which will also become the error message number, the second is * errno - if it is non-zero, the corresponding error message is included * in the text and finally the message text itself. Note that it is not * 100% clean to use the internal errcode, as it may be reached from * multiple actual error causes. However, it is much better than having * no error code at all (and in most cases, a single internal error code * maps to a specific error event). * rgerhards, 2008-06-27 */ void __attribute__((format(printf, 4, 5))) LogMsg( const int iErrno, const int iErrCode, const int severity, const char *fmt, ...) { va_list ap; char buf[2048]; int lenBuf; va_start(ap, fmt); lenBuf = vsnprintf(buf, sizeof(buf), fmt, ap); if (lenBuf < 0) { strncpy(buf, "error message lost due to problem with vsnprintf", sizeof(buf)); } va_end(ap); buf[sizeof(buf) - 1] = '\0'; /* just to be on the safe side... */ doLogMsg(iErrno, iErrCode, severity, buf); } /* Write an oversize message to the oversize message error log. * We do NOT handle errors during writing that log other than emitting * yet another error message. The reason is that there really is nothing * else that we could do in that case. * rgerhards, 2018-05-03 */ rsRetVal ATTR_NONNULL() writeOversizeMessageLog(const smsg_t *const pMsg) { struct json_object *json = NULL; char *rendered = NULL; struct json_object *jval; uchar *buf; size_t toWrite; ssize_t wrRet; int dummy; int mutexLocked = 0; DEFiRet; ISOBJ_TYPE_assert(pMsg, msg); if (glblGetOversizeMsgErrorFile(runConf) == NULL) { FINALIZE; } pthread_mutex_lock(&oversizeMsgLogMut); mutexLocked = 1; if (fdOversizeMsgLog == -1) { fdOversizeMsgLog = open((char *)glblGetOversizeMsgErrorFile(runConf), O_WRONLY | O_CREAT | O_APPEND | O_LARGEFILE | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); if (fdOversizeMsgLog == -1) { LogError(errno, RS_RET_ERR, "error opening oversize message log file %s", glblGetOversizeMsgErrorFile(runConf)); FINALIZE; } } assert(fdOversizeMsgLog != -1); json = json_object_new_object(); if (json == NULL) { FINALIZE; } getRawMsg(pMsg, &buf, &dummy); jval = json_object_new_string((char *)buf); json_object_object_add(json, "rawmsg", jval); getInputName(pMsg, &buf, &dummy); jval = json_object_new_string((char *)buf); json_object_object_add(json, "input", jval); CHKmalloc(rendered = strdup((char *)fjson_object_to_json_string(json))); toWrite = strlen(rendered) + 1; /* Note: we overwrite the '\0' terminator with '\n' -- so we avoid * calling malloc() -- write() does NOT need '\0'! */ rendered[toWrite - 1] = '\n'; /* NO LONGER A STRING! */ wrRet = write(fdOversizeMsgLog, rendered, toWrite); if (wrRet != (ssize_t)toWrite) { LogError(errno, RS_RET_IO_ERROR, "error writing oversize message log file %s, write returned %lld", glblGetOversizeMsgErrorFile(runConf), (long long)wrRet); } finalize_it: free(rendered); if (mutexLocked) { pthread_mutex_unlock(&oversizeMsgLogMut); } if (json != NULL) { fjson_object_put(json); } RETiRet; } void errmsgDoHUP(void) { pthread_mutex_lock(&oversizeMsgLogMut); if (fdOversizeMsgLog != -1) { close(fdOversizeMsgLog); fdOversizeMsgLog = -1; } pthread_mutex_unlock(&oversizeMsgLogMut); } void errmsgExit(void) { if (fdOversizeMsgLog != -1) { close(fdOversizeMsgLog); } }