// DragonX Wallet - ImGui Edition // Copyright 2024-2026 The Hush Developers // Released under the GPLv3 // // lite_diagnostics.h — a small, thread-safe in-memory log of lite-wallet diagnostic events // (server connection attempts, wallet open/create/restore, sync milestones, errors). Written // from the controller's background threads and the App; read by the lite Console tab. Bounded // so it can't grow without limit. Header-only (a Meyers singleton) so both the wallet layer // and the UI can use it with no extra link target. #pragma once #include #include #include #include #include #include #include #include namespace dragonx { namespace wallet { class LiteDiagnostics { public: // Defined in lite_diagnostics.cpp (a single TU) so there is exactly one instance across the // whole binary — no reliance on the linker folding an inline-function static across TUs. static LiteDiagnostics& instance(); // Append a timestamped line (thread-safe). Safe to call from background threads. void log(const std::string& message) { std::string line = timestamp(); line += message; std::lock_guard lk(mutex_); lines_.push_back(std::move(line)); if (lines_.size() > kMaxLines) lines_.pop_front(); ++generation_; } // Copy of the current lines (oldest first). std::vector snapshot() const { std::lock_guard lk(mutex_); return std::vector(lines_.begin(), lines_.end()); } // Monotonic counter bumped on every change — lets readers re-snapshot only when it differs. std::uint64_t generation() const { std::lock_guard lk(mutex_); return generation_; } void clear() { std::lock_guard lk(mutex_); lines_.clear(); ++generation_; } private: LiteDiagnostics() = default; static std::string timestamp() { std::time_t t = std::time(nullptr); std::tm tmv{}; #ifdef _WIN32 localtime_s(&tmv, &t); #else localtime_r(&t, &tmv); #endif char buf[16]; std::snprintf(buf, sizeof(buf), "%02d:%02d:%02d ", tmv.tm_hour, tmv.tm_min, tmv.tm_sec); return std::string(buf); } static constexpr std::size_t kMaxLines = 500; mutable std::mutex mutex_; std::deque lines_; std::uint64_t generation_ = 0; }; // Convenience: append a lite diagnostic line. inline void liteLog(const std::string& message) { LiteDiagnostics::instance().log(message); } } // namespace wallet } // namespace dragonx