/* * Author: Patrick-Christopher Mattulat * Company: Lynar Studios * E-Mail: webmaster@lynarstudios.com * Created: 2020-08-20 * Changed: 2023-05-24 * * */ #include #include #include #include #include #if defined(_MSC_VER) || defined(__APPLE__) #include #endif using ls::std::core::Class; using ls::std::core::NullPointerArgumentEvaluator; using ls::std::core::interface_type::IWriter; using ls::std::core::type::byte_type; using ls::std::io::Logger; using ls::std::io::LogLevel; using ls::std::io::LogLevelValue; using ls::std::io::NewLine; using std::put_time; using std::shared_ptr; using std::string; using std::string_view; using std::stringstream; using std::time; Logger::Logger(const shared_ptr &_writer) : Class("Logger"), logLevel(LogLevelValue::INFO) { this->_assignWriter(_writer); } Logger::~Logger() noexcept = default; void Logger::debug(const byte_type *_data) const { if (this->logLevel >= LogLevelValue::DEBUG) { this->_log(_data, LogLevel(LogLevelValue::DEBUG)); } } void Logger::error(const byte_type *_data) const { if (this->logLevel >= LogLevelValue::ERR) { this->_log(_data, LogLevel(LogLevelValue::ERR)); } } void Logger::fatal(const byte_type *_data) const { if (this->logLevel >= LogLevelValue::FATAL) { this->_log(_data, LogLevel(LogLevelValue::FATAL)); } } LogLevel Logger::getLogLevel() const { return this->logLevel; } void Logger::hideLogLevel() { this->displayLogLevel = false; } void Logger::hideTimestamp() { this->displayTimestamp = false; } void Logger::info(const byte_type *_data) const { if (this->logLevel >= LogLevelValue::INFO) { this->_log(_data, LogLevel(LogLevelValue::INFO)); } } void Logger::setLogLevel(const LogLevelValue &_logLevelValue) { this->logLevel = _logLevelValue; } void Logger::showLogLevel() { this->displayLogLevel = true; } void Logger::showTimestamp() { this->displayTimestamp = true; } void Logger::trace(const byte_type *_data) const { if (this->logLevel >= LogLevelValue::TRACE) { this->_log(_data, LogLevel(LogLevelValue::TRACE)); } } void Logger::warn(const byte_type *_data) const { if (this->logLevel >= LogLevelValue::WARN) { this->_log(_data, LogLevel(LogLevelValue::WARN)); } } void Logger::_assignWriter(const shared_ptr &_writer) { NullPointerArgumentEvaluator{_writer, "writer reference is null!"}.evaluate(); this->writer = _writer; } string Logger::_buildCharacterChain(size_t _amount) { string fillContent{}; for (size_t iteration{}; iteration < _amount; iteration++) { fillContent += ' '; } return fillContent; } string Logger::_createFillContent(string_view _text) { size_t padSize = 10; size_t fillSize = _text.size() > padSize ? 0 : padSize - _text.size(); string fillContent{}; if (fillSize > 0) { fillContent = Logger::_buildCharacterChain(fillSize); } return fillContent; } string Logger::_generateTimeString(const tm *_localTime) { stringstream _stream{}; _stream << put_time(_localTime, "%Y-%m-%d %H:%M:%S"); return _stream.str(); } string Logger::_getLogLevelString(const LogLevel &_logLevel) const { string logLevelString{}; if (this->displayLogLevel) { logLevelString = Logger::_padRight(string{_logLevel.toString() + ":"}); } return logLevelString; } string Logger::_getTimestampString() const { time_t timestamp = ::time(nullptr); struct tm localTime { }; #if defined(unix) || defined(__APPLE__) ::localtime_r(×tamp, &localTime); #endif #ifdef _WIN32 ::localtime_s(&localTime, ×tamp); #endif string timestampString{}; if (this->displayTimestamp) { timestampString = "[" + Logger::_generateTimeString(&localTime) + "] "; } return timestampString; } void Logger::_log(const byte_type *_data, const LogLevel &_logLevel) const { string logLevelString = this->_getLogLevelString(_logLevel); string timestampString = this->_getTimestampString(); string message = timestampString + logLevelString + string(_data) + NewLine::getUnixNewLine(); this->writer->write(message); } string Logger::_padRight(const string &_text) { return _text + Logger::_createFillContent(_text); }