Diagnostics & logging: - add verbose logging system (VERBOSE_LOGF) with toggle in Settings - forward app-level log messages to Console tab for in-UI visibility - add detailed connection attempt logging (attempt #, daemon state, config paths, auth failures, port owner identification) - detect HTTP 401 auth failures and show actionable error messages - identify port owner process (PID + name) on both Linux and Windows - demote noisy acrylic/shader traces from DEBUG_LOGF to VERBOSE_LOGF - persist verbose_logging preference in settings.json - link iphlpapi on Windows for GetExtendedTcpTable Security & encryption: - update local encryption state immediately after encryptwallet RPC so Settings reflects the change before daemon restarts - show notifications for encrypt success/failure and PIN skip - use dedicated RPC client for z_importwallet during decrypt flow to avoid blocking main rpc_ curl_mutex (which starved peer/tx refresh) - force full state refresh (addresses, transactions, peers) after successful wallet import Network tab: - redesign peers refresh button as glass-panel with icon + label, matching the mining button style - add spinning arc animation while peer data is loading (peer_refresh_in_progress_ atomic flag set/cleared in refreshPeerInfo) - prevent double-click spam during refresh - add refresh-button size to ui.toml Other: - use fast_rpc_ for rescan polling to avoid blocking on main rpc_ - enable DRAGONX_DEBUG in all build configs (was debug-only) - setup.sh: pull latest xmrig-hac when repo already exists
103 lines
2.1 KiB
C++
103 lines
2.1 KiB
C++
// DragonX Wallet - ImGui Edition
|
|
// Copyright 2024-2026 The Hush Developers
|
|
// Released under the GPLv3
|
|
|
|
#include "logger.h"
|
|
|
|
#include <cstdarg>
|
|
#include <ctime>
|
|
#include <chrono>
|
|
#include <iomanip>
|
|
#include <sstream>
|
|
|
|
namespace dragonx {
|
|
namespace util {
|
|
|
|
Logger::Logger() = default;
|
|
|
|
Logger::~Logger()
|
|
{
|
|
if (file_.is_open()) {
|
|
file_.close();
|
|
}
|
|
}
|
|
|
|
Logger& Logger::instance()
|
|
{
|
|
static Logger logger;
|
|
return logger;
|
|
}
|
|
|
|
bool Logger::init(const std::string& path)
|
|
{
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
|
|
if (file_.is_open()) {
|
|
file_.close();
|
|
}
|
|
|
|
file_.open(path, std::ios::out | std::ios::app);
|
|
initialized_ = file_.is_open();
|
|
|
|
if (initialized_) {
|
|
write("=== Logger initialized ===");
|
|
}
|
|
|
|
return initialized_;
|
|
}
|
|
|
|
void Logger::write(const std::string& message)
|
|
{
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
|
|
// Get current timestamp
|
|
auto now = std::chrono::system_clock::now();
|
|
auto time = std::chrono::system_clock::to_time_t(now);
|
|
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
|
|
now.time_since_epoch()) % 1000;
|
|
|
|
std::stringstream ss;
|
|
ss << std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S");
|
|
ss << '.' << std::setfill('0') << std::setw(3) << ms.count();
|
|
ss << " | " << message;
|
|
|
|
std::string line = ss.str();
|
|
|
|
// Write to file if open
|
|
if (file_.is_open()) {
|
|
file_ << line << std::endl;
|
|
file_.flush();
|
|
}
|
|
|
|
// Also write to stdout in debug mode
|
|
#ifdef DRAGONX_DEBUG
|
|
printf("%s\n", line.c_str());
|
|
#endif
|
|
|
|
// Forward to callback (e.g. ConsoleTab) with the raw message
|
|
if (callback_) {
|
|
callback_(message);
|
|
}
|
|
}
|
|
|
|
void Logger::writef(const char* format, ...)
|
|
{
|
|
char buffer[4096];
|
|
|
|
va_list args;
|
|
va_start(args, format);
|
|
vsnprintf(buffer, sizeof(buffer), format, args);
|
|
va_end(args);
|
|
|
|
write(buffer);
|
|
}
|
|
|
|
void Logger::setCallback(std::function<void(const std::string&)> cb)
|
|
{
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
callback_ = std::move(cb);
|
|
}
|
|
|
|
} // namespace util
|
|
} // namespace dragonx
|