blob: 4200052ffd883dc02506eec28659a3e8418a9d3e [file] [log] [blame]
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -05001#pragma once
2
Sunny Srivastava5779d972025-08-08 01:45:23 -05003#include "types.hpp"
4
Souvik Roya8c3c092025-09-11 10:49:29 +00005#include <filesystem>
6#include <fstream>
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -05007#include <iostream>
Sunny Srivastava5779d972025-08-08 01:45:23 -05008#include <memory>
Souvik Roya8c3c092025-09-11 10:49:29 +00009#include <mutex>
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -050010#include <source_location>
11#include <string_view>
12
13namespace vpd
14{
Sunny Srivastava5779d972025-08-08 01:45:23 -050015
16/**
17 * @brief Enum class defining placeholder tags.
18 *
19 * The tag will be used by APIs to identify the endpoint for a given log
20 * message.
21 */
22enum class PlaceHolder
23{
Souvik Roya5e18b82025-09-25 05:59:56 +000024 DEFAULT, /* logs to the journal */
25 PEL, /* Creates a PEL */
26 COLLECTION, /* Logs collection messages */
27 VPD_WRITE /* Logs VPD write details */
Sunny Srivastava5779d972025-08-08 01:45:23 -050028};
29
30/**
31 * @brief Class to handle file operations w.r.t logging.
32 * Based on the placeholder the class will handle different file operations to
33 * log error messages.
34 */
Souvik Roya5e18b82025-09-25 05:59:56 +000035class ILogFileHandler
Sunny Srivastava5779d972025-08-08 01:45:23 -050036{
Souvik Roya8c3c092025-09-11 10:49:29 +000037 protected:
38 // absolute file path of log file
39 std::filesystem::path m_filePath{};
40
41 // max number of log entries in file
42 size_t m_maxEntries{256};
43
Sunny Srivastava5779d972025-08-08 01:45:23 -050044 /**
Souvik Roya8c3c092025-09-11 10:49:29 +000045 * @brief API to rotate file.
Sunny Srivastava5779d972025-08-08 01:45:23 -050046 *
Souvik Roya8c3c092025-09-11 10:49:29 +000047 * This API rotates the logs within a file by deleting specified number of
48 * oldest entries.
Sunny Srivastava5779d972025-08-08 01:45:23 -050049 *
Souvik Roya8c3c092025-09-11 10:49:29 +000050 * @param[in] i_numEntriesToDelete - Number of entries to delete.
51 *
52 * @throw std::runtime_error
Sunny Srivastava5779d972025-08-08 01:45:23 -050053 */
Souvik Roya8c3c092025-09-11 10:49:29 +000054 virtual void rotateFile(
55 [[maybe_unused]] const unsigned i_numEntriesToDelete = 5);
56
57 /**
58 * @brief Constructor.
59 * Private so that can't be initialized by class(es) other than friends.
60 *
61 * @param[in] i_filePath - Absolute path of the log file.
62 * @param[in] i_maxEntries - Maximum number of entries in the log file after
63 * which the file will be rotated.
64 */
65 ILogFileHandler(const std::filesystem::path& i_filePath,
66 const size_t i_maxEntries) :
67 m_filePath{i_filePath}, m_maxEntries{i_maxEntries}
Sunny Srivastava5779d972025-08-08 01:45:23 -050068 {
Souvik Roya8c3c092025-09-11 10:49:29 +000069 // TODO: open the file in append mode
Sunny Srivastava5779d972025-08-08 01:45:23 -050070 }
71
Sunny Srivastava5779d972025-08-08 01:45:23 -050072 /**
Souvik Roya8c3c092025-09-11 10:49:29 +000073 * @brief API to generate timestamp in string format.
74 *
75 * @return Returns timestamp in string format on success, otherwise returns
76 * empty string in case of any error.
Sunny Srivastava5779d972025-08-08 01:45:23 -050077 */
Souvik Roya8c3c092025-09-11 10:49:29 +000078 static inline std::string timestamp() noexcept
79 {
80 // TODO: generate timestamp.
81 return std::string{};
82 }
Sunny Srivastava5779d972025-08-08 01:45:23 -050083
Souvik Roya8c3c092025-09-11 10:49:29 +000084 public:
85 // deleted methods
86 ILogFileHandler() = delete;
87 ILogFileHandler(const ILogFileHandler&) = delete;
88 ILogFileHandler(const ILogFileHandler&&) = delete;
89 ILogFileHandler operator=(const ILogFileHandler&) = delete;
90 ILogFileHandler operator=(const ILogFileHandler&&) = delete;
91
92 /**
93 * @brief API to log a message to file.
94 *
95 * @param[in] i_message - Message to log.
96 *
97 * @throw std::runtime_error
98 */
99 virtual void logMessage(
100 [[maybe_unused]] const std::string_view& i_message) = 0;
101
102 // destructor
103 virtual ~ILogFileHandler()
104 {
105 // TODO: close the filestream
106 }
Sunny Srivastava5779d972025-08-08 01:45:23 -0500107};
108
109/**
110 * @brief Singleton class to handle error logging for the repository.
111 */
112class Logger
113{
114 public:
115 /**
116 * @brief Deleted Methods
117 */
Souvik Roya5e18b82025-09-25 05:59:56 +0000118 Logger(const Logger&) = delete; // Copy constructor
119 Logger(const Logger&&) = delete; // Move constructor
120 Logger operator=(const Logger&) = delete; // Copy assignment operator
121 Logger operator=(const Logger&&) = delete; // Move assignment operator
Sunny Srivastava5779d972025-08-08 01:45:23 -0500122
123 /**
124 * @brief Method to get instance of Logger class.
125 */
126 static std::shared_ptr<Logger> getLoggerInstance()
127 {
128 if (!m_loggerInstance)
129 {
130 m_loggerInstance = std::shared_ptr<Logger>(new Logger());
131 }
132 return m_loggerInstance;
133 }
134
135 /**
136 * @brief API to log a given error message.
137 *
138 * @param[in] i_message - Message to be logged.
139 * @param[in] i_placeHolder - States where the message needs to be logged.
140 * Default is journal.
141 * @param[in] i_pelTuple - A structure only required in case message needs
142 * to be logged as PEL.
143 * @param[in] i_location - Locatuon from where message needs to be logged.
144 */
145 void logMessage(std::string_view i_message,
146 const PlaceHolder& i_placeHolder = PlaceHolder::DEFAULT,
147 const types::PelInfoTuple* i_pelTuple = nullptr,
148 const std::source_location& i_location =
149 std::source_location::current());
150
Souvik Roya5e18b82025-09-25 05:59:56 +0000151 /**
152 * @brief API to initiate VPD collection logging.
153 *
154 * This API initiates VPD collection logging. It checks for existing
155 * collection log files and if 3 such files are found, it deletes the oldest
156 * file and initiates a VPD collection logger object, so that every new VPD
157 * collection flow always gets logged into a new file.
158 */
159 void initiateVpdCollectionLogging() noexcept;
160
161 /**
162 * @brief API to terminate VPD collection logging.
163 *
164 * This API terminates the VPD collection logging by destroying the
165 * associated VPD collection logger object.
166 */
167 void terminateVpdCollectionLogging() noexcept
168 {
169 // TODO: reset VPD collection logger
170 }
171
Sunny Srivastava5779d972025-08-08 01:45:23 -0500172 private:
173 /**
174 * @brief Constructor
175 */
Souvik Roya5e18b82025-09-25 05:59:56 +0000176 Logger() : m_vpdWriteLogger(nullptr), m_collectionLogger(nullptr)
Sunny Srivastava5779d972025-08-08 01:45:23 -0500177 {
Souvik Roya5e18b82025-09-25 05:59:56 +0000178 // TODO: initiate synchronous logger for VPD write logs
Sunny Srivastava5779d972025-08-08 01:45:23 -0500179 }
180
181 // Instance to the logger class.
182 static std::shared_ptr<Logger> m_loggerInstance;
183
Souvik Roya5e18b82025-09-25 05:59:56 +0000184 // logger object to handle VPD write logs
185 std::unique_ptr<ILogFileHandler> m_vpdWriteLogger;
186
187 // logger object to handle VPD collection logs
188 std::unique_ptr<ILogFileHandler> m_collectionLogger;
Sunny Srivastava5779d972025-08-08 01:45:23 -0500189};
190
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500191/**
192 * @brief The namespace defines logging related methods for VPD.
Sunny Srivastava5779d972025-08-08 01:45:23 -0500193 * Only for backward compatibility till new logger class comes up.
Sunny Srivastavafa5e4d32023-03-12 11:59:49 -0500194 */
195namespace logging
196{
197
198/**
199 * @brief An api to log message.
200 * This API should be called to log message. It will auto append information
201 * like file name, line and function name to the message being logged.
202 *
203 * @param[in] message - Information that we want to log.
204 * @param[in] location - Object of source_location class.
205 */
206void logMessage(std::string_view message, const std::source_location& location =
207 std::source_location::current());
208} // namespace logging
209} // namespace vpd