diff --git a/src/utils/Log.cpp b/src/utils/Log.cpp
index fb567e355fef28391c894be9ca8ca01e56f36418..b2aad14c9ed9f21b9f262d72939abbed0488d830 100644
--- a/src/utils/Log.cpp
+++ b/src/utils/Log.cpp
@@ -21,18 +21,25 @@
 namespace Aidge {
 
 /**
- * @brief Initialize console level from environment or default to Info
+ * @brief Initialize console log level from environment. If compile mode is
+ * DEBUG, then the default level is Log::Level::Debug, else it is
+ * Log::Level::Notice.
  */
 Log::Level Log::mConsoleLevel = []() {
+#ifdef NDEBUG
+    constexpr Level defaultLevel = Level::Debug;
+#else
+    constexpr Log::Level defaultLevel = Level::Notice;
+#endif
     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;
+               level[0] == 'F' ? Fatal : defaultLevel;
     }
-    return Info;
+    return defaultLevel;
 }();
 
 /**
@@ -46,18 +53,24 @@ bool Log::mConsoleColor = []() {
 }();
 
 /**
- * @brief Initialize file level from environment or default to Debug
+ * @brief Initialize file log level from environment. If compile mode is DEBUG,
+ * then the default level is Log::Level::Debug, else it is Log::Level::Notice.
  */
 Log::Level Log::mFileLevel = []() {
+#ifdef NDEBUG
+    constexpr Level defaultLevel = Level::Debug;
+#else
+    constexpr Log::Level defaultLevel = Level::Notice;
+#endif
     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;
+               level[0] == 'F' ? Fatal : defaultLevel;
     }
-    return Debug;
+    return defaultLevel;
 }();
 
 /**
@@ -79,8 +92,65 @@ int Log::mFloatingPointPrecision = 5;
  */
 void Log::log(Level level, const std::string& msg) {
     /**
-     * @brief Get the terminal color for a log level
+     * @brief Helper function to wrap text to a specified width, respecting
+     * explicit line breaks (\n) and accounting for ANSI escape sequences.
      */
+    const auto wrapText = [](const std::string& text, const std::size_t width) -> std::vector<std::string> {
+        std::vector<std::string> wrappedLines;
+        std::size_t start = 0;
+
+        while (start < text.size()) {
+            std::size_t lineWidth = 0;
+            std::size_t current = start;
+
+            while (current < text.size() && lineWidth < width) {
+                if (text[current] == '\033') {
+                    // Found ANSI escape sequence, skip until 'm'
+                    std::size_t ansiEnd = text.find('m', current);
+                    if (ansiEnd != std::string::npos) {
+                        // Add the length of the ANSI sequence to the width allowance
+                        // width += (ansiEnd - current + 1);
+                        current = ansiEnd + 1;
+                    } else {
+                        // Malformed sequence, treat as normal characters
+                        ++current;
+                    }
+                } else if (text[current] == '\n') {
+                    // Handle explicit line break
+                    break;
+                } else {
+                    // Normal character, increase line width
+                    ++lineWidth;
+                    ++current;
+                }
+            }
+
+            // Find the end of the current line
+            std::size_t lineEnd = current;
+
+            // Adjust for spaces if needed
+            if (lineEnd < text.size() && text[lineEnd] != '\n') {
+                std::size_t lastSpace = text.rfind(' ', lineEnd);
+                if (lastSpace != std::string::npos && lastSpace > start) {
+                    lineEnd = lastSpace;
+                }
+            }
+
+            // Add the wrapped line to the result
+            wrappedLines.push_back(text.substr(start, lineEnd - start));
+
+            // Move to the next segment, skipping spaces
+            start = lineEnd;
+            while (start < text.size() && (text[start] == ' ' || text[start] == '\n')) {
+                ++start;
+            }
+        }
+
+        return wrappedLines;
+    };
+
+
+    // Get the terminal color for the log level
     const auto getColor = [](Level lvl) {
         switch (lvl) {
             case Debug:   return fmt::terminal_color::green;
@@ -93,24 +163,36 @@ void Log::log(Level level, const std::string& msg) {
         }
     };
 
-    /**
-     * @brief Get the string representation of a log level
-     */
+    // Get the string representation of the log level
     const auto levelStr = EnumStrings<Level>::data[static_cast<std::size_t>(level)];
+    const std::size_t levelIndentSizes[6] = {10, 9, 11, 12, 10, 10};
+    const std::size_t width = 80 - levelIndentSizes[static_cast<std::size_t>(level)];
 
     if (level >= mConsoleLevel) {
-        // Print active contexts
         for (const auto& context : mContext) {
             fmt::println("Context: {}", context);
         }
 
-        // 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);
+        // Wrap the message and print each line
+        auto wrappedLines = wrapText(msg, width);
+        for (std::size_t i = 0; i < wrappedLines.size(); ++i) {
+            if (mConsoleColor) {
+                if (i == 0) {
+                    fmt::print("[");
+                    fmt::print(fg(getColor(level)), "{}", levelStr);
+                    fmt::print("] - {}\n", wrappedLines[i]);
+                } else {
+                    fmt::print("[");
+                    fmt::print(fg(getColor(level)), "{}", levelStr);
+                    fmt::print("]   {}\n", wrappedLines[i]);
+                }
+            } else {
+                if (i == 0) {
+                    fmt::print("[{}] - {}\n", levelStr, wrappedLines[i]);
+                } else {
+                    fmt::print("[{}]   {}\n", levelStr, wrappedLines[i]);
+                }
+            }
         }
     }
 
@@ -118,14 +200,24 @@ void Log::log(Level level, const std::string& msg) {
         if (!mFile) {
             initFile(mFileName);
         }
-        // Write contexts and message to file
+
         for (const auto& context : mContext) {
             fmt::println(mFile.get(), "Context: {}", context);
         }
-        fmt::println(mFile.get(), "{}: {}", levelStr, msg);
+
+        auto wrappedLines = wrapText(msg, width);
+        for (std::size_t i = 0; i < wrappedLines.size(); ++i) {
+            if (i == 0) {
+                fmt::println(mFile.get(), "{}: {}", levelStr, wrappedLines[i]);
+            } else {
+                fmt::println(mFile.get(), "{}   {}", levelStr, wrappedLines[i]);
+            }
+        }
     }
 }
 
+
+
 /**
  * @brief Initialize or re-initialize the log file
  * @param fileName Path to the log file