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/LocationConfig.hpp>
|
||||
#include <webserv/config/ServerConfig.hpp>
|
||||
@ -16,6 +17,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
ConfigManager::getInstance().init(argv[1]); // NOLINT
|
||||
Server server(ConfigManager::getInstance());
|
||||
|
||||
Log::info("test log message: server starting...", {{"port", "8080"}, {"mode", "production"}});
|
||||
server.start();
|
||||
|
||||
return 0;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user