// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com) // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp #include #include #include #include #include #include #include #include namespace Nz { /*! * \ingroup core * \class Nz::FileLogger * \brief Core class that represents a file logger */ /*! * \brief Constructs a FileLogger object with a file name * * \param logPath Path to log */ FileLogger::FileLogger(std::filesystem::path logPath) : m_outputPath(std::move(logPath)), m_forceStdOutput(false), m_stdReplicationEnabled(true), m_timeLoggingEnabled(true) { } /*! * \brief Destructs the object */ FileLogger::~FileLogger() = default; /*! * \brief Enables the log of the time * * \param enable If true, enables the time log */ void FileLogger::EnableTimeLogging(bool enable) { m_timeLoggingEnabled = enable; } /*! * \brief Enables the replication to the stdout * * \param enable If true, enables the replication */ void FileLogger::EnableStdReplication(bool enable) { m_stdReplicationEnabled = enable; } /*! * \brief Checks whether or not the replication to the stdout is enabled * \return true If replication is enabled */ bool FileLogger::IsStdReplicationEnabled() const { return m_stdReplicationEnabled; } /*! * \brief Checks whether or not the logging of the time is enabled * \return true If logging of the time is enabled */ bool FileLogger::IsTimeLoggingEnabled() const { return m_timeLoggingEnabled; } /*! * \brief Writes a string in the log * * \param string String to log * * \remark Produces a NazaraError if file could not be opened * * \see WriteError */ void FileLogger::Write(std::string_view string) { if (m_forceStdOutput || m_stdReplicationEnabled) { m_stdLogger.Write(string); if (m_forceStdOutput) return; } // To prevent infinite loops m_forceStdOutput = true; CallOnExit resetOnExit([this] () { m_forceStdOutput = false; }); if (!m_outputFile.is_open()) { m_outputFile.open(m_outputPath, std::ios_base::trunc | std::ios_base::out); if (!m_outputFile.is_open()) { NazaraError("Failed to open output file"); return; } } // Apply some processing before writing std::ostringstream stream; if (m_timeLoggingEnabled) { std::array buffer; time_t currentTime = std::time(nullptr); std::strftime(buffer.data(), 24, "%d/%m/%Y - %H:%M:%S: ", std::localtime(¤tTime)); stream << buffer.data(); } stream << string << '\n'; m_outputFile << stream.str(); } /*! * \brief Writes an error in the log * * \param type The error type * \param error The error text * \param line The line the error occurred * \param file The file the error occurred * \param function The function the error occurred * * \see Write */ void FileLogger::WriteError(ErrorType type, std::string_view error, unsigned int line, const char* file, const char* function) { AbstractLogger::WriteError(type, error, line, file, function); m_outputFile.flush(); } }