From 1cbb349e05a25d84bc2b006555aae82cff317e67 Mon Sep 17 00:00:00 2001 From: maelstrom Date: Fri, 23 May 2025 00:59:31 +0200 Subject: [PATCH] feat(logging): better error logging with stack trace in lua --- core/src/logger.cpp | 17 ++++++++++++ core/src/logger.h | 9 +++++- core/src/objects/base/instance.cpp | 13 +++++++++ core/src/objects/base/instance.h | 1 + core/src/objects/script.cpp | 34 +++++++++++++++++++++-- core/src/objects/script/scriptcontext.cpp | 14 ++++++++-- core/src/objects/script/scriptcontext.h | 7 +++++ editor/mainwindow.cpp | 8 ++++++ editor/mainwindow.h | 1 + 9 files changed, 98 insertions(+), 6 deletions(-) diff --git a/core/src/logger.cpp b/core/src/logger.cpp index 8af1379..d5ab497 100644 --- a/core/src/logger.cpp +++ b/core/src/logger.cpp @@ -4,10 +4,12 @@ #include #include #include +#include #include static std::ofstream logStream; static std::vector logListeners; +static std::vector traceLogListeners; std::string Logger::currentLogDir = "NULL"; void Logger::init() { @@ -29,6 +31,7 @@ void Logger::finish() { void Logger::log(std::string message, Logger::LogLevel logLevel) { std::string logLevelStr = logLevel == Logger::LogLevel::INFO ? "INFO" : logLevel == Logger::LogLevel::DEBUG ? "DEBUG" : + logLevel == Logger::LogLevel::TRACE ? "TRACE" : logLevel == Logger::LogLevel::WARNING ? "WARN" : logLevel == Logger::LogLevel::ERROR ? "ERROR" : logLevel == Logger::LogLevel::FATAL_ERROR ? "FATAL" : "?"; @@ -49,6 +52,20 @@ void Logger::log(std::string message, Logger::LogLevel logLevel) { } } +void Logger::trace(std::string source, int line, void* userData) { + std::string message = "'" + source + "' Line " + std::to_string(line); + + log(message, Logger::LogLevel::TRACE); + + for (Logger::TraceLogListener listener : traceLogListeners) { + listener(message, source, line, userData); + } +} + void Logger::addLogListener(Logger::LogListener listener) { logListeners.push_back(listener); +} + +void Logger::addLogListener(Logger::TraceLogListener listener) { + traceLogListeners.push_back(listener); } \ No newline at end of file diff --git a/core/src/logger.h b/core/src/logger.h index 8f9792b..f0b098e 100644 --- a/core/src/logger.h +++ b/core/src/logger.h @@ -8,18 +8,21 @@ namespace Logger { enum class LogLevel { INFO, DEBUG, + TRACE, WARNING, ERROR, FATAL_ERROR, }; - typedef std::function LogListener; + typedef std::function LogListener; + typedef std::function TraceLogListener; extern std::string currentLogDir; void init(); void finish(); void addLogListener(LogListener); + void addLogListener(TraceLogListener); void log(std::string message, LogLevel logLevel); inline void info(std::string message) { log(message, LogLevel::INFO); } @@ -28,6 +31,10 @@ namespace Logger { inline void error(std::string message) { log(message, LogLevel::ERROR); } inline void fatalError(std::string message) { log(message, LogLevel::FATAL_ERROR); } + inline void traceStart() { log("Stack start", LogLevel::TRACE); } + inline void traceEnd() { log("Stack end", LogLevel::TRACE); } + void trace(std::string source, int line, void* userData = nullptr); + template void logf(std::string format, LogLevel logLevel, Args&&... args) { char message[200]; diff --git a/core/src/objects/base/instance.cpp b/core/src/objects/base/instance.cpp index 871c583..5f995d0 100644 --- a/core/src/objects/base/instance.cpp +++ b/core/src/objects/base/instance.cpp @@ -429,4 +429,17 @@ std::vector>> Instance::GetRefe } return referenceProperties; +} + +std::string Instance::GetFullName() { + std::string currentName = name; + std::optional> currentParent = GetParent(); + + while (currentParent.has_value() && !currentParent.value()->IsA("DataModel")) { + currentName = currentParent.value()->name + "." + currentName; + + currentParent = currentParent.value()->GetParent(); + } + + return currentName; } \ No newline at end of file diff --git a/core/src/objects/base/instance.h b/core/src/objects/base/instance.h index 1e9734e..b1f968a 100644 --- a/core/src/objects/base/instance.h +++ b/core/src/objects/base/instance.h @@ -113,6 +113,7 @@ public: // Utility functions inline void AddChild(std::shared_ptr object) { object->SetParent(this->shared_from_this()); } std::optional> FindFirstChild(std::string); + std::string GetFullName(); // Properties result GetPropertyValue(std::string name); diff --git a/core/src/objects/script.cpp b/core/src/objects/script.cpp index 3ac6e67..235e67d 100644 --- a/core/src/objects/script.cpp +++ b/core/src/objects/script.cpp @@ -22,7 +22,8 @@ Script::Script(): Instance(&TYPE) { "workspace.Part.TouchEnded:Connect(function(otherPart)\n" " print(\"Touched ended with: \", otherPart.Name)\n" "end)\n" - "\n"; + "\n" + "error(\"Test\")"; } Script::~Script() { @@ -57,12 +58,39 @@ void Script::Run() { lua_pop(Lt, 1); // _G // Load source and push onto thread stack as function ptr - luaL_loadstring(Lt, source.c_str()); + // luaL_loadstring(Lt, source.c_str()); + luaL_loadbuffer(Lt, source.c_str(), source.size(), scriptContext->RegisterScriptSource(shared