Reputation: 582
I have basic logging process. When an error occured in the program, it has to been logging to a .txt file. I use following code for this:
#include <fstream>
fileName = "logs/error_log.txt";
ofstream myfile;
myfile.open (fileName,fstream::app);
myfile << serialized_string << endl;
myfile.close();
When an error occured it goes to error_log.txt file successfully. But when program crashed and is restarted afterward, new logs are not logged as append. As expected the way I am using creates a new file which has same name existed file and write on it. Can someone explain me how should I write older logs as well?
Edit: These are steps I have faced: I am using raspbian and I compile with following:
g++ main.cpp -lwiringPi -lpthread -lcurl -o test
That is the whole function.
int putLog(const char* process, int logType, string logData) {
isLoggerBusy = true;
string fileName;
std::string color;
switch (logType) {
case 0:
fileName = "logs/error_log.txt";
// color = "\033[0;31m";
break;
case 1:
fileName = "logs/info_log.txt";
// color = "\033[0;36m";
break;
case 2:
fileName = "logs/state_log.txt";
// color = "\033[1;33m";
break;
}
if (process == "WebSocket") {
color = "\033[1;32m";
}
json j = {
{"Process", process}, {"Time", currentDateTime()}, {"Log", logData}};
string serialized_string = j.dump();
fix_utf8_string(serialized_string);
ofstream myfile;
myfile.open(fileName, fstream::app);
cout << color << serialized_string << '\n';
myfile << serialized_string << endl;
myfile.close();
isLoggerBusy = false;
cout << "\033[0m" << endl;
return 0;
}
{"Log":"Incoming Message{\"Action\":\"Heartbeat\",\"Data\":null}","Process":"WebSocket","Time":"2018-08-16.14:53:52"}
{"Log":"GSM Setup Finished","Process":"SMSService","Time":"2018-08-16.14:54:13"}
Upvotes: 4
Views: 369
Reputation: 20141
I cannot reproduce what OP describes.
I just tested on cygwin/Windows 10. (I didn't know how to make this test on an online compiler.)
testFStreamApp.cc
:
#include <iostream>
#include <fstream>
int main()
{
std::cout << "Log error...\n";
{ std::ofstream log("testFStream.log", std::ios::out | std::ios::app);
log << "Error happened!" << std::endl;
}
std::cout << "Going to die...\n";
abort();
return 0; // should never be reached
}
Test Session:
$ g++ -std=c++11 -o testFStreamApp testFStreamApp.cc
$ rm testFStream.log
$ for i in 1 2 3; do
> echo "$i. start:"
> ./testFStreamApp
> done
1. start:
Log error...
Going to die...
Aborted (core dumped)
2. start:
Log error...
Going to die...
Aborted (core dumped)
3. start:
Log error...
Going to die...
Aborted (core dumped)
$ cat <testFStream.log
Error happened!
Error happened!
Error happened!
$
YSC pointed out that I made some silent changes. I did it assuming no relevance.
However, to erase any excuses, I tried also:
#include <iostream>
#include <fstream>
int main()
{
std::cout << "Log error...\n";
std::ofstream log;
log.open("testFStream.log", std::fstream::app);
log << "Error happened!" << std::endl;
log.close();
std::cout << "Going to die...\n";
abort();
return 0; // should never be reached
}
The output was exactly as above.
I hadn't dared to test this but doctorlove encouraged me:
#include <iostream>
#include <fstream>
int main()
{
std::cout << "Log error...\n";
std::ofstream log;
log.open("testFStream.log", std::fstream::app);
log << "Error happened!" << std::endl;
std::cout << "Going to die...\n";
abort();
log.close();
return 0; // should never be reached
}
Even in this case, I got the same result.
At this point, I must admit that cygwin is just a wrapper around the win32 API. So, in this case, I wouldn't wonder if this behaves different on other OSes.
I'm aware that std::endl
does a flush()
insight. The question is how far down (into the system) the flush()
is effective. (In daily work, I try to write the code in a way that it is not necessary to rely on such details...) ;-)
Upvotes: 4