WIP: Rework logging #48
2 changed files with 62 additions and 64 deletions
|
@ -46,6 +46,7 @@
|
|||
|
||||
#define LOG_FLAG_COLOR (1 << 0)
|
||||
#define LOG_FLAG_SYSLOG (1 << 1)
|
||||
#define LOG_FLAG_STDOUT (1 << 2)
|
||||
|
||||
/**
|
||||
* A log is defined as a configuration that describes the properties
|
||||
|
@ -110,15 +111,9 @@ extern void LogConfigUnindent(LogConfig *);
|
|||
extern void LogConfigIndentSet(LogConfig *, size_t);
|
||||
|
||||
/**
|
||||
* Set the file stream that logging output should be written to. This
|
||||
* defaults to standard output, but it can be set to standard error,
|
||||
* or any other arbitrary stream. Passing a NULL value for the stream
|
||||
* pointer sets the log output to the standard output. Note that the
|
||||
* output stream is only used if
|
||||
* .Va LOG_FLAG_SYSLOG
|
||||
* is not set.
|
||||
* Set the file stream that logging output should be written to.
|
||||
*/
|
||||
extern void LogConfigOutputSet(LogConfig *, Stream *);
|
||||
extern void LogConfigFileSet(LogConfig *, Stream *);
|
||||
|
||||
/**
|
||||
* Set a number of boolean options on a log configuration. This
|
||||
|
@ -135,12 +130,7 @@ extern void LogConfigOutputSet(LogConfig *, Stream *);
|
|||
* is checked before writing any terminal sequences.
|
||||
* .It LOG_FLAG_SYSLOG
|
||||
* When set, log output to the syslog using
|
||||
* .Xr syslog 3 ,
|
||||
* instead of logging to the file set by
|
||||
* .Fn LogConfigOutputSet .
|
||||
* This flag always overrides the stream set by that function,
|
||||
* regardless of when it was set, even if it was set after this flag
|
||||
* was set.
|
||||
* .Xr syslog 3
|
||||
* .El
|
||||
*/
|
||||
extern void LogConfigFlagSet(LogConfig *, int);
|
||||
|
|
108
src/Log.c
108
src/Log.c
|
@ -39,7 +39,7 @@ struct LogConfig
|
|||
{
|
||||
int level;
|
||||
size_t indent;
|
||||
Stream *out;
|
||||
Stream *file;
|
||||
int flags;
|
||||
char *tsFmt;
|
||||
|
||||
|
@ -65,8 +65,8 @@ LogConfigCreate(void)
|
|||
|
||||
LogConfigLevelSet(config, LOG_INFO);
|
||||
LogConfigIndentSet(config, 0);
|
||||
LogConfigOutputSet(config, NULL); /* Will set to stdout */
|
||||
LogConfigFlagSet(config, LOG_FLAG_COLOR);
|
||||
LogConfigFileSet(config, NULL);
|
||||
LogConfigFlagSet(config, LOG_FLAG_COLOR | LOG_FLAG_STDOUT);
|
||||
LogConfigTimeStampFormatSet(config, "%y-%m-%d %H:%M:%S");
|
||||
|
||||
return config;
|
||||
|
@ -185,20 +185,20 @@ LogConfigLevelSet(LogConfig * config, int level)
|
|||
}
|
||||
|
||||
void
|
||||
LogConfigOutputSet(LogConfig * config, Stream * out)
|
||||
LogConfigFileSet(LogConfig * config, Stream * file)
|
||||
{
|
||||
if (!config)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (out)
|
||||
if (file)
|
||||
{
|
||||
config->out = out;
|
||||
config->file = file;
|
||||
}
|
||||
else
|
||||
{
|
||||
config->out = StreamStdout();
|
||||
config->file = StreamStdout();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -221,43 +221,15 @@ LogConfigUnindent(LogConfig * config)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Logv(LogConfig * config, int level, const char *msg, va_list argp)
|
||||
static void
|
||||
LogPrint(Stream * stream, LogConfig * config, int level, const char *msg, va_list argp)
|
||||
{
|
||||
size_t i;
|
||||
int doColor;
|
||||
char indicator;
|
||||
|
||||
/*
|
||||
* Only proceed if we have a config and its log level is set to a
|
||||
* value that permits us to log. This is as close as we can get
|
||||
* to a no-op function if we aren't logging anything, without doing
|
||||
* some crazy macro magic.
|
||||
*/
|
||||
if (!config || level > config->level)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Misconfiguration */
|
||||
if (!config->out)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&config->lock);
|
||||
|
||||
if (LogConfigFlagGet(config, LOG_FLAG_SYSLOG))
|
||||
{
|
||||
/* No further print logic is needed; syslog will handle it all
|
||||
* for us. */
|
||||
vsyslog(level, msg, argp);
|
||||
pthread_mutex_unlock(&config->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
doColor = LogConfigFlagGet(config, LOG_FLAG_COLOR)
|
||||
&& isatty(StreamFileno(config->out));
|
||||
&& isatty(StreamFileno(stream));
|
||||
|
||||
if (doColor)
|
||||
{
|
||||
|
@ -293,10 +265,10 @@ Logv(LogConfig * config, int level, const char *msg, va_list argp)
|
|||
break;
|
||||
}
|
||||
|
||||
StreamPuts(config->out, ansi);
|
||||
StreamPuts(stream, ansi);
|
||||
}
|
||||
|
||||
StreamPutc(config->out, '[');
|
||||
StreamPutc(stream, '[');
|
||||
|
||||
if (config->tsFmt)
|
||||
{
|
||||
|
@ -309,15 +281,15 @@ Logv(LogConfig * config, int level, const char *msg, va_list argp)
|
|||
|
||||
if (tsLength)
|
||||
{
|
||||
StreamPuts(config->out, tsBuffer);
|
||||
StreamPuts(stream, tsBuffer);
|
||||
if (!isspace((unsigned char) tsBuffer[tsLength - 1]))
|
||||
{
|
||||
StreamPutc(config->out, ' ');
|
||||
StreamPutc(stream, ' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StreamPrintf(config->out, "(%lu) ", UtilThreadNo());
|
||||
StreamPrintf(stream, "(%lu) ", UtilThreadNo());
|
||||
|
||||
switch (level)
|
||||
{
|
||||
|
@ -350,24 +322,60 @@ Logv(LogConfig * config, int level, const char *msg, va_list argp)
|
|||
break;
|
||||
}
|
||||
|
||||
StreamPrintf(config->out, "%c]", indicator);
|
||||
StreamPrintf(stream, "%c]", indicator);
|
||||
|
||||
if (doColor)
|
||||
{
|
||||
/* ANSI Reset */
|
||||
StreamPuts(config->out, "\033[0m");
|
||||
StreamPuts(stream, "\033[0m");
|
||||
}
|
||||
|
||||
StreamPutc(config->out, ' ');
|
||||
StreamPutc(stream, ' ');
|
||||
for (i = 0; i < config->indent; i++)
|
||||
{
|
||||
StreamPutc(config->out, ' ');
|
||||
StreamPutc(config->file, ' ');
|
||||
}
|
||||
|
||||
StreamVprintf(config->out, msg, argp);
|
||||
StreamPutc(config->out, '\n');
|
||||
StreamVprintf(stream, msg, argp);
|
||||
StreamPutc(stream, '\n');
|
||||
|
||||
StreamFlush(config->out);
|
||||
StreamFlush(stream);
|
||||
}
|
||||
|
||||
void
|
||||
Logv(LogConfig * config, int level, const char *msg, va_list argp)
|
||||
{
|
||||
/*
|
||||
* Only proceed if we have a config and its log level is set to a
|
||||
* value that permits us to log. This is as close as we can get
|
||||
* to a no-op function if we aren't logging anything, without doing
|
||||
* some crazy macro magic.
|
||||
*/
|
||||
if (!config || level > config->level)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Misconfiguration */
|
||||
if (!config->file)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&config->lock);
|
||||
|
||||
if (LogConfigFlagGet(config, LOG_FLAG_SYSLOG))
|
||||
{
|
||||
vsyslog(level, msg, argp);
|
||||
}
|
||||
|
||||
if (LogConfigFlagGet(config, LOG_FLAG_STDOUT)) {
|
||||
LogPrint(StreamStdout(), config, level, msg, argp);
|
||||
}
|
||||
|
||||
if (config->file) {
|
||||
LogPrint(config->file, config, level, msg, argp);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&config->lock);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue