upload
This commit is contained in:
+210
@@ -0,0 +1,210 @@
|
||||
#pragma once
|
||||
#pragma warning(disable : 4996)
|
||||
#include <deque>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <string>
|
||||
#include <atomic>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include "LogArg.h"
|
||||
#include "Export.h"
|
||||
#include <condition_variable>
|
||||
|
||||
namespace uns
|
||||
{
|
||||
enum ServerLogLevel
|
||||
{
|
||||
llAll = 0x000000,
|
||||
llTrace = 0x000001,
|
||||
llDebug = 0x000010,
|
||||
llInfo = 0x000020,
|
||||
llWarning = 0x000030,
|
||||
llError = 0x000040,
|
||||
llFatal = 0x000050,
|
||||
llOff = 0xFFFFFF
|
||||
};
|
||||
|
||||
enum LogRotationPeriod
|
||||
{
|
||||
RP_None = 0,
|
||||
RP_Hourly = 1,
|
||||
RP_Daily = 2
|
||||
};
|
||||
|
||||
std::string UNSWSC_DLL_EXPORT toBinary(long number, int bits);
|
||||
std::string UNSWSC_DLL_EXPORT toBinary(std::uint32_t number, int bits);
|
||||
std::string UNSWSC_DLL_EXPORT toBinary(unsigned long number, int bits);
|
||||
};
|
||||
|
||||
class UNSWSC_DLL_EXPORT ServerLogger
|
||||
{
|
||||
private:
|
||||
std::fstream LogStream;
|
||||
std::string LogFileName;
|
||||
std::atomic<uns::ServerLogLevel> CurrentLevel; //避免数据竟态UB
|
||||
|
||||
// 异步队列与线程控制
|
||||
std::deque<std::string> LogQueue;
|
||||
std::mutex QueueMutex;
|
||||
std::condition_variable QueueCV;
|
||||
std::thread WorkerThread;
|
||||
std::atomic_bool WorkerRunning;
|
||||
std::atomic_bool ThreadRunningFlag;
|
||||
|
||||
// 日志分时段(轮转)支持
|
||||
uns::LogRotationPeriod RotatePeriod;
|
||||
std::time_t CurrentFilePeriodStart;
|
||||
|
||||
// 新增:大小轮转支持
|
||||
std::size_t MaxFileSizeBytes; // 最大文件大小(字节)
|
||||
int CurrentOSLIndex; // 当前 period 下的 OSL 索引(从 0 开始)
|
||||
|
||||
private:
|
||||
std::string GenerateLogHeader(uns::ServerLogLevel LogLevel);
|
||||
std::string GenerateFileInfo(std::string filename, int line_num);
|
||||
void WriteBatchToOutputs(const std::deque<std::string>& batch)
|
||||
;
|
||||
void WorkerLoop();
|
||||
std::string MakeRotatedFileName(const std::string& base, std::time_t t, int osl_index = 0);
|
||||
void RotateIfNeeded(std::time_t now, bool check_size_after_write = false);
|
||||
|
||||
void LogImpl(uns::ServerLogLevel level, const std::string& format, const uns::LogArg* args, size_t count);
|
||||
void LogFImpl(uns::ServerLogLevel level, const std::string& filename, int line_num, const std::string& format, const uns::LogArg* args, size_t count);
|
||||
void LogFMTImpl(uns::ServerLogLevel level, const std::string& format, const uns::LogArg* args, size_t count);
|
||||
void LogFMT_FImpl(uns::ServerLogLevel level, const std::string& filename, int line_num, const std::string& format, const uns::LogArg* args, size_t count);
|
||||
|
||||
public:
|
||||
ServerLogger();
|
||||
ServerLogger(uns::ServerLogLevel log_level, std::string file = "", uns::LogRotationPeriod rotation = uns::RP_None, std::size_t max_bytes = 50 * 1024 * 1024);
|
||||
ServerLogger(const ServerLogger& obj) = delete;
|
||||
~ServerLogger();
|
||||
|
||||
public:
|
||||
bool InitLogger(uns::ServerLogLevel log_level, const std::string& file = "", uns::LogRotationPeriod rotation = uns::RP_None, std::size_t max_bytes = 50 * 1024 * 1024);
|
||||
void CloseLog();
|
||||
void DisableLog();
|
||||
void FlushLogBuffer();
|
||||
void EnableLog(uns::ServerLogLevel level);
|
||||
|
||||
template<typename... Args>
|
||||
void Log(uns::ServerLogLevel level, const std::string& format, Args&&... args);
|
||||
template<typename... Args>
|
||||
void LogF(uns::ServerLogLevel level, const std::string& filename, int line_num, const std::string format, Args&&... args);
|
||||
template<typename... Args>
|
||||
void LogFMT(uns::ServerLogLevel level, const std::string& format, Args&&... args);
|
||||
template<typename... Args>
|
||||
void LogFMT_F(uns::ServerLogLevel level, const std::string& filename, int line_num, const std::string format, Args&&... args);
|
||||
};
|
||||
|
||||
template<typename... Args>
|
||||
inline void ServerLogger::Log(uns::ServerLogLevel level, const std::string& format, Args&&... args)
|
||||
{
|
||||
uns::ServerLogLevel curr_level = CurrentLevel.load(std::memory_order_relaxed);
|
||||
if ((curr_level == uns::llOff) || (level < curr_level))
|
||||
return;
|
||||
|
||||
if constexpr (sizeof...(Args) == 0)
|
||||
LogImpl(level, format, nullptr, 0);
|
||||
else
|
||||
{
|
||||
// 在客户端的栈上瞬间分配数组并完成类型擦除
|
||||
uns::LogArg packed_args[] = { uns::LogArg(std::forward<Args>(args))... };
|
||||
LogImpl(level, format, packed_args, sizeof...(Args));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
inline void ServerLogger::LogF(uns::ServerLogLevel level, const std::string& filename, int line_num, std::string format, Args&&... args)
|
||||
{
|
||||
uns::ServerLogLevel curr_level = CurrentLevel.load(std::memory_order_relaxed);
|
||||
if ((curr_level == uns::llOff) || (level < curr_level))
|
||||
return;
|
||||
|
||||
if constexpr (sizeof...(Args) == 0)
|
||||
LogFImpl(level, filename, line_num, format, nullptr, 0);
|
||||
else
|
||||
{
|
||||
uns::LogArg packed_args[] = { uns::LogArg(std::forward<Args>(args))... };
|
||||
LogFImpl(level, filename, line_num, format, packed_args, sizeof...(Args));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ...Args>
|
||||
inline void ServerLogger::LogFMT(uns::ServerLogLevel level, const std::string& format, Args && ...args)
|
||||
{
|
||||
uns::ServerLogLevel curr_level = CurrentLevel.load(std::memory_order_relaxed);
|
||||
if ((curr_level == uns::llOff) || (level < curr_level))
|
||||
return;
|
||||
|
||||
if constexpr (sizeof...(Args) == 0)
|
||||
LogFMTImpl(level, format, nullptr, 0);
|
||||
else
|
||||
{
|
||||
uns::LogArg packed_args[] = { uns::LogArg(std::forward<Args>(args))... };
|
||||
LogFMTImpl(level, format, packed_args, sizeof...(Args));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ...Args>
|
||||
inline void ServerLogger::LogFMT_F(uns::ServerLogLevel level, const std::string& filename, int line_num, const std::string format, Args && ...args)
|
||||
{
|
||||
uns::ServerLogLevel curr_level = CurrentLevel.load(std::memory_order_relaxed);
|
||||
if ((curr_level == uns::llOff) || (level < curr_level))
|
||||
return;
|
||||
|
||||
if constexpr (sizeof...(Args) == 0)
|
||||
LogFMT_FImpl(level, filename, line_num, format, nullptr, 0);
|
||||
else
|
||||
{
|
||||
uns::LogArg packed_args[] = { uns::LogArg(std::forward<Args>(args))... };
|
||||
LogFMT_FImpl(level, filename, line_num, format, packed_args, sizeof...(Args));
|
||||
}
|
||||
}
|
||||
|
||||
extern UNSWSC_DLL_EXPORT ServerLogger GlobalServerLogger;
|
||||
|
||||
#if (defined(_WIN32) || defined(_WIN64))
|
||||
#define __FILENAME__ std::strrchr("\\" __FILE__, '\\') + 1
|
||||
#else
|
||||
#define __FILENAME__ std::strrchr("/" __FILE__, '/') + 1
|
||||
#endif
|
||||
|
||||
#define SCLOG_CONSOLE_INIT(__log_level__) GlobalServerLogger.InitLogger(__log_level__)
|
||||
#define SCLOG_FILE_INIT(__file_name__, __log_level__, ...) GlobalServerLogger.InitLogger(__log_level__, __file_name__, ##__VA_ARGS__)
|
||||
|
||||
#define SCLOG_WRITE(__level__, __text__, ...) GlobalServerLogger.LogF(__level__, __FILENAME__, __LINE__, __text__, ##__VA_ARGS__)
|
||||
#define SCLOG_TRACE(__text__, ...) GlobalServerLogger.LogF(uns::llTrace, __FILENAME__, __LINE__, __text__, ##__VA_ARGS__)
|
||||
#define SCLOG_DEBUG(__text__, ...) GlobalServerLogger.LogF(uns::llDebug, __FILENAME__, __LINE__, __text__, ##__VA_ARGS__)
|
||||
#define SCLOG_INFO(__text__, ...) GlobalServerLogger.LogF(uns::llInfo, __FILENAME__, __LINE__, __text__, ##__VA_ARGS__)
|
||||
#define SCLOG_WARNING(__text__, ...) GlobalServerLogger.LogF(uns::llWarning, __FILENAME__, __LINE__, __text__, ##__VA_ARGS__)
|
||||
#define SCLOG_ERROR(__text__, ...) GlobalServerLogger.LogF(uns::llError, __FILENAME__, __LINE__, __text__, ##__VA_ARGS__)
|
||||
#define SCLOG_FATAL(__text__, ...) GlobalServerLogger.LogF(uns::llFatal, __FILENAME__, __LINE__, __text__, ##__VA_ARGS__)
|
||||
|
||||
#define SCLOG_SHORT_WRITE(__level__, __text__, ...) GlobalServerLogger.Log(__level__, __text__, ##__VA_ARGS__)
|
||||
#define SCLOG_SHORT_TRACE(__text__, ...) GlobalServerLogger.Log(uns::llTrace, __text__, ##__VA_ARGS__)
|
||||
#define SCLOG_SHORT_DEBUG(__text__, ...) GlobalServerLogger.Log(uns::llDebug, __text__, ##__VA_ARGS__)
|
||||
#define SCLOG_SHORT_INFO(__text__, ...) GlobalServerLogger.Log(uns::llInfo, __text__, ##__VA_ARGS__)
|
||||
#define SCLOG_SHORT_WARNING(__text__, ...) GlobalServerLogger.Log(uns::llWarning, __text__, ##__VA_ARGS__)
|
||||
#define SCLOG_SHORT_ERROR(__text__, ...) GlobalServerLogger.Log(uns::llError, __text__, ##__VA_ARGS__)
|
||||
#define SCLOG_SHORT_FATAL(__text__, ...) GlobalServerLogger.Log(uns::llFatal, __text__, ##__VA_ARGS__)
|
||||
|
||||
#define SCLOGF_WRITE(__level__, __text__, ...) GlobalServerLogger.LogFMT_F(__level__, __FILENAME__, __LINE__, __text__, ##__VA_ARGS__)
|
||||
#define SCLOGF_TRACE(__text__, ...) GlobalServerLogger.LogFMT_F(uns::llTrace, __FILENAME__, __LINE__, __text__, ##__VA_ARGS__)
|
||||
#define SCLOGF_DEBUG(__text__, ...) GlobalServerLogger.LogFMT_F(uns::llDebug, __FILENAME__, __LINE__, __text__, ##__VA_ARGS__)
|
||||
#define SCLOGF_INFO(__text__, ...) GlobalServerLogger.LogFMT_F(uns::llInfo, __FILENAME__, __LINE__, __text__, ##__VA_ARGS__)
|
||||
#define SCLOGF_WARNING(__text__, ...) GlobalServerLogger.LogFMT_F(uns::llWarning, __FILENAME__, __LINE__, __text__, ##__VA_ARGS__)
|
||||
#define SCLOGF_ERROR(__text__, ...) GlobalServerLogger.LogFMT_F(uns::llError, __FILENAME__, __LINE__, __text__, ##__VA_ARGS__)
|
||||
#define SCLOGF_FATAL(__text__, ...) GlobalServerLogger.LogFMT_F(uns::llFatal, __FILENAME__, __LINE__, __text__, ##__VA_ARGS__)
|
||||
|
||||
#define SCLOGF_SHORT_WRITE(__level__, __text__, ...) GlobalServerLogger.LogFMT(__level__, __text__, ##__VA_ARGS__)
|
||||
#define SCLOGF_SHORT_TRACE(__text__, ...) GlobalServerLogger.LogFMT(uns::llTrace, __text__, ##__VA_ARGS__)
|
||||
#define SCLOGF_SHORT_DEBUG(__text__, ...) GlobalServerLogger.LogFMT(uns::llDebug, __text__, ##__VA_ARGS__)
|
||||
#define SCLOGF_SHORT_INFO(__text__, ...) GlobalServerLogger.LogFMT(uns::llInfo, __text__, ##__VA_ARGS__)
|
||||
#define SCLOGF_SHORT_WARNING(__text__, ...) GlobalServerLogger.LogFMT(uns::llWarning, __text__, ##__VA_ARGS__)
|
||||
#define SCLOGF_SHORT_ERROR(__text__, ...) GlobalServerLogger.LogFMT(uns::llError, __text__, ##__VA_ARGS__)
|
||||
#define SCLOGF_SHORT_FATAL(__text__, ...) GlobalServerLogger.LogFMT(uns::llFatal, __text__, ##__VA_ARGS__)
|
||||
|
||||
#define SCLOG_ENABLE(__level__) GlobalServerLogger.EnableLog(__level__)
|
||||
#define SCLOG_DISABLE() GlobalServerLogger.DisableLog()
|
||||
#define SCLOG_CLOSE() GlobalServerLogger.CloseLog()
|
||||
Reference in New Issue
Block a user