#pragma once #include #include #include #include #include #include #include class Log { private: enum LOG_TYPE { log_generic = 0, log_debug, log_error, log_warn, num_log_type }; static inline int32_t current_open_hour; static inline std::fstream file_stream[ num_log_type ]; static inline std::mutex log_lock; static const char *GetTimeStamp(); static void CheckFileStatus( LOG_TYPE type ); static void WriteToLog( LOG_TYPE type, const std::string &message ); static std::string WideToMulti( const std::wstring &input ) { if( input.empty() ) return ""; int sizeNeeded = WideCharToMultiByte( CP_UTF8, 0, input.data(), ( int )input.size(), nullptr, 0, nullptr, nullptr ); std::string result( sizeNeeded, 0 ); WideCharToMultiByte( CP_UTF8, 0, input.data(), ( int )input.size(), std::data( result ), sizeNeeded, nullptr, nullptr ); return result; } template static std::string ToString( const T &value ) { if constexpr( std::is_same_v ) { return WideToMulti( value ); } else if constexpr( std::is_same_v ) { return value; } else { std::ostringstream oss; oss << value; return oss.str(); } } template static std::string Format( const std::string &formatStr, Args&&... args ) { std::ostringstream oss; size_t last = 0, next = 0; std::vector values = { ToString( std::forward( args ) )... }; size_t index = 0; while( ( next = formatStr.find( "{}", last ) ) != std::string::npos ) { oss << formatStr.substr( last, next - last ); if( index < values.size() ) { oss << values[ index++ ]; } else { oss << "{}"; // unmatched placeholder } last = next + 2; } oss << formatStr.substr( last ); return oss.str(); } public: static Log &Get() { static Log instance; return instance; } Log(); ~Log(); template static void Info( const std::string &format, Args&&... args ) { WriteToLog( log_generic, Format( format, std::forward( args )... ) ); } template static void Warn( const std::string &format, Args&&... args ) { WriteToLog( log_warn, Format( format, std::forward( args )... ) ); } template static void Debug( const std::string &format, Args&&... args ) { #ifdef _DEBUG WriteToLog( log_debug, Format( format, std::forward( args )... ) ); #endif } template static void Error( const std::string &format, Args&&... args ) { WriteToLog( log_error, Format( format, std::forward( args )... ) ); } static void Packet( std::vector p, size_t size, bool send ); static void ToFile( std::string prefix, std::vector p, size_t size ); };