diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 13a287c..316d63a 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -160,6 +160,10 @@ add_executable(MassBuilderSaveTool WIN32
Maps/WeaponTypes.hpp
ToastQueue/ToastQueue.h
ToastQueue/ToastQueue.cpp
+ Logger/Logger.h
+ Logger/Logger.cpp
+ Logger/MagnumLogBuffer.h
+ Logger/MagnumLogBuffer.cpp
Utilities/Crc32.h
FontAwesome/IconsFontAwesome5.h
FontAwesome/IconsFontAwesome5Brands.h
diff --git a/src/Logger/Logger.cpp b/src/Logger/Logger.cpp
new file mode 100644
index 0000000..577e288
--- /dev/null
+++ b/src/Logger/Logger.cpp
@@ -0,0 +1,111 @@
+// MassBuilderSaveTool
+// Copyright (C) 2021-2022 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#ifdef SAVETOOL_DEBUG_BUILD
+#include
+#else
+#include
+#endif
+#include
+
+#include
+#include
+
+#include "Logger.h"
+
+using Containers::Array;
+using Utility::Debug;
+using Utility::Warning;
+using Utility::Error;
+
+namespace MassBuilderSaveTool { namespace Logger {
+
+#ifndef SAVETOOL_DEBUG_BUILD
+static std::ofstream log_file{"SaveToolLog.txt", std::ios::trunc};
+#endif
+
+static std::mutex _logMutex;
+
+static Array _entries;
+
+inline Debug&
+operator<<(Debug& out, const LogEntry& entry) {
+ using namespace Containers::Literals;
+
+ static char formatted_time[22] = {'\0'};
+ std::strftime(&formatted_time[0], sizeof(formatted_time)/sizeof(formatted_time[0]), "[%Y-%m-%d %H:%M:%S]", &entry.timestamp);
+ out << formatted_time;
+
+#ifdef SAVETOOL_DEBUG_BUILD
+#define COLOUR(col) << Debug::color(Debug::Color::col)
+#else
+#define COLOUR(col)
+#endif
+
+ switch(entry.type) {
+ case EntryType::Info:
+ out << "[INFO]"_s COLOUR(Default);
+ break;
+ case EntryType::Success:
+ out << "[SUCCESS]"_s COLOUR(Green);
+ break;
+ case EntryType::Warning:
+ out << "[WARNING]"_s COLOUR(Yellow);
+ break;
+ case EntryType::Error:
+ out << "[ERROR]"_s COLOUR(Red);
+ break;
+ }
+
+#undef DEBUG_COLOUR
+
+ out << entry.message << Debug::resetColor;
+
+ return out;
+}
+
+void
+initialise() {
+ arrayReserve(_entries, 100);
+}
+
+void
+addEntry(EntryType type, StringView message) {
+ _logMutex.lock();
+
+ auto time = std::time(nullptr);
+
+ LogEntry entry{
+ *std::localtime(&time), type,
+ (message.back() == '\n') ? String{message.exceptSuffix(1)} : String{message}
+ };
+
+ Debug{
+#ifndef SAVETOOL_DEBUG_BUILD
+ &log_file
+#else
+ &std::cout
+#endif
+ } << entry;
+
+ arrayAppend(_entries, std::move(entry));
+
+ _logMutex.unlock();
+}
+
+} // Logger
+
+} // MassBuilderSaveTool
diff --git a/src/Logger/Logger.h b/src/Logger/Logger.h
new file mode 100644
index 0000000..a1abd36
--- /dev/null
+++ b/src/Logger/Logger.h
@@ -0,0 +1,54 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021-2022 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include
+
+#include
+
+using namespace Corrade;
+
+using Containers::String;
+using Containers::StringView;
+
+namespace MassBuilderSaveTool { namespace Logger {
+
+enum class EntryType {
+ Info,
+ Success,
+ Warning,
+ Error,
+};
+
+struct LogEntry {
+ std::tm timestamp;
+ EntryType type;
+ String message;
+};
+
+void initialise();
+
+void addEntry(EntryType type, StringView message);
+
+} // Logger
+
+} // MassBuilderSaveTool
+
+#define LOG_INFO(message) MassBuilderSaveTool::Logger::addEntry(MassBuilderSaveTool::Logger::EntryType::Info, message)
+#define LOG_SUCCESS(message) MassBuilderSaveTool::Logger::addEntry(MassBuilderSaveTool::Logger::EntryType::Success, message)
+#define LOG_WARNING(message) MassBuilderSaveTool::Logger::addEntry(MassBuilderSaveTool::Logger::EntryType::Warning, message)
+#define LOG_ERROR(message) MassBuilderSaveTool::Logger::addEntry(MassBuilderSaveTool::Logger::EntryType::Error, message)
diff --git a/src/Logger/MagnumLogBuffer.cpp b/src/Logger/MagnumLogBuffer.cpp
new file mode 100644
index 0000000..8fa3416
--- /dev/null
+++ b/src/Logger/MagnumLogBuffer.cpp
@@ -0,0 +1,34 @@
+// MassBuilderSaveTool
+// Copyright (C) 2021-2022 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "MagnumLogBuffer.h"
+
+namespace MassBuilderSaveTool { namespace Logger {
+
+MagnumLogBuffer::MagnumLogBuffer(EntryType type): std::stringbuf(std::ios_base::out), _type{type} {}
+
+MagnumLogBuffer::~MagnumLogBuffer() = default;
+
+int
+MagnumLogBuffer::sync() {
+ addEntry(_type, str().c_str());
+ str({});
+ return 0;
+}
+
+} // Logger
+
+} // MassBuilderSaveTool
diff --git a/src/Logger/MagnumLogBuffer.h b/src/Logger/MagnumLogBuffer.h
new file mode 100644
index 0000000..39aa5a8
--- /dev/null
+++ b/src/Logger/MagnumLogBuffer.h
@@ -0,0 +1,38 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021-2022 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include
+
+#include "Logger.h"
+
+namespace MassBuilderSaveTool { namespace Logger {
+
+class MagnumLogBuffer : public std::stringbuf {
+ public:
+ explicit MagnumLogBuffer(EntryType type);
+ ~MagnumLogBuffer();
+
+ private:
+ int sync() override;
+
+ EntryType _type;
+};
+
+} // Logger
+
+} // MassBuilderSaveTool