1#define _POSIX_C_SOURCE 200809L
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <time.h>
6#include <stdarg.h>
7#include <unistd.h>
8#include <sys/time.h>
9
10#include "glitch.h"
11
12static LogLevel max_level = LOG_INFO;
13
14static const char* level_strings[] = {
15 "ERROR",
16 "WARN",
17 "INFO",
18 "DEBUG",
19};
20
21static const char* level_colors[] = {
22 COLOR_ERROR,
23 COLOR_WARNING,
24 COLOR_INFO,
25 COLOR_DEBUG,
26};
27
28void set_log_level(LogLevel level) {
29 max_level = level;
30}
31
32LogLevel get_log_level_from_env(void) {
33 const char *env = getenv("LOG_LEVEL");
34 if (env) {
35 int level = atoi(env);
36 if (level >= 0 && level <= 3) {
37 return (LogLevel)level;
38 }
39 }
40
41 return max_level;
42}
43
44void log_message(FILE *stream, LogLevel level, const char* format, ...) {
45 if (max_level < level) return;
46
47 struct timeval tv;
48 gettimeofday(&tv, NULL);
49 struct tm* tm_info = localtime(&tv.tv_sec);
50
51 char time_str[24];
52 strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", tm_info);
53
54 const char *color = isatty(fileno(stream)) ? level_colors[level] : "";
55 const char *reset = isatty(fileno(stream)) ? COLOR_RESET : "";
56
57 const char* log_format = "%s[%s.%03d] [%-5s] ";
58 fprintf(stream, log_format,
59 color,
60 time_str,
61 (int)(tv.tv_usec / 1000),
62 level_strings[level]);
63
64 va_list args;
65 va_start(args, format);
66 vfprintf(stream, format, args);
67 va_end(args);
68
69 fprintf(stream, "%s\n", reset);
70 fflush(stream);
71}