memory\!, working on logging!

v1
Brett 2023-07-20 21:44:52 -04:00
parent a1331db389
commit 7033474455
7 changed files with 140 additions and 39 deletions

View File

@ -54,7 +54,7 @@ namespace blt::profiling {
profile getProfile(const std::string& profileName);
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
);

View File

@ -13,13 +13,21 @@
namespace blt::logging {
enum LOG_LEVEL {
enum class LogLevel {
// low level
TRACE0, TRACE1, TRACE2, TRACE3,
// normal
BLT_TRACE = 0, BLT_DEBUG = 1, BLT_INFO = 2,
TRACE, DEBUG, INFO,
WARN,
// errors
BLT_WARN = 3, BLT_ERROR = 4, BLT_FATAL = 5,
ERROR, FATAL,
// default
BLT_NONE = 6
NONE
};
class ILogHandler {
public:
virtual void log(std::string message, LogLevel level) = 0;
};
struct LOG_PROPERTIES {
@ -31,7 +39,7 @@ namespace blt::logging {
// print the whole path or just the file name?
bool m_logFullPath = false;
const char* m_directory = "./";
LOG_LEVEL minLevel = BLT_TRACE;
LogLevel minLevel = LogLevel::TRACE;
explicit constexpr LOG_PROPERTIES(
bool useColor, bool logToConsole, bool logToFile, const char* directory
@ -43,7 +51,7 @@ namespace blt::logging {
};
struct logger {
LOG_LEVEL level;
LogLevel level;
void log_internal(const std::string& str) const;
// evil hack, todo: better way
@ -64,18 +72,18 @@ namespace blt::logging {
static void flush_all();
};
static logger std_out{BLT_NONE};
static logger std_out{LogLevel::NONE};
static logger trace{BLT_TRACE};
static logger debug{BLT_DEBUG};
static logger info{BLT_INFO};
static logger warn{BLT_WARN};
static logger error{BLT_ERROR};
static logger fatal{BLT_FATAL};
static logger trace{LogLevel::TRACE};
static logger debug{LogLevel::DEBUG};
static logger info{LogLevel::INFO};
static logger warn{LogLevel::WARN};
static logger error{LogLevel::ERROR};
static logger fatal{LogLevel::FATAL};
static inline logger& getLoggerFromLevel(LOG_LEVEL level) {
static logger loggerLevelDecode[7]{trace, debug, info, warn, error, fatal, std_out};
return loggerLevelDecode[level];
static inline logger& getLoggerFromLevel(LogLevel level) {
static logger loggerLevelDecode[11]{trace, trace, trace, trace, trace, debug, info, warn, error, fatal, std_out};
return loggerLevelDecode[(int)level];
}
static inline logger& operator<<(logger& out, const std::string& str) {
@ -92,7 +100,7 @@ namespace blt::logging {
void init(LOG_PROPERTIES properties);
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, ...
);
@ -111,7 +119,7 @@ namespace blt::logging {
*/
template<typename T, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
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);
}
@ -133,12 +141,12 @@ namespace blt::logging {
#define BLT_FATAL(format, ...)
#else
#ifndef BLT_DISABLE_LOGGING
#define BLT_TRACE(format, ...) log_internal(format, blt::logging::BLT_TRACE, __FILE__, __LINE__, true, ##__VA_ARGS__)
#define BLT_DEBUG(format, ...) log_internal(format, blt::logging::BLT_DEBUG, __FILE__, __LINE__, true, ##__VA_ARGS__)
#define BLT_INFO(format, ...) log_internal(format, blt::logging::BLT_INFO, __FILE__, __LINE__, true, ##__VA_ARGS__)
#define BLT_WARN(format, ...) log_internal(format, blt::logging::BLT_WARN, __FILE__, __LINE__, true, ##__VA_ARGS__)
#define BLT_ERROR(format, ...) log_internal(format, blt::logging::BLT_ERROR, __FILE__, __LINE__, true, ##__VA_ARGS__)
#define BLT_FATAL(format, ...) log_internal(format, blt::logging::BLT_FATAL, __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::LogLevel::DEBUG, __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::LogLevel::WARN, __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::LogLevel::FATAL, __FILE__, __LINE__, true, ##__VA_ARGS__)
#endif
#endif

View File

@ -7,7 +7,53 @@
#ifndef BLT_TESTS_MEMORY_H
#define BLT_TESTS_MEMORY_H
#include <initializer_list>
#include <iterator>
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.
* 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;
};
/**
* 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

View File

@ -30,7 +30,7 @@ namespace blt::profiling {
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);
for (const auto& line : lines)
logger << line << "\n";
@ -104,7 +104,7 @@ namespace blt::profiling {
}
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];
const auto& intervals = profile.intervals;

View File

@ -22,6 +22,8 @@
// https://publications.gbdirect.co.uk//c_book/chapter9/stdarg.html
// https://cplusplus.com/reference/cstdio/printf/
#include <blt/std/memory.h>
namespace blt::logging {
@ -120,7 +122,7 @@ namespace blt::logging {
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)
return;
std::string outputString = system::getTimeStringLog();
@ -133,13 +135,13 @@ namespace blt::logging {
outputString += "] ";
}
outputString += levelNames[level];
outputString += levelNames[(int)level];
outputString += str;
std::string fileString = outputString;
if (BLT_LOGGING_PROPERTIES.m_useColor) {
outputString = levelColors[level] + outputString;
outputString = levelColors[(int)level] + outputString;
outputString += "\033[0m";
}
@ -149,7 +151,7 @@ namespace blt::logging {
}
if (BLT_LOGGING_PROPERTIES.m_logToConsole) {
if (level > BLT_WARN)
if (level > LogLevel::WARN)
std::cerr << outputString;
else
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_start(args, auto_line);
@ -181,7 +183,7 @@ namespace blt::logging {
}
// 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 {
auto id = std::this_thread::get_id();
@ -191,7 +193,7 @@ namespace blt::logging {
if (blt::string::contains(str, "\n")){
// make sure new lines are properly formatted to prevent danging lines. Ie "[trace]: .... [debug]: ...."
bool hasEndingLinefeed = str[str.length()-1] == '\n';
if (level == BLT_NONE) {
if (level == LogLevel::NONE) {
std::cout << th_str;
} else
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];
if (th_str.empty())
return;

View File

@ -38,7 +38,7 @@ static void runProfilingAndTableTests() {
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::string::TableFormatter formatter;

View File

@ -140,9 +140,9 @@ static inline void test_queues() {
fill_queues();
random_access();
BLT_PRINT_PROFILE("Insert", blt::logging::LOG_LEVEL::BLT_INFO, true);
BLT_PRINT_PROFILE("Access", blt::logging::LOG_LEVEL::BLT_INFO, true);
BLT_PRINT_PROFILE("Random", blt::logging::LOG_LEVEL::BLT_INFO, true);
BLT_PRINT_PROFILE("Insert", blt::logging::LogLevel::INFO, true);
BLT_PRINT_PROFILE("Access", blt::logging::LogLevel::INFO, true);
BLT_PRINT_PROFILE("Random", blt::logging::LogLevel::INFO, true);
}
#endif //BLT_TESTS_QUEUE_TESTS_H