Refactor logging system: enhance Channel and FileChannel classes to use getter/setter for log level, improve log context formatting in StdoutChannel, and update main to test logging context
This commit is contained in:
parent
6803524989
commit
6b85be65b8
@ -1,4 +1,11 @@
|
|||||||
#include <webserv/log/Channel.hpp>
|
#include <webserv/log/Channel.hpp>
|
||||||
|
|
||||||
|
Log::Level Channel::getLogLevel() const
|
||||||
|
{
|
||||||
|
return logLevel_;
|
||||||
|
}
|
||||||
|
|
||||||
Channel::Channel(Log::Level logLevel) : logLevel_(logLevel) {}
|
void Channel::setLogLevel(Log::Level level)
|
||||||
|
{
|
||||||
|
logLevel_ = level;
|
||||||
|
}
|
||||||
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include <webserv/log/Log.hpp>
|
#include <webserv/log/Log.hpp>
|
||||||
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@ -10,17 +9,18 @@ class Channel
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Channel() = default;
|
Channel() = default;
|
||||||
Channel(Log::Level logLevel);
|
|
||||||
virtual ~Channel() = default;
|
virtual ~Channel() = default;
|
||||||
|
|
||||||
Channel(const Channel &other) = delete;
|
Channel(const Channel &other) = delete;
|
||||||
Channel(const Channel &&other) = delete;
|
Channel(Channel &&other) = delete;
|
||||||
Channel &operator=(const Channel &other) = delete;
|
Channel &operator=(const Channel &other) = delete;
|
||||||
Channel &&operator=(const Channel &&other) = delete;
|
Channel &operator=(Channel &&other) = delete;
|
||||||
|
virtual void log(const Log::Level &logLevel, const std::string &message,
|
||||||
virtual void log(Log::Level &logLevel, const std::string &message,
|
|
||||||
const std::map<std::string, std::string> &context = {}) = 0;
|
const std::map<std::string, std::string> &context = {}) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
[[nodiscard]] Log::Level getLogLevel() const;
|
||||||
|
void setLogLevel(Log::Level level);
|
||||||
|
|
||||||
|
private:
|
||||||
Log::Level logLevel_{Log::Level::Trace};
|
Log::Level logLevel_{Log::Level::Trace};
|
||||||
};
|
};
|
||||||
@ -8,8 +8,9 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
FileChannel::FileChannel(const std::string &filename, std::ios_base::openmode mode, Log::Level logLevel)
|
FileChannel::FileChannel(const std::string &filename, std::ios_base::openmode mode, Log::Level logLevel)
|
||||||
: Channel(logLevel), filename_(filename), fileStream_(filename, mode)
|
: filename_(filename), fileStream_(filename, mode)
|
||||||
{
|
{
|
||||||
|
setLogLevel(logLevel);
|
||||||
if (!fileStream_.is_open())
|
if (!fileStream_.is_open())
|
||||||
{
|
{
|
||||||
std::cerr << "Failed to open log file: " << filename << '\n';
|
std::cerr << "Failed to open log file: " << filename << '\n';
|
||||||
@ -24,9 +25,10 @@ FileChannel::~FileChannel()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileChannel::log(Log::Level &logLevel, const std::string &message, const std::map<std::string, std::string> &context)
|
void FileChannel::log(const Log::Level &logLevel, const std::string &message,
|
||||||
|
const std::map<std::string, std::string> &context)
|
||||||
{
|
{
|
||||||
if (logLevel < logLevel_)
|
if (logLevel < getLogLevel())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -48,11 +50,18 @@ void FileChannel::log(Log::Level &logLevel, const std::string &message, const st
|
|||||||
// Log the context if it exists
|
// Log the context if it exists
|
||||||
if (!context.empty())
|
if (!context.empty())
|
||||||
{
|
{
|
||||||
fileStream_ << "Context:" << '\n';
|
fileStream_ << "\n\t| Context: {";
|
||||||
|
bool first = true;
|
||||||
for (const auto &[key, value] : context)
|
for (const auto &[key, value] : context)
|
||||||
{
|
{
|
||||||
fileStream_ << " " << key << ": " << value << '\n';
|
if (!first)
|
||||||
|
{
|
||||||
|
fileStream_ << ", ";
|
||||||
}
|
}
|
||||||
|
fileStream_ << key << ": " << value;
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
fileStream_ << "}\n";
|
||||||
}
|
}
|
||||||
fileStream_ << std::flush;
|
fileStream_ << std::flush;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include <webserv/log/Channel.hpp>
|
#include <webserv/log/Channel.hpp>
|
||||||
|
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -13,12 +12,12 @@ class FileChannel : public Channel
|
|||||||
FileChannel(const std::string &filename, std::ios_base::openmode mode, Log::Level logLevel = Log::Level::Trace);
|
FileChannel(const std::string &filename, std::ios_base::openmode mode, Log::Level logLevel = Log::Level::Trace);
|
||||||
|
|
||||||
FileChannel(const FileChannel &other) = delete;
|
FileChannel(const FileChannel &other) = delete;
|
||||||
FileChannel(const FileChannel &&other) = delete;
|
FileChannel(FileChannel &&other) = delete;
|
||||||
FileChannel &operator=(const FileChannel &other) = delete;
|
FileChannel &operator=(const FileChannel &other) = delete;
|
||||||
FileChannel &&operator=(const FileChannel &&other) = delete;
|
FileChannel &operator=(FileChannel &&other) = delete;
|
||||||
|
|
||||||
~FileChannel();
|
~FileChannel() override;
|
||||||
void log(Log::Level &logLevel, const std::string &message,
|
void log(const Log::Level &logLevel, const std::string &message,
|
||||||
const std::map<std::string, std::string> &context = {}) override;
|
const std::map<std::string, std::string> &context = {}) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
#include <source_location>
|
#include <source_location>
|
||||||
|
|
||||||
Log::Log()
|
Log::Log()
|
||||||
@ -22,7 +23,7 @@ void Log::setStdoutChannel(Log::Level logLevel)
|
|||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
log.channels_.insert({"stdout", std::unique_ptr<Channel>(new StdoutChannel(logLevel))});
|
log.channels_["stdout"] = std::make_unique<StdoutChannel>(logLevel);
|
||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
catch (const std::exception &e)
|
||||||
{
|
{
|
||||||
@ -39,7 +40,7 @@ void Log::setFileChannel(const std::string &filename, std::ios_base::openmode mo
|
|||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
log.channels_.insert({"file", std::unique_ptr<Channel>(new FileChannel(filename, mode, logLevel))});
|
log.channels_["file"] = std::make_unique<FileChannel>(filename, mode, logLevel);
|
||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
catch (const std::exception &e)
|
||||||
{
|
{
|
||||||
@ -135,12 +136,12 @@ const char *Log::logLevelToColor(Log::Level level)
|
|||||||
return mapping.color;
|
return mapping.color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "\033[0m"; // Default to reset
|
return RESET_COLOR; // Default to reset
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Log::logLevelToColoredString(Log::Level level)
|
std::string Log::logLevelToColoredString(Log::Level level)
|
||||||
{
|
{
|
||||||
return std::string(Log::logLevelToColor(level)) + Log::logLevelToString(level) + "\033[0m";
|
return std::string(Log::logLevelToColor(level)) + Log::logLevelToString(level) + RESET_COLOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log::Level Log::stringToLogLevel(const std::string &level)
|
Log::Level Log::stringToLogLevel(const std::string &level)
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// #include <webserv/log/Channel.hpp>
|
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <map>
|
#include <map>
|
||||||
@ -27,9 +25,9 @@ class Log
|
|||||||
};
|
};
|
||||||
|
|
||||||
Log(const Log &other) = delete;
|
Log(const Log &other) = delete;
|
||||||
Log(const Log &&other) = delete;
|
Log(Log &&other) = delete;
|
||||||
Log &operator=(const Log &other) = delete;
|
Log &operator=(const Log &other) = delete;
|
||||||
Log &&operator=(const Log &&other) = delete;
|
Log &operator=(Log &&other) = delete;
|
||||||
|
|
||||||
void log(Level level, const std::string &message, const std::map<std::string, std::string> &context,
|
void log(Level level, const std::string &message, const std::map<std::string, std::string> &context,
|
||||||
const std::source_location &location);
|
const std::source_location &location);
|
||||||
@ -52,6 +50,7 @@ class Log
|
|||||||
const std::source_location &location = std::source_location::current());
|
const std::source_location &location = std::source_location::current());
|
||||||
static void fatal(const std::string &message, const std::map<std::string, std::string> &context = {},
|
static void fatal(const std::string &message, const std::map<std::string, std::string> &context = {},
|
||||||
const std::source_location &location = std::source_location::current());
|
const std::source_location &location = std::source_location::current());
|
||||||
|
|
||||||
static std::string logLevelToString(Level level);
|
static std::string logLevelToString(Level level);
|
||||||
static const char *logLevelToColor(Level level);
|
static const char *logLevelToColor(Level level);
|
||||||
static std::string logLevelToColoredString(Level level);
|
static std::string logLevelToColoredString(Level level);
|
||||||
@ -66,20 +65,20 @@ class Log
|
|||||||
std::chrono::steady_clock::time_point start_time_;
|
std::chrono::steady_clock::time_point start_time_;
|
||||||
std::unordered_map<std::string, std::unique_ptr<Channel>> channels_;
|
std::unordered_map<std::string, std::unique_ptr<Channel>> channels_;
|
||||||
|
|
||||||
|
struct LevelMapping
|
||||||
|
|
||||||
struct LogLevelMapping
|
|
||||||
{
|
{
|
||||||
Log::Level level;
|
Log::Level level;
|
||||||
std::string_view name;
|
std::string_view name;
|
||||||
const char *color;
|
const char *color;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr static std::array<LogLevelMapping, 6> LOG_LEVEL_MAP = {
|
constexpr static std::array<LevelMapping, 6> LOG_LEVEL_MAP = {
|
||||||
{{.level = Log::Level::Trace, .name = "TRACE", .color = "\033[36m"},
|
{{.level = Log::Level::Trace, .name = "TRACE", .color = "\033[36m"},
|
||||||
{.level = Log::Level::Debug, .name = "DEBUG", .color = "\033[90m"},
|
{.level = Log::Level::Debug, .name = "DEBUG", .color = "\033[90m"},
|
||||||
{.level = Log::Level::Info, .name = "INFO", .color = "\033[37m"},
|
{.level = Log::Level::Info, .name = "INFO", .color = "\033[37m"},
|
||||||
{.level = Log::Level::Warn, .name = "WARN", .color = "\033[33m"},
|
{.level = Log::Level::Warn, .name = "WARN", .color = "\033[33m"},
|
||||||
{.level = Log::Level::Error, .name = "ERROR", .color = "\033[31m"},
|
{.level = Log::Level::Error, .name = "ERROR", .color = "\033[31m"},
|
||||||
{.level = Log::Level::Fatal, .name = "FATAL", .color = "\033[1;31m"}}};
|
{.level = Log::Level::Fatal, .name = "FATAL", .color = "\033[1;31m"}}};
|
||||||
|
|
||||||
|
constexpr static const char* RESET_COLOR = "\033[0m";
|
||||||
};
|
};
|
||||||
|
|||||||
@ -3,19 +3,19 @@
|
|||||||
#include <webserv/log/Channel.hpp>
|
#include <webserv/log/Channel.hpp>
|
||||||
#include <webserv/log/Log.hpp>
|
#include <webserv/log/Log.hpp>
|
||||||
|
|
||||||
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
StdoutChannel::StdoutChannel(Log::Level logLevel) : Channel(logLevel) {}
|
StdoutChannel::StdoutChannel(Log::Level logLevel)
|
||||||
|
{
|
||||||
|
setLogLevel(logLevel);
|
||||||
|
}
|
||||||
|
|
||||||
StdoutChannel::~StdoutChannel() {}
|
void StdoutChannel::log(const Log::Level &logLevel, const std::string &message,
|
||||||
|
|
||||||
void StdoutChannel::log(Log::Level &logLevel, const std::string &message,
|
|
||||||
const std::map<std::string, std::string> &context)
|
const std::map<std::string, std::string> &context)
|
||||||
{
|
{
|
||||||
if (logLevel < logLevel_)
|
if (logLevel < getLogLevel())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -25,12 +25,18 @@ void StdoutChannel::log(Log::Level &logLevel, const std::string &message,
|
|||||||
std::cout << message;
|
std::cout << message;
|
||||||
if (!context.empty())
|
if (!context.empty())
|
||||||
{
|
{
|
||||||
std::cout << " Context: {";
|
std::cout << "\n\t| Context: {";
|
||||||
|
bool first = true;
|
||||||
for (const auto &[key, value] : context)
|
for (const auto &[key, value] : context)
|
||||||
{
|
{
|
||||||
std::cout << key << ": " << value << ", ";
|
if (!first)
|
||||||
|
{
|
||||||
|
std::cout << ", ";
|
||||||
}
|
}
|
||||||
std::cout << "}";
|
std::cout << key << ": " << value;
|
||||||
|
first = false;
|
||||||
}
|
}
|
||||||
std::cout << "\n";
|
std::cout << "}\n";
|
||||||
|
}
|
||||||
|
std::cout << "\n" << std::flush;
|
||||||
}
|
}
|
||||||
@ -8,12 +8,12 @@ class StdoutChannel : public Channel
|
|||||||
StdoutChannel(Log::Level logLevel = Log::Level::Trace);
|
StdoutChannel(Log::Level logLevel = Log::Level::Trace);
|
||||||
|
|
||||||
StdoutChannel(const StdoutChannel &other) = delete;
|
StdoutChannel(const StdoutChannel &other) = delete;
|
||||||
StdoutChannel(const StdoutChannel &&other) = delete;
|
StdoutChannel(StdoutChannel &&other) = delete;
|
||||||
StdoutChannel &operator=(const StdoutChannel &other) = delete;
|
StdoutChannel &operator=(const StdoutChannel &other) = delete;
|
||||||
StdoutChannel &&operator=(const StdoutChannel &&other) = delete;
|
StdoutChannel &operator=(StdoutChannel &&other) = delete;
|
||||||
|
|
||||||
~StdoutChannel();
|
~StdoutChannel() override = default;
|
||||||
|
|
||||||
void log(Log::Level &logLevel, const std::string &message,
|
void log(const Log::Level &logLevel, const std::string &message,
|
||||||
const std::map<std::string, std::string> &context = {}) override;
|
const std::map<std::string, std::string> &context = {}) override;
|
||||||
};
|
};
|
||||||
@ -18,6 +18,7 @@ int main(int argc, char **argv)
|
|||||||
Log::setFileChannel("webserv.log", std::ios_base::app, Log::Level::Trace);
|
Log::setFileChannel("webserv.log", std::ios_base::app, Log::Level::Trace);
|
||||||
Log::setStdoutChannel(Log::Level::Info);
|
Log::setStdoutChannel(Log::Level::Info);
|
||||||
Log::info("\n======================\nStarting webserv...\n======================\n");
|
Log::info("\n======================\nStarting webserv...\n======================\n");
|
||||||
|
Log::warning("Testing context", {{ "key1", "value1"}, {"key2", "value2"}});
|
||||||
ConfigManager::getInstance().init(argv[1]); // NOLINT
|
ConfigManager::getInstance().init(argv[1]); // NOLINT
|
||||||
Server server(ConfigManager::getInstance());
|
Server server(ConfigManager::getInstance());
|
||||||
server.start();
|
server.start();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user