diff --git a/.github/workflows/linux-x64-gpu.yml b/.github/workflows/linux-x64-gpu.yml index ca75f2287..c29940c7c 100644 --- a/.github/workflows/linux-x64-gpu.yml +++ b/.github/workflows/linux-x64-gpu.yml @@ -55,6 +55,7 @@ jobs: cd /work source /opt/conda/bin/activate conda activate py38 + apt install libspdlog-dev -y mkdir build && cd build bash ../generate.sh make make -j$(nproc) && make install diff --git a/builder/manywheel/entrypoint_build.sh b/builder/manywheel/entrypoint_build.sh index c9c2cae6e..48e25b485 100755 --- a/builder/manywheel/entrypoint_build.sh +++ b/builder/manywheel/entrypoint_build.sh @@ -12,6 +12,7 @@ conda activate $PYTHON_VERSION cd lmdeploy mkdir -p build && cd build && rm -rf * +apt install libspdlog-dev -y bash ../generate.sh make make -j$(nproc) && make install if [ $? != 0 ]; then diff --git a/src/turbomind/utils/CMakeLists.txt b/src/turbomind/utils/CMakeLists.txt index 82f08ef1b..a8b9f4923 100644 --- a/src/turbomind/utils/CMakeLists.txt +++ b/src/turbomind/utils/CMakeLists.txt @@ -26,7 +26,11 @@ target_link_libraries(cuda_utils PUBLIC CUDA::cudart) add_library(logger STATIC logger.cc) set_property(TARGET logger PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET logger PROPERTY CUDA_RESOLVE_DEVICE_SYMBOLS ON) -target_link_libraries(logger PUBLIC CUDA::cudart) +if (UNIX) + target_link_libraries(logger PUBLIC CUDA::cudart -lpthread) +else () + target_link_libraries(logger PUBLIC CUDA::cudart) +endif () add_library(cublasAlgoMap STATIC cublasAlgoMap.cc) set_property(TARGET cublasAlgoMap PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/src/turbomind/utils/logger.cc b/src/turbomind/utils/logger.cc index 9788a8fad..fba7cfb9f 100644 --- a/src/turbomind/utils/logger.cc +++ b/src/turbomind/utils/logger.cc @@ -17,10 +17,22 @@ #include "src/turbomind/utils/logger.h" #include +#ifndef _MSC_VER +#include +#include +#include +#include +#endif + namespace turbomind { Logger::Logger() { +#ifndef _MSC_VER + // TODO: use config + SpdLogger::get_instance().set_log_path("/var/log/lmdeploy.log"); + SpdLogger::get_instance().init(); +#endif char* is_first_rank_only_char = std::getenv("TM_LOG_FIRST_RANK_ONLY"); bool is_first_rank_only = (is_first_rank_only_char != nullptr && std::string(is_first_rank_only_char) == "ON") ? true : false; @@ -56,4 +68,33 @@ Logger::Logger() } } +#ifndef _MSC_VER +void SpdLogger::init() +{ + if (inited_) { + return; + } + + spdlog::init_thread_pool(8192, 1); + + // rotate 500 MB + auto basic_sink = std::make_shared(path_, 500 * 1024 * 1024, 0); + // async + auto logger = std::make_shared( + "logger", basic_sink, spdlog::thread_pool(), spdlog::async_overflow_policy::overrun_oldest); + logger->set_level(spdlog::level::trace); + // ms, thread_id + logger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%t] %v"); + + logger_ = logger; + + spdlog::register_logger(logger_); + + // real-time refresh + logger_->flush_on(spdlog::level::trace); + + inited_ = true; +} +#endif + } // namespace turbomind diff --git a/src/turbomind/utils/logger.h b/src/turbomind/utils/logger.h index 3e9f25e9e..a9bbc3f9f 100644 --- a/src/turbomind/utils/logger.h +++ b/src/turbomind/utils/logger.h @@ -20,6 +20,10 @@ #include #include +#ifndef _MSC_VER +#include +#endif + #include "src/turbomind/utils/string_utils.h" namespace turbomind { @@ -30,11 +34,41 @@ namespace turbomind { #undef ERROR #endif +#ifndef _MSC_VER +class SpdLogger { +public: + static SpdLogger& get_instance() + { + static SpdLogger spdlogger; + return spdlogger; + } + spdlog::logger* get_logger() + { + return logger_.get(); + } + + void set_log_path(const std::string& path) + { + path_ = path; + } + void init(); + +private: + SpdLogger() = default; + ~SpdLogger() = default; + SpdLogger(const SpdLogger&) = delete; + SpdLogger& operator=(const SpdLogger&) = delete; + + std::string path_; + bool inited_ = false; + std::shared_ptr logger_; +}; +#endif + class Logger { public: - enum Level - { + enum Level { TRACE = 0, DEBUG = 10, INFO = 20, @@ -47,17 +81,20 @@ class Logger { thread_local Logger instance; return instance; } - Logger(Logger const&) = delete; + Logger(Logger const&) = delete; void operator=(Logger const&) = delete; template void log(const Level level, const std::string format, const Args&... args) { if (level_ <= level) { - std::string fmt = getPrefix(level) + format + "\n"; - // FILE* out = level_ < WARNING ? stdout : stderr; + std::string fmt = getPrefix(level) + format + "\n"; std::string logstr = fmtstr(fmt, args...); +#ifdef _MSC_VER fprintf(stderr, "%s", logstr.c_str()); +#else + SpdLogger::get_instance().get_logger()->log(spdlog::level::trace, logstr); +#endif } } @@ -65,10 +102,13 @@ class Logger { void log(const Level level, const int rank, const std::string format, const Args&... args) { if (level_ <= level) { - std::string fmt = getPrefix(level, rank) + format + "\n"; - // FILE* out = level_ < WARNING ? stdout : stderr; + std::string fmt = getPrefix(level, rank) + format + "\n"; std::string logstr = fmtstr(fmt, args...); +#ifdef _MSC_VER fprintf(stderr, "%s", logstr.c_str()); +#else + SpdLogger::get_instance().get_logger()->log(spdlog::level::trace, logstr); +#endif } }