missing project/build files
[client-tools.git] / src / external / 3rd / library / platform / utils / Base / linux / Logger.cpp
blobf305703d58b111a7536cfe40c74aae4a164ed9ab
1 #include "../Logger.h"
2 #include "Mutex.h"
3 #include <sys/stat.h>
5 using namespace std;
7 #ifdef EXTERNAL_DISTRO
8 namespace NAMESPACE
11 #endif
12 namespace Base
15 const char file_sep = '/';
17 Logger::Logger(const char *prefix, int level, unsigned size, bool rollDate)
18 : m_defaultLevel(level), m_defaultSize(size), m_dirPrefix(prefix), m_rollDate(rollDate)
20 char buf[1024];
21 FILE *logDir = NULL;
23 logDir = fopen(m_dirPrefix.c_str(), "r+");
24 if(errno == ENOENT)
26 cmkdir(m_dirPrefix.c_str(), 0755);
28 else if(logDir != NULL)
30 fclose(logDir);
33 tm now;
34 time_t t = time(NULL);
35 localtime_r(&t, &now);
37 memcpy(&m_lastDateTime, &now, sizeof(tm));
38 if(m_rollDate)
40 sprintf(buf, "%s%c%2.2d-%2.2d-%2.2d", m_dirPrefix.c_str(), file_sep, (now.tm_mon + 1), now.tm_mday, (now.tm_year % 100));
42 else
44 sprintf(buf, "%s", m_dirPrefix.c_str());
46 logDir = fopen(buf, "r+");
47 if(errno == ENOENT)
49 cmkdir(buf, 0755);
51 else if(logDir != NULL)
53 fclose(logDir);
55 m_logPrefix = buf;
58 Logger::~Logger()
60 map<unsigned, LogInfo *>::iterator iter;
61 for(iter = m_logTable.begin(); iter != m_logTable.end(); iter++)
63 log((*iter).first, LOG_FILEONLY, "---=== Log Stopped ===---");
64 fflush((*iter).second->file);
65 fclose((*iter).second->file);
66 delete((*iter).second);
69 m_logTable.clear();
72 void Logger::flush(unsigned logenum)
74 map<unsigned, LogInfo *>::iterator iter = m_logTable.find(logenum);
76 if(iter != m_logTable.end())
78 LogInfo *info = (*iter).second;
79 fflush(info->file);
80 info->used = 0;
84 void Logger::flushAll()
86 map<unsigned, LogInfo *>::iterator iter;
88 for(iter = m_logTable.begin(); iter != m_logTable.end(); iter++)
90 LogInfo *info = (*iter).second;
91 fflush(info->file);
92 info->used = 0;
96 void Logger::addLog(const char *id, unsigned logenum, int level, unsigned size)
98 LogInfo *newLog = new LogInfo;
99 newLog->filename = m_logPrefix + file_sep + id + ".log";
100 newLog->name = id;
101 newLog->used = 0;
102 newLog->max = size;
103 newLog->last = 0;
104 newLog->level = level;
106 m_logTable.insert(pair<unsigned, LogInfo *>(logenum, newLog));
108 if(strcmp("stdout", id) == 0)
110 newLog->file = stdout;
112 else if(strcmp("stderr", id) == 0)
114 newLog->file = stderr;
116 else
118 newLog->file = fopen(newLog->filename.c_str(), "a+");
120 log(logenum, LOG_FILEONLY, "---=== Log Started ===---");
123 void Logger::addLog(const char *id, unsigned logenum)
125 LogInfo *newLog = new LogInfo;
126 newLog->filename = m_logPrefix + file_sep + id + ".log";
127 newLog->name = id;
128 newLog->used = 0;
129 newLog->max = m_defaultSize;
130 newLog->last = 0;
131 newLog->level = m_defaultLevel;
133 m_logTable.insert(pair<unsigned, LogInfo *>(logenum, newLog));
135 if(strcmp("stdout", id) == 0)
137 newLog->file = stdout;
139 else if(strcmp("stderr", id) == 0)
141 newLog->file = stderr;
143 else
145 newLog->file = fopen(newLog->filename.c_str(), "a+");
147 log(logenum, LOG_FILEONLY, "---===Log Started ===---");
150 void Logger::updateLog(unsigned logenum, int level, unsigned size)
152 map<unsigned, LogInfo *>::iterator iter = m_logTable.find(logenum);
154 if(iter != m_logTable.end())
156 (*iter).second->level = level;
157 (*iter).second->max = size;
161 void Logger::removeLog(unsigned logenum)
163 map<unsigned, LogInfo *>::iterator iter = m_logTable.find(logenum);
165 if(iter != m_logTable.end())
167 log((*iter).first, LOG_ALWAYS, "---=== Log Stopped ===---");
168 fflush((*iter).second->file);
169 fclose((*iter).second->file);
170 delete((*iter).second);
174 void Logger::logSimple(unsigned logenum, int level, const char *message)
176 map<unsigned, LogInfo *>::iterator iter = m_logTable.find(logenum);
177 if(iter == m_logTable.end())
179 return;
181 time_t t = time(NULL);
182 LogInfo *info = (*iter).second;
183 if(level >= info->level)
185 return;
187 if(level == LOG_FILEONLY && ((info->file == stderr) || (info->file == stdout)))
189 return;
191 if(info->last != t)
193 memcpy(&info->ts, localtime(&t), sizeof(tm));
194 info->last = t;
197 if(m_rollDate && info->ts.tm_mday != m_lastDateTime.tm_mday)
199 #if defined(_REENTRANT)
200 rLock.Lock();
201 #endif
202 if(info->ts.tm_mday != m_lastDateTime.tm_mday)
204 memcpy(&m_lastDateTime, &info->ts, sizeof(tm));
205 rollDate(t);
207 #if defined(_REENTRANT)
208 rLock.Unlock();
209 #endif
211 if(iter != m_logTable.end())
213 if(info->max > 0)
215 int tmp = fprintf(info->file, "[%2.2d/%2.2d/%2.2d %2.2d:%2.2d:%2.2d] %s\n", (info->ts.tm_mon + 1), info->ts.tm_mday, (info->ts.tm_year % 100), info->ts.tm_hour, info->ts.tm_min, info->ts.tm_sec, message);
216 info->used += tmp;
217 if(info->used > info->max)
219 fflush(info->file);
220 info->used = 0;
223 else
225 fprintf(info->file, "[%2.2d/%2.2d/%2.2d %2.2d:%2.2d:%2.2d] %s\n", (info->ts.tm_mon + 1), info->ts.tm_mday, (info->ts.tm_year % 100), info->ts.tm_hour, info->ts.tm_min, info->ts.tm_sec, message);
226 fflush(info->file);
230 void Logger::log(unsigned logenum, int level, const char *message, ...)
232 char buf[2048];
233 va_list varg;
234 va_start(varg, message);
235 vsnprintf(buf, 2047, message, varg);
236 buf[2047] = 0;
237 va_end(varg);
239 map<unsigned, LogInfo *>::iterator iter = m_logTable.find(logenum);
240 if(iter == m_logTable.end())
242 return;
244 time_t t = time(NULL);
245 LogInfo *info = (*iter).second;
246 if(level >= info->level)
248 return;
250 if(level == LOG_FILEONLY && ((info->file == stderr) || (info->file == stdout)))
252 return;
254 if(info->last != t)
256 localtime_r(&t, &info->ts);
257 info->last = t;
259 if(m_rollDate && info->ts.tm_mday != m_lastDateTime.tm_mday)
261 #if defined(_REENTRANT)
262 rLock.Lock();
263 #endif
264 if(info->ts.tm_mday != m_lastDateTime.tm_mday)
266 memcpy(&m_lastDateTime, &info->ts, sizeof(tm));
267 rollDate(t);
269 #if defined(_REENTRANT)
270 rLock.Unlock();
271 #endif
274 if(iter != m_logTable.end())
276 if(info->max > 0)
278 int tmp = fprintf(info->file, "[%2.2d/%2.2d/%2.2d %2.2d:%2.2d:%2.2d] %s\n", (info->ts.tm_mon + 1), info->ts.tm_mday, (info->ts.tm_year % 100), info->ts.tm_hour, info->ts.tm_min, info->ts.tm_sec, buf);
279 info->used += tmp;
280 if(info->used > info->max)
282 fflush(info->file);
283 info->used = 0;
286 else
288 fprintf(info->file, "[%2.2d/%2.2d/%2.2d %2.2d:%2.2d:%2.2d] %s\n", (info->ts.tm_mon + 1), info->ts.tm_mday, (info->ts.tm_year % 100), info->ts.tm_hour, info->ts.tm_min, info->ts.tm_sec, buf);
289 fflush(info->file);
294 void Logger::rollDate(time_t t)
296 char buf[80];
297 FILE *logDir = NULL;
299 logDir = fopen(m_dirPrefix.c_str(), "r+");
300 if(errno == ENOENT)
302 cmkdir(m_dirPrefix.c_str(), 0755);
304 else if(logDir != NULL)
306 fclose(logDir);
309 tm now;
310 localtime_r(&t, &now);
312 sprintf(buf, "%s%c%2.2d-%2.2d-%2.2d", m_dirPrefix.c_str(), file_sep, (now.tm_mon + 1), now.tm_mday, (now.tm_year % 100));
313 logDir = fopen(buf, "r+");
315 if(errno == ENOENT)
317 cmkdir(buf, 0755);
319 else if(logDir != NULL)
321 fclose(logDir);
323 m_logPrefix = buf;
325 map<unsigned, LogInfo *>::iterator iter;
326 for(iter = m_logTable.begin(); iter != m_logTable.end(); iter++)
328 (*iter).second->filename = m_logPrefix + file_sep + (*iter).second->name.c_str() + ".log";
329 fflush((*iter).second->file);
330 fclose((*iter).second->file);
331 (*iter).second->file = fopen((*iter).second->filename.c_str(), "a+");
332 memcpy(&((*iter).second->ts), &now, sizeof(tm));
336 // mkdir function that creates intermediate directories
337 void Logger::cmkdir(const char *dir, int mode)
339 char dirbuf[128];
340 strncpy(dirbuf, dir, 127);
341 dirbuf[127] = 0;
342 char *j = dirbuf, *i = dirbuf;
343 int handle;
345 while(*i)
347 if(*i == file_sep)
349 (*i) = 0;
350 // handle = open(j, O_EXCL); // Ben's original code
351 // if((handle > 0) || (errno != EISDIR && errno != ENOENT))
352 // {
353 // perror("Logger::cmkdir():");
354 // abort();
355 // }
357 // This doesnt work under Linux, it returns a valid handle
358 // Instead: see if file exists. If it doesnt, create directory ok
359 // If it exists, do stat to see if it is a dir.
360 // If it is a dir, then ok, create the directory.
361 // If it is a file, error
362 // ging 9-16-2002
364 handle = open(j, O_RDONLY);
365 if (handle > 0)
367 struct stat stat_buffer;
368 int ret = fstat(handle,&stat_buffer);
369 if ((ret == -1) || ((stat_buffer.st_mode | S_IFDIR) == 0))
371 perror("Logger::cmkdir():");
372 abort();
376 mkdir(j, mode);
377 close(handle);
378 (*i) = file_sep;
380 else if(*(i + 1) == 0)
382 mkdir(j, mode);
384 i++;
387 #ifdef EXTERNAL_DISTRO
389 #endif