i3
|
00001 /* 00002 * vim:ts=4:sw=4:expandtab 00003 * 00004 * i3 - an improved dynamic tiling window manager 00005 * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE) 00006 * 00007 * log.c: Setting of loglevels, logging functions. 00008 * 00009 */ 00010 #include <stdarg.h> 00011 #include <stdio.h> 00012 #include <string.h> 00013 #include <stdbool.h> 00014 #include <stdlib.h> 00015 #include <sys/time.h> 00016 #include <unistd.h> 00017 #include <fcntl.h> 00018 00019 #include "util.h" 00020 #include "log.h" 00021 00022 /* loglevels.h is autogenerated at make time */ 00023 #include "loglevels.h" 00024 00025 static uint64_t loglevel = 0; 00026 static bool verbose = false; 00027 static FILE *errorfile; 00028 char *errorfilename; 00029 00030 /* 00031 * Initializes logging by creating an error logfile in /tmp (or 00032 * XDG_RUNTIME_DIR, see get_process_filename()). 00033 * 00034 */ 00035 void init_logging() { 00036 errorfilename = get_process_filename("errorlog"); 00037 if (errorfilename == NULL) { 00038 ELOG("Could not initialize errorlog\n"); 00039 return; 00040 } 00041 00042 errorfile = fopen(errorfilename, "w"); 00043 if (fcntl(fileno(errorfile), F_SETFD, FD_CLOEXEC)) { 00044 ELOG("Could not set close-on-exec flag\n"); 00045 } 00046 } 00047 00048 /* 00049 * Set verbosity of i3. If verbose is set to true, informative messages will 00050 * be printed to stdout. If verbose is set to false, only errors will be 00051 * printed. 00052 * 00053 */ 00054 void set_verbosity(bool _verbose) { 00055 verbose = _verbose; 00056 } 00057 00058 /* 00059 * Enables the given loglevel. 00060 * 00061 */ 00062 void add_loglevel(const char *level) { 00063 /* Handle the special loglevel "all" */ 00064 if (strcasecmp(level, "all") == 0) { 00065 loglevel = UINT64_MAX; 00066 return; 00067 } 00068 00069 for (int i = 0; i < sizeof(loglevels) / sizeof(char*); i++) { 00070 if (strcasecmp(loglevels[i], level) != 0) 00071 continue; 00072 00073 /* The position in the array (plus one) is the amount of times 00074 * which we need to shift 1 to the left to get our bitmask for 00075 * the specific loglevel. */ 00076 loglevel |= (1 << (i+1)); 00077 break; 00078 } 00079 } 00080 00081 /* 00082 * Logs the given message to stdout while prefixing the current time to it. 00083 * This is to be called by *LOG() which includes filename/linenumber/function. 00084 * 00085 */ 00086 void vlog(char *fmt, va_list args) { 00087 static char timebuf[64]; 00088 static struct tm result; 00089 00090 /* Get current time */ 00091 time_t t = time(NULL); 00092 /* Convert time to local time (determined by the locale) */ 00093 struct tm *tmp = localtime_r(&t, &result); 00094 /* Generate time prefix */ 00095 strftime(timebuf, sizeof(timebuf), "%x %X - ", tmp); 00096 #ifdef DEBUG_TIMING 00097 struct timeval tv; 00098 gettimeofday(&tv, NULL); 00099 printf("%s%d.%d - ", timebuf, tv.tv_sec, tv.tv_usec); 00100 #else 00101 printf("%s", timebuf); 00102 #endif 00103 vprintf(fmt, args); 00104 } 00105 00106 /* 00107 * Logs the given message to stdout while prefixing the current time to it, 00108 * but only if verbose mode is activated. 00109 * 00110 */ 00111 void verboselog(char *fmt, ...) { 00112 va_list args; 00113 00114 if (!verbose) 00115 return; 00116 00117 va_start(args, fmt); 00118 vlog(fmt, args); 00119 va_end(args); 00120 } 00121 00122 /* 00123 * Logs the given message to stdout while prefixing the current time to it. 00124 * 00125 */ 00126 void errorlog(char *fmt, ...) { 00127 va_list args; 00128 00129 va_start(args, fmt); 00130 vlog(fmt, args); 00131 va_end(args); 00132 00133 /* also log to the error logfile, if opened */ 00134 va_start(args, fmt); 00135 vfprintf(errorfile, fmt, args); 00136 fflush(errorfile); 00137 va_end(args); 00138 } 00139 00140 /* 00141 * Logs the given message to stdout while prefixing the current time to it, 00142 * but only if the corresponding debug loglevel was activated. 00143 * This is to be called by DLOG() which includes filename/linenumber 00144 * 00145 */ 00146 void debuglog(uint64_t lev, char *fmt, ...) { 00147 va_list args; 00148 00149 if ((loglevel & lev) == 0) 00150 return; 00151 00152 va_start(args, fmt); 00153 vlog(fmt, args); 00154 va_end(args); 00155 }