I've a singleton logger class which will be used to write data into a single file and I'm just wondering how to handle the ofstream
object in case of application crash.
#ifndef LOG_ERROR_H_
#define LOG_ERROR_H_
#include <iostream>
#include <thread>
#include <mutex>
#include <string>
#include <fstream>
#include <memory>
namespace batch
{
class ErrorLogger
{
public:
ErrorLogger(const ErrorLogger &) = delete;
static ErrorLogger& Instance(std::string filename_)
{
static ErrorLogger error_instance(filename_);
return error_instance;
}
void WriteLine(std::string content)
{
try
{
std::lock_guard<std::mutex> lk(error_stream_mutex);
error_stream << content << std::endl;
}
catch(std::runtime_error const& e)
{
//cout
}
}
~ErrorLogger()
{
error_stream.close(); //Destructor is not getting called, should I explicitly call it?
}
private:
std::ofstream error_stream;
std::mutex error_stream_mutex;
ErrorLogger(std::string filename)
{
error_stream.open(filename);
if (error_stream.fail())
{
throw std::iostream::failure("Cannot open file: " + filename);
}
}
};
}
#endif
What I tried is instead of keeping the ofstream
object open always, instantiate once and then open
, close
during writing but let's assume a scenario where I get the instance and the ofstream
object is initialized and before calling WriteLine
(), the application crashed then how should I handle the ofstream
object?
ErrorLogger(std::string filename)
{
error_stream(filename);
if (error_stream.fail())
{
throw std::iostream::failure("Cannot open file: " + filename);
}
}
void WriteLine(std::string content)
{
try
{
error_stream.open(filename);
if (error_stream.fail())
{
throw std::iostream::failure("Cannot open file: " + filename);
}
std::lock_guard<std::mutex> lk(error_stream_mutex);
error_stream << content << std::endl;
error_stream.close();
}
catch(std::runtime_error const& e)
{
//cout
}
}
So the question is how to properly handle error_stream (in a positive scenario as well as application crash scenario) i.e when should I close it, right now it is not getting closed.