#include "tlogger.h" #include #include namespace TC { // ConsoleOutput实现 void ConsoleOutput::write(LogLevel level, const std::string& message) { std::ostream& stream = (level >= LogLevel::WARNING) ? std::cerr : std::cout; stream << message << std::endl; stream.flush(); } // FileOutput实现 FileOutput::FileOutput(const std::string& filename) { m_file.open(filename, std::ios::app); if (!m_file.is_open()) { std::cerr << "Failed to open log file: " << filename << std::endl; } } FileOutput::~FileOutput() { if (m_file.is_open()) { m_file.close(); } } void FileOutput::write(LogLevel level, const std::string& message) { std::lock_guard lock(m_mutex); if (m_file.is_open()) { m_file << message << std::endl; m_file.flush(); } } // Logger实现 Logger& Logger::instance() { static Logger instance; return instance; } void Logger::setLevel(LogLevel level) { std::lock_guard lock(m_mutex); m_level = level; } LogLevel Logger::getLevel() const { std::lock_guard lock(m_mutex); return m_level; } void Logger::addOutput(std::unique_ptr output) { std::lock_guard lock(m_mutex); m_outputs.push_back(std::move(output)); } void Logger::clearOutputs() { std::lock_guard lock(m_mutex); m_outputs.clear(); } void Logger::debug(const std::string& message) { if (shouldLog(LogLevel::DEBUG)) { log(LogLevel::DEBUG, message); } } void Logger::info(const std::string& message) { if (shouldLog(LogLevel::INFO)) { log(LogLevel::INFO, message); } } void Logger::warning(const std::string& message) { if (shouldLog(LogLevel::WARNING)) { log(LogLevel::WARNING, message); } } void Logger::error(const std::string& message) { if (shouldLog(LogLevel::ERROR)) { log(LogLevel::ERROR, message); } } void Logger::initialize(const std::string& logFile, LogLevel level, bool enableConsole, bool enableQt) { Logger& logger = instance(); logger.clearOutputs(); logger.setLevel(level); // 添加文件输出 if (!logFile.empty()) { logger.addOutput(std::make_unique(logFile)); } // 添加控制台输出 if (enableConsole) { logger.addOutput(std::make_unique()); } logger.info("AV Logger initialized"); } void Logger::log(LogLevel level, const std::string& message) { std::lock_guard lock(m_mutex); std::string formattedMessage = getCurrentTime() + " [" + levelToString(level) + "] " + message; for (auto& output : m_outputs) { if (output) { output->write(level, formattedMessage); } } } bool Logger::shouldLog(LogLevel level) const { return level >= m_level; } std::string Logger::getCurrentTime() const { auto now = std::chrono::system_clock::now(); auto time_t = std::chrono::system_clock::to_time_t(now); auto ms = std::chrono::duration_cast(now.time_since_epoch()) % 1000; std::ostringstream oss; oss << std::put_time(std::localtime(&time_t), "%Y-%m-%d %H:%M:%S"); oss << '.' << std::setfill('0') << std::setw(3) << ms.count(); return oss.str(); } std::string Logger::levelToString(LogLevel level) const { switch (level) { case LogLevel::DEBUG: return "DEBUG"; case LogLevel::INFO: return "INFO"; case LogLevel::WARNING: return "WARN"; case LogLevel::ERROR: return "ERROR"; default: return "UNKNOWN"; } } } // namespace TC