add logger class (#29)

* add logger class

* add LOCATION macro for logger

* added printing in files
This commit is contained in:
Bechir Braham 2024-03-26 17:40:19 +01:00 committed by GitHub
parent 7e913b3385
commit e280742a6c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 195 additions and 8 deletions

View File

@ -98,11 +98,12 @@ endif()
add_subdirectory(core)
add_subdirectory(file_io)
add_subdirectory(utils)
#Overall target to link to when using the library
add_library(aare INTERFACE)
target_link_libraries(aare INTERFACE core file_io)
target_link_libraries(aare INTERFACE core file_io utils)
target_include_directories(aare INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>

View File

@ -1,12 +1,13 @@
add_executable(json_example json_file_read.cpp)
add_executable(numpy_example numpy_file_read.cpp)
set(EXAMPLE_LIST "json_example;logger_example;numpy_example")
foreach(example ${EXAMPLE_LIST})
add_executable(${example} ${example}.cpp)
target_link_libraries(${example} PUBLIC aare PRIVATE aare_compiler_flags)
endforeach()
target_link_libraries(json_example PRIVATE aare_compiler_flags)
target_link_libraries(numpy_example PRIVATE aare_compiler_flags)
target_link_libraries(json_example PUBLIC aare)
target_link_libraries(numpy_example PUBLIC aare)

View File

@ -1,6 +1,7 @@
// Your First C++ Program
#include "aare/ContextManager.hpp"
#include <iostream>
#include "aare/utils/logger.hpp"
#define AARE_ROOT_DIR_VAR "PROJECT_ROOT_DIR"
@ -26,4 +27,9 @@ int main() {
test(file, 2);
test(file, 9);
aare::logger::debug(LOCATION,"Hello", "World");
}

View File

@ -0,0 +1,36 @@
#include "aare/utils/logger.hpp"
#include <iostream>
#include <fstream>
int main() {
aare::logger::debug(LOCATION, "hello", 1, "world", std::vector<long>{1, 2, 3, 4, 5});
aare::logger::debug(LOCATION, "setting verbosity to INFO");
aare::logger::set_verbosity(aare::logger::INFO);
aare::logger::debug(LOCATION, "NOTHING SHOULD BE PRINTED");
aare::logger::info(LOCATION, "info printed");
// writing to file
std::ofstream textfile;
textfile.open("Test.txt");
aare::logger::set_streams(textfile.rdbuf());
aare::logger::info(LOCATION, "info printed to file");
// writing with a local logger instance
aare::logger::Logger logger;
logger.set_verbosity(aare::logger::WARNING);
logger.debug(LOCATION, "NOTHING SHOULD BE PRINTED");
logger.info(LOCATION, "NOTHING SHOULD BE PRINTED");
logger.warn(LOCATION, "warning printed in std::cout");
aare::logger::info(LOCATION, "info printed in file ##");
textfile.close();
// setting file output by path
// user doesn't have to close file
aare::logger::set_output_file("Test2.txt");
aare::logger::info(LOCATION, "info printed to Test2.txt");
return 0;
}

4
utils/CMakeLists.txt Normal file
View File

@ -0,0 +1,4 @@
add_library(utils STATIC src/logger.cpp)
target_include_directories(utils PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)

View File

@ -0,0 +1,123 @@
#pragma once
#include <filesystem>
#include <fstream>
#include <iostream>
#include <vector>
#define LOCATION std::string(__FILE__) + std::string(":") + std::to_string(__LINE__) + ":" + std::string(__func__) + ":"
// operator overload to print vectors
// typename T must be printable (i.e. have the << operator)
template <typename T> std::ostream &operator<<(std::ostream &out, const std::vector<T> &v) {
out << "[";
size_t last = v.size() - 1;
for (size_t i = 0; i < v.size(); ++i) {
out << v[i];
if (i != last)
out << ", ";
}
out << "]";
return out;
}
namespace aare {
namespace logger {
enum LOGGING_LEVEL {
DEBUG = 0,
INFO = 1,
WARNING = 2,
ERROR = 3
};
class Logger {
std::streambuf *standard_buf = std::cout.rdbuf();
std::streambuf *error_buf = std::cerr.rdbuf();
std::ostream *standard_output;
std::ostream *error_output;
LOGGING_LEVEL VERBOSITY_LEVEL = LOGGING_LEVEL::DEBUG;
std::ofstream out_file;
public:
void set_output_file(std::string filename) {
if (out_file.is_open())
out_file.close();
out_file.open(filename);
set_streams(out_file.rdbuf());
}
void set_streams(std::streambuf *out, std::streambuf *err) {
delete standard_output;
delete error_output;
standard_output = new std::ostream(out);
error_output = new std::ostream(err);
}
void set_streams(std::streambuf *out) { set_streams(out, out); }
void set_verbosity(LOGGING_LEVEL level) { VERBOSITY_LEVEL = level; }
Logger() {
standard_output = new std::ostream(standard_buf);
error_output = new std::ostream(error_buf);
}
~Logger() {
if (out_file.is_open())
out_file.close();
standard_output->flush();
error_output->flush();
delete standard_output;
delete error_output;
}
template <LOGGING_LEVEL level, typename... Strings> void log(const Strings... s) {
if (level >= VERBOSITY_LEVEL)
log_<level>(s...);
}
template <typename... Strings> void debug(const Strings... s) { log<LOGGING_LEVEL::DEBUG>("[DEBUG]", s...); }
template <typename... Strings> void info(const Strings... s) { log<LOGGING_LEVEL::INFO>("[INFO]", s...); }
template <typename... Strings> void warn(const Strings... s) { log<LOGGING_LEVEL::WARNING>("[WARN]", s...); }
template <typename... Strings> void error(const Strings... s) { log<LOGGING_LEVEL::ERROR>("[ERROR]", s...); }
private:
template <LOGGING_LEVEL level> void log_() {
if (level == LOGGING_LEVEL::ERROR) {
*error_output << std::endl;
} else {
*standard_output << std::endl;
}
}
template <LOGGING_LEVEL level, typename First, typename... Strings> void log_(First arg, const Strings... s) {
if (level == LOGGING_LEVEL::ERROR) {
*error_output << (arg) << ' ';
error_output->flush();
} else {
*standard_output << (arg) << ' ';
standard_output->flush();
}
log_<level>(s...);
}
};
namespace internal {
extern aare::logger::Logger logger_instance;
} // namespace internal
template <LOGGING_LEVEL level, typename... Strings> void log(const Strings... s) {
internal::logger_instance.log<level>(s...);
}
template <typename... Strings> void debug(const Strings... s) { internal::logger_instance.debug(s...); }
template <typename... Strings> void info(const Strings... s) { internal::logger_instance.info(s...); }
template <typename... Strings> void warn(const Strings... s) { internal::logger_instance.warn(s...); }
template <typename... Strings> void error(const Strings... s) { internal::logger_instance.error(s...); }
extern void set_streams(std::streambuf *out, std::streambuf *err);
extern void set_streams(std::streambuf *out);
extern void set_verbosity(LOGGING_LEVEL level);
extern void set_output_file(std::string filename);
extern Logger &get_logger_instance();
} // namespace logger
} // namespace aare

14
utils/src/logger.cpp Normal file
View File

@ -0,0 +1,14 @@
#include "aare/utils/logger.hpp"
namespace aare {
namespace logger {
namespace internal {
aare::logger::Logger logger_instance = aare::logger::Logger();
} // namespace internal
void set_streams(std::streambuf *out, std::streambuf *err) { internal::logger_instance.set_streams(out, err); }
void set_streams(std::streambuf *out) { internal::logger_instance.set_streams(out); }
void set_verbosity(LOGGING_LEVEL level) { internal::logger_instance.set_verbosity(level); }
Logger &get_logger_instance() { return internal::logger_instance; }
void set_output_file(std::string filename){ internal::logger_instance.set_output_file(filename); }
} // namespace logger
} // namespace aare

View File

@ -0,0 +1,2 @@
#include "aare/utils/logger.hpp"
#include <catch2/catch_test_macros.hpp>