Redirect qt logs to nim-chronicles (#15234)

* fix: initialize nim gc
This commit is contained in:
Igor Sirotin 2024-07-05 16:10:59 +01:00 committed by GitHub
parent 41ba77e525
commit fecbd4005e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 65 additions and 28 deletions

View File

@ -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 status_go
import keycard_go import keycard_go
@ -85,6 +85,44 @@ proc ensureDirectories*(dataDir, tmpDir, logDir: string) =
createDir(tmpDir) createDir(tmpDir)
createDir(logDir) 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() = proc mainProc() =
when defined(macosx) and defined(arm64): when defined(macosx) and defined(arm64):
@ -160,6 +198,7 @@ proc mainProc() =
app.icon(app.applicationDirPath & statusAppIconPath) app.icon(app.applicationDirPath & statusAppIconPath)
prepareLogging() prepareLogging()
installMessageHandler(logHandlerCallback)
singletonInstance.engine.addImportPath("qrc:/") singletonInstance.engine.addImportPath("qrc:/")
singletonInstance.engine.addImportPath("qrc:/./imports") singletonInstance.engine.addImportPath("qrc:/./imports")
@ -203,9 +242,7 @@ proc mainProc() =
keycardServiceQObjPointer = cast[pointer](appController.keycardService.vptr) keycardServiceQObjPointer = cast[pointer](appController.keycardService.vptr)
setupRemoteSignalsHandling() setupRemoteSignalsHandling()
info fmt("Version: {APP_VERSION}") info "app info", version=APP_VERSION, commit=GIT_COMMIT, currentDateTime=now()
info fmt("Commit: {GIT_COMMIT}")
info "Current date:", currentDateTime=now()
info "starting application controller..." info "starting application controller..."
appController.start() appController.start()

View File

@ -64,6 +64,10 @@ DOS_API void DOS_CALL dos_qtwebview_initialize(void);
DOS_API void DOS_CALL dos_qguiapplication_try_enable_threaded_renderer(); 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 /// \brief Create a QGuiApplication
/// \note The created QGuiApplication should be freed by calling dos_qguiapplication_delete() /// \note The created QGuiApplication should be freed by calling dos_qguiapplication_delete()
DOS_API void DOS_CALL dos_qguiapplication_create(); DOS_API void DOS_CALL dos_qguiapplication_create();

View File

@ -187,33 +187,30 @@ void dos_qguiapplication_try_enable_threaded_renderer()
qputenv("QSG_RENDER_LOOP", QByteArrayLiteral("threaded")); qputenv("QSG_RENDER_LOOP", QByteArrayLiteral("threaded"));
} }
static MessageHandlerCallback messageHandlerCallback = nullptr;
// This catches the QT and QML logs and outputs them. // 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 // 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) void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{ {
QByteArray localMsg = msg.toLocal8Bit(); 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* file = context.file ? context.file : "";
const char* function = context.function ? context.function : ""; const char* function = context.function ? context.function : "";
switch (type) { int messageType = int(type);
case QtDebugMsg:
fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); messageHandlerCallback(messageType, message, category, file, function, context.line);
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;
} }
void dos_installMessageHandler(MessageHandlerCallback messageHandler)
{
messageHandlerCallback = messageHandler;
qInstallMessageHandler(myMessageOutput);
} }
void dos_qguiapplication_create() 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. // We increase js stack size to prevent "Maximum call stack size exceeded" on UI loading.
qputenv("QV4_JS_MAX_STACK_SIZE", "10485760"); qputenv("QV4_JS_MAX_STACK_SIZE", "10485760");
qputenv("QT_QUICK_CONTROLS_HOVER_ENABLED", "1"); qputenv("QT_QUICK_CONTROLS_HOVER_ENABLED", "1");
qInstallMessageHandler(myMessageOutput);
new QGuiApplication(argc, argv); new QGuiApplication(argc, argv);
#ifdef Q_OS_MACOS #ifdef Q_OS_MACOS

2
vendor/nimqml vendored

@ -1 +1 @@
Subproject commit 20d4db12bb40dcf1c549ab3149ca0b4b791e90b7 Subproject commit 10f8dc4ca2d67acbf6bc7e0f49f4c0c8ff2737a0