Go nuts with Qt
[ipdf/code.git] / src / log.cpp
1 /**
2  * @file log.cpp
3  * @brief Implement logging and error handling functions
4  */
5
6
7 // --- Custom headers --- //
8 #include "common.h"
9
10 #include <cstdio>
11 #include <unistd.h>
12 #include <stdarg.h>
13 #include <execinfo.h>
14
15 #ifdef LOG_SYSLOG
16
17 static void InitSyslog()
18 {
19         static bool init = false;
20         if (!init)
21         {
22                 openlog(Options::program_name, LOG_PERROR | LOG_PID, LOG_USER);
23                 init = true;
24         }
25 }
26
27 #endif //LOG_SYSLOG
28
29 static const char * unspecified_funct = "???";
30
31
32
33 /**
34  * Print a message to stderr and log it via syslog. The message must be
35  * less than BUFSIZ characters long, or it will be truncated.
36  * @param level - Specify how severe the message is.
37         If level is higher (less urgent) than the program's verbosity (see options.h) no message will be printed
38  * @param funct - String indicating the function name from which this function was called.
39         If this is NULL, Log will show the unspecified_funct string instead
40  * @param file - Source file containing the function
41  * @param line - Line in the source file at which Log is called
42  * @param fmt - A format string
43  * @param ... - Arguments to be printed according to the format string
44  */
45 void LogEx(int level, const char * funct, const char * file, int line, ...)
46 {
47         //Todo: consider setlogmask(3) to filter messages
48         const char *fmt;
49         char buffer[BUFSIZ];
50         va_list va;
51
52         // Don't print the message unless we need to
53         //if (level > Globals::Verbosity())
54         //      return;
55
56         va_start(va, line);
57         fmt = va_arg(va, const char*);
58         
59         if (fmt == NULL) // sanity check
60                 Fatal("Format string is NULL");
61
62         vsnprintf(buffer, BUFSIZ, fmt, va);
63         va_end(va);
64
65         if (funct == NULL)
66                 funct = unspecified_funct;
67
68         // Make a human readable severity string
69         const char *severity;
70         switch (level)
71         {
72                 case LOG_ERR:
73                         severity = "ERROR";
74                         break;
75                 case LOG_WARNING:
76                         severity = "WARNING";
77                         break;
78                 case LOG_NOTICE:
79                         severity = "notice";
80                         break;
81                 case LOG_INFO:
82                         severity = "info";
83                         break;
84                 default:
85                         severity = "debug";
86                         break;
87         }
88
89         #ifdef LOG_SYSLOG
90                 InitSyslog();
91                 syslog(level, "%s: %s (%s:%d) - %s", severity, funct, file, line, buffer);
92         #else
93                 //fprintf(stderr, "%s[%d]: %s: %s (%s:%d) - %s\n", Options::program_name, getpid(), severity, funct, file, line, buffer);
94                 fprintf(stderr, "%s: %s (%s:%d) - %s\n", severity, funct, file, line, buffer);
95         #endif //LOG_SYSLOG
96         
97 }
98
99 /**
100  * Handle a Fatal error in the program by printing a message and exiting the program
101  *      CALLING THIS FUNCTION WILL CAUSE THE PROGAM TO EXIT
102  * @param funct - Name of the calling function
103  * @param file - Name of the source file containing the calling function
104  * @param line - Line in the source file at which Fatal is called
105  * @param fmt - A format string
106  * @param ... - Arguments to be printed according to the format string
107  */
108 void FatalEx(const char * funct, const char * file, int line, ...)
109 {
110         const char *fmt;
111         char buffer[BUFSIZ];
112         va_list va;
113         va_start(va, line);
114         fmt = va_arg(va, const char*);
115         
116         if (fmt == NULL)
117         {
118                 // Fatal error in the Fatal function.
119                 // (This really shouldn't happen unless someone does something insanely stupid)
120                 Fatal("Format string is NULL");
121                 return; // Should never get here
122         }
123
124         vsnprintf(buffer, BUFSIZ, fmt,va);
125         va_end(va);
126
127         if (funct == NULL)
128                 funct = unspecified_funct;
129
130         #ifdef LOG_SYSLOG
131                 InitSyslog();
132                 syslog(LOG_CRIT, "FATAL: %s (%s:%d) - %s", funct, file, line, buffer);
133         #else
134                 //fprintf(stderr, "%s[%d]: FATAL: %s (%s:%d) - %s\n", Options::program_name, getpid(), funct, file, line, buffer);
135                 fprintf(stderr, "FATAL: %s (%s:%d) - %s\n", funct, file, line, buffer);
136
137         #endif //LOG_SYSLOG
138
139         exit(EXIT_FAILURE);
140 }
141
142
143 /**
144  * Print a backtrace
145  */
146 void Backtrace(int size)
147 {
148         void * buffer[100];
149         int actual_size = backtrace(buffer, size);
150         backtrace_symbols_fd(buffer, actual_size, fileno(stderr));
151 }
152

UCC git Repository :: git.ucc.asn.au