aboutsummaryrefslogtreecommitdiff
path: root/src/brussel.common/Log.cpp
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2023-10-19 22:50:07 -0700
committerrtk0c <[email protected]>2025-08-16 11:31:16 -0700
commit297232d21594b138bb368a42b5b0d085ff9ed6aa (patch)
tree075d5407e1e12a9d35cbee6e4c20ad34e0765c42 /src/brussel.common/Log.cpp
parentd5cd34ff69f7fd134d5450696f298af1a864afbc (diff)
The great renaming: switch to "module style"
Diffstat (limited to 'src/brussel.common/Log.cpp')
-rw-r--r--src/brussel.common/Log.cpp116
1 files changed, 116 insertions, 0 deletions
diff --git a/src/brussel.common/Log.cpp b/src/brussel.common/Log.cpp
new file mode 100644
index 0000000..83d81e9
--- /dev/null
+++ b/src/brussel.common/Log.cpp
@@ -0,0 +1,116 @@
+#include "Log.hpp"
+
+#include "Macros.hpp"
+
+#include <robin_hood.h>
+#include <algorithm>
+#include <cstdio>
+
+namespace ProjectBrussel_UNITY_ID {
+using namespace Log;
+
+const char* MapMessageLevelToString(MessageLevel level) {
+ switch (level) {
+ using enum MessageLevel;
+ case Debug: return "DEBUG";
+ case Info: return "INFO";
+ case Warning: return "WARN";
+ case Error: return "ERROR";
+ default: UNREACHABLE;
+ }
+}
+
+void PrintMessage(const Message& msg) {
+ using namespace std::chrono;
+
+ auto t = system_clock::to_time_t(msg.time);
+ char timeStr[128];
+ strftime(timeStr, sizeof(timeStr), "%H:%M:%S", localtime(&t));
+ printf("[%s][%s][%s:%u] %.*s\n",
+ MapMessageLevelToString(msg.level),
+ timeStr,
+ msg.srcLoc.function_name(),
+ msg.srcLoc.line(),
+ PRINTF_STRING_VIEW(msg.text));
+}
+
+MessageBufferId gNextBufferId = 0;
+robin_hood::unordered_map<MessageBufferId, MessageBuffer*> gBuffers;
+} // namespace ProjectBrussel_UNITY_ID
+
+namespace Log {
+bool gPrintToStdOut = true;
+#if BRUSSEL_DEV_ENV
+MessageBuffer gDefaultBuffer;
+MessageBufferId gDefaultBufferId;
+#endif
+} // namespace Log
+
+Log::MessageBufferId Log::RegisterBuffer(MessageBuffer& buffer) {
+ using namespace ProjectBrussel_UNITY_ID;
+
+ auto id = gNextBufferId++;
+ gBuffers.try_emplace(id, &buffer);
+ return id;
+}
+
+void Log::UnregisterBuffer(MessageBufferId id) {
+ using namespace ProjectBrussel_UNITY_ID;
+
+ gBuffers.erase(id);
+}
+
+Log::MessageBuffer* Log::GetBuffer(MessageBufferId id) {
+ using namespace ProjectBrussel_UNITY_ID;
+
+ auto iter = gBuffers.find(id);
+ if (iter != gBuffers.end()) {
+ return iter->second;
+ } else {
+ return nullptr;
+ }
+}
+
+void Log::DumpRegisteredBuffers() {
+ using namespace ProjectBrussel_UNITY_ID;
+
+ puts("================ BEGIN LOG BUFFER DUMP ================");
+ for (const auto& [id, buffer] : gBuffers) {
+ printf("Buffer #%d at %p\n", id, buffer);
+ printf("Buffer size: %zu\n", buffer->messages.capacity());
+ bool needsWrapAround = buffer->messages.GetHeadIdx() >= buffer->messages.GetTailIdx();
+ if (needsWrapAround) {
+ printf("Fill size: %zu in [%zu,%zu) and [0,%zu)\n",
+ buffer->messages.size(),
+ // First chunk: [begin,end)
+ buffer->messages.GetHeadIdx(),
+ buffer->messages.capacity(),
+ // Second chunk: [0,end)
+ buffer->messages.GetTailIdx());
+ } else {
+ printf("Fill size: %zu in [%zu,%zu)\n",
+ buffer->messages.size(),
+ // [begin,end)
+ buffer->messages.GetHeadIdx(),
+ buffer->messages.GetTailIdx());
+ }
+ for (const auto& msg : buffer->messages) {
+ // Indent log messages in this buffer
+ printf("\t");
+ PrintMessage(msg);
+ }
+ }
+ puts("================ END LOG BUFFER DUMP ================");
+}
+
+void Log::Add(const Message& msg) {
+ using namespace ProjectBrussel_UNITY_ID;
+
+ if (gPrintToStdOut) {
+ PrintMessage(msg);
+ }
+
+ for (auto& [_, buffer] : gBuffers) {
+ buffer->messages.push_back(msg);
+ }
+}