Program Listing for File LogFile.cpp¶
↰ Return to documentation for file (necsim/LogFile.cpp
)
// This file is part of necsim project which is released under MIT license.
// See file **LICENSE.txt** or visit https://opensource.org/licenses/MIT) for full license details.
#include <sstream>
#include <iomanip>
#include <boost/filesystem.hpp>
#include "LogFile.h"
#include "file_system.h"
#include "custom_exceptions.h"
namespace necsim
{
string getTime()
{
#ifdef DEBUG
auto t = time(nullptr);
auto tm = *localtime(&t);
stringstream ss;
ss << put_time(&tm, LOGNAME_FORMAT);
return ss.str();
#endif
return string("");
}
string getDefaultLogFile()
{
time_t now = time(0);
static char name[30];
strftime(name, sizeof(name), LOGNAME_FORMAT, localtime(&now));
boost::filesystem::path full_path(boost::filesystem::current_path());
string out = full_path.string() + "/log/" + string(name) + ".log";
return out;
}
void getUniqueFileName(string &basic_string)
{
boost::filesystem::path file_path(basic_string);
const string file_name = basic_string.substr(0, basic_string.find('.'));
const string file_extension = basic_string.substr(basic_string.find('.'));
unsigned long iterator = 0;
while(boost::filesystem::exists(file_path))
{
if(iterator > 10000000)
{
basic_string = file_name + file_extension;
throw FatalException("Could not create unique file name after 10000000 tries.");
}
basic_string = file_name + "_" + to_string(iterator) + file_extension; // NOLINT
file_path = boost::filesystem::path(basic_string);
iterator++;
}
}
LogFile::LogFile()
{
init(getDefaultLogFile());
}
LogFile::LogFile(string file_name_in)
{
init(file_name_in);
}
LogFile::~LogFile()
{
output_stream << getTime() << " LOGGING ENDED" << endl;
output_stream.close();
}
void LogFile::init(string file_name_in)
{
createParent(file_name_in);
file_name = file_name_in;
getUniqueFileName(file_name);
output_stream.open(file_name);
if(!output_stream)
{
// Throw runtime error to avoid problems of attempting to write py object out before the logger has been set.
throw runtime_error("Could not create log file at " + file_name_in + ".");
}
levels_map[0] = "noneset";
levels_map[10] = "debug";
levels_map[20] = "info";
levels_map[30] = "warning";
levels_map[40] = "error";
levels_map[50] = "critical";
output_stream << getTime() << " LOGGING STARTED" << endl;
}
void LogFile::write(const int &level, string message)
{
if(levels_map.count(level) == 0)
{
throw FatalException("Logging level must be one of 0, 10, 20, 30, 40 or 50.");
}
output_stream << getTime() << " ";
replace(message.begin(), message.end(), '\n', ' ');
output_stream << levels_map[level] << ": " << message << endl;
}
void LogFile::write(const int &level, stringstream &message)
{
write(level, message.str());
}
}