memory\!, working on logging!
parent
a1331db389
commit
7033474455
|
@ -54,7 +54,7 @@ namespace blt::profiling {
|
||||||
profile getProfile(const std::string& profileName);
|
profile getProfile(const std::string& profileName);
|
||||||
|
|
||||||
void printProfile(
|
void printProfile(
|
||||||
const std::string& profileName, logging::LOG_LEVEL loggingLevel = logging::BLT_NONE,
|
const std::string& profileName, logging::LogLevel loggingLevel = logging::LogLevel::NONE,
|
||||||
bool averageHistory = false
|
bool averageHistory = false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -13,13 +13,21 @@
|
||||||
|
|
||||||
namespace blt::logging {
|
namespace blt::logging {
|
||||||
|
|
||||||
enum LOG_LEVEL {
|
enum class LogLevel {
|
||||||
|
// low level
|
||||||
|
TRACE0, TRACE1, TRACE2, TRACE3,
|
||||||
// normal
|
// normal
|
||||||
BLT_TRACE = 0, BLT_DEBUG = 1, BLT_INFO = 2,
|
TRACE, DEBUG, INFO,
|
||||||
|
WARN,
|
||||||
// errors
|
// errors
|
||||||
BLT_WARN = 3, BLT_ERROR = 4, BLT_FATAL = 5,
|
ERROR, FATAL,
|
||||||
// default
|
// default
|
||||||
BLT_NONE = 6
|
NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
class ILogHandler {
|
||||||
|
public:
|
||||||
|
virtual void log(std::string message, LogLevel level) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LOG_PROPERTIES {
|
struct LOG_PROPERTIES {
|
||||||
|
@ -31,7 +39,7 @@ namespace blt::logging {
|
||||||
// print the whole path or just the file name?
|
// print the whole path or just the file name?
|
||||||
bool m_logFullPath = false;
|
bool m_logFullPath = false;
|
||||||
const char* m_directory = "./";
|
const char* m_directory = "./";
|
||||||
LOG_LEVEL minLevel = BLT_TRACE;
|
LogLevel minLevel = LogLevel::TRACE;
|
||||||
|
|
||||||
explicit constexpr LOG_PROPERTIES(
|
explicit constexpr LOG_PROPERTIES(
|
||||||
bool useColor, bool logToConsole, bool logToFile, const char* directory
|
bool useColor, bool logToConsole, bool logToFile, const char* directory
|
||||||
|
@ -43,7 +51,7 @@ namespace blt::logging {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct logger {
|
struct logger {
|
||||||
LOG_LEVEL level;
|
LogLevel level;
|
||||||
|
|
||||||
void log_internal(const std::string& str) const;
|
void log_internal(const std::string& str) const;
|
||||||
// evil hack, todo: better way
|
// evil hack, todo: better way
|
||||||
|
@ -64,18 +72,18 @@ namespace blt::logging {
|
||||||
static void flush_all();
|
static void flush_all();
|
||||||
};
|
};
|
||||||
|
|
||||||
static logger std_out{BLT_NONE};
|
static logger std_out{LogLevel::NONE};
|
||||||
|
|
||||||
static logger trace{BLT_TRACE};
|
static logger trace{LogLevel::TRACE};
|
||||||
static logger debug{BLT_DEBUG};
|
static logger debug{LogLevel::DEBUG};
|
||||||
static logger info{BLT_INFO};
|
static logger info{LogLevel::INFO};
|
||||||
static logger warn{BLT_WARN};
|
static logger warn{LogLevel::WARN};
|
||||||
static logger error{BLT_ERROR};
|
static logger error{LogLevel::ERROR};
|
||||||
static logger fatal{BLT_FATAL};
|
static logger fatal{LogLevel::FATAL};
|
||||||
|
|
||||||
static inline logger& getLoggerFromLevel(LOG_LEVEL level) {
|
static inline logger& getLoggerFromLevel(LogLevel level) {
|
||||||
static logger loggerLevelDecode[7]{trace, debug, info, warn, error, fatal, std_out};
|
static logger loggerLevelDecode[11]{trace, trace, trace, trace, trace, debug, info, warn, error, fatal, std_out};
|
||||||
return loggerLevelDecode[level];
|
return loggerLevelDecode[(int)level];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline logger& operator<<(logger& out, const std::string& str) {
|
static inline logger& operator<<(logger& out, const std::string& str) {
|
||||||
|
@ -92,7 +100,7 @@ namespace blt::logging {
|
||||||
void init(LOG_PROPERTIES properties);
|
void init(LOG_PROPERTIES properties);
|
||||||
|
|
||||||
void log_internal(
|
void log_internal(
|
||||||
const std::string& format, LOG_LEVEL level, const char* file, int currentLine,
|
const std::string& format, LogLevel level, const char* file, int currentLine,
|
||||||
int auto_line, ...
|
int auto_line, ...
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -111,7 +119,7 @@ namespace blt::logging {
|
||||||
*/
|
*/
|
||||||
template<typename T, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
|
template<typename T, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
|
||||||
inline void log_internal(
|
inline void log_internal(
|
||||||
T t, LOG_LEVEL level, const char* file, int currentLine, int auto_line
|
T t, LogLevel level, const char* file, int currentLine, int auto_line
|
||||||
) {
|
) {
|
||||||
log_internal(std::to_string(t), level, file, currentLine, auto_line);
|
log_internal(std::to_string(t), level, file, currentLine, auto_line);
|
||||||
}
|
}
|
||||||
|
@ -133,12 +141,12 @@ namespace blt::logging {
|
||||||
#define BLT_FATAL(format, ...)
|
#define BLT_FATAL(format, ...)
|
||||||
#else
|
#else
|
||||||
#ifndef BLT_DISABLE_LOGGING
|
#ifndef BLT_DISABLE_LOGGING
|
||||||
#define BLT_TRACE(format, ...) log_internal(format, blt::logging::BLT_TRACE, __FILE__, __LINE__, true, ##__VA_ARGS__)
|
#define BLT_TRACE(format, ...) log_internal(format, blt::logging::LogLevel::TRACE, __FILE__, __LINE__, true, ##__VA_ARGS__)
|
||||||
#define BLT_DEBUG(format, ...) log_internal(format, blt::logging::BLT_DEBUG, __FILE__, __LINE__, true, ##__VA_ARGS__)
|
#define BLT_DEBUG(format, ...) log_internal(format, blt::logging::LogLevel::DEBUG, __FILE__, __LINE__, true, ##__VA_ARGS__)
|
||||||
#define BLT_INFO(format, ...) log_internal(format, blt::logging::BLT_INFO, __FILE__, __LINE__, true, ##__VA_ARGS__)
|
#define BLT_INFO(format, ...) log_internal(format, blt::logging::LogLevel::INFO, __FILE__, __LINE__, true, ##__VA_ARGS__)
|
||||||
#define BLT_WARN(format, ...) log_internal(format, blt::logging::BLT_WARN, __FILE__, __LINE__, true, ##__VA_ARGS__)
|
#define BLT_WARN(format, ...) log_internal(format, blt::logging::LogLevel::WARN, __FILE__, __LINE__, true, ##__VA_ARGS__)
|
||||||
#define BLT_ERROR(format, ...) log_internal(format, blt::logging::BLT_ERROR, __FILE__, __LINE__, true, ##__VA_ARGS__)
|
#define BLT_ERROR(format, ...) log_internal(format, blt::logging::LogLevel::ERROR, __FILE__, __LINE__, true, ##__VA_ARGS__)
|
||||||
#define BLT_FATAL(format, ...) log_internal(format, blt::logging::BLT_FATAL, __FILE__, __LINE__, true, ##__VA_ARGS__)
|
#define BLT_FATAL(format, ...) log_internal(format, blt::logging::LogLevel::FATAL, __FILE__, __LINE__, true, ##__VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,53 @@
|
||||||
#ifndef BLT_TESTS_MEMORY_H
|
#ifndef BLT_TESTS_MEMORY_H
|
||||||
#define BLT_TESTS_MEMORY_H
|
#define BLT_TESTS_MEMORY_H
|
||||||
|
|
||||||
|
#include <initializer_list>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
namespace blt {
|
namespace blt {
|
||||||
|
|
||||||
|
template<typename V>
|
||||||
|
struct ptr_iterator {
|
||||||
|
public:
|
||||||
|
using iterator_category = std::random_access_iterator_tag;
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
using value_type = V;
|
||||||
|
using pointer = value_type*;
|
||||||
|
using reference = value_type&;
|
||||||
|
|
||||||
|
explicit ptr_iterator(V* v): _v(v) {}
|
||||||
|
|
||||||
|
reference operator*() const { return *_v; }
|
||||||
|
pointer operator->() { return _v; }
|
||||||
|
ptr_iterator& operator++() {
|
||||||
|
_v++;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
ptr_iterator& operator--() {
|
||||||
|
_v--;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
ptr_iterator operator++(int){
|
||||||
|
auto tmp = *this;
|
||||||
|
++(*this);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
ptr_iterator operator--(int){
|
||||||
|
auto tmp = *this;
|
||||||
|
--(*this);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
friend bool operator==(const ptr_iterator& a, const ptr_iterator& b) {
|
||||||
|
return a._v == b._v;
|
||||||
|
}
|
||||||
|
friend bool operator!=(const ptr_iterator& a, const ptr_iterator& b) {
|
||||||
|
return a._v != b._v;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
V* _v;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an encapsulation of a T array which will be automatically deleted when this object goes out of scope.
|
* Creates an encapsulation of a T array which will be automatically deleted when this object goes out of scope.
|
||||||
* This is a simple buffer meant to be used only inside of a function and not moved around, with a few minor exceptions.
|
* This is a simple buffer meant to be used only inside of a function and not moved around, with a few minor exceptions.
|
||||||
|
@ -77,6 +123,51 @@ namespace blt {
|
||||||
|
|
||||||
~nullptr_initializer() = default;
|
~nullptr_initializer() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a hash-map like association between an enum key and any arbitrary value.
|
||||||
|
* The storage is backed by a contiguous array for faster access.
|
||||||
|
* @tparam K enum value
|
||||||
|
* @tparam V associated value
|
||||||
|
*/
|
||||||
|
template<typename K, typename V>
|
||||||
|
class enum_storage {
|
||||||
|
private:
|
||||||
|
V* _values;
|
||||||
|
size_t _size = 0;
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
enum_storage(std::initializer_list<std::pair<K, V>> init){
|
||||||
|
for (auto& i : init)
|
||||||
|
_size = std::max((size_t)i, _size);
|
||||||
|
_values = new V[_size];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline V& operator[](size_t index){
|
||||||
|
return _values[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const V& operator[](size_t index) const {
|
||||||
|
return _values[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline size_t size() const {
|
||||||
|
return _size;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr_iterator<V> begin(){
|
||||||
|
return ptr_iterator{_values};
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr_iterator<V> end(){
|
||||||
|
return ptr_iterator{&_values[_size]};
|
||||||
|
}
|
||||||
|
|
||||||
|
~enum_storage(){
|
||||||
|
delete[] _values;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //BLT_TESTS_MEMORY_H
|
#endif //BLT_TESTS_MEMORY_H
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace blt::profiling {
|
||||||
difference(difference), name(std::move(name)), total(total) {}
|
difference(difference), name(std::move(name)), total(total) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void println(const std::vector<std::string>&& lines, logging::LOG_LEVEL level) {
|
inline void println(const std::vector<std::string>&& lines, logging::LogLevel level) {
|
||||||
auto& logger = logging::getLoggerFromLevel(level);
|
auto& logger = logging::getLoggerFromLevel(level);
|
||||||
for (const auto& line : lines)
|
for (const auto& line : lines)
|
||||||
logger << line << "\n";
|
logger << line << "\n";
|
||||||
|
@ -104,7 +104,7 @@ namespace blt::profiling {
|
||||||
}
|
}
|
||||||
|
|
||||||
void printProfile(
|
void printProfile(
|
||||||
const std::string& profileName, logging::LOG_LEVEL loggingLevel, bool averageHistory
|
const std::string& profileName, logging::LogLevel loggingLevel, bool averageHistory
|
||||||
) {
|
) {
|
||||||
auto& profile = profiles[profileName];
|
auto& profile = profiles[profileName];
|
||||||
const auto& intervals = profile.intervals;
|
const auto& intervals = profile.intervals;
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
// https://publications.gbdirect.co.uk//c_book/chapter9/stdarg.html
|
// https://publications.gbdirect.co.uk//c_book/chapter9/stdarg.html
|
||||||
// https://cplusplus.com/reference/cstdio/printf/
|
// https://cplusplus.com/reference/cstdio/printf/
|
||||||
|
|
||||||
|
#include <blt/std/memory.h>
|
||||||
|
|
||||||
|
|
||||||
namespace blt::logging {
|
namespace blt::logging {
|
||||||
|
|
||||||
|
@ -120,7 +122,7 @@ namespace blt::logging {
|
||||||
return final;
|
return final;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void log(const std::string& str, bool hasEndingLinefeed, LOG_LEVEL level, const char* file, int currentLine, int auto_line){
|
inline void log(const std::string& str, bool hasEndingLinefeed, LogLevel level, const char* file, int currentLine, int auto_line){
|
||||||
if (level < BLT_LOGGING_PROPERTIES.minLevel)
|
if (level < BLT_LOGGING_PROPERTIES.minLevel)
|
||||||
return;
|
return;
|
||||||
std::string outputString = system::getTimeStringLog();
|
std::string outputString = system::getTimeStringLog();
|
||||||
|
@ -133,13 +135,13 @@ namespace blt::logging {
|
||||||
outputString += "] ";
|
outputString += "] ";
|
||||||
}
|
}
|
||||||
|
|
||||||
outputString += levelNames[level];
|
outputString += levelNames[(int)level];
|
||||||
outputString += str;
|
outputString += str;
|
||||||
|
|
||||||
std::string fileString = outputString;
|
std::string fileString = outputString;
|
||||||
|
|
||||||
if (BLT_LOGGING_PROPERTIES.m_useColor) {
|
if (BLT_LOGGING_PROPERTIES.m_useColor) {
|
||||||
outputString = levelColors[level] + outputString;
|
outputString = levelColors[(int)level] + outputString;
|
||||||
outputString += "\033[0m";
|
outputString += "\033[0m";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +151,7 @@ namespace blt::logging {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BLT_LOGGING_PROPERTIES.m_logToConsole) {
|
if (BLT_LOGGING_PROPERTIES.m_logToConsole) {
|
||||||
if (level > BLT_WARN)
|
if (level > LogLevel::WARN)
|
||||||
std::cerr << outputString;
|
std::cerr << outputString;
|
||||||
else
|
else
|
||||||
std::cout << outputString;
|
std::cout << outputString;
|
||||||
|
@ -160,7 +162,7 @@ namespace blt::logging {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void log_internal(const std::string& format, LOG_LEVEL level, const char* file, int currentLine, int auto_line, ...) {
|
void log_internal(const std::string& format, LogLevel level, const char* file, int currentLine, int auto_line, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, auto_line);
|
va_start(args, auto_line);
|
||||||
|
|
||||||
|
@ -181,7 +183,7 @@ namespace blt::logging {
|
||||||
}
|
}
|
||||||
|
|
||||||
// stores an association between thread -> log level -> current line buffer
|
// stores an association between thread -> log level -> current line buffer
|
||||||
std::unordered_map<std::thread::id, std::unordered_map<LOG_LEVEL, std::string>> thread_local_strings;
|
std::unordered_map<std::thread::id, std::unordered_map<LogLevel, std::string>> thread_local_strings;
|
||||||
|
|
||||||
void logger::log_internal(const std::string& str) const {
|
void logger::log_internal(const std::string& str) const {
|
||||||
auto id = std::this_thread::get_id();
|
auto id = std::this_thread::get_id();
|
||||||
|
@ -191,7 +193,7 @@ namespace blt::logging {
|
||||||
if (blt::string::contains(str, "\n")){
|
if (blt::string::contains(str, "\n")){
|
||||||
// make sure new lines are properly formatted to prevent danging lines. Ie "[trace]: .... [debug]: ...."
|
// make sure new lines are properly formatted to prevent danging lines. Ie "[trace]: .... [debug]: ...."
|
||||||
bool hasEndingLinefeed = str[str.length()-1] == '\n';
|
bool hasEndingLinefeed = str[str.length()-1] == '\n';
|
||||||
if (level == BLT_NONE) {
|
if (level == LogLevel::NONE) {
|
||||||
std::cout << th_str;
|
std::cout << th_str;
|
||||||
} else
|
} else
|
||||||
logging::log(th_str, false, level, "", -1, !hasEndingLinefeed);
|
logging::log(th_str, false, level, "", -1, !hasEndingLinefeed);
|
||||||
|
@ -201,7 +203,7 @@ namespace blt::logging {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void flushLogger_internal(std::thread::id id, LOG_LEVEL level){
|
void flushLogger_internal(std::thread::id id, LogLevel level){
|
||||||
auto th_str = thread_local_strings[id][level];
|
auto th_str = thread_local_strings[id][level];
|
||||||
if (th_str.empty())
|
if (th_str.empty())
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -38,7 +38,7 @@ static void runProfilingAndTableTests() {
|
||||||
BLT_END_INTERVAL("Help", "UnderSet" + std::to_string(i));
|
BLT_END_INTERVAL("Help", "UnderSet" + std::to_string(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
BLT_PRINT_PROFILE("Help", blt::logging::LOG_LEVEL::BLT_TRACE);
|
BLT_PRINT_PROFILE("Help", blt::logging::LogLevel::TRACE);
|
||||||
BLT_TRACE("");
|
BLT_TRACE("");
|
||||||
|
|
||||||
blt::string::TableFormatter formatter;
|
blt::string::TableFormatter formatter;
|
||||||
|
|
|
@ -140,9 +140,9 @@ static inline void test_queues() {
|
||||||
fill_queues();
|
fill_queues();
|
||||||
random_access();
|
random_access();
|
||||||
|
|
||||||
BLT_PRINT_PROFILE("Insert", blt::logging::LOG_LEVEL::BLT_INFO, true);
|
BLT_PRINT_PROFILE("Insert", blt::logging::LogLevel::INFO, true);
|
||||||
BLT_PRINT_PROFILE("Access", blt::logging::LOG_LEVEL::BLT_INFO, true);
|
BLT_PRINT_PROFILE("Access", blt::logging::LogLevel::INFO, true);
|
||||||
BLT_PRINT_PROFILE("Random", blt::logging::LOG_LEVEL::BLT_INFO, true);
|
BLT_PRINT_PROFILE("Random", blt::logging::LogLevel::INFO, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //BLT_TESTS_QUEUE_TESTS_H
|
#endif //BLT_TESTS_QUEUE_TESTS_H
|
||||||
|
|
Loading…
Reference in New Issue