WIP: Rework logging #48
2 changed files with 62 additions and 63 deletions
|
@ -46,6 +46,7 @@
|
||||||
|
|
||||||
#define LOG_FLAG_COLOR (1 << 0)
|
#define LOG_FLAG_COLOR (1 << 0)
|
||||||
#define LOG_FLAG_SYSLOG (1 << 1)
|
#define LOG_FLAG_SYSLOG (1 << 1)
|
||||||
|
#define LOG_FLAG_STDOUT (1 << 2)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A log is defined as a configuration that describes the properties
|
* 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);
|
extern void LogConfigIndentSet(LogConfig *, size_t);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the file stream that logging output should be written to. This
|
* Set the file stream that logging output should be written to.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
extern void LogConfigOutputSet(LogConfig *, Stream *);
|
extern void LogConfigFileSet(LogConfig *, Stream *);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a number of boolean options on a log configuration. This
|
* 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.
|
* is checked before writing any terminal sequences.
|
||||||
* .It LOG_FLAG_SYSLOG
|
* .It LOG_FLAG_SYSLOG
|
||||||
* When set, log output to the syslog using
|
* When set, log output to the syslog using
|
||||||
* .Xr syslog 3 ,
|
* .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.
|
|
||||||
* .El
|
* .El
|
||||||
*/
|
*/
|
||||||
extern void LogConfigFlagSet(LogConfig *, int);
|
extern void LogConfigFlagSet(LogConfig *, int);
|
||||||
|
|
107
src/Log.c
107
src/Log.c
|
@ -26,6 +26,7 @@
|
||||||
#include <Memory.h>
|
#include <Memory.h>
|
||||||
#include <Util.h>
|
#include <Util.h>
|
||||||
|
|
||||||
|
#include <cstdarg>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -39,7 +40,7 @@ struct LogConfig
|
||||||
{
|
{
|
||||||
int level;
|
int level;
|
||||||
size_t indent;
|
size_t indent;
|
||||||
Stream *out;
|
Stream *file;
|
||||||
int flags;
|
int flags;
|
||||||
char *tsFmt;
|
char *tsFmt;
|
||||||
|
|
||||||
|
@ -65,8 +66,8 @@ LogConfigCreate(void)
|
||||||
|
|
||||||
LogConfigLevelSet(config, LOG_INFO);
|
LogConfigLevelSet(config, LOG_INFO);
|
||||||
LogConfigIndentSet(config, 0);
|
LogConfigIndentSet(config, 0);
|
||||||
LogConfigOutputSet(config, NULL); /* Will set to stdout */
|
LogConfigFileSet(config, NULL);
|
||||||
LogConfigFlagSet(config, LOG_FLAG_COLOR);
|
LogConfigFlagSet(config, LOG_FLAG_COLOR | LOG_FLAG_STDOUT);
|
||||||
LogConfigTimeStampFormatSet(config, "%y-%m-%d %H:%M:%S");
|
LogConfigTimeStampFormatSet(config, "%y-%m-%d %H:%M:%S");
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
|
@ -185,20 +186,20 @@ LogConfigLevelSet(LogConfig * config, int level)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LogConfigOutputSet(LogConfig * config, Stream * out)
|
LogConfigFileSet(LogConfig * config, Stream * file)
|
||||||
{
|
{
|
||||||
if (!config)
|
if (!config)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (out)
|
if (file)
|
||||||
{
|
{
|
||||||
config->out = out;
|
config->file = file;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
config->out = StreamStdout();
|
config->file = StreamStdout();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -222,42 +223,14 @@ LogConfigUnindent(LogConfig * config)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Logv(LogConfig * config, int level, const char *msg, va_list argp)
|
LogPrint(Stream * stream, LogConfig * config, int level, const char *msg, va_list argp)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
int doColor;
|
int doColor;
|
||||||
char indicator;
|
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)
|
doColor = LogConfigFlagGet(config, LOG_FLAG_COLOR)
|
||||||
&& isatty(StreamFileno(config->out));
|
&& isatty(StreamFileno(stream));
|
||||||
|
|
||||||
if (doColor)
|
if (doColor)
|
||||||
{
|
{
|
||||||
|
@ -293,10 +266,10 @@ Logv(LogConfig * config, int level, const char *msg, va_list argp)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
StreamPuts(config->out, ansi);
|
StreamPuts(stream, ansi);
|
||||||
}
|
}
|
||||||
|
|
||||||
StreamPutc(config->out, '[');
|
StreamPutc(stream, '[');
|
||||||
|
|
||||||
if (config->tsFmt)
|
if (config->tsFmt)
|
||||||
{
|
{
|
||||||
|
@ -309,15 +282,15 @@ Logv(LogConfig * config, int level, const char *msg, va_list argp)
|
||||||
|
|
||||||
if (tsLength)
|
if (tsLength)
|
||||||
{
|
{
|
||||||
StreamPuts(config->out, tsBuffer);
|
StreamPuts(stream, tsBuffer);
|
||||||
if (!isspace((unsigned char) tsBuffer[tsLength - 1]))
|
if (!isspace((unsigned char) tsBuffer[tsLength - 1]))
|
||||||
{
|
{
|
||||||
StreamPutc(config->out, ' ');
|
StreamPutc(stream, ' ');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StreamPrintf(config->out, "(%lu) ", UtilThreadNo());
|
StreamPrintf(stream, "(%lu) ", UtilThreadNo());
|
||||||
|
|
||||||
switch (level)
|
switch (level)
|
||||||
{
|
{
|
||||||
|
@ -350,24 +323,60 @@ Logv(LogConfig * config, int level, const char *msg, va_list argp)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
StreamPrintf(config->out, "%c]", indicator);
|
StreamPrintf(stream, "%c]", indicator);
|
||||||
|
|
||||||
if (doColor)
|
if (doColor)
|
||||||
{
|
{
|
||||||
/* ANSI Reset */
|
/* ANSI Reset */
|
||||||
StreamPuts(config->out, "\033[0m");
|
StreamPuts(stream, "\033[0m");
|
||||||
}
|
}
|
||||||
|
|
||||||
StreamPutc(config->out, ' ');
|
StreamPutc(stream, ' ');
|
||||||
for (i = 0; i < config->indent; i++)
|
for (i = 0; i < config->indent; i++)
|
||||||
{
|
{
|
||||||
StreamPutc(config->out, ' ');
|
StreamPutc(config->file, ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
StreamVprintf(config->out, msg, argp);
|
StreamVprintf(stream, msg, argp);
|
||||||
StreamPutc(config->out, '\n');
|
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);
|
pthread_mutex_unlock(&config->lock);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue