diff --git a/CMakeLists.txt b/CMakeLists.txt
index 565ebad55999941996524d8dd8031ee139e7eaea..9e09a0eab161ba1079349001694904aa41e98898 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -125,7 +125,7 @@ if (PYBIND)
     add_pybind_dependency(${module_name})
     ##
 
-    target_link_libraries(${pybind_module_name} PRIVATE fmt::fmt)
+    target_link_libraries(${pybind_module_name} PUBLIC fmt::fmt)
 endif()
 
 target_link_libraries(${module_name} PUBLIC fmt::fmt)
diff --git a/include/aidge/utils/Log.hpp b/include/aidge/utils/Log.hpp
index f92d5cf66f20e851e81867989a91ea2840b7db62..8c576fc811dcfb74168e752b0b7dc87ad2c1a482 100644
--- a/include/aidge/utils/Log.hpp
+++ b/include/aidge/utils/Log.hpp
@@ -9,26 +9,28 @@
  *
  ********************************************************************************/
 
-#ifndef AIDGE_LOG_H_
-#define AIDGE_LOG_H_
+#ifndef AIDGE_CORE_UTILS_LOG_H_
+#define AIDGE_CORE_UTILS_LOG_H_
 
 #include <memory>
+#include <string>
 #include <vector>
 
 #include <fmt/format.h>
-#include <fmt/ranges.h>
+#include <fmt/color.h>
+#ifdef PYBIND
+#include <pybind11/pybind11.h>
+#endif
 
-#include "aidge/data/half.hpp"
 #include "aidge/utils/Attributes.hpp"
 
