diff --git a/webserv/log/Channel.cpp b/webserv/log/Channel.cpp index 5c14b55..ff5c7b1 100644 --- a/webserv/log/Channel.cpp +++ b/webserv/log/Channel.cpp @@ -29,4 +29,9 @@ std::string Channel::printContext(const std::map &cont } return ss.str(); +} + +bool Channel::isStdOut() const +{ + return false; } \ No newline at end of file diff --git a/webserv/log/Channel.hpp b/webserv/log/Channel.hpp index dc357d0..345884a 100644 --- a/webserv/log/Channel.hpp +++ b/webserv/log/Channel.hpp @@ -18,6 +18,7 @@ class Channel const std::map &context = {}) = 0; + [[nodiscard]] virtual bool isStdOut() const; protected: [[nodiscard]] static std::string printContext(const std::map &context); diff --git a/webserv/log/Log.cpp b/webserv/log/Log.cpp index f264183..af12486 100644 --- a/webserv/log/Log.cpp +++ b/webserv/log/Log.cpp @@ -1,7 +1,6 @@ -#include - #include // for Channel #include // for FileChannel +#include #include // for StdoutChannel #include // for duration_cast, operator-, steady_clock, duration, seconds @@ -66,8 +65,21 @@ void Log::log(Level level, const std::string &message, const std::mapisStdOut() && _statusActive) + { + // Clear status line before logging to stdout + clearStatus(); + } it.second->log(level, message, context); + + if (it.second->isStdOut() && wasActive) + { + // Reprint status line after logging to stdout + status(statusBackup); + } } } @@ -173,4 +185,35 @@ Log::Level Log::stringToLogLevel(const std::string &level) } } return Level::Info; // Default fallback +} + +std::string Log::_statusMessage; +bool Log::_statusActive = false; + +void Log::status(const std::string &message) +{ + _statusMessage = message; + _statusActive = true; + + // Save cursor position, move to bottom, clear line, print status, restore cursor + std::cout << "\033[s" // Save cursor position + << "\033[999;0H" // Move to bottom row + << "\033[2K" // Clear entire line + << "\033[7m" // Reverse video (inverted colors) + << message << "\033[0m" // Reset formatting + << "\033[u" // Restore cursor position + << std::flush; +} + +void Log::clearStatus() +{ + if (_statusActive) + { + _statusActive = false; + std::cout << "\033[s" // Save cursor position + << "\033[999;0H" // Move to bottom row + << "\033[2K" // Clear entire line + << "\033[u" // Restore cursor position + << std::flush; + } } \ No newline at end of file diff --git a/webserv/log/Log.hpp b/webserv/log/Log.hpp index bca3bf2..a46ab29 100644 --- a/webserv/log/Log.hpp +++ b/webserv/log/Log.hpp @@ -63,6 +63,9 @@ class Log static void error(const std::string &message, const std::map &context = {}); static void fatal(const std::string &message, const std::map &context = {}); + static void status(const std::string &message); + static void clearStatus(); + static std::string logLevelToString(Level level); static const char *logLevelToColor(Level level); static std::string logLevelToColoredString(Level level); @@ -71,6 +74,8 @@ class Log static void clearChannels(); private: + static std::string _statusMessage; + static bool _statusActive; Log(); ~Log() = default; diff --git a/webserv/log/StdoutChannel.cpp b/webserv/log/StdoutChannel.cpp index bd7c410..cbdfba3 100644 --- a/webserv/log/StdoutChannel.cpp +++ b/webserv/log/StdoutChannel.cpp @@ -1,6 +1,5 @@ -#include - #include // for Log +#include #include // for operator<<, setfill, setw #include // for basic_ostream, operator<<, basic_ostream::operator<<, cerr, cout, flush, ostream @@ -16,4 +15,9 @@ void StdoutChannel::log(const Log::Level &logLevel, const std::string &message, out << message << '\n'; out << printContext(context); out << std::flush; +} + +bool StdoutChannel::isStdOut() const +{ + return true; } \ No newline at end of file diff --git a/webserv/log/StdoutChannel.hpp b/webserv/log/StdoutChannel.hpp index 2811b05..58d3dd7 100644 --- a/webserv/log/StdoutChannel.hpp +++ b/webserv/log/StdoutChannel.hpp @@ -20,4 +20,6 @@ class StdoutChannel : public Channel void log(const Log::Level &logLevel, const std::string &message, const std::map &context = {}) override; + + [[nodiscard]] bool isStdOut() const override; }; \ No newline at end of file diff --git a/webserv/server/Server.cpp b/webserv/server/Server.cpp index e4d9ae7..f8f8be1 100644 --- a/webserv/server/Server.cpp +++ b/webserv/server/Server.cpp @@ -312,6 +312,8 @@ void Server::run() struct epoll_event events[MAX_EVENTS]; // NOLINT while (stop_ == 0) { + std::string status = "Active connections: " + std::to_string(clients_.size()); + Log::status(status); pollSockets(); pollClients(); handleEpoll(events, MAX_EVENTS); // NOLINT (cppcoreguidelines-pro-bounds-pointer-arithmetic)