From fecbd4005e514814ea1b8f69ffc6fa9b41f65fab Mon Sep 17 00:00:00 2001 From: Igor Sirotin Date: Fri, 5 Jul 2024 16:10:59 +0100 Subject: [PATCH] Redirect qt logs to nim-chronicles (#15234) * fix: initialize nim gc --- src/nim_status_client.nim | 45 +++++++++++++++++-- .../lib/include/DOtherSide/DOtherSide.h | 4 ++ vendor/DOtherSide/lib/src/DOtherSide.cpp | 42 ++++++++--------- vendor/nimqml | 2 +- 4 files changed, 65 insertions(+), 28 deletions(-) diff --git a/src/nim_status_client.nim b/src/nim_status_client.nim index 338f695bc7..7b755de5e0 100644 --- a/src/nim_status_client.nim +++ b/src/nim_status_client.nim @@ -1,4 +1,4 @@ -import NimQml, chronicles, os, stew/shims/strformat, strutils, times, md5, json +import NimQml, chronicles, os, stew/shims/strformat, strutils, times, md5, json, re import status_go import keycard_go @@ -85,6 +85,44 @@ proc ensureDirectories*(dataDir, tmpDir, logDir: string) = createDir(tmpDir) createDir(logDir) +proc logHandlerCallback(messageType: cint, message: cstring, category: cstring, file: cstring, function: cstring, line: cint) {.cdecl, exportc.} = + # Initialize Nim GC stack bottom for foreign threads + # https://status-im.github.io/nim-style-guide/interop.html#calling-nim-code-from-other-languages + when declared(setupForeignThreadGc): + setupForeignThreadGc() + when declared(nimGC_setStackBottom): + var locals {.volatile, noinit.}: pointer + locals = addr(locals) + nimGC_setStackBottom(locals) + + var text = $message + let fileString = $file + + if fileString != "" and text.startsWith(fileString): + text = text[fileString.len..^1] # Remove filepath + text = text.replace(re"[:0-9]+:\s*") # Remove line, column, colons and space separator + + logScope: + chroniclesLineNumbers = false + topics = "qt" + category = $category + file = fileString & ":" & $line + text + + case int(messageType): + of 0: # QtDebugMsg + debug "qt message" + of 1: # QtWarningMsg + warn "qt warning" + of 2: # QtCriticalMsg + error "qt error" + of 3: # QtFatalMsg + fatal "qt fatal error" + of 4: # QtInfoMsg + info "qt message" + else: + warn "qt message of unknown type", messageType = int(messageType) + proc mainProc() = when defined(macosx) and defined(arm64): @@ -160,6 +198,7 @@ proc mainProc() = app.icon(app.applicationDirPath & statusAppIconPath) prepareLogging() + installMessageHandler(logHandlerCallback) singletonInstance.engine.addImportPath("qrc:/") singletonInstance.engine.addImportPath("qrc:/./imports") @@ -203,9 +242,7 @@ proc mainProc() = keycardServiceQObjPointer = cast[pointer](appController.keycardService.vptr) setupRemoteSignalsHandling() - info fmt("Version: {APP_VERSION}") - info fmt("Commit: {GIT_COMMIT}") - info "Current date:", currentDateTime=now() + info "app info", version=APP_VERSION, commit=GIT_COMMIT, currentDateTime=now() info "starting application controller..." appController.start() diff --git a/vendor/DOtherSide/lib/include/DOtherSide/DOtherSide.h b/vendor/DOtherSide/lib/include/DOtherSide/DOtherSide.h index 14849bb41a..3147356941 100644 --- a/vendor/DOtherSide/lib/include/DOtherSide/DOtherSide.h +++ b/vendor/DOtherSide/lib/include/DOtherSide/DOtherSide.h @@ -64,6 +64,10 @@ DOS_API void DOS_CALL dos_qtwebview_initialize(void); DOS_API void DOS_CALL dos_qguiapplication_try_enable_threaded_renderer(); +typedef void (DOS_CALL *MessageHandlerCallback)(int type, const char* data, const char* category, const char* file, const char* func, int line); + +DOS_API void dos_installMessageHandler(MessageHandlerCallback logHandler); + /// \brief Create a QGuiApplication /// \note The created QGuiApplication should be freed by calling dos_qguiapplication_delete() DOS_API void DOS_CALL dos_qguiapplication_create(); diff --git a/vendor/DOtherSide/lib/src/DOtherSide.cpp b/vendor/DOtherSide/lib/src/DOtherSide.cpp index 4f9518b95d..286751d17d 100644 --- a/vendor/DOtherSide/lib/src/DOtherSide.cpp +++ b/vendor/DOtherSide/lib/src/DOtherSide.cpp @@ -187,33 +187,30 @@ void dos_qguiapplication_try_enable_threaded_renderer() qputenv("QSG_RENDER_LOOP", QByteArrayLiteral("threaded")); } +static MessageHandlerCallback messageHandlerCallback = nullptr; + // This catches the QT and QML logs and outputs them. // This is necessary on Windows, because otherwise we do not get any logs at all void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) { - QByteArray localMsg = msg.toLocal8Bit(); - const char *file = context.file ? context.file : ""; - const char *function = context.function ? context.function : ""; - switch (type) { - case QtDebugMsg: - fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); - break; - case QtInfoMsg: - fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); - break; - case QtWarningMsg: - fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); - break; - case QtCriticalMsg: - fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); - break; - case QtFatalMsg: - fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); - break; - default: - fprintf(stderr, "Default: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); - break; + if (messageHandlerCallback == nullptr) { + return; } + + auto localMessage = msg.toLocal8Bit(); + const char* message = localMessage.constData(); + const char* category = context.category ? context.category : ""; + const char* file = context.file ? context.file : ""; + const char* function = context.function ? context.function : ""; + int messageType = int(type); + + messageHandlerCallback(messageType, message, category, file, function, context.line); +} + +void dos_installMessageHandler(MessageHandlerCallback messageHandler) +{ + messageHandlerCallback = messageHandler; + qInstallMessageHandler(myMessageOutput); } void dos_qguiapplication_create() @@ -240,7 +237,6 @@ void dos_qguiapplication_create() // We increase js stack size to prevent "Maximum call stack size exceeded" on UI loading. qputenv("QV4_JS_MAX_STACK_SIZE", "10485760"); qputenv("QT_QUICK_CONTROLS_HOVER_ENABLED", "1"); - qInstallMessageHandler(myMessageOutput); new QGuiApplication(argc, argv); #ifdef Q_OS_MACOS diff --git a/vendor/nimqml b/vendor/nimqml index 20d4db12bb..10f8dc4ca2 160000 --- a/vendor/nimqml +++ b/vendor/nimqml @@ -1 +1 @@ -Subproject commit 20d4db12bb40dcf1c549ab3149ca0b4b791e90b7 +Subproject commit 10f8dc4ca2d67acbf6bc7e0f49f4c0c8ff2737a0