diff --git a/.gitmodules b/.gitmodules
index a07713df3ce33f27773946cc3ee1b75b445d0ba0..cb79c58058e9360e53f096be77cbf0ee2aca2282 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -2,3 +2,7 @@
 	path = Data
 	url = ../../AirShowerPhysics/corsika-data
 	branch = master
+[submodule "ThirdParty/spdlog"]
+	path = ThirdParty/spdlog
+	url = https://github.com/gabime/spdlog.git
+	shallow = true
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9b2a52509c41ab385cb38dda0a7bffd834d5dbda..7e0d2ca7bc102a71982c184fafa9a9a86d63de5a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -79,6 +79,9 @@ set (CMAKE_SHARED_LINKER_FLAGS_COVERAGE "--coverage")
 # clang produces a lot of unecessary warnings without this:
 add_compile_options ("$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wno-nonportable-include-path>")
 
+# set a flag to inform code that we are in debug mode
+set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")
+
 # COAST - interface, this requires CORSIKA7 to be installed first
 # COAST will allow you to program code in CORSIKA8 and execute it inside CORSIKA7
 if (WITH_COAST)
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..21664424d401b2a34848542f9f3b91ad57c9c8a7
--- /dev/null
+++ b/Framework/Logging/Logging.h
@@ -0,0 +1,188 @@
+/*
+ * (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.
+ *
+ * See testLogging.cc for a complete set of examples for
+ * how the logging functions should be used.
+ */
+
+#pragma once
+
+// Configure some behaviour of sdlog.
+// This must be done before spdlog is included.
+
+// use the coarse system clock. This is *much* faster
+// but introduces a real time error of O(10 ms).
+#define SPDLOG_CLOCK_COARSE
+
+// do not create a default logger (we provide our own "corsika" logger)
+#define SPDLOG_DISABLE_DEFAULT_LOGGER
+
+// use __PRETTY_FUNCTION__ instead of __FUNCTION__ where
+// printing function names in trace statements. This is much
+// nicer than __FUNCTION__ under GCC/clang.
+#define SPDLOG_FUNCTION __PRETTY_FUNCTION__
+
+// if this is a Debug build, include debug messages in objects
+#ifdef DEBUG
+// trace is the highest level of logging (ALL messages will be printed)
+#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_TRACE
+#else // otherwise, remove everything but "critical" messages
+#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_CRITICAL
+#endif
+
+#include <spdlog/spdlog.h>
+#include "spdlog/sinks/stdout_color_sinks.h"
+
+namespace corsika::logging {
+
+  // bring spdlog into the corsika::logging namespace
+  using namespace spdlog;
+
+  /*
+   * The default pattern for CORSIKA8 loggers.
+   */
+  const std::string default_pattern{"[%n:%^%-8l%$] %v"};
+
+  /**
+   * Create a new C8-style logger.
+   *
+   * Use this if you are explicitly (and can guarantee) that you
+   * are creating a logger for the first time. It is recommended
+   * that for regular usage, the `GetLogger` function is used instead
+   * as that will also create the logger if it has not yet been created.
+   *
+   * Calling `CreateLogger` twice to create the same logger will
+   * result in an spdlog duplicate exception.
+   *
+   * @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
+    // this is currently a colorized multi-threading safe logger
+    auto logger = spdlog::stdout_color_mt(name);
+
+    // set the default C8 format
+    logger->set_pattern(default_pattern);
+
+    // 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 smart pointer to an existing logger.
+   *
+   * This should be the default method for code to obtain a
+   * logger. If the logger *does not* exist, it is *created* and
+   * returned to the caller.
+   *
+   * This should be preferred over `CreateLogger`.
+   *
+   * @param name    The name of the logger to get.
+   * @param defaultlog   If True, make this the default logger.
+   * @returns              The constructed and formatted logger.
+   */
+  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);
+    }
+  }
+
+  /**
+   * The default "corsika" logger.
+   */
+  inline auto corsika = GetLogger("corsika", true);
+
+  /**
+   * Set the default log level for all *newly* created loggers.
+   *
+   *  @param name    The minimum log level required to print.
+   *
+   */
+  auto SetDefaultLevel(level::level_enum const minlevel) -> void {
+    spdlog::set_level(minlevel);
+  }
+
+  /**
+   * Set the log level for the "corsika" logger.
+   *
+   * @param name    The minimum log level required to print.
+   *
+   */
+  auto SetLevel(level::level_enum const minlevel) -> void {
+    corsika->set_level(minlevel);
+  }
+
+  /**
+   * Set the log level for a specific logger.
+   *
+   * @param logger  The logger to set the level of.
+   * @param name    The minimum log level required to print.
+   *
+   */
+  template <typename TLogger>
+  auto SetLevel(TLogger& logger, level::level_enum const minlevel) -> void {
+    logger->set_level(minlevel);
+  }
+
+  /**
+   * Add the source (filename, line no) info to the logger.
+   *
+   * @param logger  The logger to set the level of.
+   *
+   */
+  template <typename TLogger>
+  auto AddSourceInfo(TLogger& logger) -> void {
+    logger->set_pattern("[%n:%^%-8l%$(%s:%!:%#)] %v");
+  }
+
+  /**
+   * Reset the logging pattern to the default.
+   *
+   * @param logger  The logger to set the level of.
+   *
+   */
+  template <typename TLogger>
+  auto ResetPattern(TLogger& logger) -> void {
+    logger->set_pattern(default_pattern);
+  }
+
+// define our macro-style loggers
+#define C8LOG_TRACE SPDLOG_TRACE
+#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_TRACE SPDLOG_LOGGER_TRACE
+#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..bf919058053a662873ec472c76330e5f16b6a1d2 100644
--- a/Framework/Logging/testLogging.cc
+++ b/Framework/Logging/testLogging.cc
@@ -1,23 +1,117 @@
 /*
- * (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!!");
+
+    // get a reference to an unknown logger
+    auto logger = logging::GetLogger("loggerD");
+
+    // now set the default log level for this logger
+    logging::SetLevel(logger, logging::level::critical);
+
+    // now try the various logging functions
+    logger->info("This should NOT be printed!");
+    logger->warn("This should NOT be printed!");
+    logger->debug("This should NOT be printed!");
+    logger->error("This should NOT be printed!");
+    logger->critical("This SHOULD BE printed!!");
+
+    // and reset it for the next tests
+    logging::SetDefaultLevel(logging::level::debug);
+    logging::SetLevel(logging::level::debug);
+  }
+
+  SECTION("test macro style logging") {
+
+    // these print with the "corsika" logger
+    C8LOG_INFO("test macro style logging");
+    C8LOG_DEBUG("test macro style logging");
+    C8LOG_ERROR("test macro style logging");
+    C8LOG_CRITICAL("test macro style logging");
+
+    // get a reference to an unknown logger
+    auto logger = logging::GetLogger("loggerE");
+
+    // add the filename, source information to this logger
+    logging::AddSourceInfo(logger);
+
+    // these print with the "loggerE" logger
+    C8LOG_LOGGER_INFO(logger, "test macro style logging");
+    C8LOG_LOGGER_WARN(logger, "test macro style logging");
 
-  SECTION("sectionTwo") {}
+    // reset the logging pattern
+    logging::ResetPattern(logger);
 
-  SECTION("sectionThree") {}
+    // these trace macros should not print file, function, and line
+    C8LOG_LOGGER_TRACE(logger, "test macro style logging:");
+  }
 }
diff --git a/Processes/StackInspector/StackInspector.cc b/Processes/StackInspector/StackInspector.cc
index 56b1f0df8f4819c07b4c77f431e54851d3ad2344..af2270ecf32a185f66ae9464acf5885676fb7260 100644
--- a/Processes/StackInspector/StackInspector.cc
+++ b/Processes/StackInspector/StackInspector.cc
@@ -11,8 +11,6 @@
 #include <corsika/process/stack_inspector/StackInspector.h>
 #include <corsika/units/PhysicalUnits.h>
 
-#include <corsika/logging/Logger.h>
-
 #include <corsika/setup/SetupTrajectory.h>
 
 #include <chrono>
diff --git a/Setup/CMakeLists.txt b/Setup/CMakeLists.txt
index f37e2dfd4c5c1e09d062d26ecbe1394c918f574a..62fed414210d221775b238ef0d70f1a949501029 100644
--- a/Setup/CMakeLists.txt
+++ b/Setup/CMakeLists.txt
@@ -1,7 +1,6 @@
 set (
   SETUP_HEADERS
   SetupStack.h
-  SetupLogger.h
   SetupEnvironment.h
   SetupTrajectory.h
   )
diff --git a/Setup/SetupLogger.h b/Setup/SetupLogger.h
deleted file mode 100644
index 27b3db663a7744c290c6b7c3ceb40c1cd6247c79..0000000000000000000000000000000000000000
--- a/Setup/SetupLogger.h
+++ /dev/null
@@ -1,11 +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 {}
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
diff --git a/ThirdParty/spdlog b/ThirdParty/spdlog
new file mode 160000
index 0000000000000000000000000000000000000000..58875bdcd790dd2f5cb8d95ef1da7970de0a4530
--- /dev/null
+++ b/ThirdParty/spdlog
@@ -0,0 +1 @@
+Subproject commit 58875bdcd790dd2f5cb8d95ef1da7970de0a4530