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>
|
||||||
Levitating marked this conversation as resolved
Outdated
|
|||||||
#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
|
||||||
Levitating marked this conversation as resolved
Outdated
lda
commented
I'd probably consider making LogPrint static here, as it's not even part of the public includes. I'd probably consider making LogPrint static here, as it's not even part of the public includes.
Levitating
commented
Yes it should be static! Yes it should be static!
|
|||||||
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
I think you meant stdarg.h, as those kind of includes are C++isms.
It was most likely automatically added by my IDE by accident.