diff --git a/src/Lib/Log.cc b/src/Lib/Log.cc
index 5d66c93ea2a46de3f5ae4960db2e5a2ec9b59778..a30d0193057ddb1e3c13beaf118a5a7bf0637a02 100644
--- a/src/Lib/Log.cc
+++ b/src/Lib/Log.cc
@@ -10,6 +10,18 @@ LogSinkDispatcher::getDispatcherName() const noexcept
 {
     return dispatcherName;
 }
+
+StderrLogSinkDispatcher::StderrLogSinkDispatcher(LogSink *const sink) noexcept
+    : LogSinkDispatcher(sink, std::string_view{ "stderr" })
+{
+}
+
+void
+StderrLogSinkDispatcher::handleLogMessage(const std::string_view category,
+                                          const LogMessage &msg) noexcept
+{
+    std::cerr << '[' << category << ']' << msg.getTextBuffer() << '\n';
+}
 }
 
 // Vivy::LogSink implementation
diff --git a/src/Lib/Log.hh b/src/Lib/Log.hh
index 31eeea320fc75d0aa684aae8afc5ad06bcb392ff..c74b0b05be69433ccfef35a410863acc37dab87f 100644
--- a/src/Lib/Log.hh
+++ b/src/Lib/Log.hh
@@ -14,7 +14,7 @@
 #define VIVY_DCL_LOG_SINK(sink) std::shared_ptr<LogSink> sink{ VIVY_NEW_LOG_SINK() };
 
 #define VIVY_LOGGABLE_OBJECT(sink, name, logger)                             \
-    std::shared_ptr<Logger> logger = VIVY_GET_LOGGER(sink, name);            \
+    std::shared_ptr<Logger> logger{ VIVY_GET_LOGGER(sink, name) };           \
     LogMessage logFatal() const noexcept { return VIVY_LOG_FATAL(logger); }  \
     LogMessage logError() const noexcept { return VIVY_LOG_ERR(logger); }    \
     LogMessage logWarning() const noexcept { return VIVY_LOG_WARN(logger); } \
@@ -184,4 +184,12 @@ public:
     LogMessage logEvent(const char *fileName, const char *functionName, const int lineNumber,
                         const LogLevel) noexcept;
 };
+
+class StderrLogSinkDispatcher : public LogSinkDispatcher {
+    VIVY_UNMOVABLE_OBJECT(StderrLogSinkDispatcher)
+
+public:
+    explicit StderrLogSinkDispatcher(LogSink *const sink) noexcept;
+    void handleLogMessage(const std::string_view, const LogMessage &) noexcept override;
+};
 }