summaryrefslogtreecommitdiffstats
path: root/lib/log.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/log.c')
-rw-r--r--lib/log.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/lib/log.c b/lib/log.c
new file mode 100644
index 0000000..4924782
--- /dev/null
+++ b/lib/log.c
@@ -0,0 +1,67 @@
+#include <string.h>
+#include <time.h>
+#include "log.h"
+
+/* TODO: replace this with something thread-safe later. */
+
+static unsigned log_level = LOG_INFO;
+
+void vl_log_setlevel(unsigned level)
+{
+ log_level = level;
+}
+
+#define MAX_LOGLEN ((size_t)4096)
+#define MAX_LOGTIMELEN ((size_t)64) /* december 999th of 10000 A.D. at 100 o'clock */
+
+static const char *const log_names[] = {
+ "TRACE",
+ "DEBUG",
+ "INFO",
+ "WARN",
+ "ERROR",
+ NULL
+};
+
+static FILE *log_stream(unsigned level)
+{
+ switch (level) {
+ case LOG_TRACE:
+ case LOG_DEBUG:
+ case LOG_INFO:
+ return stdout;
+ default:
+ return stderr;
+ }
+}
+
+void vl_logv(unsigned level, const char *fmt, va_list args)
+{
+ char buf[MAX_LOGLEN];
+ char datebuf[MAX_LOGTIMELEN];
+ time_t now;
+ struct tm now_tm;
+
+ if (log_level > level) return;
+ if (level > LOG_ERROR) return;
+
+ vsnprintf(buf, MAX_LOGLEN, fmt, args);
+ strcpy(buf + MAX_LOGLEN - 4, "...");
+
+ now = time(NULL);
+ localtime_r(&now, &now_tm);
+
+ if (!strftime(datebuf, MAX_LOGTIMELEN, "%H:%M:%S", &now_tm)) {
+ strcpy(datebuf, "???");
+ }
+
+ fprintf(log_stream(level), "[%s] %s: %s\n", datebuf, log_names[level], buf);
+}
+
+void vl_log(unsigned level, const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ vl_logv(level, fmt, args);
+ va_end(args);
+}