const char *IDisplayer::HeaderString () { static char header[1024]; smprintf(header, 1024, "\nLog Starting [%s]\n", dateToHumanString()); return header; }
const char *IDisplayer::dateToHumanString () { time_t date; time (&date); return dateToHumanString (date); }
// Log format: "2000/01/15 12:05:30 <ProcessName> <LogType> <ThreadId> <FileName> <Line> : <Msg>" void CFileDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *message ) { bool needSpace = false; //stringstream ss; string str; // if the filename is not set, don't log if (_FileName.empty()) return; if (args.Date != 0 && !_Raw) { str += dateToHumanString(args.Date); needSpace = true; } if (args.LogType != CLog::LOG_NO && !_Raw) { if (needSpace) { str += " "; needSpace = false; } str += logTypeToString(args.LogType); needSpace = true; } // Write thread identifier if ( args.ThreadId != 0 && !_Raw) { if (needSpace) { str += " "; needSpace = false; } #ifdef NL_OS_WINDOWS str += NLMISC::toString("%4x", args.ThreadId); #else str += NLMISC::toString("%4u", args.ThreadId); #endif needSpace = true; } if (!args.ProcessName.empty() && !_Raw) { if (needSpace) { str += " "; needSpace = false; } str += args.ProcessName; needSpace = true; } if (args.FileName != NULL && !_Raw) { if (needSpace) { str += " "; needSpace = false; } str += CFile::getFilename(args.FileName); needSpace = true; } if (args.Line != -1 && !_Raw) { if (needSpace) { str += " "; needSpace = false; } str += NLMISC::toString(args.Line); needSpace = true; } if (args.FuncName != NULL && !_Raw) { if (needSpace) { str += " "; needSpace = false; } str += args.FuncName; needSpace = true; } if (needSpace) { str += " : "; needSpace = false; } str += message; if (_FilePointer > (FILE*)1) { // if the file is too big (>5mb), rename it and create another one (check only after 20 lines to speed up) if (_LastLogSizeChecked++ > 20) { int res = ftell (_FilePointer); if (res > 5*1024*1024) { fclose (_FilePointer); rename (_FileName.c_str(), CFile::findNewFile (_FileName).c_str()); _FilePointer = (FILE*) 1; _LastLogSizeChecked = 0; } } } if (_FilePointer == (FILE*)1) { _FilePointer = fopen (_FileName.c_str(), "at"); if (_FilePointer == NULL) printf ("Can't open log file '%s': %s\n", _FileName.c_str(), strerror (errno)); } if (_FilePointer != 0) { if (_NeedHeader) { const char *hs = HeaderString(); fwrite (hs, strlen (hs), 1, _FilePointer); _NeedHeader = false; } if(!str.empty()) fwrite (str.c_str(), str.size(), 1, _FilePointer); if(!args.CallstackAndLog.empty()) fwrite (args.CallstackAndLog.c_str(), args.CallstackAndLog.size (), 1, _FilePointer); fflush (_FilePointer); } }
// Log format in clipboard: "2000/01/15 12:05:30 <LogType> <ProcessName> <FileName> <Line>: <Msg>" // Log format on the screen: in debug "<ProcessName> <FileName> <Line>: <Msg>" // in release "<Msg>" void CMsgBoxDisplayer::doDisplay ( const CLog::TDisplayInfo& args, const char *message) { #ifdef NL_OS_WINDOWS bool needSpace = false; // stringstream ss; string str; // create the string for the clipboard if (args.Date != 0) { str += dateToHumanString(args.Date); needSpace = true; } if (args.LogType != CLog::LOG_NO) { //if (needSpace) { ss << " "; needSpace = false; } if (needSpace) { str += " "; needSpace = false; } str += logTypeToString(args.LogType); needSpace = true; } if (!args.ProcessName.empty()) { //if (needSpace) { ss << " "; needSpace = false; } if (needSpace) { str += " "; needSpace = false; } str += args.ProcessName; needSpace = true; } if (args.FileName != NULL) { //if (needSpace) { ss << " "; needSpace = false; } if (needSpace) { str += " "; needSpace = false; } str += CFile::getFilename(args.FileName); needSpace = true; } if (args.Line != -1) { //if (needSpace) { ss << " "; needSpace = false; } if (needSpace) { str += " "; needSpace = false; } str += NLMISC::toString(args.Line); needSpace = true; } if (args.FuncName != NULL) { //if (needSpace) { ss << " "; needSpace = false; } if (needSpace) { str += " "; needSpace = false; } str += args.FuncName; needSpace = true; } if (needSpace) { str += ": "; needSpace = false; } str += message; CSystemUtils::copyTextToClipboard(str); // create the string on the screen needSpace = false; // stringstream ss2; string str2; #ifdef NL_DEBUG if (!args.ProcessName.empty()) { if (needSpace) { str2 += " "; needSpace = false; } str2 += args.ProcessName; needSpace = true; } if (args.FileName != NULL) { if (needSpace) { str2 += " "; needSpace = false; } str2 += CFile::getFilename(args.FileName); needSpace = true; } if (args.Line != -1) { if (needSpace) { str2 += " "; needSpace = false; } str2 += NLMISC::toString(args.Line); needSpace = true; } if (args.FuncName != NULL) { if (needSpace) { str2 += " "; needSpace = false; } str2 += args.FuncName; needSpace = true; } if (needSpace) { str2 += ": "; needSpace = false; } #endif // NL_DEBUG str2 += message; str2 += "\n\n(this message was copied in the clipboard)"; /* if (IsDebuggerPresent ()) { // Must break in assert call DebugNeedAssert = true; } else */ { // Display the report string body; body += toString(LogTypeToString[2][args.LogType]) + "\n"; body += "ProcName: " + args.ProcessName + "\n"; body += "Date: " + string(dateToHumanString(args.Date)) + "\n"; if(args.FileName == NULL) body += "File: <Unknown>\n"; else body += "File: " + string(args.FileName) + "\n"; body += "Line: " + toString(args.Line) + "\n"; if (args.FuncName == NULL) body += "FuncName: <Unknown>\n"; else body += "FuncName: " + string(args.FuncName) + "\n"; body += "Reason: " + toString(message); body += args.CallstackAndLog; string subject; // procname is host/service_name-sid we only want the service_name to avoid redondant mail string procname; string::size_type pos = args.ProcessName.find ("/"); if (pos == string::npos) { procname = args.ProcessName; } else { string::size_type pos2 = args.ProcessName.find ("-", pos+1); if (pos2 == string::npos) { procname = args.ProcessName.substr (pos+1); } else { procname = args.ProcessName.substr (pos+1, pos2-pos-1); } } subject += procname + " NeL " + toString(LogTypeToString[0][args.LogType]) + " " + (args.FileName?string(args.FileName):"") + " " + toString(args.Line) + " " + (args.FuncName?string(args.FuncName):""); // Check the envvar NEL_IGNORE_ASSERT if (getenv ("NEL_IGNORE_ASSERT") == NULL) { // yoyo: allow only to send the crash report once. Because users usually click ignore, // which create noise into list of bugs (once a player crash, it will surely continues to do it). std::string filename = getLogDirectory() + NL_CRASH_DUMP_FILE; if (ReportDebug == report (args.ProcessName + " NeL " + toString(logTypeToString(args.LogType, true)), "", subject, body, true, 2, true, 1, !isCrashAlreadyReported(), IgnoreNextTime, filename.c_str())) { INelContext::getInstance().setDebugNeedAssert(true); } // no more sent mail for crash setCrashAlreadyReported(true); } /* // Check the envvar NEL_IGNORE_ASSERT if (getenv ("NEL_IGNORE_ASSERT") == NULL) { // Ask the user to continue, debug or ignore int result = MessageBox (NULL, ss2.str().c_str (), logTypeToString(args.LogType, true), MB_ABORTRETRYIGNORE | MB_ICONSTOP); if (result == IDABORT) { // Exit the program now exit (EXIT_FAILURE); } else if (result == IDRETRY) { // Give the debugger a try DebugNeedAssert = true; } else if (result == IDIGNORE) { // Continue, do nothing } } */ } #endif }
void CQtDisplayer::doDisplay ( const NLMISC::CLog::TDisplayInfo& args, const char *message ) { bool needSpace = false; std::string str; if(m_DlgDebug==NULL) return; QTextCharFormat format; if (args.Date != 0 && !_Raw) { str += dateToHumanString(args.Date); needSpace = true; } if (args.LogType != NLMISC::CLog::LOG_NO && !_Raw) { if (needSpace) { str += " "; needSpace = false; } str += logTypeToString(args.LogType); if (args.LogType == NLMISC::CLog::LOG_WARNING) format.setForeground(QBrush(QColor("red"))); else format.setForeground(QBrush(QColor("black"))); needSpace = true; } // Write thread identifier /*if ( args.ThreadId != 0 && !_Raw) { if (needSpace) { str += " "; needSpace = false; } str += NLMISC::toString(args.ThreadId); needSpace = true; }*/ /*if (!args.ProcessName.empty() && !_Raw) { if (needSpace) { str += " "; needSpace = false; } str += args.ProcessName; needSpace = true; }*/ //if (args.FileName != NULL && !_Raw) { // if (needSpace) { str += " "; needSpace = false; } // str += NLMISC::CFile::getFilename(args.FileName); // needSpace = true; //} /*if (args.Line != -1 && !_Raw) { if (needSpace) { str += " "; needSpace = false; } str += NLMISC::toString(args.Line); needSpace = true; }*/ if (args.FuncName != NULL && !_Raw) { if (needSpace) { str += " "; needSpace = false; } str += args.FuncName; needSpace = true; } if (needSpace) { str += " : "; needSpace = false; } str += message; m_DlgDebug->textCursor().insertText(str.c_str(), format); //m_DlgDebug->setCenterOnScroll(true); m_DlgDebug->centerCursor(); //m_DlgDebug->ensureCursorVisible(); }