| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- #include "logger.h"
- #include <iostream>
- #include <iomanip>
- // Qt头文件只在需要时包含
- #ifdef QT_CORE_LIB
- #include <QString>
- #include <QDebug>
- #include <QLoggingCategory>
- #endif
- namespace av {
- // 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<std::mutex> lock(m_mutex);
- if (m_file.is_open()) {
- m_file << message << std::endl;
- m_file.flush();
- }
- }
- // QtOutput实现
- void QtOutput::write(LogLevel level, const std::string& message) {
- #ifdef QT_CORE_LIB
- QString qmsg = QString::fromUtf8(message.c_str());
- switch (level) {
- case LogLevel::DEBUG:
- qDebug() << qmsg;
- break;
- case LogLevel::INFO:
- qInfo() << qmsg;
- break;
- case LogLevel::WARNING:
- qWarning() << qmsg;
- break;
- case LogLevel::ERROR:
- qCritical() << qmsg;
- break;
- }
- #else
- // 如果没有Qt,回退到控制台输出
- ConsoleOutput console;
- console.write(level, message);
- #endif
- }
- // Logger实现
- Logger& Logger::instance() {
- static Logger instance;
- return instance;
- }
- void Logger::setLevel(LogLevel level) {
- std::lock_guard<std::mutex> lock(m_mutex);
- m_level = level;
- }
- LogLevel Logger::getLevel() const {
- std::lock_guard<std::mutex> lock(m_mutex);
- return m_level;
- }
- void Logger::addOutput(std::unique_ptr<LogOutput> output) {
- std::lock_guard<std::mutex> lock(m_mutex);
- m_outputs.push_back(std::move(output));
- }
- void Logger::clearOutputs() {
- std::lock_guard<std::mutex> 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);
- }
- }
- #ifdef QT_CORE_LIB
- void Logger::qtDebug(const QString& message) {
- debug(message.toUtf8().toStdString());
- }
- void Logger::qtInfo(const QString& message) {
- info(message.toUtf8().toStdString());
- }
- void Logger::qtWarning(const QString& message) {
- warning(message.toUtf8().toStdString());
- }
- void Logger::qtError(const QString& message) {
- error(message.toUtf8().toStdString());
- }
- #endif
- 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<FileOutput>(logFile));
- }
-
- // 添加控制台输出
- if (enableConsole) {
- logger.addOutput(std::make_unique<ConsoleOutput>());
- }
-
- // 添加Qt输出
- if (enableQt) {
- logger.addOutput(std::make_unique<QtOutput>());
- }
-
- logger.info("AV Logger initialized");
- }
- void Logger::log(LogLevel level, const std::string& message) {
- std::lock_guard<std::mutex> 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<std::chrono::milliseconds>(
- 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 av
|