/*
* Copyright (c) 2020 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* 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
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* $Id: //eng/uds-releases/jasper/src/uds/logger.c#3 $
*/
#include "logger.h"
#include "common.h"
#include "errors.h"
#include "stringUtils.h"
#include "threads.h"
#include "uds.h"
typedef struct {
const char *name;
const int priority;
} PriorityName;
static const PriorityName PRIORITIES[] = {
{ "ALERT", LOG_ALERT },
{ "CRITICAL", LOG_CRIT },
{ "CRIT", LOG_CRIT },
{ "DEBUG", LOG_DEBUG },
{ "EMERGENCY", LOG_EMERG },
{ "EMERG", LOG_EMERG },
{ "ERROR", LOG_ERR },
{ "ERR", LOG_ERR },
{ "INFO", LOG_INFO },
{ "NOTICE", LOG_NOTICE },
{ "PANIC", LOG_EMERG },
{ "WARN", LOG_WARNING },
{ "WARNING", LOG_WARNING },
{ NULL, -1 },
};
static const char *const PRIORITY_STRINGS[] = {
"EMERGENCY",
"ALERT",
"CRITICAL",
"ERROR",
"WARN",
"NOTICE",
"INFO",
"DEBUG",
};
static int logLevel = LOG_INFO;
/*****************************************************************************/
int getLogLevel(void)
{
return logLevel;
}
/*****************************************************************************/
void setLogLevel(int newLogLevel)
{
logLevel = newLogLevel;
}
/*****************************************************************************/
int stringToPriority(const char *string)
{
int i;
for (i = 0; PRIORITIES[i].name != NULL; i++) {
if (strcasecmp(string, PRIORITIES[i].name) == 0) {
return PRIORITIES[i].priority;
}
}
return LOG_INFO;
}
/*****************************************************************************/
const char *priorityToString(int priority)
{
if ((priority < 0) || (priority >= (int) COUNT_OF(PRIORITY_STRINGS))) {
return "unknown";
}
return PRIORITY_STRINGS[priority];
}
/*****************************************************************************/
void logEmbeddedMessage(int priority,
const char *prefix,
const char *fmt1,
va_list args1,
const char *fmt2,
...)
{
va_list ap;
va_start(ap, fmt2);
logMessagePack(priority, prefix, fmt1, args1, fmt2, ap);
va_end(ap);
}
#pragma GCC diagnostic push
/*
* GCC (version 8.1.1 20180502 (Red Hat 8.1.1-1)) on Fedora 28 seems
* to think that this function should get a printf format
* attribute. But we have no second format string, and no additional
* arguments at the call site, and GCC also gets unhappy trying to
* analyze the format and values when there are none. So we'll just
* shut it up.
*/
#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
/**
* Log a message.
*
* This helper function exists solely to create a valid va_list with
* no useful info. It does the real work of vLogMessage, which wants a
* second va_list object to pass down.
*
* @param priority The syslog priority value for the message.
* @param format The format of the message (a printf style format)
* @param args The variadic argument list of format parameters.
**/
static void vLogMessageHelper(int priority,
const char *format,
va_list args,
...)
{
va_list dummy;
va_start(dummy, args);
logMessagePack(priority, NULL, format, args, NULL, dummy);
va_end(dummy);
}
#pragma GCC diagnostic pop
/*****************************************************************************/
void vLogMessage(int priority, const char *format, va_list args)
{
vLogMessageHelper(priority, format, args);
}
/*****************************************************************************/
void logMessage(int priority, const char *format, ...)
{
va_list args;
va_start(args, format);
vLogMessage(priority, format, args);
va_end(args);
}
/*****************************************************************************/
void logDebug(const char *format, ...)
{
va_list args;
va_start(args, format);
vLogMessage(LOG_DEBUG, format, args);
va_end(args);
}
/*****************************************************************************/
void logInfo(const char *format, ...)
{
va_list args;
va_start(args, format);
vLogMessage(LOG_INFO, format, args);
va_end(args);
}
/*****************************************************************************/
void logNotice(const char *format, ...)
{
va_list args;
va_start(args, format);
vLogMessage(LOG_NOTICE, format, args);
va_end(args);
}
/*****************************************************************************/
void logWarning(const char *format, ...)
{
va_list args;
va_start(args, format);
vLogMessage(LOG_WARNING, format, args);
va_end(args);
}
/*****************************************************************************/
void logError(const char *format, ...)
{
va_list args;
va_start(args, format);
vLogMessage(LOG_ERR, format, args);
va_end(args);
}
/*****************************************************************************/
int vLogWithStringError(int priority,
int errnum,
const char *format,
va_list args)
{
char errbuf[ERRBUF_SIZE];
logEmbeddedMessage(priority, NULL, format, args, ": %s (%d)",
stringError(errnum, errbuf, sizeof(errbuf)),
errnum);
return errnum;
}
/*****************************************************************************/
int logWithStringError(int priority, int errnum, const char *format, ...)
{
va_list args;
va_start(args, format);
vLogWithStringError(priority, errnum, format, args);
va_end(args);
return errnum;
}
/*****************************************************************************/
int logErrorWithStringError(int errnum, const char *format, ...)
{
va_list args;
va_start(args, format);
vLogWithStringError(LOG_ERR, errnum, format, args);
va_end(args);
return errnum;
}
/*****************************************************************************/
int logWarningWithStringError(int errnum, const char *format, ...)
{
va_list args;
va_start(args, format);
vLogWithStringError(LOG_WARNING, errnum, format, args);
va_end(args);
return errnum;
}
/*****************************************************************************/
int logDebugWithStringError(int errnum, const char *format, ...)
{
va_list args;
va_start(args, format);
vLogWithStringError(LOG_DEBUG, errnum, format, args);
va_end(args);
return errnum;
}
/*****************************************************************************/
int logInfoWithStringError(int errnum, const char *format, ...)
{
va_list args;
va_start(args, format);
vLogWithStringError(LOG_INFO, errnum, format, args);
va_end(args);
return errnum;
}
/*****************************************************************************/
int logNoticeWithStringError(int errnum, const char *format, ...)
{
va_list args;
va_start(args, format);
vLogWithStringError(LOG_NOTICE, errnum, format, args);
va_end(args);
return errnum;
}
/*****************************************************************************/
int logFatalWithStringError(int errnum, const char *format, ...)
{
va_list args;
va_start(args, format);
vLogWithStringError(LOG_CRIT, errnum, format, args);
va_end(args);
return errnum;
}
/*****************************************************************************/
int logUnrecoverable(int errnum, const char *format, ...)
{
if (isSuccessful(errnum)) {
return errnum;
}
va_list args;
va_start(args, format);
vLogWithStringError(LOG_CRIT, errnum, format, args);
va_end(args);
return makeUnrecoverable(errnum);
}
/*****************************************************************************/
void logFatal(const char *format, ...)
{
va_list args;
va_start(args, format);
vLogMessage(LOG_CRIT, format, args);
va_end(args);
}