logger.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. #include "logger.h"
  2. #include <iostream>
  3. #include <iomanip>
  4. // Qt头文件只在需要时包含
  5. #ifdef QT_CORE_LIB
  6. #include <QString>
  7. #include <QDebug>
  8. #include <QLoggingCategory>
  9. #endif
  10. namespace av {
  11. // ConsoleOutput实现
  12. void ConsoleOutput::write(LogLevel level, const std::string& message) {
  13. std::ostream& stream = (level >= LogLevel::WARNING) ? std::cerr : std::cout;
  14. stream << message << std::endl;
  15. stream.flush();
  16. }
  17. // FileOutput实现
  18. FileOutput::FileOutput(const std::string& filename) {
  19. m_file.open(filename, std::ios::app);
  20. if (!m_file.is_open()) {
  21. std::cerr << "Failed to open log file: " << filename << std::endl;
  22. }
  23. }
  24. FileOutput::~FileOutput() {
  25. if (m_file.is_open()) {
  26. m_file.close();
  27. }
  28. }
  29. void FileOutput::write(LogLevel level, const std::string& message) {
  30. std::lock_guard<std::mutex> lock(m_mutex);
  31. if (m_file.is_open()) {
  32. m_file << message << std::endl;
  33. m_file.flush();
  34. }
  35. }
  36. // QtOutput实现
  37. void QtOutput::write(LogLevel level, const std::string& message) {
  38. #ifdef QT_CORE_LIB
  39. QString qmsg = QString::fromUtf8(message.c_str());
  40. switch (level) {
  41. case LogLevel::DEBUG:
  42. qDebug() << qmsg;
  43. break;
  44. case LogLevel::INFO:
  45. qInfo() << qmsg;
  46. break;
  47. case LogLevel::WARNING:
  48. qWarning() << qmsg;
  49. break;
  50. case LogLevel::ERROR:
  51. qCritical() << qmsg;
  52. break;
  53. }
  54. #else
  55. // 如果没有Qt,回退到控制台输出
  56. ConsoleOutput console;
  57. console.write(level, message);
  58. #endif
  59. }
  60. // Logger实现
  61. Logger& Logger::instance() {
  62. static Logger instance;
  63. return instance;
  64. }
  65. void Logger::setLevel(LogLevel level) {
  66. std::lock_guard<std::mutex> lock(m_mutex);
  67. m_level = level;
  68. }
  69. LogLevel Logger::getLevel() const {
  70. std::lock_guard<std::mutex> lock(m_mutex);
  71. return m_level;
  72. }
  73. void Logger::addOutput(std::unique_ptr<LogOutput> output) {
  74. std::lock_guard<std::mutex> lock(m_mutex);
  75. m_outputs.push_back(std::move(output));
  76. }
  77. void Logger::clearOutputs() {
  78. std::lock_guard<std::mutex> lock(m_mutex);
  79. m_outputs.clear();
  80. }
  81. void Logger::debug(const std::string& message) {
  82. if (shouldLog(LogLevel::DEBUG)) {
  83. log(LogLevel::DEBUG, message);
  84. }
  85. }
  86. void Logger::info(const std::string& message) {
  87. if (shouldLog(LogLevel::INFO)) {
  88. log(LogLevel::INFO, message);
  89. }
  90. }
  91. void Logger::warning(const std::string& message) {
  92. if (shouldLog(LogLevel::WARNING)) {
  93. log(LogLevel::WARNING, message);
  94. }
  95. }
  96. void Logger::error(const std::string& message) {
  97. if (shouldLog(LogLevel::ERROR)) {
  98. log(LogLevel::ERROR, message);
  99. }
  100. }
  101. #ifdef QT_CORE_LIB
  102. void Logger::qtDebug(const QString& message) {
  103. debug(message.toUtf8().toStdString());
  104. }
  105. void Logger::qtInfo(const QString& message) {
  106. info(message.toUtf8().toStdString());
  107. }
  108. void Logger::qtWarning(const QString& message) {
  109. warning(message.toUtf8().toStdString());
  110. }
  111. void Logger::qtError(const QString& message) {
  112. error(message.toUtf8().toStdString());
  113. }
  114. #endif
  115. void Logger::initialize(const std::string& logFile,
  116. LogLevel level,
  117. bool enableConsole,
  118. bool enableQt) {
  119. Logger& logger = instance();
  120. logger.clearOutputs();
  121. logger.setLevel(level);
  122. // 添加文件输出
  123. if (!logFile.empty()) {
  124. logger.addOutput(std::make_unique<FileOutput>(logFile));
  125. }
  126. // 添加控制台输出
  127. if (enableConsole) {
  128. logger.addOutput(std::make_unique<ConsoleOutput>());
  129. }
  130. // 添加Qt输出
  131. if (enableQt) {
  132. logger.addOutput(std::make_unique<QtOutput>());
  133. }
  134. logger.info("AV Logger initialized");
  135. }
  136. void Logger::log(LogLevel level, const std::string& message) {
  137. std::lock_guard<std::mutex> lock(m_mutex);
  138. std::string formattedMessage = getCurrentTime() + " [" + levelToString(level) + "] " + message;
  139. for (auto& output : m_outputs) {
  140. if (output) {
  141. output->write(level, formattedMessage);
  142. }
  143. }
  144. }
  145. bool Logger::shouldLog(LogLevel level) const {
  146. return level >= m_level;
  147. }
  148. std::string Logger::getCurrentTime() const {
  149. auto now = std::chrono::system_clock::now();
  150. auto time_t = std::chrono::system_clock::to_time_t(now);
  151. auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
  152. now.time_since_epoch()) % 1000;
  153. std::ostringstream oss;
  154. oss << std::put_time(std::localtime(&time_t), "%Y-%m-%d %H:%M:%S");
  155. oss << '.' << std::setfill('0') << std::setw(3) << ms.count();
  156. return oss.str();
  157. }
  158. std::string Logger::levelToString(LogLevel level) const {
  159. switch (level) {
  160. case LogLevel::DEBUG: return "DEBUG";
  161. case LogLevel::INFO: return "INFO";
  162. case LogLevel::WARNING: return "WARN";
  163. case LogLevel::ERROR: return "ERROR";
  164. default: return "UNKNOWN";
  165. }
  166. }
  167. } // namespace av