Log each FRU VPD collection in separate files
For VPD collection logs, we need to maintain logs of last 3 FRU VPD
collections and each FRU VPD collection flow should be logged in
separate files. This commit implements these requirements.
Test:
```
- Boot rainiest, wait for FRU VPD collection to be triggered by
wait-vpd-parser.service
- observe /var/lib/vpd directory and see collection_0.log file is
created with log messages of FRU VPD collection
- Trigger another FRU VPD collection using vpd-manager
"CollectAllFRUVPD" D-bus method
- Observe collection_1.log file getting created
"CollectAllFRUVPD" D-bus method
- Repeat above steps until collection_2.log is created
- Trigger another FRU VPD Collection, observe collection_0.log file is
overwritten with logs of latest FRU VPD collection
```
Change-Id: I5ef1f9eb339fbf1597955488b00b784a173c7e70
Signed-off-by: Souvik Roy <souvikroyofficial10@gmail.com>
diff --git a/vpd-manager/src/logger.cpp b/vpd-manager/src/logger.cpp
index c57216b..321237f 100644
--- a/vpd-manager/src/logger.cpp
+++ b/vpd-manager/src/logger.cpp
@@ -1,5 +1,6 @@
#include "logger.hpp"
+#include <regex>
#include <sstream>
namespace vpd
@@ -47,17 +48,86 @@
{
try
{
- /* TODO:
- - check /var/lib/vpd for number "collection.*" log file
- - if 3 collection_[0-2].log files are found
- - delete collection_1.log
- - create collection logger object with collection_1.log
- parameter
- - else
- - create collection logger object with collection_(n+1).log
- parameter*/
+ // collection log file directory
+ const std::filesystem::path l_collectionLogDirectory{"/var/lib/vpd"};
+
+ std::error_code l_ec;
+ if (!std::filesystem::exists(l_collectionLogDirectory, l_ec))
+ {
+ if (l_ec)
+ {
+ throw std::runtime_error(
+ "File system call to exist failed with error = " +
+ l_ec.message());
+ }
+ throw std::runtime_error(
+ "Directory " + l_collectionLogDirectory.string() +
+ " does not exist");
+ }
+
+ // base name of collection log file
+ std::filesystem::path l_collectionLogFilePath{l_collectionLogDirectory};
+ l_collectionLogFilePath /= "collection";
+
+ unsigned l_collectionLogFileCount{0};
+
+ std::filesystem::file_time_type l_oldestFileTime;
+ std::filesystem::path l_oldestFilePath{l_collectionLogFilePath};
+
+ // iterate through all entries in the log directory
+ for (const auto& l_dirEntry :
+ std::filesystem::directory_iterator(l_collectionLogDirectory))
+ {
+ // check /var/lib/vpd for number "collection.*" log file
+ const std::regex l_collectionLogFileRegex{"collection.*\\.log"};
+
+ if (std::filesystem::is_regular_file(l_dirEntry.path()) &&
+ std::regex_match(l_dirEntry.path().filename().string(),
+ l_collectionLogFileRegex))
+ {
+ // check the write time of this file
+ const auto l_fileWriteTime =
+ std::filesystem::last_write_time(l_dirEntry.path());
+
+ // update oldest file path if required
+ if (l_fileWriteTime < l_oldestFileTime)
+ {
+ l_oldestFileTime = l_fileWriteTime;
+ l_oldestFilePath = l_dirEntry.path();
+ }
+
+ l_collectionLogFileCount++;
+ }
+ }
+
+ // maximum number of collection log files to maintain
+ constexpr auto l_maxCollectionLogFiles{3};
+
+ if (l_collectionLogFileCount >= l_maxCollectionLogFiles)
+ {
+ // delete oldest collection log file
+ l_collectionLogFilePath = l_oldestFilePath;
+
+ logMessage("Deleting collection log file " +
+ l_collectionLogFilePath.string());
+
+ std::error_code l_ec;
+ if (!std::filesystem::remove(l_collectionLogFilePath, l_ec))
+ {
+ logMessage("Failed to delete existing collection log file " +
+ l_collectionLogFilePath.string() +
+ " Error: " + l_ec.message());
+ }
+ }
+ else
+ {
+ l_collectionLogFilePath +=
+ "_" + std::to_string(l_collectionLogFileCount) + ".log";
+ }
+
+ // create collection logger object with collection_(n+1).log
m_collectionLogger.reset(
- new AsyncFileLogger("/var/lib/vpd/collection.log", 4096));
+ new AsyncFileLogger(l_collectionLogFilePath, 4096));
}
catch (const std::exception& l_ex)
{