Implement logging framework with Channel and StdoutChannel classes
This commit is contained in:
parent
792cda4b52
commit
0d3fd346ba
21
webserv/log/Channel.hpp
Normal file
21
webserv/log/Channel.hpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <webserv/log/Log.hpp>
|
||||||
|
#include <webserv/log/LogLevel.hpp>
|
||||||
|
|
||||||
|
class Channel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Channel() = default;
|
||||||
|
virtual ~Channel() = default;
|
||||||
|
|
||||||
|
Channel(const Channel &other) = delete;
|
||||||
|
Channel(const Channel &&other) = delete;
|
||||||
|
Channel &operator=(const Channel &other) = delete;
|
||||||
|
Channel &&operator=(const Channel &&other) = delete;
|
||||||
|
|
||||||
|
virtual void log(LogLevel &logLevel, const std::string &message,
|
||||||
|
const std::map<std::string, std::string> &context = {}) = 0;
|
||||||
|
};
|
||||||
44
webserv/log/Log.cpp
Normal file
44
webserv/log/Log.cpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#include "webserv/log/StdoutChannel.hpp"
|
||||||
|
#include <webserv/log/Log.hpp>
|
||||||
|
|
||||||
|
Log::Log()
|
||||||
|
{
|
||||||
|
channels_.insert({"stdout", std::unique_ptr<Channel>(new StdoutChannel())});
|
||||||
|
}
|
||||||
|
|
||||||
|
Log &Log::getInstance()
|
||||||
|
{
|
||||||
|
static Log instance;
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Log::log(LogLevel level, const std::string &message, const std::string &channel,
|
||||||
|
const std::map<std::string, std::string> &context)
|
||||||
|
{
|
||||||
|
auto it = channels_.find(channel);
|
||||||
|
if (it != channels_.end())
|
||||||
|
{
|
||||||
|
it->second->log(level, message, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Log::debug(const std::string &message, const std::map<std::string, std::string> &context)
|
||||||
|
{
|
||||||
|
getInstance().log(LogLevel::DEBUG, message, "stdout", context);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Log::info(const std::string &message, const std::map<std::string, std::string> &context)
|
||||||
|
{
|
||||||
|
getInstance().log(LogLevel::INFO, message, "stdout", context);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Log::warning(const std::string &message, const std::map<std::string, std::string> &context)
|
||||||
|
{
|
||||||
|
getInstance().log(LogLevel::WARN, message, "stdout", context);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Log::error(const std::string &message, const std::map<std::string, std::string> &context)
|
||||||
|
{
|
||||||
|
getInstance().log(LogLevel::ERROR, message, "stdout", context);
|
||||||
|
}
|
||||||
34
webserv/log/Log.hpp
Normal file
34
webserv/log/Log.hpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "webserv/log/Channel.hpp"
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <webserv/log/LogLevel.hpp>
|
||||||
|
|
||||||
|
class Channel; // Forward declaration
|
||||||
|
|
||||||
|
class Log
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Log(const Log &other) = delete;
|
||||||
|
Log(const Log &&other) = delete;
|
||||||
|
Log &operator=(const Log &other) = delete;
|
||||||
|
Log &&operator=(const Log &&other) = delete;
|
||||||
|
|
||||||
|
void log(LogLevel level, const std::string &message, const std::string &channel = "stdout",
|
||||||
|
const std::map<std::string, std::string> &context = {});
|
||||||
|
|
||||||
|
static void debug(const std::string &message, const std::map<std::string, std::string> &context = {});
|
||||||
|
static void info(const std::string &message, const std::map<std::string, std::string> &context = {});
|
||||||
|
static void warning(const std::string &message, const std::map<std::string, std::string> &context = {});
|
||||||
|
static void error(const std::string &message, const std::map<std::string, std::string> &context = {});
|
||||||
|
|
||||||
|
private:
|
||||||
|
Log();
|
||||||
|
~Log() = default;
|
||||||
|
static Log &getInstance();
|
||||||
|
|
||||||
|
std::unordered_map<std::string, std::unique_ptr<Channel>> channels_;
|
||||||
|
};
|
||||||
28
webserv/log/LogLevel.hpp
Normal file
28
webserv/log/LogLevel.hpp
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
enum class LogLevel : uint8_t
|
||||||
|
{
|
||||||
|
DEBUG,
|
||||||
|
INFO,
|
||||||
|
WARN,
|
||||||
|
ERROR
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::string logLevelToString(LogLevel level)
|
||||||
|
{
|
||||||
|
switch (level)
|
||||||
|
{
|
||||||
|
case LogLevel::DEBUG:
|
||||||
|
return "DEBUG";
|
||||||
|
case LogLevel::INFO:
|
||||||
|
return "INFO";
|
||||||
|
case LogLevel::WARN:
|
||||||
|
return "WARN";
|
||||||
|
case LogLevel::ERROR:
|
||||||
|
return "ERROR";
|
||||||
|
}
|
||||||
|
return "UNKNOWN"; // Fallback to silence warnings
|
||||||
|
}
|
||||||
21
webserv/log/StdoutChannel.cpp
Normal file
21
webserv/log/StdoutChannel.cpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <webserv/log/StdoutChannel.hpp>
|
||||||
|
|
||||||
|
void StdoutChannel::log(LogLevel &logLevel, const std::string &message,
|
||||||
|
const std::map<std::string, std::string> &context)
|
||||||
|
{
|
||||||
|
std::string prefix = "[" + logLevelToString(logLevel) + "] ";
|
||||||
|
std::cout << prefix;
|
||||||
|
std::cout << message;
|
||||||
|
if (!context.empty())
|
||||||
|
{
|
||||||
|
std::cout << " Context: {";
|
||||||
|
for (const auto &[key, value] : context)
|
||||||
|
{
|
||||||
|
std::cout << key << ": " << value << ", ";
|
||||||
|
}
|
||||||
|
std::cout << "}";
|
||||||
|
}
|
||||||
|
std::cout << "\n";
|
||||||
|
}
|
||||||
10
webserv/log/StdoutChannel.hpp
Normal file
10
webserv/log/StdoutChannel.hpp
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <webserv/log/Channel.hpp>
|
||||||
|
|
||||||
|
class StdoutChannel : public Channel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void log(LogLevel &logLevel, const std::string &message,
|
||||||
|
const std::map<std::string, std::string> &context = {}) override;
|
||||||
|
};
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
#include "webserv/log/Log.hpp"
|
||||||
#include <webserv/config/ConfigManager.hpp>
|
#include <webserv/config/ConfigManager.hpp>
|
||||||
#include <webserv/config/LocationConfig.hpp>
|
#include <webserv/config/LocationConfig.hpp>
|
||||||
#include <webserv/config/ServerConfig.hpp>
|
#include <webserv/config/ServerConfig.hpp>
|
||||||
@ -16,6 +17,8 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
ConfigManager::getInstance().init(argv[1]); // NOLINT
|
ConfigManager::getInstance().init(argv[1]); // NOLINT
|
||||||
Server server(ConfigManager::getInstance());
|
Server server(ConfigManager::getInstance());
|
||||||
|
|
||||||
|
Log::info("test log message: server starting...", {{"port", "8080"}, {"mode", "production"}});
|
||||||
server.start();
|
server.start();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user