aboutsummaryrefslogtreecommitdiff
path: root/contrib/epee/src/mlog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/epee/src/mlog.cpp')
-rw-r--r--contrib/epee/src/mlog.cpp56
1 files changed, 53 insertions, 3 deletions
diff --git a/contrib/epee/src/mlog.cpp b/contrib/epee/src/mlog.cpp
index fb0b4ac2b..e8248c958 100644
--- a/contrib/epee/src/mlog.cpp
+++ b/contrib/epee/src/mlog.cpp
@@ -47,6 +47,7 @@ using namespace epee;
static std::string generate_log_filename(const char *base)
{
std::string filename(base);
+ static unsigned int fallback_counter = 0;
char tmp[200];
struct tm tm;
time_t now = time(NULL);
@@ -56,7 +57,7 @@ static std::string generate_log_filename(const char *base)
#else
(!gmtime_r(&now, &tm))
#endif
- strcpy(tmp, "unknown");
+ snprintf(tmp, sizeof(tmp), "part-%u", ++fallback_counter);
else
strftime(tmp, sizeof(tmp), "%Y-%m-%d-%H-%M-%S", &tm);
tmp[sizeof(tmp) - 1] = 0;
@@ -116,7 +117,7 @@ static const char *get_default_categories(int level)
return categories;
}
-void mlog_configure(const std::string &filename_base, bool console, const std::size_t max_log_file_size)
+void mlog_configure(const std::string &filename_base, bool console, const std::size_t max_log_file_size, const std::size_t max_log_files)
{
el::Configurations c;
c.setGlobally(el::ConfigurationType::Filename, filename_base);
@@ -134,9 +135,58 @@ void mlog_configure(const std::string &filename_base, bool console, const std::s
el::Loggers::addFlag(el::LoggingFlag::DisableApplicationAbortOnFatalLog);
el::Loggers::addFlag(el::LoggingFlag::ColoredTerminalOutput);
el::Loggers::addFlag(el::LoggingFlag::StrictLogFileSizeCheck);
- el::Helpers::installPreRollOutCallback([filename_base](const char *name, size_t){
+ el::Helpers::installPreRollOutCallback([filename_base, max_log_files](const char *name, size_t){
std::string rname = generate_log_filename(filename_base.c_str());
rename(name, rname.c_str());
+ if (max_log_files != 0)
+ {
+ std::vector<boost::filesystem::path> found_files;
+ const boost::filesystem::directory_iterator end_itr;
+ for (boost::filesystem::directory_iterator iter(boost::filesystem::path(filename_base).parent_path()); iter != end_itr; ++iter)
+ {
+ const std::string filename = iter->path().string();
+ if (filename.size() >= filename_base.size() && std::memcmp(filename.data(), filename_base.data(), filename_base.size()) == 0)
+ {
+ found_files.push_back(iter->path());
+ }
+ }
+ if (found_files.size() >= max_log_files)
+ {
+ std::sort(found_files.begin(), found_files.end(), [](const boost::filesystem::path &a, const boost::filesystem::path &b) {
+ boost::system::error_code ec;
+ std::time_t ta = boost::filesystem::last_write_time(boost::filesystem::path(a), ec);
+ if (ec)
+ {
+ MERROR("Failed to get timestamp from " << a << ": " << ec);
+ ta = std::time(nullptr);
+ }
+ std::time_t tb = boost::filesystem::last_write_time(boost::filesystem::path(b), ec);
+ if (ec)
+ {
+ MERROR("Failed to get timestamp from " << b << ": " << ec);
+ tb = std::time(nullptr);
+ }
+ static_assert(std::is_integral<time_t>(), "bad time_t");
+ return ta < tb;
+ });
+ for (size_t i = 0; i <= found_files.size() - max_log_files; ++i)
+ {
+ try
+ {
+ boost::system::error_code ec;
+ boost::filesystem::remove(found_files[i], ec);
+ if (ec)
+ {
+ MERROR("Failed to remove " << found_files[i] << ": " << ec);
+ }
+ }
+ catch (const std::exception &e)
+ {
+ MERROR("Failed to remove " << found_files[i] << ": " << e.what());
+ }
+ }
+ }
+ }
});
mlog_set_common_prefix();
const char *monero_log = getenv("MONERO_LOGS");