00001
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022
00023 #ifdef XAPIAN_DEBUG_LOG
00024
00025 #include "debuglog.h"
00026
00027 #include "str.h"
00028
00029 #include <sys/types.h>
00030 #include <sys/stat.h>
00031 #include "safeerrno.h"
00032 #include "safefcntl.h"
00033 #include "safeunistd.h"
00034
00035 #include <cstdlib>
00036 #include <cstring>
00037 #include <string>
00038
00039 using namespace std;
00040
00041 DebugLogger xapian_debuglogger_;
00042
00043
00044
00045
00046 #ifndef O_SYNC
00047 # define O_SYNC 0
00048 #endif
00049
00050 DebugLogger::~DebugLogger()
00051 {
00052 LOGLINE(ALWAYS, PACKAGE_STRING": debug log ended");
00053 }
00054
00055 void
00056 DebugLogger::initialise_categories_mask()
00057 {
00058 fd = -2;
00059 const char * f = getenv("XAPIAN_DEBUG_LOG");
00060 if (f && *f) {
00061 if (f[0] == '-' && f[1] == '\0') {
00062
00063 fd = 2;
00064 } else {
00065 string fnm, pid;
00066 while (*f) {
00067 if (*f == '%' && f[1] == 'p') {
00068
00069 if (pid.empty()) pid = str(getpid());
00070 fnm += pid;
00071 f += 2;
00072 } else {
00073 fnm += *f++;
00074 }
00075 }
00076
00077 fd = open(fnm.c_str(), O_CREAT|O_WRONLY|O_SYNC|O_APPEND, 0644);
00078 if (fd == -1) {
00079
00080
00081
00082
00083 fd = 2;
00084 LOGLINE(ALWAYS, PACKAGE_STRING": Failed to open debug log '"
00085 << fnm << "' (" << strerror(errno) << ')');
00086 fd = -2;
00087 }
00088 }
00089
00090 if (fd >= 0) {
00091 const char * v = getenv("XAPIAN_DEBUG_FLAGS");
00092 if (v) {
00093 bool toggle = (*v == '-');
00094 if (toggle) ++v;
00095 categories_mask = 0;
00096 while (*v) {
00097 int ch = *v++ - '@';
00098 if (ch > 0 && ch <= 26) categories_mask |= 1ul << ch;
00099 }
00100 if (toggle) categories_mask ^= 0xffffffff;
00101 }
00102 }
00103 }
00104 LOGLINE(ALWAYS, PACKAGE_STRING": debug log started");
00105 }
00106
00107 void
00108 DebugLogger::log_line(debuglog_categories category, const string & msg)
00109 {
00110 if (fd < 0) return;
00111
00112 string line;
00113 line.reserve(9 + indent_level + msg.size());
00114 line = char(category) + '@';
00115 line += ' ';
00116 line += str(getpid());
00117 line.append(indent_level + 1, ' ');
00118 line += msg;
00119 line += '\n';
00120
00121 const char * p = line.data();
00122 size_t to_do = line.size();
00123 while (to_do) {
00124 ssize_t n = write(fd, p, to_do);
00125 if (n < 0) {
00126
00127 if (errno == EINTR) continue;
00128
00129
00130
00131 (void)close(fd);
00132 fd = 2;
00133 LOGLINE(ALWAYS, PACKAGE_STRING": Failed to write log output ("
00134 << strerror(errno) << ')');
00135 fd = -2;
00136 return;
00137 }
00138 p += n;
00139 to_do -= n;
00140 }
00141 }
00142
00143 #endif // XAPIAN_DEBUG_LOG