-
Notifications
You must be signed in to change notification settings - Fork 0
/
log.c
111 lines (96 loc) · 2.85 KB
/
log.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
* Copyright (c) 2017 rxi
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* Source code: https://github.com/rxi/log.c
*/
/*
* Modified by Yehor Smoliakov <yehors@ukr.net>
*
* Changes:
* removed color output, added milliseconds to time, added bool type,
* added typed enum for log levels, removed __FILE__ and __LINE__ definitions
* and some code style improvements
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <stdbool.h>
#include "log.h"
static struct {
void *data;
lock_fn lock;
log_level_t level;
bool quiet;
} L;
static const char *level_names[] = {
"TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"
};
static void lock(void) {
if (L.lock) {
L.lock(L.data, 1);
}
}
static void unlock(void) {
if (L.lock) {
L.lock(L.data, 0);
}
}
void log_set_level(log_level_t level) {
L.level = level;
}
void log_set_quiet(bool enable) {
L.quiet = enable ? true : false;
}
void log_log(log_level_t level, const char *fmt, ...) {
if (level < L.level) {
return;
}
/* Acquire lock */
lock();
/* Log */
if (!L.quiet) {
/* Get current time */
struct tm lt;
struct timeval tv;
size_t n, bs;
char buf[25];
gettimeofday(&tv, NULL);
localtime_r(&tv.tv_sec, <);
bs = sizeof(buf);
n = strftime(buf, bs, "%F %T", <);
if (bs > n) {
snprintf(&buf[n], bs - n, ".%04ld", tv.tv_usec);
}
buf[bs - 1] = '\0';
va_list args;
fprintf(stdout, "%s %-5s %s ", buf, level_names[level], __MODULE__);
va_start(args, fmt);
vfprintf(stdout, fmt, args);
va_end(args);
fprintf(stdout, "\n");
fflush(stdout);
}
/* Release lock */
unlock();
}