-#ifdef PYBIND
-#include <pybind11/pybind11.h> // get_shared_data, set_shared_data, PyIsInitialized
-#endif
 
 namespace Aidge {
 #ifdef PYBIND
 namespace py = pybind11;
 #endif
+
+
 /**
  * Helper to define a context anywhere, hiding the scoped variable name
  * which has no relevance.
@@ -36,100 +38,136 @@ namespace py = pybind11;
 #define AIDGE_LOG_CONTEXT(...)                                                \
     const Log::Context logContext_##__LINE__(__VA_ARGS__)
 
-template <class U> static void discard_args(U parg) {
-    (void)parg;
-}
-template <class U, class... Us> static void discard_args(U parg, Us... pargs) {
-    (void)parg;
-    discard_args(pargs...);
-}
-
 /**
- * Aidge logging class, for displaying and file logging of events.
+ * @brief Logging utility class for development and debugging
+ *
+ * The Log class provides a static interface for logging messages at different
+ * severity levels. It supports both console output (with optional colors) and
+ * file output. The logging behavior can be configured through environment
+ * variables or programmatically.
+ *
+ * Environment variables:
+ * - AIDGE_LOGLEVEL_CONSOLE: Set console output level (Debug,Info,Notice,Warn,Error,Fatal)
+ * - AIDGE_LOGLEVEL_FILE: Set file output level
+ * - AIDGE_LOG_COLOR: Enable/disable colored output ("off"/"OFF"/"0" to disable)
+ * - AIDGE_LOG_FILE: Set log file path
+ *
+ * @note Console colors are enabled by default
  */
 class Log {
-  public:
-    enum Level { Debug = 0, Info, Notice, Warn, Error, Fatal };
+public:
+    /**
+     * @brief Log severity levels in ascending order
+     */
+    enum Level {
+        Debug = 0,    ///< Detailed information for debugging
+        Info,         ///< General information about program execution
+        Notice,       ///< Normal but significant conditions
+        Warn,         ///< Warning messages for potentially problematic situations
+        Error,        ///< Error messages for serious problems
+        Fatal         ///< Critical errors that lead to program termination
+    };
 
+    /**
+     * @brief RAII class for managing logging contexts
+     *
+     * This class allows adding temporary context information to logs. When an instance
+     * is created, it adds a context message that will be displayed with all logs until
+     * the instance is destroyed.
+     *
+     * Example:
+     * @code
+     * {
+     *     Log::Context ctx("Processing file: {}", filename);
+     *     Log::info("Starting process"); // Will show context
+     *     // Context automatically removed when ctx is destroyed
+     * }
+     * @endcode
+     */
     class Context {
-      public:
-        template <typename... Args> Context(Args &&...args) {
+    public:
+        /**
+         * @brief Create a new logging context
+         * @param args Format string and arguments for the context message
+         */
+        template <typename... Args>
+        Context(Args&&... args) {
             Log::mContext.push_back(fmt::format(std::forward<Args>(args)...));
         }
 
+        /**
+         * @brief Destroy the context, removing it from the active contexts
+         */
         ~Context() {
             Log::mContext.pop_back();
         }
     };
 
     /**
-     * Detailed messages for debugging purposes, providing information helpful
-     * for developers to trace and identify issues.
-     * Detailed insights of what is happening in an operation, not useful for
-     * the end-user. The operation is performed nominally.
-     * @note This level is disabled at compile time for Release, therefore
-     * inducing no runtime overhead for Release.
+     * @brief Log a debug message
+     * @param args Format string and arguments for the message
+     * @note Debug messages are only compiled in debug builds
      */
-    template <typename... Args> static void debug(Args &&...args) {
-#ifndef NDEBUG
-        // only when compiled in Debug
-        log(Debug, fmt::format(std::forward<Args>(args)...));
+#ifdef NDEBUG
+    template <typename... Args>
+    static void debug(Args&&... /*args*/) {
+        // Debug logging disabled in release builds
+    }
 #else
-        discard_args(&args...);
-#endif
+    template <typename... Args>
+    static void debug(Args&&... args) {
+        log(Debug, fmt::format(std::forward<Args>(args)...));
     }
+#endif
 
     /**
-     * Messages that provide a record of the normal operation, about
-     * the application's state, progress, or important events.
-     * Reports normal start, end and key steps in an operation. The operation
-     * is performed nominally.
+     * @brief Log an info message
+     * @param args Format string and arguments for the message
      */
-    template <typename... Args> static void info(Args &&...args) {
+    template <typename... Args>
+    static void info(Args&&... args) {
         log(Info, fmt::format(std::forward<Args>(args)...));
     }
 
     /**
-     * Applies to normal but significant conditions that may require
-     * monitoring, like unusual or normal fallback events. Reports specific
-     * paths in an operation. The operation can still be performed normally.
+     * @brief Log a notice message
+     * @param args Format string and arguments for the message
      */
-    template <typename... Args> static void notice(Args &&...args) {
+    template <typename... Args>
+    static void notice(Args&&... args) {
         log(Notice, fmt::format(std::forward<Args>(args)...));
     }
 
     /**
-     * Indicates potential issues or situations that may lead to errors but do
-     * not necessarily cause immediate problems.
-     * Some specific steps of the operation could not be performed, but it can
-     * still provide an exploitable result.
+     * @brief Log a warning message
+     * @param args Format string and arguments for the message
      */
-    template <typename... Args> static void warn(Args &&...args) {
+    template <typename... Args>
+    static void warn(Args&&... args) {
         log(Warn, fmt::format(std::forward<Args>(args)...));
     }
 
     /**
-     * Signifies a problem or unexpected condition that the application can
-     * recover from, but attention is needed to prevent further issues.
-     * The operation could not be performed, but it does not prevent potential
-     * further operations.
+     * @brief Log an error message
+     * @param args Format string and arguments for the message
      */
-    template <typename... Args> static void error(Args &&...args) {
+    template <typename... Args>
+    static void error(Args&&... args) {
         log(Error, fmt::format(std::forward<Args>(args)...));
     }
 
     /**
-     * Represents a critical error or condition that leads to the termination
-     * of the application, indicating a severe and unrecoverable problem. The
-     * operation could not be performed and any further operation is
-     * impossible.
+     * @brief Log a fatal error message
+     * @param args Format string and arguments for the message
      */
-    template <typename... Args> static void fatal(Args &&...args) {
+    template <typename... Args>
+    static void fatal(Args&&... args) {
         log(Fatal, fmt::format(std::forward<Args>(args)...));
     }
 
     /**
-     * Set the minimum log level displayed in the console.
+     * @brief Set the minimum level for console output
+     * @param level Minimum level to display
      */
     static void setConsoleLevel(Level level) {
         mConsoleLevel = level;
@@ -137,96 +175,80 @@ class Log {
         // This means each static instance is separated and does not communicate.
         // To allow the communication between the different modules, we use PyCapsule.
         // https://docs.python.org/3/extending/extending.html#providing-a-c-api-for-an-extension-module
-        #ifdef PYBIND
-        #define _CRT_SECURE_NO_WARNINGS
+#ifdef PYBIND
+#define _CRT_SECURE_NO_WARNINGS
         if (Py_IsInitialized()){
             // Note: Setting mConsoleLevel and not level is important
             // to avoid garbage collection of the pointer.
             py::set_shared_data("consoleLevel", &mConsoleLevel);
         }
-        #endif // PYBIND
-
+#endif // PYBIND
     }
-    /**
-     * @brief Get the curent Console Level.
-     *
-     * @return const Level
-     */
-    static Level getConsoleLevel(){
-        #ifdef PYBIND
-        #define _CRT_SECURE_NO_WARNINGS
+
+    static Level getConsoleLevel() {
+#ifdef PYBIND
+#define _CRT_SECURE_NO_WARNINGS
         if (Py_IsInitialized()){
             auto shared_data = reinterpret_cast<Level *>(py::get_shared_data("consoleLevel"));
             if (shared_data)
                 mConsoleLevel = *shared_data;
         }
-        #endif // PYBIND
+#endif // PYBIND
         return mConsoleLevel;
     }
-    /**
-     * Set or disable colors on console.
-     * Initial value should be assumed true.
-     */
-    static void setConsoleColor(bool enabled) {
-        mConsoleColor = enabled;
-    }
 
     /**
-     * Set the minimum log level saved in the log file.
+     * @brief Enable or disable colored console output
+     * @param enabled True to enable colors, false to disable
      */
-    constexpr static void setFileLevel(Level level) {
-        mFileLevel = level;
-    }
+    static void setConsoleColor(bool enabled) noexcept { mConsoleColor = enabled; }
 
     /**
-     * Set the log file name.
-     * Close the current log file and open the one with the new file name.
-     * If empty, stop logging into a file.
+     * @brief Set the minimum level for file output
+     * @param level Minimum level to write to file
      */
-    static void setFileName(const std::string &fileName) {
-        if (fileName != mFileName) {
-            mFileName = fileName;
-            mFile.release();
-
-            if (!fileName.empty()) {
-                initFile(fileName);
-            }
-        }
-    }
+    static void setFileLevel(Level level) noexcept { mFileLevel = level; }
 
     /**
-     * @struct fcloseDeleter
-     * @brief Custom deleter to prevent compiler warnings when using
-     * std::unique_ptr with FILE*.
-     *
-     * Using function pointers with attributes (e.g., __attribute__((nonnull)))
-     * as deleters can trigger warnings like -Wignored-attributes. By defining a
-     * custom deleter struct, these attributes are preserved, eliminating the
-     * warnings.
+     * @brief Set the log file path
+     * @param fileName Path to log file (empty to disable file logging)
+     * @throw std::runtime_error if file cannot be opened
      */
-    struct fcloseDeleter {
-        void operator()(FILE *f) const noexcept {
-            std::fclose(f);
-        }
-    };
+    static void setFileName(const std::string& fileName);
 
 private:
     static void log(Level level, const std::string& msg);
     static void initFile(const std::string& fileName);
 
-    static Level mConsoleLevel;
-    static bool mConsoleColor;
-    static Level mFileLevel;
-    static std::string mFileName;
-    static std::unique_ptr<FILE, fcloseDeleter> mFile;
-    static std::vector<std::string> mContext;
+    struct fcloseDeleter {
+        void operator()(FILE* f) const noexcept { std::fclose(f); }
+    };
+
+    static Level mConsoleLevel;        ///< Minimum level for console output
+    static bool mConsoleColor;         ///< Whether to use colored output
+    static Level mFileLevel;           ///< Minimum level for file output
+    static std::string mFileName;      ///< Path to log file
+    static std::unique_ptr<FILE, fcloseDeleter> mFile;  ///< File handle
+    static std::vector<std::string> mContext;  ///< Stack of active contexts
 };
+
 } // namespace Aidge
 
+// Formatter specialization for Log::Level
+template <>
+struct fmt::formatter<Aidge::Log::Level> : formatter<const char*> {
+    template <typename FormatContext>
+    auto format(const Aidge::Log::Level& level, FormatContext& ctx) const {
+        const char* name = EnumStrings<Aidge::Log::Level>::data[static_cast<int>(level)];
+        return formatter<const char*>::format(name, ctx);
+    }
+};
+
 namespace {
 template <>
-const char *const EnumStrings<Aidge::Log::Level>::data[] =
-    {"Debug", "Info", "Notice", "Warn", "Error", "Fatal"};
+const char* const EnumStrings<Aidge::Log::Level>::data[] = {
+    "DEBUG", "INFO", "NOTICE", "WARNING", "ERROR", "FATAL"
+};
 }
 
-#endif // AIDGE_LOG_H_
+#endif // AIDGE_CORE_UTILS_LOG_H_
diff --git a/src/graph/Node.cpp b/src/graph/Node.cpp
index 384e946c674641f7d498d8c5745dcc745f34d751..0c5fbfdcb1284e5b4158190f588b1ca7e529aa4d 100644
--- a/src/graph/Node.cpp
+++ b/src/graph/Node.cpp
@@ -264,7 +264,7 @@ void Aidge::Node::addChildOp(std::shared_ptr<Node> otherNode, const IOIndex_t ou
         "Output index (#{}) of the node {} (of type {}) is out of bound (it has {} outputs), when trying to add the child node {} (of type {})",
         outId, name(), type(), nbOutputs(), otherNode->name(), otherNode->type());
     if (otherNode->input(otherInId).second != gk_IODefaultIndex) {
-        Log::notice("Notice: the {}-th Parent of the child node {} (of type {}) already existed", otherInId, otherNode->name(), otherNode->type());
+        Log::notice("the {}-th Parent of the child node {} (of type {}) already existed", otherInId, otherNode->name(), otherNode->type());
     }
     // manage tensors and potential previous parent
     otherNode->setInputId(otherInId, outId);
diff --git a/src/recipes/MatMulToFC.cpp b/src/recipes/MatMulToFC.cpp
index 8d902c680b8fa0d30a873b6f355734ce19d608f5..c35b2a64a6bf1186ba43b5ffb696302d0f2c1679 100644
--- a/src/recipes/MatMulToFC.cpp
+++ b/src/recipes/MatMulToFC.cpp
@@ -71,7 +71,7 @@ void Aidge::matMulToFC(std::shared_ptr<Aidge::Node> matmulNode, std::shared_ptr<
     {
         // If both inputs are producers, there is an ambiguity, but both options
         // result in a correct solution.
-        Log::notice("Notice: both MatMul inputs are Producers, assume data at input#0 and weights at input#1.");
+        Log::notice("both MatMul inputs are Producers, assume data at input#0 and weights at input#1.");
         weight = matmulNode->getParent(1);
     }
     AIDGE_ASSERT(weight != nullptr, "Could not deduce weight input for MatMul operator.");
diff --git a/src/utils/Log.cpp b/src/utils/Log.cpp
index 383fdae173814399d259fdab8858be9093204f70..5fc7a604fb795786511c09c1ce46437917e10de9 100644
--- a/src/utils/Log.cpp
+++ b/src/utils/Log.cpp
@@ -10,101 +10,144 @@
  ********************************************************************************/
 
 #include "aidge/utils/Log.hpp"
-#include "aidge/utils/ErrorHandling.hpp"
 
-#include <cstdlib>
+#include <fmt/core.h>
 
-#include <fmt/color.h>
-#include <fmt/chrono.h>
+#include <cstdlib>  // std::getenv
+#include <memory>
+#include <string>
+#include <vector>
 
-Aidge::Log::Level Aidge::Log::mConsoleLevel = []() {
-    const char* logLevel = std::getenv("AIDGE_LOGLEVEL_CONSOLE");
-    if (logLevel != nullptr) {
-        for (std::size_t i = 0; i < size(EnumStrings<Log::Level>::data); ++i) {
-            if (std::string(logLevel) == EnumStrings<Log::Level>::data[i]) {
-                return static_cast<Log::Level>(i);
-            }
-        }
+namespace Aidge {
+
+/**
+ * @brief Initialize console level from environment or default to Info
+ */
+Log::Level Log::mConsoleLevel = []() {
+    if (const char* level = std::getenv("AIDGE_LOGLEVEL_CONSOLE")) {
+        return level[0] == 'D' ? Debug :
+               level[0] == 'I' ? Info :
+               level[0] == 'N' ? Notice :
+               level[0] == 'W' ? Warn :
+               level[0] == 'E' ? Error :
+               level[0] == 'F' ? Fatal : Info;
     }
     return Info;
 }();
-bool Aidge::Log::mConsoleColor = []() {
-    const char* logColor = std::getenv("AIDGE_LOG_COLOR");
-    if (logColor == nullptr)
-        return true;
-    auto logColorStr = std::string(logColor);
-    if (logColorStr == "off" || logColorStr == "OFF" ||
-        logColorStr == "0")
-        return false;
-    return true;
+
+/**
+ * @brief Initialize color setting from environment or default to enabled
+ */
+bool Log::mConsoleColor = []() {
+    const char* color = std::getenv("AIDGE_LOG_COLOR");
+    return !color || (std::string(color) != "off" &&
+                     std::string(color) != "OFF" &&
+                     std::string(color) != "0");
 }();
-Aidge::Log::Level Aidge::Log::mFileLevel = []() {
-    const char* logLevel = std::getenv("AIDGE_LOGLEVEL_FILE");
-    if (logLevel != nullptr) {
-        for (std::size_t i = 0; i < size(EnumStrings<Log::Level>::data); ++i) {
-            if (std::string(logLevel) == EnumStrings<Log::Level>::data[i]) {
-                return static_cast<Log::Level>(i);
-            }
-        }
+
+/**
+ * @brief Initialize file level from environment or default to Debug
+ */
+Log::Level Log::mFileLevel = []() {
+    if (const char* level = std::getenv("AIDGE_LOGLEVEL_FILE")) {
+        return level[0] == 'D' ? Debug :
+               level[0] == 'I' ? Info :
+               level[0] == 'N' ? Notice :
+               level[0] == 'W' ? Warn :
+               level[0] == 'E' ? Error :
+               level[0] == 'F' ? Fatal : Debug;
     }
     return Debug;
 }();
-std::string Aidge::Log::mFileName = []() {
-    const char* logFile = std::getenv("AIDGE_LOG_FILE");
-    if (logFile != nullptr) {
-        return std::string(logFile);
-    }
-    return std::string();
+
+/**
+ * @brief Initialize file path from environment
+ */
+std::string Log::mFileName = []() {
+    const char* file = std::getenv("AIDGE_LOG_FILE");
+    return file ? std::string(file) : std::string();
 }();
-std::unique_ptr<FILE, Aidge::Log::fcloseDeleter> Aidge::Log::mFile {nullptr, Aidge::Log::fcloseDeleter()};
-std::vector<std::string> Aidge::Log::mContext;
-
-void Aidge::Log::log(Level level, const std::string& msg) {
-    if (level >= getConsoleLevel()) {
-        // Apply log level style only for console.
-        // Styles that were already applied to msg with fmt are kept also in
-        // the log file.
-        const auto modifier
-            = !mConsoleColor ? fmt::text_style()
-            : (level == Debug) ? fmt::fg(fmt::color::gray)
-            : (level == Notice) ? fmt::fg(fmt::color::medium_purple)
-            : (level == Warn) ? fmt::fg(fmt::color::orange)
-            : (level == Error) ? fmt::fg(fmt::color::red)
-            : (level == Fatal) ? fmt::bg(fmt::color::red)
-            : fmt::text_style();
 
+std::unique_ptr<FILE, Log::fcloseDeleter> Log::mFile{nullptr};
+std::vector<std::string> Log::mContext;
+
+/**
+ * @brief Internal logging implementation
+ * @param level Severity level of the message
+ * @param msg The message to log
+ */
+void Log::log(Level level, const std::string& msg) {
+    /**
+     * @brief Get the terminal color for a log level
+     */
+    const auto getColor = [](Level lvl) {
+        switch (lvl) {
+            case Debug:   return fmt::terminal_color::green;
+            case Info:    return fmt::terminal_color::blue;
+            case Notice:  return fmt::terminal_color::bright_blue;
+            case Warn:    return fmt::terminal_color::yellow;
+            case Error:   return fmt::terminal_color::red;
+            case Fatal:   return fmt::terminal_color::bright_magenta;
+            default:      return fmt::terminal_color::white;
+        }
+    };
+
+    /**
+     * @brief Get the string representation of a log level
+     */
+    const auto levelStr = EnumStrings<Level>::data[static_cast<std::size_t>(level)];
+
+    if (level >= mConsoleLevel) {
+        // Print active contexts
         for (const auto& context : mContext) {
             fmt::println("Context: {}", context);
         }
 
-        fmt::println("{}", fmt::styled(msg, modifier));
+        // Print message with colored level
+        if (mConsoleColor) {
+            fmt::print("[");
+            fmt::print(fg(getColor(level)), "{}", levelStr);
+            fmt::print("] - {}\n", msg);
+        } else {
+            fmt::print("[{}] - {}\n", levelStr, msg);
+        }
     }
 
     if (level >= mFileLevel && !mFileName.empty()) {
         if (!mFile) {
             initFile(mFileName);
         }
-
+        // Write contexts and message to file
         for (const auto& context : mContext) {
-            fmt::println("Context: {}", context);
+            fmt::println(mFile.get(), "Context: {}", context);
         }
-
-        fmt::println(mFile.get(), "{}", msg);
+        fmt::println(mFile.get(), "{}: {}", levelStr, msg);
     }
 }
 
-void Aidge::Log::initFile(const std::string& fileName) {
-    FILE* rawFile = std::fopen(fileName.c_str(), "a");
-
-    if (!rawFile) {
-        mFileName.clear(); // prevents AIDGE_THROW_OR_ABORT() to try to log into file
-        AIDGE_THROW_OR_ABORT(std::runtime_error,
-            "Could not create log file: {}", fileName);
+/**
+ * @brief Initialize or re-initialize the log file
+ * @param fileName Path to the log file
+ * @throw std::runtime_error if file cannot be opened
+ */
+void Log::initFile(const std::string& fileName) {
+    if (FILE* file = std::fopen(fileName.c_str(), "a")) {
+        mFile.reset(file);
+    } else {
+        mFileName.clear();
+        throw std::runtime_error(
+            fmt::format("Could not create log file: {}", fileName));
     }
+}
 
-    // Assign the new FILE* with the deleter
-    mFile = std::unique_ptr<FILE, fcloseDeleter>(rawFile, fcloseDeleter());
-
-    const std::time_t t = std::time(nullptr);
-    fmt::println(mFile.get(), "###### {:%Y-%m-%d %H:%M:%S} ######", fmt::localtime(t));
+void Log::setFileName(const std::string& fileName) {
+    if (fileName != mFileName) {
+        mFileName = fileName;
+        mFile.reset();
+        if (!fileName.empty()) {
+            initFile(fileName);
+        }
+    }
 }
+
+} // namespace Aidge
diff --git a/unit_tests/operator/Test_Squeeze_Op.cpp b/unit_tests/operator/Test_Squeeze_Op.cpp
index f5fd071984198a5982b36ca2cb16884657126957..f1261fffb756de17891d8c268812b2bb7a196c0a 100644
--- a/unit_tests/operator/Test_Squeeze_Op.cpp
+++ b/unit_tests/operator/Test_Squeeze_Op.cpp
@@ -446,9 +446,9 @@ TEST_CASE("[core/operator] Squeeze(forward)", "[Squeeze][forward]") {
 
         delete[] array_in;
       }
-    fmt::print("INFO: GlobalAveragePooling total execution time: {}µs\n", duration.count());
-    fmt::print("INFO: Number of operations : {}\n", number_of_operation);
-    fmt::print("INFO: Operation / µs = {}\n", number_of_operation / duration.count());
+    Log::info("GlobalAveragePooling total execution time: {}µs\n", duration.count());
+    Log::info("Number of operations : {}\n", number_of_operation);
+    Log::info("Operation / µs = {}\n", number_of_operation / duration.count());
     }
   }
 }
diff --git a/unit_tests/operator/Test_Unsqueeze_Op.cpp b/unit_tests/operator/Test_Unsqueeze_Op.cpp
index 650cbaf3ebb9cacff4a6b16a14706e9d5bf13f6e..5cedcfdfa9c7608aa99426f7c4b496537c43c324 100644
--- a/unit_tests/operator/Test_Unsqueeze_Op.cpp
+++ b/unit_tests/operator/Test_Unsqueeze_Op.cpp
@@ -373,9 +373,9 @@ TEST_CASE("[core/operator] Unsqueeze(forward)", "[Unsqueeze][forward]") {
         delete[] array_in;
       }
     }
-    fmt::print("INFO: GlobalAveragePooling total execution time: {}µs\n", duration.count());
-    fmt::print("INFO: Number of operations : {}\n", number_of_operation);
-    fmt::print("INFO: Operation / µs = {}\n", number_of_operation / duration.count());
+    Log::info("GlobalAveragePooling total execution time: {}µs\n", duration.count());
+    Log::info("Number of operations : {}\n", number_of_operation);
+    Log::info("Operation / µs = {}\n", number_of_operation / duration.count());
   }
 }
 
diff --git a/unit_tests/utils/Test_Log.cpp b/unit_tests/utils/Test_Log.cpp
index 3d8e672b84f5055a12185c3684c34bd888f0545b..1c44e232f9c8ee05bf6f8147d7789131c5a0d803 100644
--- a/unit_tests/utils/Test_Log.cpp
+++ b/unit_tests/utils/Test_Log.cpp
@@ -17,15 +17,22 @@
 
 using namespace Aidge;
 
-TEST_CASE("[core/log] Log") {
+TEST_CASE("[core/log] Log", "[Logger]") {
     SECTION("TestLog") {
-        Log::setConsoleLevel(Log::Debug);
-        Log::debug("debug");
+        Log::setConsoleLevel(Log::Level::Debug);
+        Log::debug("this is a debug message");
         Log::debug("{}", fmt::styled("green debug", fmt::fg(fmt::color::green)));
-        Log::info("info");
-        Log::notice("notice");
-        Log::warn("warn");
-        Log::error("error");
+        Log::info("this is an info message");
+        Log::notice("this is a notice message");
+        Log::warn("this is a warn message");
+        Log::error("this is an error message");
+        AIDGE_LOG_CONTEXT("Testing the context of logger");
         Log::fatal("fatal");
+        Log::debug("Now debug messages are supposed to [{}].", fmt::styled("appear", fmt::emphasis::italic));
+        Log::info("Current consol level is {}", Log::getConsoleLevel());
+        Log::setConsoleLevel(Log::Level::Warn);
+        Log::notice("This message should not appear.");
+
+
     }
 }