44#ifndef MSCCLPP_LOGGER_HPP_
55#define MSCCLPP_LOGGER_HPP_
66
7+ #include < unistd.h>
8+
79#include < bitset>
810#include < fstream>
911#include < iomanip>
1315#include < mscclpp/errors.hpp>
1416#include < sstream>
1517#include < string>
18+ #include < string_view>
1619
1720namespace mscclpp {
1821
1922typedef enum : unsigned int { NONE = 0 , DEBUG, INFO, WARN, ERROR } LogLevel;
2023typedef enum : std::size_t { ENV = 0 , NET, CONN, EXEC, NCCL, COUNT } LogSubsys;
2124
2225namespace detail {
23- std::string guessRemoveProjectPrefix (const std::string& filePathStr);
26+
27+ constexpr std::string_view filenameFromPath (const char * path) {
28+ if (path == nullptr ) return " " ;
29+ const char * last = path;
30+ for (const char * p = path; *p; ++p) {
31+ if (*p == ' /' || *p == ' \\ ' ) {
32+ last = p + 1 ; // character after separator
33+ }
34+ }
35+ return std::string_view (last);
36+ }
37+
38+ constexpr std::string_view logLevelToString (LogLevel level) {
39+ switch (level) {
40+ case LogLevel::NONE:
41+ return " NONE" ;
42+ case LogLevel::DEBUG:
43+ return " DEBUG" ;
44+ case LogLevel::INFO:
45+ return " INFO" ;
46+ case LogLevel::WARN:
47+ return " WARN" ;
48+ case LogLevel::ERROR:
49+ return " ERROR" ;
50+ default :
51+ return " UNKNOWN" ;
52+ }
53+ }
54+
55+ constexpr std::string_view logSubsysToString (LogSubsys subsys) {
56+ switch (subsys) {
57+ case LogSubsys::ENV:
58+ return " ENV" ;
59+ case LogSubsys::NET:
60+ return " NET" ;
61+ case LogSubsys::CONN:
62+ return " CONN" ;
63+ case LogSubsys::EXEC:
64+ return " EXEC" ;
65+ case LogSubsys::NCCL:
66+ return " NCCL" ;
67+ case LogSubsys::COUNT:
68+ return " ALL" ;
69+ default :
70+ return " UNKNOWN" ;
71+ }
72+ }
73+
2474std::string timestamp (const char * format = " %Y-%m-%d %X" );
25- std::string logLevelToString (LogLevel level);
26- std::string logSubsysToString (LogSubsys subsys);
27- int pid ();
75+
2876} // namespace detail
2977
3078// Bitset holding enabled subsystems.
3179using LogSubsysSet = std::bitset<static_cast <std::size_t >(LogSubsys::COUNT)>;
3280
3381class Logger {
3482 private:
35- // Overload only for string literals: const char(&)[N]
83+ // Overload for string literals: const char(&)[N]
3684 template <std::size_t N>
3785 std::string toStringHelper (const char (&value)[N]) const {
3886 // N includes the terminating '\0'; std::string(value) stops at '\0'
@@ -41,7 +89,9 @@ class Logger {
4189
4290 template <typename T>
4391 std::string toStringHelper (T&& value) const {
44- if constexpr (std::is_same_v<std::decay_t <T>, std::string>) {
92+ if constexpr (std::is_same_v<std::decay_t <T>, std::string_view>) {
93+ return std::string (value);
94+ } else if constexpr (std::is_same_v<std::decay_t <T>, std::string>) {
4595 return std::forward<T>(value);
4696 } else if constexpr (std::is_arithmetic_v<std::decay_t <T>>) {
4797 return std::to_string (value);
@@ -77,11 +127,12 @@ class Logger {
77127
78128 void setDelimiter (char delimiter) { delimiter_ = delimiter; }
79129
80- template <bool NewLine, typename ... Args>
81- std::string message (LogLevel level, LogSubsys subsys, Args&&... args) {
82- if (level < level_) return " " ;
83- if (!subsysSet_.test (static_cast <std::size_t >(subsys))) return " " ;
130+ inline bool shouldLog (LogLevel level, LogSubsys subsys) const {
131+ return level >= level_ && subsysSet_.test (static_cast <std::size_t >(subsys));
132+ }
84133
134+ template <bool NewLine, typename ... Args>
135+ std::string message (Args&&... args) {
85136 if (sizeof ...(args) == 0 ) {
86137 if constexpr (NewLine) {
87138 return header_ + " \n " ;
@@ -121,8 +172,8 @@ class Logger {
121172 }
122173
123174 template <typename ... Args>
124- void log (LogLevel level, LogSubsys subsys, Args&&... args) {
125- auto msg = message<true >(level, subsys, std::forward<Args>(args)...);
175+ void log (Args&&... args) {
176+ auto msg = message<true >(std::forward<Args>(args)...);
126177 if (msg.empty ()) return ;
127178 if (logFileStream_.is_open ()) {
128179 logFileStream_ << msg;
@@ -138,28 +189,31 @@ Logger& logger(const std::string& header, const std::string& level, char delimit
138189
139190} // namespace mscclpp
140191
141- #define LOGGER_LOG (level__, subsys__, ...) \
142- do { \
143- ::mscclpp::logger (" %@ %@ %@ %@ %@ %@:%@ " , ::mscclpp::env()->logLevel, 0) \
144- .log(level__, subsys__, ::mscclpp::detail::timestamp(), "MSCCLPP", ::mscclpp::detail::pid(), \
145- ::mscclpp::detail::logLevelToString(level__), ::mscclpp::detail::logSubsysToString(subsys__), \
146- ::mscclpp::detail::guessRemoveProjectPrefix(__FILE__), __LINE__, __VA_ARGS__); \
192+ // Helper to build log message arguments
193+ #define LOGGER_BUILD_ARGS (level__, subsys__, ...) \
194+ ::mscclpp::detail::timestamp (), "MSCCLPP", ::getpid(), ::mscclpp::detail::logLevelToString(level__), \
195+ ::mscclpp::detail::logSubsysToString(subsys__), ::mscclpp::detail::filenameFromPath(__FILE__), __LINE__, \
196+ __VA_ARGS__
197+
198+ #define LOGGER_LOG (level__, subsys__, ...) \
199+ do { \
200+ auto & logger__ = ::mscclpp::logger (" %@ %@ %@ %@ %@ %@:%@ " , ::mscclpp::env ()->logLevel , 0 ); \
201+ if (logger__.shouldLog (level__, subsys__)) { \
202+ logger__.log (LOGGER_BUILD_ARGS (level__, subsys__, __VA_ARGS__)); \
203+ } \
147204 } while (0 )
148205
149206#define LOG (level__, subsys__, ...) LOGGER_LOG(level__, subsys__, __VA_ARGS__)
150207#define DEBUG (subsys__, ...) LOGGER_LOG(::mscclpp::LogLevel::DEBUG, subsys__, __VA_ARGS__)
151208#define INFO (subsys__, ...) LOGGER_LOG(::mscclpp::LogLevel::INFO, subsys__, __VA_ARGS__)
152209#define WARN (subsys__, ...) LOGGER_LOG(::mscclpp::LogLevel::WARN, subsys__, __VA_ARGS__)
153210#define ERROR (subsys__, ...) LOGGER_LOG(::mscclpp::LogLevel::ERROR, subsys__, __VA_ARGS__)
154- #define THROW (subsys__, exception__, errorCode__, ...) \
155- do { \
156- const auto errorCodeCopy__ = errorCode__; \
157- throw exception__ ( \
158- ::mscclpp::logger (" %@ %@ %@ %@ %@ %@:%@ " , ::mscclpp::env()->logLevel, 0) \
159- .message<false>(::mscclpp::LogLevel::ERROR, subsys__, ::mscclpp::detail::timestamp(), "MSCCLPP", \
160- ::mscclpp::detail::pid(), "ERROR", ::mscclpp::detail::logSubsysToString(subsys__), \
161- ::mscclpp::detail::guessRemoveProjectPrefix(__FILE__), __LINE__, __VA_ARGS__), \
162- errorCodeCopy__); \
211+ #define THROW (subsys__, exception__, errorCode__, ...) \
212+ do { \
213+ const auto errorCodeCopy__ = errorCode__; \
214+ throw exception__ (::mscclpp::logger (" %@ %@ %@ %@ %@ %@:%@ " , ::mscclpp::env ()->logLevel , 0 ) \
215+ .message <false >(LOGGER_BUILD_ARGS (::mscclpp::LogLevel::ERROR, subsys__, __VA_ARGS__)), \
216+ errorCodeCopy__); \
163217 } while (0 )
164218
165219#endif // MSCCLPP_LOGGER_HPP_
0 commit comments