Base framework for log management
The commit implements stub of logger class and log file handler class,
which together will be further extended to implement methods required
for abstracting log management from the caller and will log message at
appropriate place.
Change-Id: Ieb53ec5d0377fbad062f1150bcbf24c335a7ce80
Signed-off-by: Sunny Srivastava <sunnsr25@in.ibm.com>
diff --git a/vpd-manager/include/logger.hpp b/vpd-manager/include/logger.hpp
index a4160c1..bedc688 100644
--- a/vpd-manager/include/logger.hpp
+++ b/vpd-manager/include/logger.hpp
@@ -1,13 +1,124 @@
#pragma once
+#include "types.hpp"
+
#include <iostream>
+#include <memory>
#include <source_location>
#include <string_view>
namespace vpd
{
+
+/**
+ * @brief Enum class defining placeholder tags.
+ *
+ * The tag will be used by APIs to identify the endpoint for a given log
+ * message.
+ */
+enum class PlaceHolder
+{
+ DEFAULT, /* logs to the journal */
+ PEL, /* Creates a PEL */
+ COLLECTION /* Logs collection messages */
+};
+
+/**
+ * @brief Class to handle file operations w.r.t logging.
+ * Based on the placeholder the class will handle different file operations to
+ * log error messages.
+ */
+class LogFileHandler
+{
+ // should hold fd's for files required as per placeholder.
+ public:
+ /**
+ * @brief API exposed to write a log message to a file.
+ *
+ * The API can be called by logger class in case log message needs to be
+ * redirected to a file. The endpoint can be decided based on the
+ * placeholder passed to the API.
+ *
+ * @param[in] i_placeHolder - Information about the endpoint.
+ */
+ void writeLogToFile([[maybe_unused]] const PlaceHolder& i_placeHolder)
+ {
+ // Handle the file operations.
+ }
+
+ // Frined class Logger.
+ friend class Logger;
+
+ private:
+ /**
+ * @brief Constructor
+ * Private so that can't be initialized by class(es) other than friends.
+ */
+ LogFileHandler() {}
+
+ /* Define APIs to handle file operation as per the placeholder. */
+};
+
+/**
+ * @brief Singleton class to handle error logging for the repository.
+ */
+class Logger
+{
+ public:
+ /**
+ * @brief Deleted Methods
+ */
+ Logger(const Logger&) = delete; // Copy constructor
+ Logger(const Logger&&) = delete; // Move constructor
+
+ /**
+ * @brief Method to get instance of Logger class.
+ */
+ static std::shared_ptr<Logger> getLoggerInstance()
+ {
+ if (!m_loggerInstance)
+ {
+ m_loggerInstance = std::shared_ptr<Logger>(new Logger());
+ }
+ return m_loggerInstance;
+ }
+
+ /**
+ * @brief API to log a given error message.
+ *
+ * @param[in] i_message - Message to be logged.
+ * @param[in] i_placeHolder - States where the message needs to be logged.
+ * Default is journal.
+ * @param[in] i_pelTuple - A structure only required in case message needs
+ * to be logged as PEL.
+ * @param[in] i_location - Locatuon from where message needs to be logged.
+ */
+ void logMessage(std::string_view i_message,
+ const PlaceHolder& i_placeHolder = PlaceHolder::DEFAULT,
+ const types::PelInfoTuple* i_pelTuple = nullptr,
+ const std::source_location& i_location =
+ std::source_location::current());
+
+ private:
+ /**
+ * @brief Constructor
+ */
+ Logger() : m_logFileHandler(nullptr)
+ {
+ m_logFileHandler =
+ std::shared_ptr<LogFileHandler>(new LogFileHandler());
+ }
+
+ // Instance to the logger class.
+ static std::shared_ptr<Logger> m_loggerInstance;
+
+ // Instance to LogFileHandler class.
+ std::shared_ptr<LogFileHandler> m_logFileHandler;
+};
+
/**
* @brief The namespace defines logging related methods for VPD.
+ * Only for backward compatibility till new logger class comes up.
*/
namespace logging
{
diff --git a/vpd-manager/include/types.hpp b/vpd-manager/include/types.hpp
index 66d7f8d..7461455 100644
--- a/vpd-manager/include/types.hpp
+++ b/vpd-manager/include/types.hpp
@@ -210,5 +210,13 @@
using MatchObjectInterfaceMap = std::map<std::string,std::shared_ptr<sdbusplus::bus::match_t>>;
/* A map of service name to match object interface map*/
using MatchObjectMap = std::map<std::string,MatchObjectInterfaceMap>;
+
+/*
+* Tuple of Error type, severity, internal rc, userdata1, userdata2, symFru, Procedure
+*/
+using PelInfoTuple =
+ std::tuple<types::ErrorType, std::optional<types::SeverityType>, uint8_t, std::optional<std::string>,
+ std::optional<std::string>, std::optional<std::string>,
+ std::optional<std::string>>;
} // namespace types
} // namespace vpd
diff --git a/vpd-manager/src/logger.cpp b/vpd-manager/src/logger.cpp
index 19959a1..62d4e9e 100644
--- a/vpd-manager/src/logger.cpp
+++ b/vpd-manager/src/logger.cpp
@@ -4,6 +4,41 @@
namespace vpd
{
+std::shared_ptr<Logger> Logger::m_loggerInstance;
+
+void Logger::logMessage(std::string_view i_message,
+ const PlaceHolder& i_placeHolder,
+ const types::PelInfoTuple* i_pelTuple,
+ const std::source_location& i_location)
+{
+ std::ostringstream l_log;
+ l_log << "FileName: " << i_location.file_name() << ","
+ << " Line: " << i_location.line() << " " << i_message;
+
+ if (i_placeHolder == PlaceHolder::COLLECTION)
+ {
+ // Log it to a specific place.
+ m_logFileHandler->writeLogToFile(i_placeHolder);
+ }
+ else if (i_placeHolder == PlaceHolder::PEL)
+ {
+ if (i_pelTuple)
+ {
+ // LOG PEL
+ // This should call create PEL API from the event logger.
+ return;
+ }
+ std::cout << "Pel info tuple required to log PEL for message <" +
+ l_log.str() + ">"
+ << std::endl;
+ }
+ else
+ {
+ // Default case, let it go to journal.
+ std::cout << l_log.str() << std::endl;
+ }
+}
+
namespace logging
{
void logMessage(std::string_view message, const std::source_location& location)
@@ -12,11 +47,6 @@
log << "FileName: " << location.file_name() << ","
<< " Line: " << location.line() << " " << message;
- /* TODO: Check on this later.
- log << "FileName: " << location.file_name() << ","
- << " Line: " << location.line() << ","
- << " Func: " << location.function_name() << ", " << message;*/
-
std::cout << log.str() << std::endl;
}
} // namespace logging