115 lines
2.5 KiB
C
Executable File
115 lines
2.5 KiB
C
Executable File
#include "log.h"
|
|
|
|
|
|
static struct {
|
|
char *name;
|
|
int set;
|
|
FILE *fps[MAX_LOGFILES];
|
|
int nfps;
|
|
int stder;
|
|
#ifdef COLOR
|
|
char *color;
|
|
#endif
|
|
} log_levels[LOG_LEVEL_COUNT] = {
|
|
{
|
|
.name = "DEBUG", .set = 1, .fps = {0}, .nfps = 0, .stder = 1,
|
|
#ifdef COLOR
|
|
.color = "\e[38;2;255;255;0m"
|
|
#endif
|
|
},
|
|
{
|
|
.name = "INFO", .set = 1, .fps = {0}, .nfps = 0, .stder = 1,
|
|
#ifdef COLOR
|
|
.color = "\e[38;2;0;224;255m"
|
|
#endif
|
|
},
|
|
{
|
|
.name = "WARN", .set = 1, .fps = {0}, .nfps = 0, .stder = 1,
|
|
#ifdef COLOR
|
|
.color = "\e[38;2;255;165;0m"
|
|
#endif
|
|
},
|
|
{
|
|
.name = "ERROR", .set = 1, .fps = {0}, .nfps = 0, .stder = 1,
|
|
#ifdef COLOR
|
|
.color = "\e[38;2;255;0;0m"
|
|
#endif
|
|
}
|
|
};
|
|
|
|
static char time_format[16] = "%T";
|
|
static int nanosecond_precision = 0;
|
|
|
|
|
|
int log_set_stderr(int level, int of){
|
|
if(level >= 0 && level < LOG_LEVEL_COUNT){
|
|
return log_levels[level].stder = of;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void log_set_level(int level, int of){
|
|
if(level >= 0 && level < LOG_LEVEL_COUNT){
|
|
log_levels[level].set = of;
|
|
}
|
|
}
|
|
|
|
int log_add_fp(int level, FILE *fp){
|
|
if(level >= 0 && level < LOG_LEVEL_COUNT && log_levels[level].nfps < MAX_LOGFILES-1){
|
|
log_levels[level].fps[log_levels[level].nfps++] = fp;
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
void log_time_format(char *tf){
|
|
strncpy(time_format, tf, sizeof(time_format)/sizeof(time_format[0]));
|
|
}
|
|
|
|
int log_nanoseconds(int n){
|
|
return nanosecond_precision = n%10;
|
|
}
|
|
|
|
void log_message(int level, char *file, int line, char *fmt, ...){
|
|
struct timespec ts;
|
|
clock_gettime(CLOCK_REALTIME, &ts);
|
|
if(level >= 0 && level < LOG_LEVEL_COUNT && log_levels[level].set){
|
|
struct tm *lt = localtime(&ts.tv_sec);
|
|
char t[32] = {0};
|
|
strftime(t, 31, time_format, lt);
|
|
char ns[9] = {0};
|
|
snprintf(ns, nanosecond_precision+1, "%ld", ts.tv_nsec);
|
|
char msg[MSG_LIMIT] = {0};
|
|
int written = snprintf(msg, MSG_LIMIT-2,
|
|
#ifdef PID
|
|
"[%d] "
|
|
#endif
|
|
"%s%s%s%s%s%s%s\t",
|
|
#ifdef PID
|
|
getpid(),
|
|
#endif
|
|
t, nanosecond_precision ? "." : "", ns,
|
|
t[0] != '\0' ? " " : "",
|
|
#ifdef COLOR
|
|
log_levels[level].color,
|
|
#else
|
|
"",
|
|
#endif
|
|
log_levels[level].name, "\e[0m"
|
|
);
|
|
if(level == LOG_DEBUG){
|
|
written += snprintf(msg+written, MSG_LIMIT-2-written, "%s:%d: ",file, line);
|
|
}
|
|
va_list args;
|
|
va_start(args, fmt);
|
|
written += vsnprintf(msg+written, MSG_LIMIT-2-written, fmt, args);
|
|
msg[written] = '\n';
|
|
if(log_levels[level].stder) fputs(msg, stderr);
|
|
for(int i = 0; i < log_levels[level].nfps; i++){
|
|
if(log_levels[level].fps[i] != NULL)
|
|
fputs(msg, log_levels[level].fps[i++]);
|
|
}
|
|
}
|
|
}
|
|
|