]> git.sur5r.net Git - i3/i3/blob - src/log.c
Merge branch 'next'
[i3/i3] / src / log.c
1 /*
2  * vim:ts=4:sw=4:expandtab
3  *
4  * i3 - an improved dynamic tiling window manager
5  * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE)
6  *
7  * log.c: Setting of loglevels, logging functions.
8  *
9  */
10 #include <stdarg.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <stdbool.h>
14 #include <stdlib.h>
15 #include <sys/time.h>
16 #include <unistd.h>
17 #include <fcntl.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 = false;
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     if (fcntl(fileno(errorfile), F_SETFD, FD_CLOEXEC)) {
44         ELOG("Could not set close-on-exec flag\n");
45     }
46 }
47
48 /*
49  * Set verbosity of i3. If verbose is set to true, informative messages will
50  * be printed to stdout. If verbose is set to false, only errors will be
51  * printed.
52  *
53  */
54 void set_verbosity(bool _verbose) {
55     verbose = _verbose;
56 }
57
58 /*
59  * Enables the given loglevel.
60  *
61  */
62 void add_loglevel(const char *level) {
63     /* Handle the special loglevel "all" */
64     if (strcasecmp(level, "all") == 0) {
65         loglevel = UINT64_MAX;
66         return;
67     }
68
69     for (int i = 0; i < sizeof(loglevels) / sizeof(char*); i++) {
70         if (strcasecmp(loglevels[i], level) != 0)
71             continue;
72
73         /* The position in the array (plus one) is the amount of times
74          * which we need to shift 1 to the left to get our bitmask for
75          * the specific loglevel. */
76         loglevel |= (1 << (i+1));
77         break;
78     }
79 }
80
81 /*
82  * Logs the given message to stdout while prefixing the current time to it.
83  * This is to be called by *LOG() which includes filename/linenumber/function.
84  *
85  */
86 void vlog(char *fmt, va_list args) {
87     static char timebuf[64];
88     static struct tm result;
89
90     /* Get current time */
91     time_t t = time(NULL);
92     /* Convert time to local time (determined by the locale) */
93     struct tm *tmp = localtime_r(&t, &result);
94     /* Generate time prefix */
95     strftime(timebuf, sizeof(timebuf), "%x %X - ", tmp);
96 #ifdef DEBUG_TIMING
97     struct timeval tv;
98     gettimeofday(&tv, NULL);
99     printf("%s%d.%d - ", timebuf, tv.tv_sec, tv.tv_usec);
100 #else
101     printf("%s", timebuf);
102 #endif
103     vprintf(fmt, args);
104 }
105
106 /*
107  * Logs the given message to stdout while prefixing the current time to it,
108  * but only if verbose mode is activated.
109  *
110  */
111 void verboselog(char *fmt, ...) {
112     va_list args;
113
114     if (!verbose)
115         return;
116
117     va_start(args, fmt);
118     vlog(fmt, args);
119     va_end(args);
120 }
121
122 /*
123  * Logs the given message to stdout while prefixing the current time to it.
124  *
125  */
126 void errorlog(char *fmt, ...) {
127     va_list args;
128
129     va_start(args, fmt);
130     vlog(fmt, args);
131     va_end(args);
132
133     /* also log to the error logfile, if opened */
134     va_start(args, fmt);
135     vfprintf(errorfile, fmt, args);
136     fflush(errorfile);
137     va_end(args);
138 }
139
140 /*
141  * Logs the given message to stdout while prefixing the current time to it,
142  * but only if the corresponding debug loglevel was activated.
143  * This is to be called by DLOG() which includes filename/linenumber
144  *
145  */
146 void debuglog(uint64_t lev, char *fmt, ...) {
147     va_list args;
148
149     if ((loglevel & lev) == 0)
150         return;
151
152     va_start(args, fmt);
153     vlog(fmt, args);
154     va_end(args);
155 }