IAP GITLAB

Commit 6bb37285 authored by Ralf Ulrich's avatar Ralf Ulrich Committed by Ralf Ulrich

Fixed Readme. Now it should reflect correct information.

Port C8 logging infrastructure to refactor.

Move implementations to .inl file in detail.

Delete commented out inline definition.

Switch to snake case and move default logger.

Remove explicit set_level methods.

Move default pattern into corsika::logging.

Remove superfluous comments and fix references.

Remove macros from .inl file.

Rename macros from C8LOG to CORSIKA_LOG

Remove double import of spdlog into corsika::logging
parent 35b66632
......@@ -51,37 +51,17 @@ which are very useful also for us.
## Installation (from source)
### Prerequisites
CORSIKA 8 is tested regularly via gitlab-CI using recent gcc and clang
versions. Additional software prerequisites: cmake, g++, git.
Furthermore, eigen3, boost, catch2, spdlog are shipped in the
ThirdParty directory, so an installation on the system is optional.
Also Pythia 8, CONEX and PROPOSAL are distributed in the ThirdParty
folder. You may also install those packages on your system and use
those; we test with Pythia version 8.235.
CORSIKA 8 is tested regularly at least on gcc7.3.0 and clang-8.0.0.
Additional software prerequisites you need to install are: eigen3, zlib, libbz2, cmake, g++, git.
On a bare Ubuntu 18.04, just add:
```
sudo apt install binutils gfortran make python3 cmake gcc g++ git libz-dev libspdlog-dev libeigen3-dev libboost-iostreams-dev
sudo apt install libeigen3-dev zlib1g-dev libbz2-dev cmake g++ git
```
Furthermore these packages are also reqommended:
add ```gcc ssh-client less rsync libboost-dev```
If you work with FreeBSD, run:
```
pkg install git cmake python3 flang eigen
Follow these steps to download and install CORSIKA 8
```
or add ```boost-libs``` if you want to use the system versions.
### Compiling
Follow these steps to download and install CORSIKA 8, master development version
```
git clone --recursive https://gitlab.ikp.kit.edu/AirShowerPhysics/corsika.git
git clone --recursive git@gitlab.ikp.kit.edu:AirShowerPhysics/corsika.git
cd corsika
mkdir ../corsika-build
cd ../corsika-build
......@@ -116,12 +96,9 @@ make install
Type `make test` to run the unit test suite.
## Running, Examples
There are various examples in the folder `Documentation/Examples`.
### Running examples
If you want to see how the first simple hadron cascade develops,
see `Documentation/Examples/cascade_example.cc` for a starting point.
and if you want to see how the first simple hadron cascade develops, see `Documentation/Examples/cascade_example.cc` for a starting point.
Run the cascade_example with:
```
......
/*
* (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.
*/
#pragma once
#include <spdlog/fmt/ostr.h> // will output whenerver a streaming operator is found
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/spdlog.h>
namespace corsika {
// many of these free functions are special to the logging
// infrastructure so we hide them in the corsika::logging namespace.
namespace logging {
/*
* The default pattern for CORSIKA8 loggers.
*/
std::string const default_pattern{"[%n:%^%-8l%$] %v"};
inline auto set_default_level(level::level_enum const minlevel) -> void {
spdlog::set_level(minlevel);
}
template <typename TLogger>
inline auto add_source_info(TLogger& logger) -> void {
logger->set_pattern("[%n:%^%-8l%$(%s:%!:%#)] %v");
}
template <typename TLogger>
inline auto reset_pattern(TLogger& logger) -> void {
logger->set_pattern(default_pattern);
}
} // namespace logging
inline std::shared_ptr<spdlog::logger> create_logger(std::string const& name,
bool const defaultlog) {
// 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(logging::default_pattern);
// if defaultlog is True, we set this as the default spdlog logger.
if (defaultlog) { spdlog::set_default_logger(logger); }
return logger;
}
inline std::shared_ptr<spdlog::logger> get_logger(std::string const& name,
bool const defaultlog) {
// 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 create_logger(name, defaultlog);
}
}
} // namespace corsika
/*
* (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
*
* See file AUTHORS for a list of contributors.
*
* 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.
*/
#ifndef _include_BufferedSink_h_
#define _include_BufferedSink_h_
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
#endif
/*
* (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
*
* See file AUTHORS for a list of contributors.
*
* 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.
*/
#ifndef _include_logger_h_
#define _include_logger_h_
#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__);
#endif
/*
* (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.hpp
*
* CORSIKA8 logging utilities.
*
* See testLogging.cpp 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 timestamp error of O(10 ms) which is fine for us.
#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/fmt/ostr.h> // will output whenerver a streaming operator is found
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/spdlog.h>
namespace corsika {
/**
* 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 `get_logger` function is used instead
* as that will also create the logger if it has not yet been created.
*
* Calling `create_logger` 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.
*/
std::shared_ptr<spdlog::logger> create_logger(std::string const& name,
bool const defaultlog = false);
/**
* 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 `create_logger`.
*
* @param name The name of the logger to get.
* @param defaultlog If True, make this the default logger.
* @returns The constructed and formatted logger.
*/
std::shared_ptr<spdlog::logger> get_logger(std::string const& name,
bool const defaultlog = false);
/**
* The default "corsika" logger.
*/
inline std::shared_ptr<spdlog::logger> corsika_logger = get_logger("corsika", true);
// many of these free functions are special to the logging
// infrastructure so we hide them in the corsika::logging namespace.
namespace logging {
// bring spdlog into the corsika::logging namespace
using namespace spdlog;
/**
* Set the default log level for all *newly* created loggers.
*
* @param name The minimum log level required to print.
*
*/
auto set_default_level(level::level_enum const minlevel) -> void;
/**
* Add the source (filename, line no) info to the logger.
*
* @param logger The logger to set the level of.
*
*/
template <typename TLogger>
auto add_source_info(TLogger& logger) -> void;
/**
* Reset the logging pattern to the default.
*
* @param logger The logger to set the level of.
*
*/
template <typename TLogger>
auto reset_pattern(TLogger& logger) -> void;
} // namespace logging
// define our macro-style loggers
// these use the default "corsika" logger
#define CORSIKA_LOG_TRACE SPDLOG_TRACE
#define CORSIKA_LOG_DEBUG SPDLOG_DEBUG
#define CORSIKA_LOG_INFO SPDLOG_INFO
#define CORSIKA_LOG_WARN SPDLOG_WARN
#define CORSIKA_LOG_ERROR SPDLOG_ERROR
#define CORSIKA_LOG_CRITICAL SPDLOG_CRITICAL
// and the specific logger versions
// these take a logger instance as their first argument
#define CORSIKA_LOGGER_TRACE SPDLOG_LOGGER_TRACE
#define CORSIKA_LOGGER_DEBUG SPDLOG_LOGGER_DEBUG
#define CORSIKA_LOGGER_INFO SPDLOG_LOGGER_INFO
#define CORSIKA_LOGGER_WARN SPDLOG_LOGGER_WARN
#define CORSIKA_LOGGER_ERROR SPDLOG_LOGGER_ERROR
#define CORSIKA_LOGGER_CRITICAL SPDLOG_LOGGER_CRITICAL
} // namespace corsika
#include <corsika/detail/framework/logging/Logging.inl>
/*
* (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
*
* See file AUTHORS for a list of contributors.
*
* 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.
*/
#ifndef _include_MessageOff_h_
#define _include_MessageOff_h_
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
#endif
/*
* (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
*
* See file AUTHORS for a list of contributors.
*
* 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.
*/
#ifndef _include_MessageOn_h_
#define _include_MessageOn_h_
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
#endif
/*
* (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
*
* See file AUTHORS for a list of contributors.
*
* 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.
*/
#ifndef _include_NoSink_h_
#define _include_NoSink_h_
namespace corsika::logging {
namespace sink {
struct NoSink {
inline void operator<<(const std::string&) {}
inline void Close() {}
};
} // namespace sink
} // namespace corsika::logging
#endif
/*
* (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
*
* See file AUTHORS for a list of contributors.
*
* 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.
*/
#ifndef _include_Sink_h_
#define _include_Sink_h_
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
#endif
......@@ -6,7 +6,7 @@ set (test_framework_sources
#testCorsikaFenv.cpp # does not work because of use of exceptions in catch2
testFourVector.cpp
testGeometry.cpp
#testLogging.cpp # irrelevant -> not used back in March
testLogging.cpp
TestMain.cpp
testParticles.cpp
testProcessSequence.cpp
......
......@@ -6,14 +6,14 @@
* the license.
*/
#include <corsika/framework/logging/Logger.h>
#include <corsika/framework/logging/Logging.hpp>
#include <catch2/catch.hpp>
using namespace corsika;
TEST_CASE("Logging", "[Logging]") {
SECTION("top level functions using corsika logger") {
SECTION("top level functions using default corsika logger") {
logging::info("This is an info message!");
logging::warn("This is a warning message!");
logging::debug("This is a debug message!");
......@@ -24,7 +24,7 @@ TEST_CASE("Logging", "[Logging]") {
SECTION("create a specific logger") {
// create a logger manually