diff --git a/Documentation/Examples/CMakeLists.txt b/Documentation/Examples/CMakeLists.txt
index 0871e4add1393c013c84a38ae509d6f2077b6e97..1592372c2c6a346def1c866508841097c4bbd1c2 100644
--- a/Documentation/Examples/CMakeLists.txt
+++ b/Documentation/Examples/CMakeLists.txt
@@ -8,12 +8,8 @@ target_link_libraries (particle_list_example CORSIKAparticles CORSIKAunits CORSI
 CORSIKA_ADD_EXAMPLE (geometry_example)
 target_link_libraries (geometry_example CORSIKAgeometry CORSIKAunits)
 
-CORSIKA_ADD_EXAMPLE (logger_example)
-target_link_libraries (logger_example CORSIKAunits CORSIKAlogging)
-
 CORSIKA_ADD_EXAMPLE (stack_example)
-target_link_libraries (stack_example SuperStupidStack CORSIKAunits
-  CORSIKAlogging)
+target_link_libraries (stack_example SuperStupidStack CORSIKAunits)
 
 # address sanitizer is making this example too slow, so we only do "undefined"
 CORSIKA_ADD_EXAMPLE (boundary_example)
diff --git a/Documentation/Examples/logger_example.cc b/Documentation/Examples/logger_example.cc
deleted file mode 100644
index 2596307b9a7ac3c9ff977a42481cbf0622b5f6b7..0000000000000000000000000000000000000000
--- a/Documentation/Examples/logger_example.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
- *
- * This software is distributed under the terms of the GNU General Public
- * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
- * the license.
- */
-
-#include <corsika/logging/Logger.h>
-#include <boost/format.hpp>
-#include <fstream>
-#include <iostream>
-#include <string>
-
-using namespace std;
-using namespace corsika::logging;
-
-int main() {
-  {
-    cout << "writing to \"another.log\"" << endl;
-    ofstream logfile("another.log");
-    sink::SinkStream unbuffered_sink(logfile);
-    sink::BufferedSinkStream sink(logfile, sink::StdBuffer(10000));
-    Logger<MessageOn, sink::BufferedSinkStream> info("\033[32m", "info", sink);
-    Logger<MessageOn, sink::BufferedSinkStream> err("\033[31m", "error", sink);
-    // logger<ostream,messageconst,StdBuffer> info(std::cout, StdBuffer(10000));
-
-    /*
-      Logging& logs = Logging::GetInstance();
-      logs.AddLogger<>("info", info);
-      auto& log_1 = logs.GetLogger("info"); // no so useful, since type of log_1 is
-      std::any
-    */
-
-    for (int i = 0; i < 10000; ++i) {
-      LOG(info, "irgendwas", " ", string("and more"), " ",
-          boost::format("error: %i message: %s. done."), i, "stupido");
-      LOG(err, "Fehler");
-    }
-  }
-
-  {
-    sink::NoSink off;
-    Logger<MessageOff> info("", "", off);
-
-    for (int i = 0; i < 10000; ++i) {
-      LOG(info, "irgendwas", string("and more"),
-          boost::format("error: %i message: %s. done."), i, "stupido", "a-number:", 8.99,
-          "ENDE");
-    }
-  }
-
-  return 0;
-}
diff --git a/Framework/Logging/BufferedSink.h b/Framework/Logging/BufferedSink.h
deleted file mode 100644
index 26aeb6c5a94bbe029b017bb00498650b10d37c64..0000000000000000000000000000000000000000
--- a/Framework/Logging/BufferedSink.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
- *
- * This software is distributed under the terms of the GNU General Public
- * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
- * the license.
- */
-
-#pragma once
-
-namespace corsika::logging {
-
-  namespace sink {
-
-    /**
-       Output buffer template. NoBuffer does nothingk.
-    */
-    /*
-    struct NoBuffer {
-      inline bool Test(const std::string&) const { return false; }
-      inline std::string GetString() const { return std::string(""); }
-      inline void Clear() {}
-      inline void Add(const std::string&) {}
-    };
-    */
-    /**
-       Output buffer template. StdBuffer records fSize characters in
-       local memeory before passing it on to further output stages.
-    */
-
-    struct StdBuffer {
-      StdBuffer(const int size)
-          : fSize(size) {}
-      inline bool Test(const std::string& s) {
-        return int(fBuffer.tellp()) + s.length() < fSize;
-      }
-      inline std::string GetString() const { return fBuffer.str(); }
-      inline void Clear() { fBuffer.str(""); }
-      inline void Add(const std::string& s) { fBuffer << s; }
-
-    private:
-      unsigned int fSize;
-      std::ostringstream fBuffer;
-    };
-
-    /**
-       Definition of Sink for log output.
-    */
-    template <typename TStream, typename TBuffer = StdBuffer>
-    class BufferedSink {
-    public:
-      BufferedSink(TStream& out, TBuffer buffer = {})
-          : fOutput(out)
-          , fBuffer(std::move(buffer)) {}
-      void operator<<(const std::string& msg) {
-        if (!fBuffer.Test(msg)) {
-          fOutput << fBuffer.GetString();
-          fBuffer.Clear();
-        }
-        if (!fBuffer.Test(msg))
-          fOutput << msg;
-        else
-          fBuffer.Add(msg);
-      }
-      void Close() { fOutput << fBuffer.GetString(); }
-
-    private:
-      TStream& fOutput;
-      TBuffer fBuffer;
-    };
-
-    typedef BufferedSink<std::ostream, StdBuffer> BufferedSinkStream;
-
-  } // namespace sink
-} // namespace corsika::logging
diff --git a/Framework/Logging/CMakeLists.txt b/Framework/Logging/CMakeLists.txt
index 4743b2b3400ea116126701bbe70027ec1b63b5ff..d74849f26c8f1c683899f51517cc150f9a787e3b 100644
--- a/Framework/Logging/CMakeLists.txt
+++ b/Framework/Logging/CMakeLists.txt
@@ -1,3 +1,4 @@
+# create the library
 add_library (CORSIKAlogging INTERFACE)
 
 # namespace of library -> location of header files
@@ -9,15 +10,10 @@ set (
 # header files of this library
 set (
   CORSIKAlogging_HEADERS
-  Logger.h
-  Sink.h
-  MessageOn.h
-  MessageOff.h
-  NoSink.h
-  Sink.h
-  BufferedSink.h
+  Logging.h
   )
 
+# copy the headers into the namespace
 CORSIKA_COPY_HEADERS_TO_NAMESPACE (CORSIKAlogging
   ${CORSIKAlogging_NAMESPACE}
   ${CORSIKAlogging_HEADERS}
@@ -32,6 +28,13 @@ target_include_directories (
   C8::ext:boost
   )
 
+# and link against spdlog
+target_link_libraries(
+  CORSIKAlogging
+  INTERFACE
+  spdlog::spdlog
+)
+
 # install library
 install (
   FILES ${CORSIKAlogging_HEADERS}
@@ -41,10 +44,9 @@ install (
 # ----------------
 # code unit testing
 
-#CORSIKA_ADD_TEST (testLogging)
-#target_link_libraries (
-#  testLogging
-#  CORSIKAlogging
-#  CORSIKAtesting
-#  )
-
+CORSIKA_ADD_TEST (testLogging)
+target_link_libraries (
+ testLogging
+ CORSIKAlogging
+ CORSIKAtesting
+ )
diff --git a/Framework/Logging/Logger.h b/Framework/Logging/Logger.h
deleted file mode 100644
index ae688460f236a02476b8d3a062a4dec3f9243328..0000000000000000000000000000000000000000
--- a/Framework/Logging/Logger.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
- *
- * This software is distributed under the terms of the GNU General Public
- * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
- * the license.
- */
-
-/**
-   @File Logger.h
-
-   Everything around logfile generation and text output.
- */
-
-#pragma once
-
-#include <iosfwd>
-#include <sstream>
-#include <string>
-#include <typeinfo>
-
-#include <boost/format.hpp>
-
-#include <corsika/logging/BufferedSink.h>
-#include <corsika/logging/MessageOff.h>
-#include <corsika/logging/MessageOn.h>
-#include <corsika/logging/NoSink.h>
-#include <corsika/logging/Sink.h>
-
-namespace corsika::logging {
-
-  /**
-     @class Logger
-
-     Defines one stream to accept messages, and to wrote those into
-     TSink.  The helper class MessageOn will convert input at
-     compile-time into message strings. The helper class MessageOff,
-     will just do nothing and will be optimized away at compile time.
-  */
-  template <typename MSG = MessageOn, typename TSink = sink::NoSink>
-  class Logger : private MSG {
-
-    using MSG::Message;
-
-  public:
-    // Logger() : fName("") {}
-    Logger(const std::string color, const std::string name, TSink& sink)
-        : fSink(sink)
-        , fName(color + "[" + name + "]\033[39m ") {}
-    ~Logger() { fSink.Close(); }
-    // Logger(const Logger&) = delete;
-
-    /**
-       Function to add string-concatenation of all inputs to output
-       sink.
-     */
-    template <typename... Strings>
-    void Log(const Strings&... inputs) {
-      fSink << MSG::Message(inputs...);
-    }
-
-    const std::string& GetName() const { return fName; }
-
-  private:
-    TSink& fSink;
-    std::string fName;
-  };
-
-} // namespace corsika::logging
-
-/**
- * @def LOG(...)
- *
- * This is the main interface to the logging facilities. If Logger
- * object are defined (e.g. log1) use as
- * @example LOG(log1, "var1=", variable1int, "var2=", variabl2double)
- * for arbitrary long sequence
- * of arguments. This may also include boost::format objects the
- * output is concatenated, if log1 is switched off at compile time,
- * the whole LOG command is optimized away by the compiler.
- */
-
-#define LOG(__LOGGER, ...)                                                           \
-  __LOGGER.Log(__LOGGER.GetName(), __FILE__, ":", __LINE__, " (", __func__, ") -> ", \
-               __VA_ARGS__);
diff --git a/Framework/Logging/Logging.h b/Framework/Logging/Logging.h
new file mode 100644
index 0000000000000000000000000000000000000000..09853d1b2abbd446b1408b46c994d03de6bbea02
--- /dev/null
+++ b/Framework/Logging/Logging.h
@@ -0,0 +1,96 @@
+/*
+ * (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu
+ *
+ *
+ * This software is distributed under the terms of the GNU General Public
+ * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
+ * the license.
+ */
+
+/**
+   @File Logging.h
+
+   CORSIKA8 logging utilities.
+ */
+
+#pragma once
+
+#include <spdlog/spdlog.h>
+#include "spdlog/sinks/stdout_color_sinks.h"
+
+
+namespace corsika::logging {
+
+  // bring spdlog into the corsika::logging namespace
+  using namespace spdlog;
+
+  /**
+   * Create a new C8-style logger.
+   *
+   * @param name           The unique name of the logger.
+   * @param defaultlog     If True, set this as the default logger.
+   * @returns              The constructed and formatted logger.
+   */
+  auto CreateLogger(std::string const& name, bool const defaultlog = false) {
+
+    // create the logger
+    auto logger = spdlog::stdout_color_mt(name);
+
+    // set the default C8 format
+    logger->set_pattern("[%n:%^%-8l%$] %v");
+
+    // if defaultlog is True, we set this as the default spdlog logger.
+    if (defaultlog) { spdlog::set_default_logger(logger); }
+
+    // and return the logger
+    return logger;
+  }
+
+  /**
+   * Get a reference to a named logger.
+   *
+   * If the logger does not exist, it is created.
+   *
+   * @param name    The name of the logger to get.
+   */
+  auto GetLogger(std::string const& name, bool const defaultlog = false) {
+
+    // attempt to get the logger from the registry
+    auto logger = spdlog::get(name);
+
+    // weg found the logger, so just return it
+    if (logger) {
+      return logger;
+    } else { // logger was not found so create it
+      return CreateLogger(name, defaultlog);
+    }
+  }
+
+  /**
+   * Set the default log level for all loggers.
+   *
+   * @param name    The minimum log level required to print.
+   *
+   */
+  auto SetDefaultLevel(level::level_enum minlevel) -> void {
+    spdlog::set_level(minlevel);
+  }
+
+  // create the default CORSIKA logger
+  inline auto corsika = GetLogger("corsika", true);
+
+// define our macro-style loggers
+#define C8LOG_DEBUG SPDLOG_DEBUG
+#define C8LOG_INFO SPDLOG_INFO
+#define C8LOG_WARN SPDLOG_WARN
+#define C8LOG_ERROR SPDLOG_ERROR
+#define C8LOG_CRITICAL SPDLOG_CRITICAL
+
+// and the specific logger versions
+#define C8LOG_LOGGER_DEBUG SPDLOG_LOGGER_DEBUG
+#define C8LOG_LOGGER_INFO SPDLOG_LOGGER_INFO
+#define C8LOG_LOGGER_WARN SPDLOG_LOGGER_WARN
+#define C8LOG_LOGGER_ERROR SPDLOG_LOGGER_ERROR
+#define C8LOG_LOGGER_CRITICAL SPDLOG_LOGGER_CRITICAL
+
+} // namespace corsika::logging
diff --git a/Framework/Logging/MessageOff.h b/Framework/Logging/MessageOff.h
deleted file mode 100644
index e25a8b30af8c89af870230837d4d1e784b3355be..0000000000000000000000000000000000000000
--- a/Framework/Logging/MessageOff.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
- *
- * This software is distributed under the terms of the GNU General Public
- * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
- * the license.
- */
-
-#pragma once
-
-namespace corsika::logging {
-
-  /**
-     Helper class to ignore all arguments to MessagesOn::Message and
-     always return empty string "".
-   */
-  class MessageOff {
-  protected:
-    template <typename First, typename... Strings>
-    std::string Message(const First&, const Strings&...) {
-      return "";
-    }
-  };
-
-} // namespace corsika::logging
diff --git a/Framework/Logging/MessageOn.h b/Framework/Logging/MessageOn.h
deleted file mode 100644
index 6c34936bf90a6e8eaecfae155482ad848eb85d57..0000000000000000000000000000000000000000
--- a/Framework/Logging/MessageOn.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
- *
- * This software is distributed under the terms of the GNU General Public
- * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
- * the license.
- */
-
-#pragma once
-
-namespace corsika::logging {
-
-  /**
-     Helper class to convert all input arguments of MessageOn::Message
-     into string-concatenated version and return this as string.
-  */
-  class MessageOn {
-  protected:
-    std::string Message() { return "\n"; }
-
-    template <typename First, typename... Strings>
-    std::string Message(const First& arg, const Strings&... rest) {
-      std::ostringstream ss;
-      ss << arg << Message(rest...);
-      return ss.str();
-    }
-
-    template <typename... Strings>
-    std::string Message(const int& arg, const Strings&... rest) {
-      return std::to_string(arg) + Message(rest...);
-    }
-
-    template <typename... Strings>
-    std::string Message(const double& arg, const Strings&... rest) {
-      return std::to_string(arg) + Message(rest...);
-    }
-
-    template <typename... Strings>
-    std::string Message(char const* arg, const Strings&... rest) {
-      return std::string(arg) + Message(rest...);
-    }
-
-    template <typename... Strings>
-    std::string Message(const std::string& arg, const Strings&... rest) {
-      return arg + Message(rest...);
-    }
-
-    // ----------------------
-    // boost format
-    template <typename... Strings>
-    std::string Message(const boost::format& fmt, const Strings&... rest) {
-      boost::format FMT(fmt);
-      return bformat(FMT, rest...);
-    }
-
-    template <typename Arg, typename... Strings>
-    std::string bformat(boost::format& fmt, const Arg& arg, const Strings&... rest) {
-      fmt % arg;
-      return bformat(fmt, rest...);
-    }
-
-    std::string bformat(boost::format& fmt) { return fmt.str() + "\n"; }
-  };
-
-} // namespace corsika::logging
diff --git a/Framework/Logging/NoSink.h b/Framework/Logging/NoSink.h
deleted file mode 100644
index 122cc255fd86275de8fc3a84b7e01a75e41dff31..0000000000000000000000000000000000000000
--- a/Framework/Logging/NoSink.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
- *
- * This software is distributed under the terms of the GNU General Public
- * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
- * the license.
- */
-
-#pragma once
-
-namespace corsika::logging {
-
-  namespace sink {
-
-    struct NoSink {
-      inline void operator<<(const std::string&) {}
-      inline void Close() {}
-    };
-
-  } // namespace sink
-} // namespace corsika::logging
diff --git a/Framework/Logging/Sink.h b/Framework/Logging/Sink.h
deleted file mode 100644
index be99c3c637c144cadbf6cd36f8f72741f4a8449c..0000000000000000000000000000000000000000
--- a/Framework/Logging/Sink.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
- *
- * This software is distributed under the terms of the GNU General Public
- * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
- * the license.
- */
-
-#pragma once
-
-namespace corsika::logging {
-
-  /**
-     a sink for the logger must implement the two functions
-     operator<<(const std::string&)
-     and
-     Close()
-
-     See example: NoSink
-   */
-
-  namespace sink {
-
-    /**
-       Definition of Sink for log output.
-    */
-    template <typename TStream>
-    class Sink {
-    public:
-      Sink(TStream& out)
-          : fOutput(out) {}
-      void operator<<(const std::string& msg) { fOutput << msg; }
-      void Close() {}
-
-    private:
-      TStream& fOutput;
-    };
-
-    typedef Sink<std::ostream> SinkStream;
-
-  } // namespace sink
-} // namespace corsika::logging
diff --git a/Framework/Logging/testLogging.cc b/Framework/Logging/testLogging.cc
index 2186894b7e570a481af968ed6d9e08ea53517dc9..2bead9a54ccc8a9a20b73c85aff673fd0e2593a7 100644
--- a/Framework/Logging/testLogging.cc
+++ b/Framework/Logging/testLogging.cc
@@ -1,23 +1,94 @@
 /*
- * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
+ * (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu
  *
  * This software is distributed under the terms of the GNU General Public
  * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
  * the license.
  */
 
-#include <corsika/logging/Logger.h>
+#include <corsika/logging/Logging.h>
 
 #include <catch2/catch.hpp>
 
-/*
-  this does nothing yet
- */
+using namespace corsika;
 
 TEST_CASE("Logging", "[Logging]") {
-  SECTION("sectionOne") {}
+  SECTION("top level functions using corsika logger") {
+    logging::info("This is an info message!");
+    logging::warn("This is a warning message!");
+    logging::debug("This is a debug message!");
+    logging::error("This is an error message!");
+    logging::critical("This is a critical error message!");
+  }
+
+  SECTION("create a specific logger") {
+
+    // create a logger manually
+    auto logger = logging::CreateLogger("loggerA");
+
+    // set a custom pattern for this logger
+    logger->set_pattern("[%n:%^%-8l%$] custom pattern: %v");
+
+    // and make sure we can log with this created object
+    logger->info("This is an info message!");
+    logger->warn("This is a warning message!");
+    logger->debug("This is a debug message!");
+    logger->error("This is an error message!");
+    logger->critical("This is a critical error message!");
+
+    // get a reference to the logger using Get
+    auto other = logging::GetLogger("loggerA");
+
+    // and make sure we can use this other reference to log
+    other->info("This is an info message!");
+    other->warn("This is a warning message!");
+    other->debug("This is a debug message!");
+    other->error("This is an error message!");
+    other->critical("This is a critical error message!");
+  }
+
+  SECTION("get a new logger") {
+
+    // get a reference to an unknown logger
+    auto logger = logging::GetLogger("loggerB");
+
+    // and make sure we can log with this created object
+    logger->info("This is an info message!");
+    logger->warn("This is a warning message!");
+    logger->debug("This is a debug message!");
+    logger->error("This is an error message!");
+    logger->critical("This is a critical error message!");
+  }
+
+  SECTION("test log level") {
+
+    // set the default log level
+    logging::SetDefaultLevel(logging::level::critical);
+
+    // and make sure we can log with this created object
+    logging::info("This should NOT be printed!");
+    logging::warn("This should NOT be printed!");
+    logging::debug("This should NOT be printed!");
+    logging::error("This should NOT be printed!");
+    logging::critical("This SHOULD BE printed!!");
+
+    // and reset it for the next tests
+    logging::SetDefaultLevel(logging::level::debug);
+  }
+
+  SECTION("test macro style printing") {
+
+    // these print with the "corsika" logger
+    C8LOG_INFO("This is a macro info msg!");
+    C8LOG_DEBUG("This is a macro debug msg!");
+    C8LOG_ERROR("This is a macro error msg!");
+    C8LOG_CRITICAL("This is a macro critical msg!");
 
-  SECTION("sectionTwo") {}
+    // get a reference to an unknown logger
+    auto logger = logging::GetLogger("loggerD");
 
-  SECTION("sectionThree") {}
+    // these print with the "loggerD" logger
+    C8LOG_LOGGER_INFO(logger, "This is a macro info msg!");
+    C8LOG_LOGGER_WARN(logger, "This is a macro warn msg!");
+  }
 }
diff --git a/ThirdParty/CMakeLists.txt b/ThirdParty/CMakeLists.txt
index f6817bf7f8cca23ad769751575987f92cfb705ae..13ea2ba05174de18daa7646059d3ab19295cc099 100644
--- a/ThirdParty/CMakeLists.txt
+++ b/ThirdParty/CMakeLists.txt
@@ -15,8 +15,10 @@ include(ExternalProject)
 set (ThirdPartyChoiceValues "C8;SYSTEM" CACHE STRING
     "List of possible values for the ThirdParty package choice")
 mark_as_advanced (ThirdPartyChoiceValues)
-  
 
+##############################################################################
+# Build spdlog
+add_subdirectory(spdlog)
 
 ##############################################################################
 # check for boost: either use C8 or system-level installation