]> git.sur5r.net Git - i3/i3/blob - src/log.c
99c2d4d3d2a5fe1218068e93e54b931bcafc174c
[i3/i3] / src / log.c
1 /*
2  * vim:ts=4:sw=4:expandtab
3  *
4  * i3 - an improved dynamic tiling window manager
5  *
6  * © 2009-2010 Michael Stapelberg and contributors
7  *
8  * See file LICENSE for license information.
9  *
10  * src/log.c: handles the setting of loglevels, contains the logging functions.
11  *
12  */
13 #include <stdarg.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include <stdbool.h>
17 #include <stdlib.h>
18
19 #include "util.h"
20 #include "log.h"
21
22 /* loglevels.h is autogenerated at make time */
23 #include "loglevels.h"
24
25 static uint64_t loglevel = 0;
26 static bool verbose = true;
27 static FILE *errorfile;
28 char *errorfilename;
29
30 /*
31  * Initializes logging by creating an error logfile in /tmp (or
32  * XDG_RUNTIME_DIR, see get_process_filename()).
33  *
34  */
35 void init_logging() {
36     errorfilename = get_process_filename("errorlog");
37     if (errorfilename == NULL) {
38         ELOG("Could not initialize errorlog\n");
39         return;
40     }
41
42     errorfile = fopen(errorfilename, "w");
43 }
44
45 /*
46  * Set verbosity of i3. If verbose is set to true, informative messages will
47  * be printed to stdout. If verbose is set to false, only errors will be
48  * printed.
49  *
50  */
51 void set_verbosity(bool _verbose) {
52     verbose = _verbose;
53 }
54
55 /*
56  * Enables the given loglevel.
57  *
58  */
59 void add_loglevel(const char *level) {
60     /* Handle the special loglevel "all" */
61     if (strcasecmp(level, "all") == 0) {
62         loglevel = UINT64_MAX;
63         return;
64     }
65
66     for (int i = 0; i < sizeof(loglevels) / sizeof(char*); i++) {
67         if (strcasecmp(loglevels[i], level) != 0)
68             continue;
69
70         /* The position in the array (plus one) is the amount of times
71          * which we need to shift 1 to the left to get our bitmask for
72          * the specific loglevel. */
73         loglevel |= (1 << (i+1));
74         break;
75     }
76 }
77
78 /*
79  * Logs the given message to stdout while prefixing the current time to it.
80  * This is to be called by *LOG() which includes filename/linenumber/function.
81  *
82  */
83 void vlog(char *fmt, va_list args) {
84     char timebuf[64];
85
86     /* Get current time */
87     time_t t = time(NULL);
88     /* Convert time to local time (determined by the locale) */
89     struct tm *tmp = localtime(&t);
90     /* Generate time prefix */
91     strftime(timebuf, sizeof(timebuf), "%x %X - ", tmp);
92     printf("%s", timebuf);
93     vprintf(fmt, args);
94 }
95
96 /*
97  * Logs the given message to stdout while prefixing the current time to it,
98  * but only if verbose mode is activated.
99  *
100  */
101 void verboselog(char *fmt, ...) {
102     va_list args;
103
104     if (!verbose)
105         return;
106
107     va_start(args, fmt);
108     vlog(fmt, args);
109     va_end(args);
110 }
111
112 /*
113  * Logs the given message to stdout while prefixing the current time to it.
114  *
115  */
116 void errorlog(char *fmt, ...) {
117     va_list args;
118
119     va_start(args, fmt);
120     vlog(fmt, args);
121     va_end(args);
122
123     /* also log to the error logfile, if opened */
124     va_start(args, fmt);
125     vfprintf(errorfile, fmt, args);
126     fflush(errorfile);
127     va_end(args);
128 }
129
130 /*
131  * Logs the given message to stdout while prefixing the current time to it,
132  * but only if the corresponding debug loglevel was activated.
133  * This is to be called by DLOG() which includes filename/linenumber
134  *
135  */
136 void debuglog(uint64_t lev, char *fmt, ...) {
137     va_list args;
138
139     if ((loglevel & lev) == 0)
140         return;
141
142     va_start(args, fmt);
143     vlog(fmt, args);
144     va_end(args);
145 }