54 LoggerEntry(
const char* fname,
const char* funcname,
unsigned line,
int lvl) :
74 typedef std::list<LoggerEntry*>
flist;
91 flist::iterator iter =
fFiles.begin();
92 while (iter !=
fFiles.end()) {
93 if ((*iter)->fFileName.compare(filename)==0)
return *iter;
153 for (
unsigned n=0; n<fMaxLine; n++)
154 if (fLines[n]) {
delete fLines[n]; }
158 delete fMutex; fMutex = 0;
165 if (fFile) fclose(fFile);
173 fLevel = fDebugLevel < fFileLevel ? fFileLevel : fDebugLevel;
179 fLevel = fDebugLevel < fFileLevel ? fFileLevel : fDebugLevel;
184 fSyslogLevel = level;
190 if ((max>0) && (max<fMaxLine))
return;
200 while (n < fMaxLine) { lin[n] = fLines[n]; n++; }
201 while (n < max) { lin[n] = 0; n++; }
204 if (fLines)
delete[] fLines;
214 if (fFile) fclose(fFile);
218 if ((fname!=0) && (strlen(fname)>0)) {
219 fLogFileName = fname;
220 fFile = fopen(fname,
"a");
222 fLogFileModified =
false;
230 fSyslogPrefix = prefix ? prefix :
"";
239 if ((mask & lPrefix) && ((mask & lNoPrefix) == 0))
240 if (fPrefix.length() > 0) {
246 if (str.length() > 0) str+=
" ";
253 if (mask & lSyslgLvl) {
254 if (str.length() > 0) str+=
" ";
261 if (mask & (lDate | lTime)) {
263 struct tm * inf = localtime_r ( &(entry->
fMsgTime), &tm_res );
265 if (str.length() > 0) str+=
" ";
266 str +=
dabc::format(
"%d-%02d-%d", inf->tm_mday, inf->tm_mon, inf->tm_year + 1900);
270 if (str.length() > 0) str+=
" ";
271 str +=
dabc::format(
"%02d:%02d:%02d", inf->tm_hour, inf->tm_min, inf->tm_sec);
275 if ((mask & lTStamp) && !(mask & lSyslgLvl)) {
277 if (str.length() > 0) str+=
" ";
282 if (str.length() > 0) str+=
" ";
288 if (str.length() > 0) str+=
":";
294 if (str.length() > 0) str+=
":";
298 if (mask & lMessage) {
299 if (str.length() > 0) str+=
" ";
303 if ((mask & lNoDrop) == 0)
308 void dabc::Logger::DoOutput(
int level,
const char* filename,
unsigned linenumber,
const char* funcname,
const char* message)
312 std::string syslogout;
318 if (linenumber>=fMaxLine)
319 _ExtendLines((linenumber/1024 + 1) * 1024);
325 fLines[linenumber] = lentry;
331 unsigned mask = level>=0 ? fDebugMask : fErrorMask;
332 unsigned fmask = mask | (fFile ? fFileMask : 0);
333 bool drop_msg = (entry->
fCounter > fLogLimit) &&
334 ((now - entry->
fLastTm) < 0.5);
338 if (drop_msg && ((mask & lNoDrop) == 0) && ((fmask & lNoDrop) == 0))
return;
343 if ((!drop_msg || (mask & lNoDrop)) && (level<=fDebugLevel)) {
345 _FillString(str, mask, entry);
347 if (str.length() > 0) {
348 FILE* out = level < 0 ? stderr : stdout;
349 fprintf(out,
"%s\n", str.c_str());
354 if (!fSyslogPrefix.empty() && (!drop_msg || (mask & lNoDrop)) && (level<=fSyslogLevel)) {
355 _FillString(syslogout, mask | lSyslgLvl, entry);
358 if (fFile && (!drop_msg || (fmask & lNoDrop)) && (level<=fFileLevel)) {
360 _FillString(str, fmask, entry);
361 if (str.length()>0) {
362 fprintf(fFile,
"%s\n", str.c_str());
364 fLogFileModified =
true;
376 if (!syslogout.empty()) {
377 openlog(fSyslogPrefix.c_str(), LOG_ODELAY, LOG_LOCAL1);
378 syslog(level < 0 ? LOG_ERR : LOG_INFO,
"%s", syslogout.c_str());
386 if (fLogReopenDisabled || (fFile==0) || fLogFileName.empty() || !fLogFileModified)
return;
390 if ((now - fLogReopenTime) > 3.) {
391 fLogReopenTime = now;
393 fFile = fopen(fLogFileName.c_str(),
"a");
394 fLogFileModified =
false;
400 if ((Instance()==0) || Instance()->fLogReopenDisabled)
return;
402 Instance()->_DoCheckTimeout();
407 if (Instance()) Instance()->fLogReopenDisabled =
true;
414 FILE* out = tofile ? fFile : stdout;
415 if (out==0) out = stdout;
417 fprintf(out,
"\n======= Begin debug statistic =============\n");
419 for (
unsigned n=0; n<fMaxLine;n++) {
421 if (entry==0)
continue;
423 LoggerLineEntry::flist::iterator iter = entry->
fFiles.begin();
425 while (iter != entry->
fFiles.end()) {
426 (*iter)->fShown =
false;
431 std::string* currfile = 0;
437 for (
unsigned n=0; n<fMaxLine;n++) {
439 if (entry==0)
continue;
441 LoggerLineEntry::flist::iterator iter = entry->
fFiles.begin();
443 while (iter != entry->
fFiles.end()) {
446 if (fentry->
fShown)
continue;
448 if ((currfile!=0) && (fentry->
fFileName.compare(*currfile) != 0))
continue;
452 fprintf(out,
"\nFile: %s\n", currfile->c_str());
455 fprintf(out,
" Line:%4u Lvl:%2d Cnt:%4u Func:%s Msg:'%s'\n",
461 }
while (currfile != 0);
463 fprintf(out,
"\n======= Stop debug statistic =============\n");
Lock guard for posix mutex.
LoggerEntry(const char *fname, const char *funcname, unsigned line, int lvl)
LoggerLineEntry(unsigned line)
std::list< LoggerEntry * > flist
LoggerEntry * GetFile(const char *filename, const char *funcname, int lvl)
void SetFileLevel(int level=0)
LoggerLineEntry ** fLines
virtual void Syslog(const char *prefix)
void CloseFile()
Close any file open by logger.
virtual void LogFile(const char *fname)
void SetPrefix(const char *prefix=0)
Logger(bool withmutex=true)
void SetSyslogLevel(int level=0)
std::string fSyslogPrefix
static Logger * Instance()
static void DisableLogReopen()
void ShowStat(bool tofile=true)
virtual void _DoCheckTimeout()
void _ExtendLines(unsigned max)
void SetDebugLevel(int level=0)
virtual void DoOutput(int level, const char *filename, unsigned linenumber, const char *funcname, const char *message)
static void CheckTimeout()
void _FillString(std::string &str, unsigned mask, LoggerEntry *entry)
void SetDebugLevel(int level=0)
std::string format(const char *fmt,...)
void SetDebugPrefix(const char *prefix=0)
void SetFileLevel(int level=0)
Class for acquiring and holding timestamps.
double AsDouble() const
Return time stamp in form of double (in seconds)