diff --git a/src/main_wayland.cpp b/src/main_wayland.cpp index 346426fd7..9ea4c9b84 100644 --- a/src/main_wayland.cpp +++ b/src/main_wayland.cpp @@ -40,6 +40,8 @@ #include #include #include +#include +#include // system #if HAVE_SYS_PRCTL_H @@ -58,6 +60,15 @@ #include #include +#if defined(QT_NO_DEBUG) +#define LOG_FILE_COUNT_MAX 2 +#else +#define LOG_FILE_COUNT_MAX 4 +#endif +#define LOG_FILE_SIZE_MAX 20*1024*1024 +#define LOG_FILE_PREFIX "ukui_kwin" +#define LOG_FILE_PATH "/.log/" + Q_IMPORT_PLUGIN(KWinIntegrationPlugin) Q_IMPORT_PLUGIN(KGlobalAccelImpl) Q_IMPORT_PLUGIN(KWindowSystemKWinPlugin) @@ -360,8 +371,106 @@ void dropNiceCapability() } // namespace + +/* +* find next log file, and do some check. +*/ +static int checkLogFile(int index) { + int logFileIndex = index; + for (size_t i = 0; i < LOG_FILE_COUNT_MAX; i++) { + logFileIndex = (logFileIndex + 1) % LOG_FILE_COUNT_MAX; + QString logFilePath = QDir::homePath() + LOG_FILE_PATH + "/" + QStringLiteral("%1_%2.log").arg(LOG_FILE_PREFIX).arg(logFileIndex); + if (!QFile::exists(logFilePath)) + break; + QFile temp(logFilePath); + if (temp.size() < LOG_FILE_SIZE_MAX) + break; + if ((LOG_FILE_COUNT_MAX - 1) == i) { + // here is the next log file. + logFileIndex = (logFileIndex + 1) % LOG_FILE_COUNT_MAX; + QString nextLogFilePath = QDir::homePath() + LOG_FILE_PATH + "/" + QStringLiteral("%1_%2.log").arg(LOG_FILE_PREFIX).arg(logFileIndex); + + // prepare rotate to next log file, so we should log some info in prev log file to make a better understanding. + FILE* tailFile = fopen(logFilePath.toLocal8Bit().constData(), "a+"); + if (tailFile) { + fprintf(tailFile, "to be continue, please check:\r\n\t[%s]", nextLogFilePath.toStdString().c_str()); + fclose(tailFile); + } + + // and make next log file be clear + QFile nextLogFile(nextLogFilePath); + nextLogFile.remove(); + } + } + return logFileIndex; +} + +static void messageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) +{ + QByteArray localMsg = msg.toLocal8Bit(); + + QDateTime dateTime = QDateTime::currentDateTime(); + QString strFormat = "yyMMdd hh:mm:ss.zzz"; + QString strDateTime = dateTime.toString(strFormat); + + FILE *log_file = nullptr; + QString logFilePath; + int fileSize; + static int currentLogFileIndex = -1; + QDir dir; + bool flag = 0; + + logFilePath = QDir::homePath() + LOG_FILE_PATH; + if (dir.mkpath(logFilePath)) { + flag = 1; + } + if (flag) { + if (-1 == currentLogFileIndex) + currentLogFileIndex = checkLogFile(currentLogFileIndex); + logFilePath = logFilePath + "/" + QStringLiteral("%1_%2.log").arg(LOG_FILE_PREFIX).arg(currentLogFileIndex); + log_file = fopen(logFilePath.toLocal8Bit().constData(), "a+"); + } + + QString src = QString(context.file ? context.file : "").section('/', -1); + QRegularExpression re("(\\w([\\S]*?)[\\s]?)(\\()"); + QRegularExpressionMatch match = re.match(context.function); + QString func = match.hasMatch() ? match.captured(1) : ""; + QString exinfo = src.isEmpty() ? QString() : QStringLiteral("(%1:%2 %3)").arg(src).arg(context.line).arg(func); + switch (type) { + case QtDebugMsg: + if (!log_file) { + break; + } + fprintf(log_file, "Debug: %s: %s %s\n", strDateTime.toStdString().c_str(), localMsg.constData(), exinfo.toStdString().c_str()); + break; + case QtInfoMsg: + fprintf(log_file? log_file: stdout, "Info: %s: %s %s\n", strDateTime.toStdString().c_str(), localMsg.constData(), exinfo.toStdString().c_str()); + break; + case QtWarningMsg: + fprintf(log_file? log_file: stderr, "Warning: %s: %s %s\n", strDateTime.toStdString().c_str(), localMsg.constData(), exinfo.toStdString().c_str()); + break; + case QtCriticalMsg: + fprintf(log_file? log_file: stderr, "Critical: %s: %s %s\n", strDateTime.toStdString().c_str(), localMsg.constData(), exinfo.toStdString().c_str()); + break; + case QtFatalMsg: + fprintf(log_file? log_file: stderr, "Fatal: %s: %s %s\n", strDateTime.toStdString().c_str(), localMsg.constData(), exinfo.toStdString().c_str()); + break; + } + + if (log_file) { + fileSize = ftell(log_file); + fclose(log_file); + if (fileSize >= LOG_FILE_SIZE_MAX) + currentLogFileIndex = checkLogFile(currentLogFileIndex); + } +} + int main(int argc, char * argv[]) { + qDebug() << "==================kdemain in before message handler==========================="; + qInstallMessageHandler(messageOutput); + qDebug() << "==================kdemain in==========================="; + KWin::disablePtrace(); KWin::Application::setupMalloc(); KWin::Application::setupLocalizedString(); diff --git a/src/main_x11.cpp b/src/main_x11.cpp index 03535831f..4171a861a 100644 --- a/src/main_x11.cpp +++ b/src/main_x11.cpp @@ -36,6 +36,8 @@ #include #include #include +#include +#include // system #ifdef HAVE_UNISTD_H @@ -43,6 +45,15 @@ #endif // HAVE_UNISTD_H #include +#if defined(QT_NO_DEBUG) +#define LOG_FILE_COUNT_MAX 2 +#else +#define LOG_FILE_COUNT_MAX 4 +#endif +#define LOG_FILE_SIZE_MAX 20*1024*1024 +#define LOG_FILE_PREFIX "ukui_kwin" +#define LOG_FILE_PATH "/.log/" + Q_LOGGING_CATEGORY(KWIN_CORE, "kwin_core", QtWarningMsg) namespace KWin @@ -334,8 +345,105 @@ void ApplicationX11::crashHandler(int signal) } // namespace +/* +* find next log file, and do some check. +*/ +static int checkLogFile(int index) { + int logFileIndex = index; + for (size_t i = 0; i < LOG_FILE_COUNT_MAX; i++) { + logFileIndex = (logFileIndex + 1) % LOG_FILE_COUNT_MAX; + QString logFilePath = QDir::homePath() + LOG_FILE_PATH + "/" + QStringLiteral("%1_%2.log").arg(LOG_FILE_PREFIX).arg(logFileIndex); + if (!QFile::exists(logFilePath)) + break; + QFile temp(logFilePath); + if (temp.size() < LOG_FILE_SIZE_MAX) + break; + if ((LOG_FILE_COUNT_MAX - 1) == i) { + // here is the next log file. + logFileIndex = (logFileIndex + 1) % LOG_FILE_COUNT_MAX; + QString nextLogFilePath = QDir::homePath() + LOG_FILE_PATH + "/" + QStringLiteral("%1_%2.log").arg(LOG_FILE_PREFIX).arg(logFileIndex); + + // prepare rotate to next log file, so we should log some info in prev log file to make a better understanding. + FILE* tailFile = fopen(logFilePath.toLocal8Bit().constData(), "a+"); + if (tailFile) { + fprintf(tailFile, "to be continue, please check:\r\n\t[%s]", nextLogFilePath.toStdString().c_str()); + fclose(tailFile); + } + + // and make next log file be clear + QFile nextLogFile(nextLogFilePath); + nextLogFile.remove(); + } + } + return logFileIndex; +} + +static void messageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) +{ + QByteArray localMsg = msg.toLocal8Bit(); + + QDateTime dateTime = QDateTime::currentDateTime(); + QString strFormat = "yyMMdd hh:mm:ss.zzz"; + QString strDateTime = dateTime.toString(strFormat); + + FILE *log_file = nullptr; + QString logFilePath; + int fileSize; + static int currentLogFileIndex = -1; + QDir dir; + bool flag = 0; + + logFilePath = QDir::homePath() + LOG_FILE_PATH; + if (dir.mkpath(logFilePath)) { + flag = 1; + } + if (flag) { + if (-1 == currentLogFileIndex) + currentLogFileIndex = checkLogFile(currentLogFileIndex); + logFilePath = logFilePath + "/" + QStringLiteral("%1_%2.log").arg(LOG_FILE_PREFIX).arg(currentLogFileIndex); + log_file = fopen(logFilePath.toLocal8Bit().constData(), "a+"); + } + + QString src = QString(context.file ? context.file : "").section('/', -1); + QRegularExpression re("(\\w([\\S]*?)[\\s]?)(\\()"); + QRegularExpressionMatch match = re.match(context.function); + QString func = match.hasMatch() ? match.captured(1) : ""; + QString exinfo = src.isEmpty() ? QString() : QStringLiteral("(%1:%2 %3)").arg(src).arg(context.line).arg(func); + switch (type) { + case QtDebugMsg: + if (!log_file) { + break; + } + fprintf(log_file, "Debug: %s: %s %s\n", strDateTime.toStdString().c_str(), localMsg.constData(), exinfo.toStdString().c_str()); + break; + case QtInfoMsg: + fprintf(log_file? log_file: stdout, "Info: %s: %s %s\n", strDateTime.toStdString().c_str(), localMsg.constData(), exinfo.toStdString().c_str()); + break; + case QtWarningMsg: + fprintf(log_file? log_file: stderr, "Warning: %s: %s %s\n", strDateTime.toStdString().c_str(), localMsg.constData(), exinfo.toStdString().c_str()); + break; + case QtCriticalMsg: + fprintf(log_file? log_file: stderr, "Critical: %s: %s %s\n", strDateTime.toStdString().c_str(), localMsg.constData(), exinfo.toStdString().c_str()); + break; + case QtFatalMsg: + fprintf(log_file? log_file: stderr, "Fatal: %s: %s %s\n", strDateTime.toStdString().c_str(), localMsg.constData(), exinfo.toStdString().c_str()); + break; + } + + if (log_file) { + fileSize = ftell(log_file); + fclose(log_file); + if (fileSize >= LOG_FILE_SIZE_MAX) + currentLogFileIndex = checkLogFile(currentLogFileIndex); + } +} + int main(int argc, char * argv[]) { + qDebug() << "==================kdemain in before message handler==========================="; + qInstallMessageHandler(messageOutput); + qDebug() << "==================kdemain in==========================="; + KWin::Application::setupMalloc(); KWin::Application::setupLocalizedString();