44#include " logger.hpp"
55
66#include < algorithm>
7+ #include < atomic>
78#include < chrono>
9+ #include < ctime>
810#include < filesystem>
911#include < fstream>
12+ #include < mutex>
1013#include < unordered_map>
1114
1215namespace mscclpp {
@@ -113,20 +116,37 @@ std::string guessRemoveProjectPrefix(const std::string& filePath) {
113116 return filePath;
114117}
115118
116- [[maybe_unused]] std::string removeProjectPrefix (const std::string& filePath, const std::string& projectPrefix = " /" ) {
117- size_t pos = filePath.find (projectPrefix);
118- if (pos != std::string::npos) {
119- return filePath.substr (pos + projectPrefix.length ());
120- }
121- return filePath; // No prefix found, return original path
122- }
123-
124119std::string timestamp (const char * format) {
120+ // Cache formatted UTC timestamp per second to reduce formatting overhead
121+ static std::atomic<time_t > cachedSecond{0 };
122+ static std::string cachedString;
123+ static std::mutex cacheMutex;
124+
125125 auto now = std::chrono::system_clock::now ();
126- auto inTime = std::chrono::system_clock::to_time_t (now);
126+ time_t currentTime = std::chrono::system_clock::to_time_t (now);
127+
128+ // Fast path: same second, return cached value
129+ time_t last = cachedSecond.load (std::memory_order_acquire);
130+ if (last == currentTime && !cachedString.empty ()) {
131+ return cachedString;
132+ }
133+
134+ // Compute new formatted time in UTC
135+ std::tm tmBuf;
136+ if (::gmtime_r (¤tTime, &tmBuf) == nullptr ) {
137+ return " " ; // Fallback on conversion failure
138+ }
127139 std::stringstream ss;
128- ss << std::put_time (std::localtime (&inTime), format);
129- return ss.str ();
140+ ss << std::put_time (&tmBuf, format);
141+ std::string newString = ss.str ();
142+
143+ // Update cache
144+ {
145+ std::lock_guard<std::mutex> lock (cacheMutex);
146+ cachedString = std::move (newString);
147+ cachedSecond.store (currentTime, std::memory_order_release);
148+ return cachedString;
149+ }
130150}
131151
132152std::string subsysFlagToString (unsigned int flag) {
@@ -150,7 +170,8 @@ std::string subsysFlagToString(unsigned int flag) {
150170
151171} // namespace detail
152172
153- static std::unordered_map<std::string, std::unique_ptr<Logger>> allLoggers;
173+ static std::once_flag globalLoggerInitFlag;
174+ static std::shared_ptr<Logger> globalLoggerPtr;
154175
155176Logger::Logger (const std::string& header, const LogLevel level, const char delimiter)
156177 : header_(header), level_(level), delimiter_(delimiter) {
@@ -165,14 +186,12 @@ Logger::Logger(const std::string& header, const LogLevel level, const char delim
165186 }
166187}
167188
168- Logger& logger (const std::string& name, const std::string& header, const std::string& levelStr, char delimiter) {
169- auto it = allLoggers.find (name);
170- if (it != allLoggers.end ()) {
171- return *(it->second );
172- }
173- LogLevel level = stringToLogLevel (levelStr);
174- allLoggers[name] = std::make_unique<Logger>(header, level, delimiter);
175- return *(allLoggers[name]);
189+ Logger& logger (const std::string& header, const std::string& levelStr, char delimiter) {
190+ std::call_once (globalLoggerInitFlag, [&]() {
191+ LogLevel level = stringToLogLevel (levelStr);
192+ globalLoggerPtr = std::make_shared<Logger>(header, level, delimiter);
193+ });
194+ return *globalLoggerPtr;
176195}
177196
178197} // namespace mscclpp
0 commit comments