impress_voice_input/src/utils/logger.cpp
impressionyang 02e100b318 feat: 初始化 Impress Voice Input 项目
基于 ONNX 的实时语音转文本输入法,C++ 跨平台实现。

核心组件:
- Qt 6 跨平台 GUI(实时识别 / 文件转写 / 配置页面)
- ONNX Runtime 推理引擎(异步模型加载)
- PortAudio 音频采集
- dr_libs 音频文件解码
- JSON 配置管理(线程安全,自动持久化)
- 日志系统(控制台 + 文件输出)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-12 15:53:05 +08:00

128 lines
3.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "logger.h"
#include <QDateTime>
#include <QDebug>
#include <QTextStream>
#include <QStandardPaths>
#include <QDir>
#include <iostream>
namespace impress {
QMutex Logger::mutex_;
QFile* Logger::logFile_ = nullptr;
void Logger::init(const QString& logFilePath) {
QMutexLocker locker(&mutex_);
qSetMessagePattern("[%{time yyyy-MM-dd hh:mm:ss.zzz}] %{message}");
// 确定日志文件路径
QString path = logFilePath;
if (path.isEmpty()) {
QString logDir = QStandardPaths::writableLocation(
QStandardPaths::AppDataLocation);
QDir().mkpath(logDir);
path = logDir + "/app.log";
}
logFile_ = new QFile(path);
if (logFile_->open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) {
// Qt 6 没有 setAutoFlush每次 write 后手动 flush
} else {
delete logFile_;
logFile_ = nullptr;
std::cerr << "[Logger] 无法打开日志文件: " << path.toStdString() << std::endl;
}
}
void Logger::shutdown() {
QMutexLocker locker(&mutex_);
if (logFile_) {
logFile_->flush();
logFile_->close();
delete logFile_;
logFile_ = nullptr;
}
}
void Logger::setLogFile(const QString& path) {
QMutexLocker locker(&mutex_);
if (logFile_) {
logFile_->flush();
logFile_->close();
delete logFile_;
}
logFile_ = new QFile(path);
if (logFile_->open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) {
// Qt 6 没有 setAutoFlush每次 write 后手动 flush
} else {
delete logFile_;
logFile_ = nullptr;
}
}
void Logger::log(LogLevel level, const QString& tag, const QString& message) {
QMutexLocker locker(&mutex_);
QString logLine = QString("[%1] [%2] [%3] %4")
.arg(getTimestamp(), levelToString(level), tag, message);
// 输出到控制台
switch (level) {
case LogLevel::Debug:
qDebug().noquote() << logLine;
break;
case LogLevel::Info:
qInfo().noquote() << logLine;
break;
case LogLevel::Warning:
qWarning().noquote() << logLine;
break;
case LogLevel::Error:
std::cerr << logLine.toStdString() << std::endl;
break;
}
// 写入文件
writeToFile(logLine);
}
void Logger::debug(const QString& tag, const QString& message) {
log(LogLevel::Debug, tag, message);
}
void Logger::info(const QString& tag, const QString& message) {
log(LogLevel::Info, tag, message);
}
void Logger::warning(const QString& tag, const QString& message) {
log(LogLevel::Warning, tag, message);
}
void Logger::error(const QString& tag, const QString& message) {
log(LogLevel::Error, tag, message);
}
QString Logger::levelToString(LogLevel level) {
switch (level) {
case LogLevel::Debug: return "DEBUG";
case LogLevel::Info: return "INFO";
case LogLevel::Warning: return "WARN";
case LogLevel::Error: return "ERROR";
}
return "UNKNOWN";
}
QString Logger::getTimestamp() {
return QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
}
void Logger::writeToFile(const QString& line) {
if (logFile_ && logFile_->isOpen()) {
QTextStream stream(logFile_);
stream.setEncoding(QStringConverter::Utf8);
stream << line << Qt::endl;
logFile_->flush();
}
}
} // namespace impress