/*
hm_base - hearthmod base library
Copyright (C) 2016 Filip Pancik
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
int hm_log_impl(unsigned long long seq_nb, int priority, struct hm_log_s *log, const char *file, const int line, const char *func, const char *msg, ...)
{
size_t len = 0;
char out[8192], buf[128];
time_t s;
struct timespec spec;
long long ms;
struct tm ts;
assert(log);
/** only display messages user asked for */
if(priority > log->priority) {
return -1;
}
//if(log->fd == STDERR_FILENO)
{
const char *colour;
switch(priority) {
case LOG_EMERG: //< system is unusable
colour = "(%llu) \33[1;31;41mLOG_EMERG\33[m";
break;
case LOG_ALERT: //< action must be taken immediately
colour = "(%llu) \33[1;33;41mLOG_ALERT\33[m";
break;
case LOG_CRIT: //< critical conditions
colour = "(%llu) \33[1;31;40mLOG_CRIT\33[m";
break;
case LOG_ERR: //< error conditions
colour = "(%llu) \33[1;34;41mLOG_ERR\33[m";
break;
case LOG_WARNING: //< warning conditions
colour = "(%llu) \33[1;37;43mLOG_WARNING\33[m";
break;
case LOG_NOTICE: //< normal, but significant, condition
colour = "(%llu) \33[1;34;47mLOG_NOTICE\33[m";
break;
case LOG_INFO: //< informational message
colour = "(%llu) \33[1;37;42mLOG_INFO\33[m";
break;
case LOG_DEBUG: //< debug-level message
colour = "(%llu) \33[1;32;40mLOG_DEBUG\33[m";
break;
case LOG_MEMORY: //< memory message
colour = "(%llu) \33[1;35;34mLOG_MEMORY\33[m";
break;
default:
colour = NULL;
}
if(colour) {
len += snprintf(out, sizeof(out), colour, seq_nb);
}
}
clock_gettime(CLOCK_REALTIME, &spec);
s = spec.tv_sec;
ms = round(spec.tv_nsec / 1.0e6);
ts = *localtime(&s);
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &ts);
len += snprintf(out + len, sizeof(out) - len, "[%s.%03lld] ", buf, ms);
va_list args;
va_start(args, msg);
len += vsnprintf(out+len, 3*sizeof(out)/4-len, msg, args);
va_end(args);
if(len >= 3*sizeof(out)/4) {
len += snprintf(out + len, sizeof(out) - len, "...");
}
len += snprintf(out+len, sizeof(out)-len, ", %s:%d(%s)\n", file, line, func);
ssize_t nwritten = write(log->fd, out, len);
return (nwritten == len) ? 0 : -1;
}
int hm_log_open(struct hm_log_s *l, const char *filename, const int priority)
{
if(filename != NULL) {
l->file = fopen(filename, "a");
if(l->file == NULL) {
return -1;
}
l->fd = fileno(l->file);
} else {
l->file = stderr;
l->fd = STDERR_FILENO;
}
l->priority = priority;
return 0;
}
int hm_log_close(struct hm_log_s *l)
{
if(l->file && l->file != stderr) {
fclose(l->file);
return 0;
} else {
return -1;
}
}