strip sensitive information from logs
This commit is contained in:
@@ -116,7 +116,8 @@
|
|||||||
"Bash(npm install *)",
|
"Bash(npm install *)",
|
||||||
"Bash(NODE_PATH=\"C:/home/alex/.npm-global/node_modules\" node build_anslib_logging_guide.js)",
|
"Bash(NODE_PATH=\"C:/home/alex/.npm-global/node_modules\" node build_anslib_logging_guide.js)",
|
||||||
"Bash(python \"C:/Users/nghia/AppData/Roaming/Claude/local-agent-mode-sessions/skills-plugin/d8e35aa4-a14e-4e20-b921-ba1b9a3cce86/cdda7cc8-a1c7-42ff-98b4-473ec3e8b9fb/skills/docx/scripts/office/validate.py\" \"C:/Projects/CLionProjects/ANSCORE/docs/ANSLIB_Logging_Guide.docx\")",
|
"Bash(python \"C:/Users/nghia/AppData/Roaming/Claude/local-agent-mode-sessions/skills-plugin/d8e35aa4-a14e-4e20-b921-ba1b9a3cce86/cdda7cc8-a1c7-42ff-98b4-473ec3e8b9fb/skills/docx/scripts/office/validate.py\" \"C:/Projects/CLionProjects/ANSCORE/docs/ANSLIB_Logging_Guide.docx\")",
|
||||||
"Bash(python \"C:/Users/nghia/AppData/Roaming/Claude/local-agent-mode-sessions/skills-plugin/d8e35aa4-a14e-4e20-b921-ba1b9a3cce86/cdda7cc8-a1c7-42ff-98b4-473ec3e8b9fb/skills/docx/scripts/office/soffice.py\" --headless --convert-to pdf --outdir \"C:/Projects/CLionProjects/ANSCORE/docs\" \"C:/Projects/CLionProjects/ANSCORE/docs/ANSLIB_Logging_Guide.docx\")"
|
"Bash(python \"C:/Users/nghia/AppData/Roaming/Claude/local-agent-mode-sessions/skills-plugin/d8e35aa4-a14e-4e20-b921-ba1b9a3cce86/cdda7cc8-a1c7-42ff-98b4-473ec3e8b9fb/skills/docx/scripts/office/soffice.py\" --headless --convert-to pdf --outdir \"C:/Projects/CLionProjects/ANSCORE/docs\" \"C:/Projects/CLionProjects/ANSCORE/docs/ANSLIB_Logging_Guide.docx\")",
|
||||||
|
"Bash(sort -t: -k1 -u)"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,10 +13,12 @@ namespace ANSCENTER
|
|||||||
// pointers are write-once globals — concurrent reads are race-free.
|
// pointers are write-once globals — concurrent reads are race-free.
|
||||||
using ANSLogger_LogFnT = void(*)(const char*, const char*, const char*, int);
|
using ANSLogger_LogFnT = void(*)(const char*, const char*, const char*, int);
|
||||||
using ANSCENTER_IsDbgEnFnT = int (*)(void);
|
using ANSCENTER_IsDbgEnFnT = int (*)(void);
|
||||||
ANSLogger_LogFnT g_ANSLogger_LogInfo = nullptr;
|
using ANSCENTER_DebugLogFnT = void(*)(const char*);
|
||||||
ANSLogger_LogFnT g_ANSLogger_LogError = nullptr;
|
ANSLogger_LogFnT g_ANSLogger_LogInfo = nullptr;
|
||||||
ANSLogger_LogFnT g_ANSLogger_LogFatal = nullptr;
|
ANSLogger_LogFnT g_ANSLogger_LogError = nullptr;
|
||||||
ANSCENTER_IsDbgEnFnT g_ANSCENTER_IsDebugViewEnabled = nullptr;
|
ANSLogger_LogFnT g_ANSLogger_LogFatal = nullptr;
|
||||||
|
ANSCENTER_IsDbgEnFnT g_ANSCENTER_IsDebugViewEnabled = nullptr;
|
||||||
|
ANSCENTER_DebugLogFnT g_ANSCENTER_DebugLog = nullptr;
|
||||||
|
|
||||||
// Pre-load all ANSCORE DLLs from the Shared folder using full paths.
|
// Pre-load all ANSCORE DLLs from the Shared folder using full paths.
|
||||||
// This ensures the correct versions are loaded regardless of PATH order
|
// This ensures the correct versions are loaded regardless of PATH order
|
||||||
@@ -45,10 +47,11 @@ namespace ANSCENTER
|
|||||||
// Use GetModuleHandleA — the DLL is already in this process's module
|
// Use GetModuleHandleA — the DLL is already in this process's module
|
||||||
// list courtesy of the LoadLibraryA above, so refcount is unchanged.
|
// list courtesy of the LoadLibraryA above, so refcount is unchanged.
|
||||||
if (HMODULE lic = GetModuleHandleA("ANSLicensingSystem.dll")) {
|
if (HMODULE lic = GetModuleHandleA("ANSLicensingSystem.dll")) {
|
||||||
g_ANSLogger_LogInfo = (ANSLogger_LogFnT) GetProcAddress(lic, "ANSLogger_LogInfo");
|
g_ANSLogger_LogInfo = (ANSLogger_LogFnT) GetProcAddress(lic, "ANSLogger_LogInfo");
|
||||||
g_ANSLogger_LogError = (ANSLogger_LogFnT) GetProcAddress(lic, "ANSLogger_LogError");
|
g_ANSLogger_LogError = (ANSLogger_LogFnT) GetProcAddress(lic, "ANSLogger_LogError");
|
||||||
g_ANSLogger_LogFatal = (ANSLogger_LogFnT) GetProcAddress(lic, "ANSLogger_LogFatal");
|
g_ANSLogger_LogFatal = (ANSLogger_LogFnT) GetProcAddress(lic, "ANSLogger_LogFatal");
|
||||||
g_ANSCENTER_IsDebugViewEnabled = (ANSCENTER_IsDbgEnFnT)GetProcAddress(lic, "ANSCENTER_IsDebugViewEnabled");
|
g_ANSCENTER_IsDebugViewEnabled = (ANSCENTER_IsDbgEnFnT) GetProcAddress(lic, "ANSCENTER_IsDebugViewEnabled");
|
||||||
|
g_ANSCENTER_DebugLog = (ANSCENTER_DebugLogFnT)GetProcAddress(lic, "ANSCENTER_DebugLog");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -288,6 +291,20 @@ namespace ANSCENTER
|
|||||||
PreloadSharedDllsOnce();
|
PreloadSharedDllsOnce();
|
||||||
return g_ANSCENTER_IsDebugViewEnabled ? g_ANSCENTER_IsDebugViewEnabled() : 0;
|
return g_ANSCENTER_IsDebugViewEnabled ? g_ANSCENTER_IsDebugViewEnabled() : 0;
|
||||||
}
|
}
|
||||||
|
void ANSLIB::DebugLog(const char* preformattedLine) {
|
||||||
|
PreloadSharedDllsOnce();
|
||||||
|
if (!preformattedLine) return;
|
||||||
|
if (g_ANSCENTER_DebugLog) {
|
||||||
|
// Preferred path: licensing DLL applies the prefix scrubber and emits.
|
||||||
|
g_ANSCENTER_DebugLog(preformattedLine);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Fallback for environments where ANSLicensingSystem.dll is missing:
|
||||||
|
// emit raw to DebugView + stderr without filtering. Better than dropping.
|
||||||
|
OutputDebugStringA(preformattedLine);
|
||||||
|
std::fputs(preformattedLine, stderr);
|
||||||
|
std::fflush(stderr);
|
||||||
|
}
|
||||||
void ANSLIB::LogInfo(const char* src, const char* msg, const char* file, int line) {
|
void ANSLIB::LogInfo(const char* src, const char* msg, const char* file, int line) {
|
||||||
PreloadSharedDllsOnce();
|
PreloadSharedDllsOnce();
|
||||||
if (g_ANSLogger_LogInfo) g_ANSLogger_LogInfo(src, msg, file, line);
|
if (g_ANSLogger_LogInfo) g_ANSLogger_LogInfo(src, msg, file, line);
|
||||||
|
|||||||
@@ -305,6 +305,14 @@ namespace ANSCENTER {
|
|||||||
// Used by the ANSLIB_DBG macro below; can also be called directly to
|
// Used by the ANSLIB_DBG macro below; can also be called directly to
|
||||||
// gate expensive log-prep work.
|
// gate expensive log-prep work.
|
||||||
static int IsDebugViewEnabled();
|
static int IsDebugViewEnabled();
|
||||||
|
|
||||||
|
// DebugView emit. Hands a pre-formatted "[Tag] body\n" line to
|
||||||
|
// ANSCENTER_DebugLog inside the licensing DLL, which strips noise path
|
||||||
|
// prefixes (e.g. C:\ProgramData\ANSCENTER\, C:\ProgramData\<profile>\)
|
||||||
|
// before writing to OutputDebugStringA + stderr. Used by ANSLIB_DBG.
|
||||||
|
// If the licensing DLL is unavailable, falls back to raw emit (no
|
||||||
|
// filtering) so messages aren't lost.
|
||||||
|
static void DebugLog(const char* preformattedLine);
|
||||||
private:
|
private:
|
||||||
HMODULE dllHandle = nullptr;
|
HMODULE dllHandle = nullptr;
|
||||||
bool loaded = false;
|
bool loaded = false;
|
||||||
@@ -455,16 +463,22 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ANSLIB_DBG: DebugView logging macro mirroring ANS_DBG, but the gate function
|
// ANSLIB_DBG: DebugView logging macro mirroring ANS_DBG. Both the gate and the
|
||||||
// is dynamic-loaded inside ANSLIB.dll — consumers don't need to link or even
|
// emit path are dynamic-loaded inside ANSLIB.dll — consumers don't need to
|
||||||
// know about ANSLicensingSystem.dll. Output goes to BOTH OutputDebugStringA
|
// link or even know about ANSLicensingSystem.dll. Output goes to BOTH
|
||||||
// (DebugView) and stderr, identical format to ANS_DBG: "[tag] formatted\n".
|
// OutputDebugStringA (DebugView) and stderr, identical format to ANS_DBG:
|
||||||
|
// "[tag] formatted\n".
|
||||||
|
//
|
||||||
|
// Noise path prefixes (e.g. C:\ProgramData\ANSCENTER\, C:\ProgramData\<profile>\)
|
||||||
|
// are stripped centrally inside ANSCENTER_DebugLog before emit, so log lines
|
||||||
|
// like "loaded from C:\ProgramData\Jh7O7nUe7vS\Models\Foo" appear as
|
||||||
|
// "loaded from Models\Foo".
|
||||||
//
|
//
|
||||||
// Usage: ANSLIB_DBG("MyModule", "value=%d ptr=%p", val, ptr);
|
// Usage: ANSLIB_DBG("MyModule", "value=%d ptr=%p", val, ptr);
|
||||||
//
|
//
|
||||||
// Hot-path cost when gate is OFF: one indirect call (atomic load + branch
|
// Hot-path cost when gate is OFF: one indirect call. When gate is ON: snprintf
|
||||||
// inside ANSLicensingSystem). When gate is ON: snprintf to a 1024-byte stack
|
// to a 1024-byte stack buffer + cross-DLL call into ANSCENTER_DebugLog (which
|
||||||
// buffer + OutputDebugStringA + fputs. No heap, no per-call allocation.
|
// scrubs prefixes then emits). No heap, no per-call allocation in the macro.
|
||||||
#ifndef ANSCORE_DEBUGVIEW
|
#ifndef ANSCORE_DEBUGVIEW
|
||||||
#define ANSCORE_DEBUGVIEW 1 // 1 = runtime-gated (default), 0 = hard-off (stripped)
|
#define ANSCORE_DEBUGVIEW 1 // 1 = runtime-gated (default), 0 = hard-off (stripped)
|
||||||
#endif
|
#endif
|
||||||
@@ -473,9 +487,7 @@ public:
|
|||||||
if (::ANSCENTER::ANSLIB::IsDebugViewEnabled()) { \
|
if (::ANSCENTER::ANSLIB::IsDebugViewEnabled()) { \
|
||||||
char _ansl_dbg_buf[1024]; \
|
char _ansl_dbg_buf[1024]; \
|
||||||
snprintf(_ansl_dbg_buf, sizeof(_ansl_dbg_buf), "[" tag "] " fmt "\n", ##__VA_ARGS__); \
|
snprintf(_ansl_dbg_buf, sizeof(_ansl_dbg_buf), "[" tag "] " fmt "\n", ##__VA_ARGS__); \
|
||||||
OutputDebugStringA(_ansl_dbg_buf); \
|
::ANSCENTER::ANSLIB::DebugLog(_ansl_dbg_buf); \
|
||||||
fputs(_ansl_dbg_buf, stderr); \
|
|
||||||
fflush(stderr); \
|
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -14,12 +14,18 @@
|
|||||||
#include "base64.h"
|
#include "base64.h"
|
||||||
#include <spdlog/sinks/base_sink.h>
|
#include <spdlog/sinks/base_sink.h>
|
||||||
#include <winnt.h>
|
#include <winnt.h>
|
||||||
|
#include <algorithm>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <cctype>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
// Forward-declare OutputDebugStringA without pulling in <windows.h> (which
|
||||||
|
// drags winsock conflicts as noted in ANSLicense.h). Used by ANSCENTER_DebugLog.
|
||||||
|
extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA(const char* lpOutputString);
|
||||||
|
|
||||||
#define MAX_CUSTOMER_NAME_LEN 100
|
#define MAX_CUSTOMER_NAME_LEN 100
|
||||||
#define FEATURE_1 0x1
|
#define FEATURE_1 0x1
|
||||||
#define FEATURE_2 0x2
|
#define FEATURE_2 0x2
|
||||||
@@ -30,6 +36,135 @@
|
|||||||
#define FEATURE_7 0x40
|
#define FEATURE_7 0x40
|
||||||
#define FEATURE_8 0x80
|
#define FEATURE_8 0x80
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Log-prefix scrubber.
|
||||||
|
//
|
||||||
|
// We don't want noisy fully-qualified per-machine paths in log lines:
|
||||||
|
// "model loaded from C:\ProgramData\Jh7O7nUe7vS\Models\EngineModels\X"
|
||||||
|
// becomes
|
||||||
|
// "model loaded from Models\EngineModels\X"
|
||||||
|
//
|
||||||
|
// The prefix list is built once on first use and combines:
|
||||||
|
// - hardcoded ANSCENTER ProgramData roots (edit kStaticPrefixes below),
|
||||||
|
// - the OS temp directory resolved at runtime via std::filesystem,
|
||||||
|
// - per-OS conventional temp/env-var paths (TEMP/TMP on Windows;
|
||||||
|
// /tmp/, /var/tmp/, TMPDIR on POSIX).
|
||||||
|
//
|
||||||
|
// Each prefix is normalised to lowercase, has a trailing separator forced,
|
||||||
|
// and is added in BOTH `\` and `/` slash flavours so the matcher works on
|
||||||
|
// either form. Prefixes are sorted longest-first so a more specific prefix
|
||||||
|
// (e.g. C:\Users\Bob\AppData\Local\Temp\) wins over a shorter overlapping one.
|
||||||
|
//
|
||||||
|
// Case-insensitive, handles both `\` and `/` separators. Single pass, O(N*P)
|
||||||
|
// where N is message length and P is prefix count (~5–10 in practice). Called
|
||||||
|
// from every SPDLogger::Log* path and from ANSCENTER_DebugLog (the choke point
|
||||||
|
// used by ANS_DBG / ANSLIB_DBG).
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
inline std::string to_lower_ascii(const std::string& s) {
|
||||||
|
std::string out(s.size(), '\0');
|
||||||
|
for (size_t i = 0; i < s.size(); ++i) {
|
||||||
|
out[i] = static_cast<char>(std::tolower(static_cast<unsigned char>(s[i])));
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append both `\` and `/` slash flavours of `raw` to `dst`, lower-cased
|
||||||
|
// and with a trailing separator forced. Empty / pathologically short
|
||||||
|
// entries are skipped.
|
||||||
|
inline void push_prefix_variants(std::vector<std::string>& dst, const std::string& raw) {
|
||||||
|
if (raw.size() < 2) return;
|
||||||
|
std::string normalised = raw;
|
||||||
|
char last = normalised.back();
|
||||||
|
if (last != '\\' && last != '/') normalised.push_back('\\');
|
||||||
|
std::string lowerBs = to_lower_ascii(normalised);
|
||||||
|
std::string lowerFs = lowerBs;
|
||||||
|
for (char& c : lowerFs) if (c == '\\') c = '/';
|
||||||
|
dst.push_back(lowerBs);
|
||||||
|
if (lowerFs != lowerBs) dst.push_back(lowerFs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the prefix table once. Function-local static is initialised
|
||||||
|
// exactly once per process (C++11 magic-static rule, thread-safe).
|
||||||
|
const std::vector<std::string>& GetLogPrefixesLower() {
|
||||||
|
static const std::vector<std::string> kPrefixesLower = []() {
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
// 1. Hardcoded ANSCENTER ProgramData roots — edit this list to
|
||||||
|
// add or remove well-known noise prefixes that aren't tied to
|
||||||
|
// the OS temp/user dir.
|
||||||
|
static const char* kStaticPrefixes[] = {
|
||||||
|
"C:\\ProgramData\\ANSCENTER\\",
|
||||||
|
"C:\\ProgramData\\Jh7O7nUe7vS\\",
|
||||||
|
nullptr,
|
||||||
|
};
|
||||||
|
for (int i = 0; kStaticPrefixes[i]; ++i) {
|
||||||
|
push_prefix_variants(v, kStaticPrefixes[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. OS temp directory (Windows: usually %LOCALAPPDATA%\Temp;
|
||||||
|
// Linux: usually /tmp; macOS: /private/var/folders/...).
|
||||||
|
try {
|
||||||
|
push_prefix_variants(v, std::filesystem::temp_directory_path().string());
|
||||||
|
} catch (...) { /* ignore — fallbacks below cover most cases */ }
|
||||||
|
|
||||||
|
// 3. Per-OS conventional fallbacks in case temp_directory_path()
|
||||||
|
// differs from what the env vars say or returns nothing useful.
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (const char* p = std::getenv("TEMP")) push_prefix_variants(v, p);
|
||||||
|
if (const char* p = std::getenv("TMP")) push_prefix_variants(v, p);
|
||||||
|
push_prefix_variants(v, "C:\\Windows\\Temp\\"); // SYSTEM/services temp
|
||||||
|
#else
|
||||||
|
if (const char* p = std::getenv("TMPDIR")) push_prefix_variants(v, p);
|
||||||
|
push_prefix_variants(v, "/tmp/");
|
||||||
|
push_prefix_variants(v, "/var/tmp/");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 4. De-duplicate (env vars + filesystem API often agree).
|
||||||
|
std::sort(v.begin(), v.end());
|
||||||
|
v.erase(std::unique(v.begin(), v.end()), v.end());
|
||||||
|
|
||||||
|
// 5. Sort longest-first so specific prefixes win over shorter
|
||||||
|
// overlapping ones (e.g. AppData\Local\Temp\ before AppData\).
|
||||||
|
std::sort(v.begin(), v.end(),
|
||||||
|
[](const std::string& a, const std::string& b) {
|
||||||
|
return a.size() > b.size();
|
||||||
|
});
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}();
|
||||||
|
return kPrefixesLower;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string strip_log_prefixes(const std::string& input) {
|
||||||
|
if (input.empty()) return input;
|
||||||
|
|
||||||
|
const auto& prefixes = GetLogPrefixesLower();
|
||||||
|
std::string lower = to_lower_ascii(input);
|
||||||
|
|
||||||
|
std::string out;
|
||||||
|
out.reserve(input.size());
|
||||||
|
size_t i = 0;
|
||||||
|
while (i < input.size()) {
|
||||||
|
bool matched = false;
|
||||||
|
for (const auto& p : prefixes) {
|
||||||
|
if (i + p.size() <= input.size() &&
|
||||||
|
lower.compare(i, p.size(), p) == 0) {
|
||||||
|
i += p.size();
|
||||||
|
matched = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!matched) {
|
||||||
|
out.push_back(input[i]);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace ANSCENTER
|
namespace ANSCENTER
|
||||||
{
|
{
|
||||||
template <typename T> T GetData(const boost::property_tree::ptree& pt, const std::string& key)
|
template <typename T> T GetData(const boost::property_tree::ptree& pt, const std::string& key)
|
||||||
@@ -242,13 +377,14 @@ namespace ANSCENTER
|
|||||||
//__FUNCTION__
|
//__FUNCTION__
|
||||||
void SPDLogger::LogTrace(const std::string& source, const std::string& message, const std::string& fileSource, int lineSource) {
|
void SPDLogger::LogTrace(const std::string& source, const std::string& message, const std::string& fileSource, int lineSource) {
|
||||||
std::string msg = "[" + path_to_filename(fileSource) + "] [" + std::to_string(lineSource) + "] " + source;
|
std::string msg = "[" + path_to_filename(fileSource) + "] [" + std::to_string(lineSource) + "] " + source;
|
||||||
|
std::string scrubbed = strip_log_prefixes(message);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto logger = spdlog::get("anslogger_console");
|
auto logger = spdlog::get("anslogger_console");
|
||||||
if (logger) logger->trace("{}: {}", msg, message);
|
if (logger) logger->trace("{}: {}", msg, scrubbed);
|
||||||
|
|
||||||
auto eventLogger = spdlog::get("anslogger_event");
|
auto eventLogger = spdlog::get("anslogger_event");
|
||||||
if (eventLogger) eventLogger->trace("{}: {}", msg, message);
|
if (eventLogger) eventLogger->trace("{}: {}", msg, scrubbed);
|
||||||
}
|
}
|
||||||
catch (const std::exception& e) {
|
catch (const std::exception& e) {
|
||||||
std::cerr << "SPDLogger::LogError - Exception: " << e.what() << std::endl;
|
std::cerr << "SPDLogger::LogError - Exception: " << e.what() << std::endl;
|
||||||
@@ -256,14 +392,15 @@ namespace ANSCENTER
|
|||||||
}
|
}
|
||||||
void SPDLogger::LogInfo(const std::string& source, const std::string& message, const std::string& fileSource, int lineSource) {
|
void SPDLogger::LogInfo(const std::string& source, const std::string& message, const std::string& fileSource, int lineSource) {
|
||||||
std::string msg = "[" + path_to_filename(fileSource) + "] [" + std::to_string(lineSource) + "] " + source;
|
std::string msg = "[" + path_to_filename(fileSource) + "] [" + std::to_string(lineSource) + "] " + source;
|
||||||
|
std::string scrubbed = strip_log_prefixes(message);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto logger = spdlog::get("anslogger_console");
|
auto logger = spdlog::get("anslogger_console");
|
||||||
if (logger) {
|
if (logger) {
|
||||||
logger->info("{}: {}", msg, message);
|
logger->info("{}: {}", msg, scrubbed);
|
||||||
}
|
}
|
||||||
auto eventLogger = spdlog::get("anslogger_event");
|
auto eventLogger = spdlog::get("anslogger_event");
|
||||||
if (eventLogger) eventLogger->info("{}: {}", msg, message);
|
if (eventLogger) eventLogger->info("{}: {}", msg, scrubbed);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (const std::exception& e) {
|
catch (const std::exception& e) {
|
||||||
@@ -272,11 +409,12 @@ namespace ANSCENTER
|
|||||||
}
|
}
|
||||||
void SPDLogger::LogWarn(const std::string& source, const std::string& message, const std::string& fileSource, int lineSource) {
|
void SPDLogger::LogWarn(const std::string& source, const std::string& message, const std::string& fileSource, int lineSource) {
|
||||||
std::string messageSource = "[" + path_to_filename(fileSource) + "] [" + std::to_string(lineSource) + "] " + source;
|
std::string messageSource = "[" + path_to_filename(fileSource) + "] [" + std::to_string(lineSource) + "] " + source;
|
||||||
|
std::string scrubbed = strip_log_prefixes(message);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto logger = spdlog::get("anslogger_console");
|
auto logger = spdlog::get("anslogger_console");
|
||||||
if (logger) {
|
if (logger) {
|
||||||
logger->warn("{}: {}", messageSource, message);
|
logger->warn("{}: {}", messageSource, scrubbed);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::cerr << "SPDLogger::LogWarn - Logger not initialized: anslogger_console" << std::endl;
|
std::cerr << "SPDLogger::LogWarn - Logger not initialized: anslogger_console" << std::endl;
|
||||||
@@ -288,11 +426,12 @@ namespace ANSCENTER
|
|||||||
}
|
}
|
||||||
void SPDLogger::LogDebug(const std::string& source, const std::string& message, const std::string& fileSource, int lineSource) {
|
void SPDLogger::LogDebug(const std::string& source, const std::string& message, const std::string& fileSource, int lineSource) {
|
||||||
std::string msg = "[" + path_to_filename(fileSource) + "] [" + std::to_string(lineSource) + "] " + source;
|
std::string msg = "[" + path_to_filename(fileSource) + "] [" + std::to_string(lineSource) + "] " + source;
|
||||||
|
std::string scrubbed = strip_log_prefixes(message);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto logger = spdlog::get("anslogger_console");
|
auto logger = spdlog::get("anslogger_console");
|
||||||
if (logger) {
|
if (logger) {
|
||||||
logger->debug("{}: {}", msg, message);
|
logger->debug("{}: {}", msg, scrubbed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const std::exception& e) {
|
catch (const std::exception& e) {
|
||||||
@@ -301,13 +440,14 @@ namespace ANSCENTER
|
|||||||
}
|
}
|
||||||
void SPDLogger::LogError(const std::string& source, const std::string& message, const std::string& fileSource, int lineSource) {
|
void SPDLogger::LogError(const std::string& source, const std::string& message, const std::string& fileSource, int lineSource) {
|
||||||
std::string msg = "[" + path_to_filename(fileSource) + "] [" + std::to_string(lineSource) + "] " + source;
|
std::string msg = "[" + path_to_filename(fileSource) + "] [" + std::to_string(lineSource) + "] " + source;
|
||||||
|
std::string scrubbed = strip_log_prefixes(message);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto logger = spdlog::get("anslogger_console");
|
auto logger = spdlog::get("anslogger_console");
|
||||||
if (logger) logger->error("{}: {}", msg, message);
|
if (logger) logger->error("{}: {}", msg, scrubbed);
|
||||||
|
|
||||||
auto eventLogger = spdlog::get("anslogger_event");
|
auto eventLogger = spdlog::get("anslogger_event");
|
||||||
if (eventLogger) eventLogger->error("{}: {}", msg, message);
|
if (eventLogger) eventLogger->error("{}: {}", msg, scrubbed);
|
||||||
}
|
}
|
||||||
catch (const std::exception& e) {
|
catch (const std::exception& e) {
|
||||||
std::cerr << "SPDLogger::LogError - Exception: " << e.what() << std::endl;
|
std::cerr << "SPDLogger::LogError - Exception: " << e.what() << std::endl;
|
||||||
@@ -315,13 +455,14 @@ namespace ANSCENTER
|
|||||||
}
|
}
|
||||||
void SPDLogger::LogFatal(const std::string& source, const std::string& message, const std::string& fileSource, int lineSource) {
|
void SPDLogger::LogFatal(const std::string& source, const std::string& message, const std::string& fileSource, int lineSource) {
|
||||||
std::string msg = "[" + path_to_filename(fileSource) + "] [" + std::to_string(lineSource) + "] " + source;
|
std::string msg = "[" + path_to_filename(fileSource) + "] [" + std::to_string(lineSource) + "] " + source;
|
||||||
|
std::string scrubbed = strip_log_prefixes(message);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto logger = spdlog::get("anslogger_console");
|
auto logger = spdlog::get("anslogger_console");
|
||||||
if (logger) logger->critical("{}: {}", msg, message);
|
if (logger) logger->critical("{}: {}", msg, scrubbed);
|
||||||
|
|
||||||
auto eventLogger = spdlog::get("anslogger_event");
|
auto eventLogger = spdlog::get("anslogger_event");
|
||||||
if (eventLogger) eventLogger->critical("{}: {}", msg, message);
|
if (eventLogger) eventLogger->critical("{}: {}", msg, scrubbed);
|
||||||
}
|
}
|
||||||
catch (const std::exception& e) {
|
catch (const std::exception& e) {
|
||||||
std::cerr << "SPDLogger::LogFatal - Exception: " << e.what() << std::endl;
|
std::cerr << "SPDLogger::LogFatal - Exception: " << e.what() << std::endl;
|
||||||
@@ -352,6 +493,19 @@ extern "C" {
|
|||||||
src ? src : "", msg ? msg : "", file ? file : "", line);
|
src ? src : "", msg ? msg : "", file ? file : "", line);
|
||||||
} catch (...) {}
|
} catch (...) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DebugView emit path used by ANS_DBG and ANSLIB_DBG. Single choke point
|
||||||
|
// so the prefix scrubber lives in one place; macros just hand off the
|
||||||
|
// already-formatted "[Tag] body\n" buffer here.
|
||||||
|
ANSLICENSE_API void ANSCENTER_DebugLog(const char* buf) {
|
||||||
|
if (!buf) return;
|
||||||
|
try {
|
||||||
|
std::string scrubbed = strip_log_prefixes(buf);
|
||||||
|
OutputDebugStringA(scrubbed.c_str());
|
||||||
|
std::fputs(scrubbed.c_str(), stderr);
|
||||||
|
std::fflush(stderr);
|
||||||
|
} catch (...) {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ANSCENTER
|
namespace ANSCENTER
|
||||||
|
|||||||
@@ -39,36 +39,25 @@ extern "C" {
|
|||||||
ANSLICENSE_API void ANSLogger_LogInfo (const char* src, const char* msg, const char* file, int line);
|
ANSLICENSE_API void ANSLogger_LogInfo (const char* src, const char* msg, const char* file, int line);
|
||||||
ANSLICENSE_API void ANSLogger_LogError(const char* src, const char* msg, const char* file, int line);
|
ANSLICENSE_API void ANSLogger_LogError(const char* src, const char* msg, const char* file, int line);
|
||||||
ANSLICENSE_API void ANSLogger_LogFatal(const char* src, const char* msg, const char* file, int line);
|
ANSLICENSE_API void ANSLogger_LogFatal(const char* src, const char* msg, const char* file, int line);
|
||||||
|
|
||||||
|
// DebugView choke point shared by ANS_DBG and ANSLIB_DBG. Strips noise
|
||||||
|
// path prefixes before emitting to OutputDebugStringA + stderr.
|
||||||
|
ANSLICENSE_API void ANSCENTER_DebugLog(const char* preformattedLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ANS_DBG: Debug logging macro for DebugView (OutputDebugStringA on Windows).
|
// ANS_DBG: Debug logging macro for DebugView (OutputDebugStringA on Windows).
|
||||||
// Usage: ANS_DBG("MyModule", "value=%d ptr=%p", val, ptr);
|
// Usage: ANS_DBG("MyModule", "value=%d ptr=%p", val, ptr);
|
||||||
// Output: [MyModule] value=42 ptr=0x1234
|
// Output: [MyModule] value=42 ptr=0x1234
|
||||||
// NOTE: We avoid #include <windows.h> here to prevent winsock.h/winsock2.h
|
//
|
||||||
// conflicts. Instead, forward-declare OutputDebugStringA directly.
|
// Routes through ANSCENTER_DebugLog so noise path prefixes (e.g. the
|
||||||
#if ANSCORE_DEBUGVIEW && defined(_WIN32)
|
// ProgramData profile dir) are stripped centrally before emit. The macro just
|
||||||
extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA(const char* lpOutputString);
|
// formats on the caller's stack and hands off the buffer.
|
||||||
// Emit to BOTH DebugView (OutputDebugStringA) AND stderr so console apps
|
#if ANSCORE_DEBUGVIEW
|
||||||
// (ANSCV-UnitTest, ANSLPR-UnitTest, ANSUtilities_test, etc.) show the message
|
|
||||||
// without needing to attach DebugView. fputs + fflush keeps lines atomic even
|
|
||||||
// when multiple threads log concurrently.
|
|
||||||
#define ANS_DBG(tag, fmt, ...) do { \
|
#define ANS_DBG(tag, fmt, ...) do { \
|
||||||
if (ANSCENTER_IsDebugViewEnabled()) { \
|
if (ANSCENTER_IsDebugViewEnabled()) { \
|
||||||
char _ans_dbg_buf[1024]; \
|
char _ans_dbg_buf[1024]; \
|
||||||
snprintf(_ans_dbg_buf, sizeof(_ans_dbg_buf), "[" tag "] " fmt "\n", ##__VA_ARGS__); \
|
snprintf(_ans_dbg_buf, sizeof(_ans_dbg_buf), "[" tag "] " fmt "\n", ##__VA_ARGS__); \
|
||||||
OutputDebugStringA(_ans_dbg_buf); \
|
ANSCENTER_DebugLog(_ans_dbg_buf); \
|
||||||
fputs(_ans_dbg_buf, stderr); \
|
|
||||||
fflush(stderr); \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
#elif ANSCORE_DEBUGVIEW
|
|
||||||
// Non-Windows: stderr only.
|
|
||||||
#define ANS_DBG(tag, fmt, ...) do { \
|
|
||||||
if (ANSCENTER_IsDebugViewEnabled()) { \
|
|
||||||
char _ans_dbg_buf[1024]; \
|
|
||||||
snprintf(_ans_dbg_buf, sizeof(_ans_dbg_buf), "[" tag "] " fmt "\n", ##__VA_ARGS__); \
|
|
||||||
fputs(_ans_dbg_buf, stderr); \
|
|
||||||
fflush(stderr); \
|
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// dllmain.cpp : Defines the entry point for the DLL application.
|
// dllmain.cpp : Defines the entry point for the DLL application.
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "ANSUtilities.h"
|
#include "ANSUtilities.h"
|
||||||
|
#include "Utility.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
@@ -697,7 +698,7 @@ extern "C" ANSULT_API int AESEncryption(const char* inputString, const char* in
|
|||||||
}
|
}
|
||||||
extern "C" ANSULT_API int MD5HashFile(const char* filePath, LStrHandle decryptionMessage)
|
extern "C" ANSULT_API int MD5HashFile(const char* filePath, LStrHandle decryptionMessage)
|
||||||
{
|
{
|
||||||
ANS_DBG("ANSUTIL","MD5HashFile: filePath=%s", filePath ? filePath : "(null)");
|
ANS_DBG("ANSUTIL","MD5HashFile: filePath=%s", filePath ? path_to_filename(std::string(filePath)).c_str() : "(null)");
|
||||||
if (filePath == nullptr || decryptionMessage == nullptr) return 0;
|
if (filePath == nullptr || decryptionMessage == nullptr) return 0;
|
||||||
try {
|
try {
|
||||||
std::string st = ANSCENTER::ANSUtilities::MD5HashFile(filePath);
|
std::string st = ANSCENTER::ANSUtilities::MD5HashFile(filePath);
|
||||||
|
|||||||
Reference in New Issue
Block a user