diff --git a/client/StdAfx.h b/client/StdAfx.h index 2e037a9..9fab1ea 100644 --- a/client/StdAfx.h +++ b/client/StdAfx.h @@ -24,12 +24,6 @@ #pragma once #endif // _MSC_VER > 1000 -#ifdef _DEBUG -#define Mprintf(format, ...) printf(format, ##__VA_ARGS__) -#else -#define Mprintf(format, ...) -#endif - // 检测内存泄漏,需安装VLD;否则请注释此行 #include "vld.h" @@ -49,50 +43,6 @@ #include #pragma comment(lib, "winmm.lib") -// 高精度的睡眠函数 -#define Sleep_m(ms) { timeBeginPeriod(1); Sleep(ms); timeEndPeriod(1); } - -// 以步长n毫秒在条件C下等待T秒(n是步长,必须能整除1000) -#define WAIT_n(C, T, n) {assert(!(1000%(n)));int s=(1000*(T))/(n);do{Sleep(n);}while((C)&&(--s));} - -// 在条件C成立时等待T秒(步长10ms) -#define WAIT(C, T) { timeBeginPeriod(1); WAIT_n(C, T, 10); timeEndPeriod(1); } - -// 在条件C成立时等待T秒(步长1ms) -#define WAIT_1(C, T) { timeBeginPeriod(1); WAIT_n(C, T, 1); timeEndPeriod(1); } - -#include -#include -#include - -// 智能计时器,计算函数的耗时 -class auto_tick -{ -private: - const char *func; - int span; - clock_t tick; - __inline clock_t now() const { return clock(); } - __inline int time() const { return now() - tick; } - -public: - auto_tick(const char *func_name, int th = 5) : func(func_name), span(th), tick(now()) { } - ~auto_tick() { stop(); } - - __inline void stop() { - if (span != 0) { int s(this->time()); if (s > span)Mprintf("[%s]执行时间: [%d]ms.\n", func, s); span = 0; } - } -}; - -#ifdef _DEBUG -// 智能计算当前函数的耗时,超时会打印 -#define AUTO_TICK(thresh) auto_tick TICK(__FUNCTION__, thresh) -#define STOP_TICK TICK.stop() -#else -#define AUTO_TICK(thresh) -#define STOP_TICK -#endif - #ifndef SAFE_DELETE #define SAFE_DELETE(p) if(NULL !=(p)){ delete (p);(p) = NULL;} #endif @@ -105,42 +55,5 @@ public: #define SAFE_DELETE_AR(p) if(NULL !=(p)){ delete[] (p);(p) = NULL;} #endif -class CLock -{ -private: - CRITICAL_SECTION m_cs; -public: - CLock() - { - InitializeCriticalSection(&m_cs); - } - ~CLock() - { - DeleteCriticalSection(&m_cs); - } - - void Unlock() - { - LeaveCriticalSection(&m_cs); - } - - void Lock() - { - EnterCriticalSection(&m_cs); - } -}; - -class CAutoLock -{ -private: - CRITICAL_SECTION &m_cs; -public: - CAutoLock(CRITICAL_SECTION& cs) : m_cs(cs) - { - EnterCriticalSection(&m_cs); - } - ~CAutoLock() - { - LeaveCriticalSection(&m_cs); - } -}; +#include "common/logger.h" +#include "common/locker.h" diff --git a/common/locker.h b/common/locker.h new file mode 100644 index 0000000..9722a77 --- /dev/null +++ b/common/locker.h @@ -0,0 +1,141 @@ +#pragma once + +#pragma warning(disable: 4996) +#pragma warning(disable: 4819) + +// 浜掓枼閿併佺潯鐪犲嚱鏁般佽嚜鍔ㄩ攣銆佽嚜鍔ㄨ鏃躲佽嚜鍔ㄦ棩蹇楃瓑 + +#include "logger.h" + +// 鑷姩鏃ュ織 +class CAutoLog +{ +private: + CRITICAL_SECTION *m_cs; + const char* name; +public: + CAutoLog(const char* _name, CRITICAL_SECTION *cs=NULL) : name(_name), m_cs(cs) + { + Mprintf(">>> Enter thread %s: [%d]\n", name ? name : "", GetCurrentThreadId()); + if (m_cs)EnterCriticalSection(m_cs); + } + + ~CAutoLog() + { + if (m_cs)LeaveCriticalSection(m_cs); + Mprintf(">>> Leave thread %s: [%d]\n", name ? name : "", GetCurrentThreadId()); + } +}; + +class CLock { +public: + CLock(CRITICAL_SECTION& cs) : m_cs(&cs) + { + Lock(); + } + CLock() : m_cs(nullptr) + { + InitializeCriticalSection(&i_cs); + } + ~CLock() + { + m_cs ? Unlock() : DeleteCriticalSection(&i_cs); + } + + void Unlock() + { + LeaveCriticalSection(m_cs ? m_cs : &i_cs); + } + + void Lock() + { + EnterCriticalSection(m_cs ? m_cs : &i_cs); + } + + void unlock() + { + LeaveCriticalSection(m_cs ? m_cs : &i_cs); + } + + void lock() + { + EnterCriticalSection(m_cs ? m_cs : &i_cs); + } + +protected: + CRITICAL_SECTION* m_cs; // 澶栭儴閿 + CRITICAL_SECTION i_cs; // 鍐呴儴閿 +}; + +typedef CLock CLocker; + +class CAutoLock +{ +private: + CRITICAL_SECTION &m_cs; + +public: + CAutoLock(CRITICAL_SECTION& cs) : m_cs(cs) + { + EnterCriticalSection(&m_cs); + } + + ~CAutoLock() + { + LeaveCriticalSection(&m_cs); + } +}; + +// 鏅鸿兘璁℃椂鍣紝璁$畻鍑芥暟鐨勮楁椂 +class auto_tick { +private: + const char* func; + int span; + clock_t tick; + __inline clock_t now() const { + return clock(); + } + __inline int time() const { + return now() - tick; + } + +public: + auto_tick(const char* func_name, int th = 5) : func(func_name), span(th), tick(now()) { } + ~auto_tick() { + stop(); + } + + __inline void stop() { + if (span != 0) { + int s(this->time()); + if (s > span)Mprintf("[%s] cost: [%d]ms.\n", func, s); + span = 0; + } + } +}; + +#ifdef _DEBUG +// 鏅鸿兘璁$畻褰撳墠鍑芥暟鐨勮楁椂锛岃秴鏃朵細鎵撳嵃 +#define AUTO_TICK(thresh) auto_tick TICK(__FUNCTION__, thresh) +#define STOP_TICK TICK.stop() +#else +#define AUTO_TICK(thresh) +#define STOP_TICK +#endif + +#define AUTO_TICK_C AUTO_TICK + +#include +#pragma comment(lib, "winmm.lib") + +// 楂樼簿搴︾殑鐫$湢鍑芥暟 +#define Sleep_m(ms) { Sleep(ms); } + +// 浠ユ闀縩姣鍦ㄦ潯浠禖涓嬬瓑寰匱绉(n鏄闀匡紝蹇呴』鑳芥暣闄1000) +#define WAIT_n(C, T, n) { int s=(1000*(T))/(n); s=max(s,1); do{Sleep(n);}while((C)&&(--s)); } + +// 鍦ㄦ潯浠禖鎴愮珛鏃剁瓑寰匱绉(姝ラ暱10ms) +#define WAIT(C, T) { WAIT_n(C, T, 10); } + +// 鍦ㄦ潯浠禖鎴愮珛鏃剁瓑寰匱绉(姝ラ暱1ms) +#define WAIT_1(C, T) { WAIT_n(C, T, 1); } diff --git a/common/logger.h b/common/logger.h new file mode 100644 index 0000000..ab4be04 --- /dev/null +++ b/common/logger.h @@ -0,0 +1,234 @@ +#pragma once +#pragma warning(disable: 4996) +#ifdef _WIN32 +#ifdef _WINDOWS +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "skCrypter.h" +#include + + +inline bool stringToBool(const std::string& str) { + std::string lower = str; + std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower); + return (lower == "true" || lower == "1"); +} + +class Logger { +public: + enum LogLevel { + InfoLevel, WarningLevel, ErrorLevel + }; + + // 单例模式 + static Logger& getInstance() { + static Logger instance; + if (instance.pid.empty()) { + char buf[16] = {}; + sprintf_s(buf, "%d", GetCurrentProcessId()); + instance.pid = buf; + instance.InitLogFile("C:\\Windows\\Temp", instance.pid); +#ifdef _WINDOWS + instance.enable = true; // 主控日志默认打开 +#else + char var[32] = {}; + const char* name = skCrypt("ENABLE_LOG"); + DWORD size = GetEnvironmentVariableA(name, var, sizeof(var)); + instance.enable = stringToBool(var); + instance.log("logger.h", __LINE__, "GetEnvironmentVariable: %s=%s\n", name, var); +#endif + } + return instance; + } + + // 禁止拷贝和赋值 + Logger(const Logger&) = delete; + Logger& operator=(const Logger&) = delete; + + // 设置日志文件名 + void setLogFile(const std::string& filename) { + std::lock_guard lock(fileMutex); + logFileName = filename; + } + + // 启用日志 + void usingLog(bool b = true) { + enable = b; + } + + // 写日志,支持 printf 格式化 + void log(const char* file, int line, const char* format, ...) { + va_list args; + va_start(args, format); + + std::string message = formatString(format, args); + + va_end(args); + + auto timestamp = getCurrentTimestamp(); + std::string id = pid.empty() ? "" : "[" + pid + "]"; + + std::string logEntry = id + "[" + timestamp + "] [" + file + ":" + std::to_string(line) + "] " + message; + if (enable) + { + if (running) { + std::lock_guard lock(queueMutex); + logQueue.push(logEntry); + } else { + writeToFile(logEntry); + } + } +#ifndef _WINDOWS +#ifdef _DEBUG + printf(logEntry.c_str()); +#endif +#endif + cv.notify_one(); // 通知写线程 + } + + // 停止日志系统 + void stop() { + if (!running) return; + { + std::lock_guard lock(queueMutex); + running = false; // 设置运行状态 + } + cv.notify_one(); + if (workerThread.joinable()) { + workerThread.join(); + } + for (int i = 0; threadRun && i++ < 1000; Sleep(1)); + } + +private: + // 日志按月份起名 + void InitLogFile(const std::string & dir, const std::string& pid) { + time_t currentTime = time(nullptr); + tm* localTime = localtime(¤tTime); + char timeString[32]; + strftime(timeString, sizeof(timeString), "%Y-%m", localTime); + char fileName[100]; +#ifdef _WINDOWS + sprintf_s(fileName, "\\YAMA_%s_%s.txt", timeString, pid.c_str()); +#else + sprintf_s(fileName, "\\log_%s_%s.txt", timeString, pid.c_str()); +#endif + logFileName = dir + fileName; + } + std::string logFileName; // 日志文件名 + bool enable; // 是否启用 + bool threadRun; // 日志线程状态 + std::queue logQueue; // 日志队列 + std::mutex queueMutex; // 队列互斥锁 + std::condition_variable cv; // 条件变量 + std::atomic running; // 是否运行 + std::thread workerThread; // 后台线程 + std::mutex fileMutex; // 文件写入锁 + std::string pid; // 进程ID + + Logger() : enable(false), threadRun(false), running(true), workerThread(&Logger::processLogs, this) {} + + ~Logger() { + stop(); + } + + // 后台线程处理日志 + void processLogs() { + threadRun = true; + while (running) { + std::unique_lock lock(queueMutex); + cv.wait(lock, [this]() { + return !running || !logQueue.empty(); + }); + + while (running && !logQueue.empty()) { + std::string logEntry = logQueue.front(); + logQueue.pop(); + lock.unlock(); + + // 写入日志文件 + writeToFile(logEntry); + + lock.lock(); + } + lock.unlock(); + } + threadRun = false; + } + + // 写入文件 + void writeToFile(const std::string& logEntry) { + std::lock_guard lock(fileMutex); + std::ofstream logFile(logFileName, std::ios::app); + if (logFile.is_open()) { + logFile << logEntry << std::endl; + } + } + + // 获取当前时间戳 + std::string getCurrentTimestamp() { + auto now = std::chrono::system_clock::now(); + auto in_time_t = std::chrono::system_clock::to_time_t(now); + + std::tm tm; +#ifdef _WIN32 + localtime_s(&tm, &in_time_t); // Windows 安全版本 +#else + localtime_r(&in_time_t, &tm); // POSIX 安全版本 +#endif + + std::stringstream ss; + ss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S"); + return ss.str(); + } + + // 将日志级别转换为字符串 + std::string logLevelToString(LogLevel level) { + switch (level) { + case InfoLevel: return "INFO"; + case WarningLevel: return "WARNING"; + case ErrorLevel: return "ERROR"; + default: return "UNKNOWN"; + } + } + + // 格式化字符串 + std::string formatString(const char* format, va_list args) { + char buffer[1024]; + vsnprintf(buffer, sizeof(buffer), format, args); + return std::string(buffer); + } +}; + +inline const char* getFileName(const char* path) { + const char* fileName = strrchr(path, '\\'); + if (!fileName) { + fileName = strrchr(path, '/'); + } + return fileName ? fileName + 1 : path; +} + +#ifdef _WINDOWS +#ifdef _DEBUG +#define Mprintf(format, ...) TRACE(format, __VA_ARGS__) +#else +#define Mprintf(format, ...) Logger::getInstance().log(getFileName(__FILE__), __LINE__, format, __VA_ARGS__) +#endif +#else +#define Mprintf(format, ...) Logger::getInstance().log(getFileName(skCrypt(__FILE__)), __LINE__, skCrypt(format), __VA_ARGS__) +#endif + +#endif // _WIN32 diff --git a/server/2015Remote/IOCPServer.h b/server/2015Remote/IOCPServer.h index 3399301..bdb2aa3 100644 --- a/server/2015Remote/IOCPServer.h +++ b/server/2015Remote/IOCPServer.h @@ -373,47 +373,6 @@ public: typedef IOCPServer ISocketBase; -class CLock -{ -public: - CLock(CRITICAL_SECTION& cs) : m_cs(&cs) - { - Lock(); - } - CLock() : m_cs(nullptr) - { - InitializeCriticalSection(&i_cs); - } - ~CLock() - { - m_cs ? Unlock() : DeleteCriticalSection(&i_cs); - } - - void Unlock() - { - LeaveCriticalSection(m_cs ? m_cs : &i_cs); - } - - void Lock() - { - EnterCriticalSection(m_cs ? m_cs : &i_cs); - } - - void unlock() - { - LeaveCriticalSection(m_cs ? m_cs : &i_cs); - } - - void lock() - { - EnterCriticalSection(m_cs ? m_cs : &i_cs); - } - -protected: - CRITICAL_SECTION* m_cs; // 外部锁 - CRITICAL_SECTION i_cs; // 内部锁 -}; - #define TRACK_OVERLAPPEDPLUS 0 class OVERLAPPEDPLUS diff --git a/server/2015Remote/stdafx.h b/server/2015Remote/stdafx.h index 0be2720..97cfff3 100644 --- a/server/2015Remote/stdafx.h +++ b/server/2015Remote/stdafx.h @@ -20,12 +20,6 @@ #define VC_EXTRALEAN // 从 Windows 头中排除极少使用的资料 #endif -#ifdef _DEBUG -#define Mprintf(format, ...) TRACE(format, ##__VA_ARGS__) -#else -#define Mprintf(format, ...) -#endif - // 移除对话框中MFC控件的支持,减小静态编译程序的大小 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS @@ -117,47 +111,9 @@ enum #include #pragma comment(lib, "winmm.lib") -// 高精度的睡眠函数 -#define Sleep_m(ms) { timeBeginPeriod(1); Sleep(ms); timeEndPeriod(1); } - -// 以步长n毫秒在条件C下等待T秒(n是步长,必须能整除1000) -#define WAIT_n(C, T, n) {assert(!(1000%(n)));int s=(1000*(T))/(n);do{Sleep(n);}while((C)&&(--s));} - -// 在条件C成立时等待T秒(步长10ms) -#define WAIT(C, T) { timeBeginPeriod(1); WAIT_n(C, T, 10); timeEndPeriod(1); } - -// 在条件C成立时等待T秒(步长1ms) -#define WAIT_1(C, T) { timeBeginPeriod(1); WAIT_n(C, T, 1); timeEndPeriod(1); } - -// 智能计时器,计算函数的耗时 -class auto_tick -{ -private: - const char *func; - int span; - clock_t tick; - __inline clock_t now() const { return clock(); } - __inline int time() const { return now() - tick; } - -public: - auto_tick(const char *func_name, int th = 5) : func(func_name), span(th), tick(now()) { } - ~auto_tick() { stop(); } - - __inline void stop() { - if (span != 0) { int s(this->time()); if (s > span)TRACE("[%s]执行时间: [%d]ms.\n", func, s); span = 0; } - } -}; - -#ifdef _DEBUG -// 智能计算当前函数的耗时,超时会打印 -#define AUTO_TICK(thresh) auto_tick TICK(__FUNCTION__, thresh) -#define STOP_TICK TICK.stop() -#else -#define AUTO_TICK(thresh) -#define STOP_TICK -#endif - #define SAFE_DELETE(p) if(p){ delete (p); (p) = NULL; } #define SAFE_DELETE_ARRAY(p) if(p){ delete[] (p); (p) = NULL; } +#include "common/logger.h" +#include "common/locker.h" #include "common/commands.h"