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

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