151 lines
3.7 KiB
C
151 lines
3.7 KiB
C
#include "include/conf.h"
|
|
|
|
#include "include/def.h"
|
|
|
|
#include "include/log.h"
|
|
#include "include/clrs.h"
|
|
|
|
#include <time.h>
|
|
#include <stdio.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <stdarg.h>
|
|
|
|
static const char *dp_log_level_str(dp_LogLevel level) {
|
|
switch (level) {
|
|
case DP_LOG_DEBUG: return "debug";
|
|
case DP_LOG_INFO: return "info";
|
|
case DP_LOG_WARN: return "warn";
|
|
case DP_LOG_ERROR: return "error";
|
|
case DP_LOG_FATAL: return "fatal";
|
|
default: return "???";
|
|
}
|
|
}
|
|
|
|
static const char *dp_log_level_clr(dp_LogLevel level) {
|
|
switch (level) {
|
|
case DP_LOG_DEBUG: return DP_CLR_BOLD DP_CLR_MAGENTA;
|
|
case DP_LOG_INFO: return DP_CLR_BOLD DP_CLR_CYAN;
|
|
case DP_LOG_WARN: return DP_CLR_BOLD DP_CLR_YELLOW;
|
|
case DP_LOG_ERROR: return DP_CLR_BOLD DP_CLR_RED;
|
|
case DP_LOG_FATAL: return DP_CLR_BOLD DP_CLR_UNDERLINE DP_CLR_RED;
|
|
default: return DP_CLR_BOLD;
|
|
}
|
|
}
|
|
|
|
void dp_log(dp_Logger *logger,
|
|
dp_LogLevel level,
|
|
const char *who,
|
|
const char *msg) {
|
|
if (!logger || !msg || !who || level < logger->_min_level) {
|
|
return;
|
|
}
|
|
|
|
const char *label = dp_log_level_str(level);
|
|
const char *colour = dp_log_level_clr(level);
|
|
const char *target =
|
|
(logger->_target && *logger->_target) ? logger->_target : "root";
|
|
FILE *out = (level >= DP_LOG_WARN) ? stderr : stdout;
|
|
|
|
char timestamp[42] = {0};
|
|
time_t now = time(NULL);
|
|
struct tm *tm_ptr = localtime(&now);
|
|
|
|
if (tm_ptr) {
|
|
(void)strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S",
|
|
tm_ptr);
|
|
}
|
|
|
|
(void)fprintf(out,
|
|
DP_CLR_DIM "%s" DP_CLR_RESET " | %s%-5s%s (" DP_CLR_BOLD
|
|
"%s @ %s" DP_CLR_RESET ") %s\n",
|
|
timestamp, colour, label, DP_CLR_RESET, target, who, msg);
|
|
|
|
if (logger->_file) {
|
|
(void)fprintf(logger->_file, "%s | %-5s (%s @ %s) %s\n", timestamp,
|
|
label, target, who, msg);
|
|
(void)fflush(logger->_file);
|
|
}
|
|
}
|
|
|
|
void dp_logf(dp_Logger *logger,
|
|
dp_LogLevel level,
|
|
const char *who,
|
|
const char *fmt,
|
|
...) {
|
|
if (!logger || !fmt || !who || level < logger->_min_level) {
|
|
return;
|
|
}
|
|
|
|
char buf[1024];
|
|
|
|
va_list args;
|
|
va_start(args, fmt);
|
|
(void)vsnprintf(buf, sizeof(buf), fmt, args);
|
|
va_end(args);
|
|
|
|
dp_log(logger, level, who, buf);
|
|
}
|
|
|
|
void dp_err(dp_Logger *logger,
|
|
dp_LogLevel level,
|
|
const char *who,
|
|
const char *msg) {
|
|
if (!logger || !who || !msg || level < logger->_min_level) {
|
|
return;
|
|
}
|
|
|
|
dp_logf(logger, level, who, "%s: %s (errno %d)", msg, strerror(errno),
|
|
errno);
|
|
}
|
|
|
|
void dp_log_flush(dp_Logger *logger) {
|
|
(void)logger;
|
|
(void)fflush(stdout);
|
|
(void)fflush(stderr);
|
|
}
|
|
|
|
void dp_log_set_target(dp_Logger *logger, const char *target) {
|
|
if (!logger) {
|
|
return;
|
|
}
|
|
|
|
logger->_target = target;
|
|
}
|
|
|
|
void dp_log_inherit(dp_Logger *src, dp_Logger *dest) {
|
|
if (src) {
|
|
dest->_target = NULL;
|
|
dest->_min_level = src->_min_level;
|
|
}
|
|
}
|
|
|
|
void dp_log_set_level(dp_Logger *logger, dp_LogLevel level) {
|
|
if (logger) {
|
|
logger->_min_level = level;
|
|
}
|
|
}
|
|
|
|
bool dp_log_set_file(dp_Logger *logger,
|
|
const char *filename,
|
|
const char *modes) {
|
|
if (!logger || !filename || !modes) {
|
|
return false;
|
|
}
|
|
|
|
FILE *file = fopen(filename, modes);
|
|
|
|
if (!file) {
|
|
return false;
|
|
}
|
|
|
|
logger->_file = file;
|
|
|
|
return true;
|
|
}
|
|
|
|
void dp_log_close_file(dp_Logger *logger) {
|
|
if (logger && logger->_file) {
|
|
(void)fclose(logger->_file);
|
|
}
|
|
}
|