consider my logging class
void LogWriter::InitLogWriter(void)
{
wcout.flush();
wcerr.flush();
COUT_BACKUP = wcout.rdbuf(); // save original cout buffer
CERR_BACKUP = wcerr.rdbuf(); //save original cerr buffer
FileStreamOpen = false;
switch(m_nTraceLvl)
{
case OffLevel:
StopOutput();
break;
case ErrorLevel:
OutputErrorsToFile(s_TraceFile);
break;
case DetailLevel:
OutputAllToFile(s_TraceFile);
break;
default:
StopOutput();
break;
}
wcout << "Initialize Log Writer" << endl;
}
void LogWriter::OutputAllToFile(TCHAR* fileName)
{
wstreambuf* fb = GetFileBufferStream(fileName);
wcout.rdbuf(fb); // push wcout buffer to file
wcerr.rdbuf(fb); // push cerr buffer to file
FileStreamOpen = true;
}
void LogWriter::OutputErrorsToFile(TCHAR* fileName)
{
wstreambuf* fb = GetFileBufferStream(fileName);
wcerr.rdbuf(fb);
FileStreamOpen = true;
wofstream fout("/dev/null");
wcout.rdbuf(fout.rdbuf()); // redirect 'cout' to a 'fout'
}
void LogWriter::StopOutput(void)
{
wofstream fout("/dev/null");
wcout.rdbuf(fout.rdbuf()); // redirect 'cout' to a 'fout'
wcerr.rdbuf(fout.rdbuf()); // redirect cerr to fout
}
wstreambuf* LogWriter::GetFileBufferStream(TCHAR* fileName)
{
filestr.open(fileName);
return filestr.rdbuf(); // get file's streambuf
}
void LogWriter::Dispose()
{
wcout << "Kill Log Writer" << endl;
wcout.rdbuf(COUT_BACKUP); // restore the original stream buffer
wcerr.rdbuf(CERR_BACKUP);
if(FileStreamOpen)
{
filestr.close();
}
}
Now if i set my Tracing to DetailLevel (2) all is fine. All my logging goes to the file. But if i choose OffLevel or ErrorLevel my program crashes.. my debugger doesn't turn on so i added cout << "." on every line (i hate doing that, but it works) and it points me to
wcout.rdbuf(fout.rdbuf()); // redirect 'cout' to a 'fout'
as being my culprit... I switched around redirecting wcout first with wcerr being redirected and it worked (but wcerr was not called yet)
so that is my question? am I supposed to dispose wcout first? I tried flushing first..that didn't work.. so i don't know. What am I doing wrong?
Also as a bonus.. how come all my output doesn't go to the file until I close my LogWriter? IE LogWriter::Dispose()
You crash because wofstream fout("/dev/null");
is created on the stack and is destroyed as soon as you leave the function.
Treat /dev/null
exactly like you treat the file. That is, call OutputErrorsToFile("/dev/null")
inside StopOutput()
. In fact you don't even need /dev/null
: just use wcout.rdbuf(nullptr)
, which should work faster too.
To write into the file immediately call .flush()
or use std::flush
manipulator.