minor fixes, all files now use new logging libray, expect things to be broken!

main
Brett 2025-03-09 23:04:41 -04:00
parent be46e8552b
commit b334bbcae4
25 changed files with 1034 additions and 2100 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.20)
include(cmake/color.cmake)
set(BLT_VERSION 5.2.4)
set(BLT_VERSION 5.2.5)
set(BLT_TARGET BLT)

View File

@ -13,7 +13,7 @@
#include <unordered_map>
#include <string>
#include <blt/std/string.h>
#include <blt/std/logging.h>
#include <blt/logging/logging.h>
#include <unordered_set>
namespace blt::fs

View File

@ -15,7 +15,7 @@
#include "blt/format/format.h"
#include "blt/fs/filesystem.h"
#include "blt/std/logging.h"
#include "blt/logging/logging.h"
#include "blt/std/memory.h"
#include <blt/std/hashmap.h>

View File

@ -203,14 +203,21 @@ namespace blt::logging
}
template <typename... Args>
void log(log_level_t level, const char* file, const i32 line, std::string fmt, Args&&... args)
void log(const log_level_t level, const char* file, const i32 line, std::string fmt, Args&&... args)
{
auto& logger = get_global_logger();
auto& config = get_global_config();
auto user_str = logger.log(std::move(fmt), std::forward<Args>(args)...);
const auto& config = get_global_config();
std::string user_str = logger.log(std::move(fmt), std::forward<Args>(args)...);
if (!user_str.empty() && user_str.back() == '\n')
user_str.pop_back();
if (level == log_level_t::NONE)
{
println(user_str);
return;
}
auto log_fmt_str = config.generate(user_str, get_thread_name(), level, file, line);
if (log_fmt_str)
print(std::move(*log_fmt_str));
print(*log_fmt_str);
}
namespace detail

View File

@ -115,7 +115,8 @@ namespace blt::logging
INFO,
WARN,
ERROR,
FATAL
FATAL,
NONE
};
inline constexpr size_t LOG_LEVEL_COUNT = 6;

View File

@ -27,7 +27,7 @@
#include <blt/std/hashmap.h>
#include <blt/std/types.h>
#include <blt/std/expected.h>
#include <blt/std/logging.h>
#include <blt/logging/logging.h>
#include <variant>
namespace blt

View File

@ -11,7 +11,7 @@
#include <blt/std/queue.h>
#include <vector>
#include <unordered_map>
#include <blt/std/logging.h>
#include <blt/logging/logging.h>
#include <fstream>
#include <cstdint>
@ -54,7 +54,7 @@ namespace blt::profiling {
profile getProfile(const std::string& profileName);
void printProfile(
const std::string& profileName, logging::log_level loggingLevel = logging::log_level::NONE,
const std::string& profileName, logging::log_level_t loggingLevel = logging::log_level_t::NONE,
bool averageHistory = false
);

View File

@ -11,7 +11,7 @@
#include <cstdint>
#include <string>
#include <vector>
#include <blt/std/logging.h>
#include <blt/logging/logging.h>
namespace blt
{
@ -98,7 +98,7 @@ namespace blt
void endInterval(interval_t* interval);
void printProfile(profile_t& profiler, std::uint32_t flags = AVERAGE_HISTORY | PRINT_CYCLES | PRINT_THREAD | PRINT_WALL,
sort_by sort = sort_by::CYCLES, blt::logging::log_level log_level = blt::logging::log_level::NONE);
sort_by sort = sort_by::CYCLES, blt::logging::log_level_t log_level = blt::logging::log_level_t::NONE);
void writeProfile(std::ostream& stream, profile_t& profiler,
std::uint32_t flags = AVERAGE_HISTORY | PRINT_CYCLES | PRINT_THREAD | PRINT_WALL,
@ -113,7 +113,7 @@ namespace blt
void endInterval(const std::string& profile_name, const std::string& interval_name);
void printProfile(const std::string& profile_name, std::uint32_t flags = AVERAGE_HISTORY | PRINT_CYCLES | PRINT_THREAD | PRINT_WALL,
sort_by sort = sort_by::CYCLES, blt::logging::log_level log_level = blt::logging::log_level::NONE);
sort_by sort = sort_by::CYCLES, blt::logging::log_level_t log_level = blt::logging::log_level_t::NONE);
void writeProfile(std::ostream& stream, const std::string& profile_name,
std::uint32_t flags = AVERAGE_HISTORY | PRINT_CYCLES | PRINT_THREAD | PRINT_WALL,

File diff suppressed because it is too large Load Diff

View File

@ -1,436 +0,0 @@
/*
* Created by Brett on 20/07/23.
* Licensed under GNU General Public License V3.0
* See LICENSE file for license detail
*/
#ifndef BLT_TESTS_LOGGING2_H
#define BLT_TESTS_LOGGING2_H
#include <string>
#include <type_traits>
#include <functional>
#include <sstream>
#include <blt/config.h>
#include <blt/std/types.h>
#include <iostream>
#include <cstdarg>
namespace blt::logging
{
namespace ansi
{
inline auto ESC(std::string_view str)
{
return std::string("\033") += str;
}
inline const auto CUR_HOME = ESC("[H");
inline auto CUR_MOVE(blt::size_t line, blt::size_t column)
{
return ESC("[{" + std::to_string(line) + "};{" + std::to_string(column) + "}H");
}
inline auto CUR_UP(blt::size_t lines)
{
return ESC("[" + std::to_string(lines) + "A");
}
inline auto CUR_DOWN(blt::size_t lines)
{
return ESC("[" + std::to_string(lines) + "B");
}
inline auto CUR_RIGHT(blt::size_t columns)
{
return ESC("[" + std::to_string(columns) + "C");
}
inline auto CUR_LEFT(blt::size_t columns)
{
return ESC("[" + std::to_string(columns) + "D");
}
inline auto CUR_BEGIN_NEXT(blt::size_t lines_down)
{
return ESC("[" + std::to_string(lines_down) + "E");
}
inline auto CUR_BEGIN_PREV(blt::size_t lines_up)
{
return ESC("[" + std::to_string(lines_up) + "F");
}
inline auto CUR_COLUMN(blt::size_t column)
{
return ESC("[" + std::to_string(column) + "G");
}
inline auto CUR_POS()
{
return ESC("[6n");
}
inline auto CUR_SCROLL_UP()
{
return ESC(" M");
}
inline auto CUR_SAVE_DEC()
{
return ESC(" 7");
}
inline auto CUR_LOAD_DEC()
{
return ESC(" 8");
}
inline auto CUR_SAVE_SCO()
{
return ESC("[s");
}
inline auto CUR_LOAD_SCO()
{
return ESC("[u");
}
inline auto RESET = ESC("[0m");
inline auto BOLD = "1";
inline auto RESET_BOLD = "22";
inline auto DIM = "2";
inline auto RESET_DIM = "22";
inline auto ITALIC = "3";
inline auto RESET_ITALIC = "23";
inline auto UNDERLINE = "4";
inline auto RESET_UNDERLINE = "24";
inline auto BLINKING = "5";
inline auto RESET_BLINKING = "25";
inline auto INVERSE = "7";
inline auto RESET_INVERSE = "27";
inline auto HIDDEN = "8";
inline auto RESET_HIDDEN = "28";
inline auto STRIKETHROUGH = "9";
inline auto RESET_STRIKETHROUGH = "29";
inline auto COLOR_DEFAULT = "39";
inline auto BACKGROUND_DEFAULT = "49";
inline auto BLACK = "30";
inline auto RED = "31";
inline auto GREEN = "32";
inline auto YELLOW = "33";
inline auto BLUE = "34";
inline auto MAGENTA = "35";
inline auto CYAN = "36";
inline auto WHITE = "37";
inline auto BLACK_BACKGROUND = "40";
inline auto RED_BACKGROUND = "41";
inline auto GREEN_BACKGROUND = "42";
inline auto YELLOW_BACKGROUND = "43";
inline auto BLUE_BACKGROUND = "44";
inline auto MAGENTA_BACKGROUND = "45";
inline auto CYAN_BACKGROUND = "46";
inline auto WHITE_BACKGROUND = "47";
inline auto BRIGHT_BLACK = "90";
inline auto BRIGHT_RED = "91";
inline auto BRIGHT_GREEN = "92";
inline auto BRIGHT_YELLOW = "93";
inline auto BRIGHT_BLUE = "94";
inline auto BRIGHT_MAGENTA = "95";
inline auto BRIGHT_CYAN = "96";
inline auto BRIGHT_WHITE = "97";
inline auto BRIGHT_BLACK_BACKGROUND = "100";
inline auto BRIGHT_RED_BACKGROUND = "101";
inline auto BRIGHT_GREEN_BACKGROUND = "102";
inline auto BRIGHT_YELLOW_BACKGROUND = "103";
inline auto BRIGHT_BLUE_BACKGROUND = "104";
inline auto BRIGHT_MAGENTA_BACKGROUND = "105";
inline auto BRIGHT_CYAN_BACKGROUND = "106";
inline auto BRIGHT_WHITE_BACKGROUND = "107";
template<typename... Args>
inline auto make_color(Args... colors)
{
std::string mode;
((mode += std::string(colors) + ";"), ...);
return ESC("[" + mode.substr(0, mode.size() - 1) + "m");
}
}
enum class log_level
{
// default
NONE,
// low level
TRACE0, TRACE1, TRACE2, TRACE3,
// normal
TRACE, DEBUG, INFO,
// errors
WARN, ERROR, FATAL,
};
struct tag_func_param
{
blt::logging::log_level level;
const std::string& file, line, raw_string, formatted_string;
};
struct tag
{
// tag without the ${{ or }}
std::string tag;
// function to run: log level, file, line, and raw user input string are provided
std::function<std::string(const tag_func_param&)> func;
};
struct log_format
{
/**
* the log output format is the string which will be used to create the log output string
*
* Available tags:
* - ${{YEAR}} // current year
* - ${{MONTH}} // current month
* - ${{DAY}} // current day
* - ${{HOUR}} // current hour
* - ${{MINUTE}} // current minute
* - ${{SECOND}} // current second
* - ${{MS}} // current unix time
* - ${{NS}} // current ns from the high resolution system timer
* - ${{ISO_YEAR}} // ISO formatted 'year-month-day' in a single variable
* - ${{TIME}} // 'hour:minute:second' formatted string in a single variable
* - ${{FULL_TIME}} // 'year-month-day hour:minute:second' in a single variable
* - ${{LF}} // log level color (ANSI color code)
* - ${{ER}} // Error red
* - ${{CNR}} // conditional error red (only outputs if log level is an error!)
* - ${{RC}} // ANSI color reset
* - ${{LOG_LEVEL}} // current log level
* - ${{THREAD_NAME}} // current thread name, NOTE: thread names must be set by calling "setThreadName()" from the thread in question!
* - ${{FILE}} // file from which the macro is invoked
* - ${{LINE}} // line in the from which the macro is invoked
* - ${{RAW_STR}} // raw user string without formatting applied (NOTE: format args are not provided!)
* - ${{STR}} // the user supplied string (format applied!)
*/
std::string logOutputFormat = "\033[94m[${{TIME}}]${{RC}} ${{LF}}[${{LOG_LEVEL}}]${{RC}} \033[35m(${{FILE}}:${{LINE}})${{RC}} ${{CNR}}${{STR}}${{RC}}\n";
std::string levelNames[11] = {"STDOUT", "TRACE0", "TRACE1", "TRACE2", "TRACE3", "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"};
std::string levelColors[11] = {"\033[0m", "\033[22;97m", "\033[97m", "\033[97m", "\033[97m", "\033[97m", "\033[36m", "\033[92m", "\033[93m",
"\033[91m", "\033[97;41m"};
// if true prints the whole path to the file (eg /home/user/.../.../project/src/source.cpp:line#)
bool printFullFileName = false;
// the logging lib will keep track of the largest line found so far and try to keep the spacing accordingly
// this is not thread safe!
bool ensureAlignment = false;
// should we log to file?
bool logToFile = false;
// should we log to console?
bool logToConsole = true;
// where should we log? (empty for current binary directory) should end in a / if not empty!
std::string logFilePath;
// logs to a file called $fileName_$count.log where count is the number of rollover files
// this accepts any of the macros above, using level names and colors should work but isn't supported.
std::string logFileName = "${{ISO_YEAR}}";
// default limit on file size: 10mb;
size_t logMaxFileSize = 1024 * 1024 * 10;
/**
* Variables below this line should never be changed by the user!
*/
// the current alignment width found (you shouldn't chance this variable!)
size_t currentWidth = 0;
// current number of file roll-overs. you shouldn't change this either.
size_t currentRollover = 0;
std::string lastFile;
};
struct logger
{
log_level level;
const char* file;
int line;
};
struct empty_logger
{
};
void log_internal(const std::string& format, log_level level, const char* file, int line, std::va_list& args);
void log_stream_internal(const std::string& str, const logger& logger);
template<typename T>
inline std::string to_string_stream(const T& t)
{
std::stringstream stream;
stream << t;
return stream.str();
}
template<typename T>
inline static void log_stream(const T& t, const logger& logger)
{
if constexpr (std::is_arithmetic_v<T> && !std::is_same_v<T, char>)
{
log_stream_internal(std::to_string(t), logger);
} else if constexpr (std::is_same_v<T, std::string> || std::is_same_v<T, const char*>)
{
log_stream_internal(t, logger);
} else
{
log_stream_internal(to_string_stream(t), logger);
}
}
template<typename T>
inline void log(T t, log_level level, const char* file, int line, ...)
{
std::va_list args;
va_start(args, line);
if constexpr (std::is_arithmetic_v<T>)
{
log_internal(std::to_string(t), level, file, line, args);
} else if constexpr (std::is_same_v<T, std::string>)
{
log_internal(t, level, file, line, args);
} else if constexpr (std::is_same_v<T, const char*>)
{
log_internal(std::string(t), level, file, line, args);
} else
{
log_internal(to_string_stream(t), level, file, line, args);
}
va_end(args);
}
template<typename T>
static inline const blt::logging::logger& operator<<(const blt::logging::logger& out, const T& t)
{
log_stream(t, out);
return out;
}
template<typename T>
static inline const blt::logging::empty_logger& operator<<(const blt::logging::empty_logger& out, const T&)
{
return out;
}
void flush();
void newline();
void setThreadName(const std::string& name);
void setLogFormat(const log_format& format);
void setLogColor(log_level level, const std::string& newFormat);
void setLogName(log_level level, const std::string& newFormat);
void setLogOutputFormat(const std::string& newFormat);
void setLogToFile(bool shouldLogToFile);
void setLogToConsole(bool shouldLogToConsole);
void setLogPath(const std::string& path);
void setLogFileName(const std::string& fileName);
void setMaxFileSize(size_t fileSize);
}
#if defined(__clang__) || defined(__llvm__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
#endif
#ifdef BLT_DISABLE_LOGGING
#define BLT_LOG(format, level, ...)
#define BLT_LOG_STREAM(level)
#define BLT_TRACE0_STREAM
#define BLT_TRACE1_STREAM
#define BLT_TRACE2_STREAM
#define BLT_TRACE3_STREAM
#define BLT_TRACE_STREAM
#define BLT_DEBUG_STREAM
#define BLT_INFO_STREAM
#define BLT_WARN_STREAM
#define BLT_ERROR_STREAM
#define BLT_FATAL_STREAM
#define BLT_TRACE(format, ...)
#define BLT_DEBUG(format, ...)
#define BLT_INFO(format, ...)
#define BLT_WARN(format, ...)
#define BLT_ERROR(format, ...)
#define BLT_FATAL(format, ...)
#else
#define BLT_NEWLINE() blt::logging::newline()
#define BLT_LOG(format, level, ...) blt::logging::log(format, level, __FILE__, __LINE__, ##__VA_ARGS__)
#define BLT_LOG_STREAM(level) blt::logging::logger{level, __FILE__, __LINE__}
#ifdef BLT_DISABLE_TRACE
#define BLT_TRACE(format, ...)
#define BLT_TRACE0_STREAM blt::logging::empty_logger{}
#define BLT_TRACE1_STREAM blt::logging::empty_logger{}
#define BLT_TRACE2_STREAM blt::logging::empty_logger{}
#define BLT_TRACE3_STREAM blt::logging::empty_logger{}
#define BLT_TRACE_STREAM blt::logging::empty_logger{}
#else
#define BLT_TRACE(format, ...) BLT_LOG(format, blt::logging::log_level::TRACE, ##__VA_ARGS__)
#define BLT_TRACE0_STREAM BLT_LOG_STREAM(blt::logging::log_level::TRACE0)
#define BLT_TRACE1_STREAM BLT_LOG_STREAM(blt::logging::log_level::TRACE1)
#define BLT_TRACE2_STREAM BLT_LOG_STREAM(blt::logging::log_level::TRACE2)
#define BLT_TRACE3_STREAM BLT_LOG_STREAM(blt::logging::log_level::TRACE3)
#define BLT_TRACE_STREAM BLT_LOG_STREAM(blt::logging::log_level::TRACE)
#endif
#ifdef BLT_DISABLE_DEBUG
#define BLT_DEBUG(format, ...)
#define BLT_DEBUG_STREAM blt::logging::empty_logger{}
#else
#define BLT_DEBUG(format, ...) BLT_LOG(format, blt::logging::log_level::DEBUG, ##__VA_ARGS__)
#define BLT_DEBUG_STREAM BLT_LOG_STREAM(blt::logging::log_level::DEBUG)
#endif
#ifdef BLT_DISABLE_INFO
#define BLT_INFO(format, ...)
#define BLT_INFO_STREAM blt::logging::empty_logger{}
#else
#define BLT_INFO(format, ...) BLT_LOG(format, blt::logging::log_level::INFO, ##__VA_ARGS__)
#define BLT_INFO_STREAM BLT_LOG_STREAM(blt::logging::log_level::INFO)
#endif
#ifdef BLT_DISABLE_WARN
#define BLT_WARN(format, ...)
#define BLT_WARN_STREAM blt::logging::empty_logger{}
#else
#define BLT_WARN(format, ...) BLT_LOG(format, blt::logging::log_level::WARN, ##__VA_ARGS__)
#define BLT_WARN_STREAM BLT_LOG_STREAM(blt::logging::log_level::WARN)
#endif
#ifdef BLT_DISABLE_ERROR
#define BLT_ERROR(format, ...)
#define BLT_ERROR_STREAM blt::logging::empty_logger{}
#else
#define BLT_ERROR(format, ...) BLT_LOG(format, blt::logging::log_level::ERROR, ##__VA_ARGS__)
#define BLT_ERROR_STREAM BLT_LOG_STREAM(blt::logging::log_level::ERROR)
#endif
#ifdef BLT_DISABLE_FATAL
#define BLT_FATAL(format, ...)
#define BLT_FATAL_STREAM blt::logging::empty_logger{}
#else
#define BLT_FATAL(format, ...) BLT_LOG(format, blt::logging::log_level::FATAL, ##__VA_ARGS__)
#define BLT_FATAL_STREAM BLT_LOG_STREAM(blt::logging::log_level::FATAL)
#endif
#endif
#if defined(__clang__) || defined(__llvm__)
#pragma clang diagnostic pop
#endif
#endif //BLT_TESTS_LOGGING2_H

View File

@ -19,9 +19,11 @@
#ifndef BLT_MMAP_H
#define BLT_MMAP_H
#include <blt/std/logging.h>
#include <blt/std/types.h>
#include <cstdlib>
#include <exception>
#include <string>
#include <string_view>
// size of 2mb in bytes
inline constexpr blt::size_t BLT_2MB_SIZE = 2048 * 1024;
@ -41,7 +43,7 @@ namespace blt
public:
bad_alloc_t() = default;
explicit bad_alloc_t(std::string_view str): str(str)
explicit bad_alloc_t(const std::string_view str): str(str)
{}
explicit bad_alloc_t(std::string str): str(std::move(str))

View File

@ -6,7 +6,7 @@
#include <blt/format/format.h>
#include <blt/std/string.h>
#include <cmath>
#include "blt/std/logging.h"
#include "blt/logging/logging.h"
#include "blt/std/assert.h"
#include "blt/std/utility.h"
#include <stack>

View File

@ -17,5 +17,4 @@
*/
#include <blt/fs/filesystem.h>
#include <cstring>
#include <blt/std/logging.h>

View File

@ -4,7 +4,7 @@
* See LICENSE file for license detail
*/
#include <blt/fs/nbt.h>
#include <blt/std/logging.h>
#include <blt/logging/logging.h>
#include <cassert>
#include <type_traits>

View File

@ -20,7 +20,7 @@
#include <blt/parse/argparse_v2.h>
#include <blt/std/assert.h>
#include <blt/meta/type_traits.h>
#include <blt/std/logging.h>
#include <blt/logging/logging.h>
#include <blt/iterator/enumerate.h>
#include <blt/fs/path_helper.h>
#include <blt/std/string.h>

View File

@ -26,7 +26,7 @@
#include <charconv>
#include "blt/std/assert.h"
#include "blt/std/utility.h"
#include <blt/std/logging.h>
#include <blt/logging/logging.h>
namespace blt::parse
{
@ -101,24 +101,23 @@ namespace blt::parse
return;
}
auto elements = blt::string::split(std::string(tokenizer.read_fully()), " ");
auto elements = string::split(tokenizer.read_fully(), " ");
BLT_ASSERT(elements.size() >= 2 && "Current line doesn't have enough arguments to process!");
float x = get(elements[0]), y = get(elements[1]);
BLT_DEBUG_STREAM << "Loaded value of (" << x << ", " << y << ")";
BLT_DEBUG("Loaded value of ({}, {})", x, y);
if (elements.size() < 3)
{
if (type == 't')
uvs.push_back(uv_t{x, y});
else
BLT_ERROR("Unable to parse line '%s' type '%c' not recognized for arg count", std::string(tokenizer.read_fully()).c_str(), type);
BLT_ERROR("Unable to parse line '{}' type '{:c}' not recognized for arg count", tokenizer.read_fully(), type);
} else
{
float z = get(elements[2]);
BLT_DEBUG_STREAM << " with z: " << z;
BLT_DEBUG(" with z: {}", z);
if (!handle_vertex_and_normals(x, y, z, type))
BLT_ERROR("Unable to parse line '%s' type '%c' not recognized", std::string(tokenizer.read_fully()).c_str(), type);
BLT_ERROR("Unable to parse line '{}' type '{:c}' not recognized", tokenizer.read_fully(), type);
}
BLT_DEBUG_STREAM << "\n";
}
bool obj_loader::handle_vertex_and_normals(float x, float y, float z, char type)

View File

@ -18,7 +18,7 @@
#include <blt/parse/templating.h>
#include <blt/std/string.h>
#include <cctype>
#include "blt/std/logging.h"
#include "blt/logging/logging.h"
namespace blt
{

View File

@ -7,7 +7,7 @@
#include <mutex>
#include <vector>
#include <blt/std/time.h>
#include <blt/std/logging.h>
#include <blt/logging/logging.h>
#include <iostream>
#include <algorithm>
#include <blt/format/format.h>
@ -32,9 +32,9 @@ 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, const logging::log_level_t level) {
for (const auto& line : lines)
BLT_LOG_STREAM(level) << line << "\n";
BLT_LOG(level, "{}", line);
// auto& logger = logging::getLoggerFromLevel(level);
// for (const auto& line : lines)
// logger << line << "\n";
@ -108,7 +108,7 @@ namespace blt::profiling {
}
void printProfile(
const std::string& profileName, logging::log_level loggingLevel, bool averageHistory
const std::string& profileName, const logging::log_level_t loggingLevel, const bool averageHistory
) {
auto& profile = profiles[profileName];
const auto& intervals = profile.intervals;

View File

@ -187,11 +187,11 @@ namespace blt
stream << line << "\n";
}
void printProfile(profile_t& profiler, const std::uint32_t flags, sort_by sort, blt::logging::log_level log_level)
void printProfile(profile_t& profiler, const std::uint32_t flags, sort_by sort, blt::logging::log_level_t log_level)
{
std::stringstream stream;
writeProfile(stream, profiler, flags, sort);
BLT_LOG_STREAM(log_level) << stream.str();
BLT_LOG(log_level, "{}", stream.str());
}
profile_t::~profile_t()
@ -237,7 +237,7 @@ namespace blt
profiles.erase(profile_name);
}
void _internal::printProfile(const std::string& profile_name, std::uint32_t flags, sort_by sort, blt::logging::log_level log_level)
void _internal::printProfile(const std::string& profile_name, std::uint32_t flags, sort_by sort, blt::logging::log_level_t log_level)
{
if (profiles.find(profile_name) == profiles.end())
return;

View File

@ -3,15 +3,15 @@
* Licensed under GNU General Public License V3.0
* See LICENSE file for license detail
*/
#include <blt/std/assert.h>
#include <blt/std/utility.h>
#include <blt/std/logging.h>
#include <blt/std/string.h>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <exception>
#include <cstring>
#include <exception>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <blt/logging/logging.h>
#include <blt/std/assert.h>
#include <blt/std/string.h>
#include <blt/std/utility.h>
struct abort_exception final : public std::exception
{
@ -48,8 +48,8 @@ struct abort_exception final : public std::exception
#ifdef IS_GNU_BACKTRACE
#include <execinfo.h>
#include <cstdlib>
#include <execinfo.h>
#endif

View File

@ -15,68 +15,52 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <blt/std/error.h>
#include <blt/std/logging.h>
#include <blt/logging/logging.h>
namespace blt::error
{
void print_socket_error()
{
switch (errno)
{
case EINVAL:
BLT_WARN("Invalid argument");
break;
case EACCES:
BLT_WARN("Permission denied");
break;
case EPERM:
BLT_WARN("Operation not permitted");
break;
case EADDRINUSE:
BLT_WARN("Address already in use");
break;
case EADDRNOTAVAIL:
BLT_WARN("Cannot copy_fast requested address");
break;
case EAFNOSUPPORT:
BLT_WARN("Address family not supported by protocol");
break;
case EAGAIN:
BLT_WARN("Try again");
break;
case EALREADY:
BLT_WARN("Operation already in progress");
break;
case EBADF:
BLT_WARN("Bad file number");
break;
case ECONNREFUSED:
BLT_WARN("Connection refused");
break;
case EFAULT:
BLT_WARN("Bad address");
break;
case EINPROGRESS:
BLT_WARN("Operation now in progress");
break;
case EINTR:
BLT_WARN("Interrupted system call");
break;
case EISCONN:
BLT_WARN("Transport endpoint is already connected");
break;
case ENETUNREACH:
BLT_WARN("Network is unreachable");
break;
case ENOTSOCK:
BLT_WARN("Socket operation_t on non-socket");
break;
case EPROTOTYPE:
BLT_WARN("Protocol wrong type for socket");
break;
case ETIMEDOUT:
BLT_WARN("Connection timed out");
break;
}
}
}
void print_socket_error()
{
switch (errno)
{
case EINVAL: BLT_WARN("Invalid argument");
break;
case EACCES: BLT_WARN("Permission denied");
break;
case EPERM: BLT_WARN("Operation not permitted");
break;
case EADDRINUSE: BLT_WARN("Address already in use");
break;
case EADDRNOTAVAIL: BLT_WARN("Cannot copy_fast requested address");
break;
case EAFNOSUPPORT: BLT_WARN("Address family not supported by protocol");
break;
case EAGAIN: BLT_WARN("Try again");
break;
case EALREADY: BLT_WARN("Operation already in progress");
break;
case EBADF: BLT_WARN("Bad file number");
break;
case ECONNREFUSED: BLT_WARN("Connection refused");
break;
case EFAULT: BLT_WARN("Bad address");
break;
case EINPROGRESS: BLT_WARN("Operation now in progress");
break;
case EINTR: BLT_WARN("Interrupted system call");
break;
case EISCONN: BLT_WARN("Transport endpoint is already connected");
break;
case ENETUNREACH: BLT_WARN("Network is unreachable");
break;
case ENOTSOCK: BLT_WARN("Socket operation_t on non-socket");
break;
case EPROTOTYPE: BLT_WARN("Protocol wrong type for socket");
break;
case ETIMEDOUT: BLT_WARN("Connection timed out");
break;
default:
break;
}
}
}

View File

@ -1,627 +0,0 @@
/*
* Created by Brett on 20/07/23.
* Licensed under GNU General Public License V3.0
* See LICENSE file for license detail
*/
#include <blt/std/logging.h>
#include <iostream>
#include <chrono>
#include <ctime>
#include <unordered_map>
#include <thread>
#include <cstdarg>
#include <iostream>
#include <vector>
#if defined(CXX17_FILESYSTEM) || defined (CXX17_FILESYSTEM_LIBFS)
#include <filesystem>
#elif defined(CXX11_EXP_FILESYSTEM) || defined (CXX11_EXP_FILESYSTEM_LIBFS)
#include <experimental/filesystem>
#else
#include <filesystem>
#endif
#include <ios>
#include <fstream>
template <typename K, typename V>
using hashmap = std::unordered_map<K, V>;
namespace blt::logging
{
/**
* Used to store fast associations between built in tags and their respective values
*/
class tag_map
{
private:
tag* tags;
size_t size;
[[nodiscard]] static inline size_t hash(const tag& t)
{
size_t h = t.tag[1] * 3 - t.tag[0];
return h - 100;
}
// TODO: fix
void expand()
{
auto newSize = size * 2;
auto newTags = new tag[newSize];
for (size_t i = 0; i < size; i++)
newTags[i] = tags[i];
delete[] tags;
tags = newTags;
size = newSize;
}
public:
tag_map(std::initializer_list<tag> initial_tags)
{
size_t max = 0;
for (const auto& t : initial_tags)
max = std::max(max, hash(t));
tags = new tag[(size = max + 1)];
for (const auto& t : initial_tags)
insert(t);
}
tag_map(const tag_map& copy)
{
tags = new tag[(size = copy.size)];
for (size_t i = 0; i < size; i++)
tags[i] = copy.tags[i];
}
void insert(const tag& t)
{
auto h = hash(t);
//if (h > size)
// expand();
if (!tags[h].tag.empty())
std::cerr << "Tag not empty! " << tags[h].tag << "!!!\n";
tags[h] = t;
}
tag& operator[](const std::string& name) const
{
auto h = hash(tag{name, nullptr});
if (h > size)
std::cerr << "Tag out of bounds";
return tags[h];
}
~tag_map()
{
delete[] tags;
tags = nullptr;
}
};
class LogFileWriter
{
private:
std::string m_path;
std::fstream* output = nullptr;
public:
explicit LogFileWriter() = default;
void writeLine(const std::string& path, const std::string& line)
{
if (path != m_path || output == nullptr)
{
clear();
delete output;
output = new std::fstream(path, std::ios::out | std::ios::app);
if (!output->good())
{
throw std::runtime_error("Unable to open console filestream!\n");
}
}
if (!output->good())
{
std::cerr << "There has been an error in the logging file stream!\n";
output->clear();
}
*output << line;
}
void clear()
{
if (output != nullptr)
{
try
{
output->flush();
output->close();
}
catch (std::exception& e)
{
std::cerr << e.what() << "\n";
}
}
}
~LogFileWriter()
{
clear();
delete(output);
}
};
#ifdef WIN32
#define BLT_NOW() auto t = std::time(nullptr); tm now{}; localtime_s(&now, &t)
#else
#define BLT_NOW() auto t = std::time(nullptr); auto now_ptr = std::localtime(&t); auto& now = *now_ptr
#endif
//#define BLT_NOW() auto t = std::time(nullptr); tm now; localtime_s(&now, &t); //auto now = std::localtime(&t)
#define BLT_ISO_YEAR(S) auto S = std::to_string(now.tm_year + 1900); \
S += '-'; \
S += ensureHasDigits(now.tm_mon+1, 2); \
S += '-'; \
S += ensureHasDigits(now.tm_mday, 2);
#define BLT_CUR_TIME(S) auto S = ensureHasDigits(now.tm_hour, 2); \
S += ':'; \
S += ensureHasDigits(now.tm_min, 2); \
S += ':'; \
S += ensureHasDigits(now.tm_sec, 2);
static inline std::string ensureHasDigits(int current, int digits)
{
std::string asString = std::to_string(current);
auto length = digits - asString.length();
if (length <= 0)
return asString;
std::string zeros;
zeros.reserve(length);
for (unsigned int i = 0; i < length; i++)
{
zeros += '0';
}
return zeros + asString;
}
log_format loggingFormat{};
hashmap<std::thread::id, std::string> loggingThreadNames;
hashmap<std::thread::id, hashmap<blt::logging::log_level, std::string>> loggingStreamLines;
LogFileWriter writer;
const std::unique_ptr<tag_map> tagMap = std::make_unique<tag_map>(tag_map{
{
"YEAR", [](const tag_func_param&) -> std::string
{
BLT_NOW();
return std::to_string(now.tm_year);
}
},
{
"MONTH", [](const tag_func_param&) -> std::string
{
BLT_NOW();
return ensureHasDigits(now.tm_mon + 1, 2);
}
},
{
"DAY", [](const tag_func_param&) -> std::string
{
BLT_NOW();
return ensureHasDigits(now.tm_mday, 2);
}
},
{
"HOUR", [](const tag_func_param&) -> std::string
{
BLT_NOW();
return ensureHasDigits(now.tm_hour, 2);
}
},
{
"MINUTE", [](const tag_func_param&) -> std::string
{
BLT_NOW();
return ensureHasDigits(now.tm_min, 2);
}
},
{
"SECOND", [](const tag_func_param&) -> std::string
{
BLT_NOW();
return ensureHasDigits(now.tm_sec, 2);
}
},
{
"MS", [](const tag_func_param&) -> std::string
{
return std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::high_resolution_clock::now().time_since_epoch()).count()
);
}
},
{
"NS", [](const tag_func_param&) -> std::string
{
return std::to_string(std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::high_resolution_clock::now().time_since_epoch()).count()
);
}
},
{
"ISO_YEAR", [](const tag_func_param&) -> std::string
{
BLT_NOW();
BLT_ISO_YEAR(returnStr);
return returnStr;
}
},
{
"TIME", [](const tag_func_param&) -> std::string
{
BLT_NOW();
BLT_CUR_TIME(returnStr);
return returnStr;
}
},
{
"FULL_TIME", [](const tag_func_param&) -> std::string
{
BLT_NOW();
BLT_ISO_YEAR(ISO);
BLT_CUR_TIME(TIME);
ISO += ' ';
ISO += TIME;
return ISO;
}
},
{
"LF", [](const tag_func_param& f) -> std::string
{
return loggingFormat.levelColors[(int)f.level];
}
},
{
"ER", [](const tag_func_param&) -> std::string
{
return loggingFormat.levelColors[(int)log_level::ERROR];
}
},
{
"CNR", [](const tag_func_param& f) -> std::string
{
return f.level >= log_level::ERROR ? loggingFormat.levelColors[(int)log_level::ERROR] : "";
}
},
{
"RC", [](const tag_func_param&) -> std::string
{
return "\033[0m";
}
},
{
"LOG_LEVEL", [](const tag_func_param& f) -> std::string
{
return loggingFormat.levelNames[(int)f.level];
}
},
{
"THREAD_NAME", [](const tag_func_param&) -> std::string
{
if (loggingThreadNames.find(std::this_thread::get_id()) == loggingThreadNames.end())
return "UNKNOWN";
return loggingThreadNames[std::this_thread::get_id()];
}
},
{
"FILE", [](const tag_func_param& f) -> std::string
{
return f.file;
}
},
{
"LINE", [](const tag_func_param& f) -> std::string
{
return f.line;
}
},
{
"RAW_STR", [](const tag_func_param& f) -> std::string
{
return f.raw_string;
}
},
{
"STR", [](const tag_func_param& f) -> std::string
{
return f.formatted_string;
}
}
});
static inline std::vector<std::string> split(std::string s, const std::string& delim)
{
size_t pos = 0;
std::vector<std::string> tokens;
while ((pos = s.find(delim)) != std::string::npos)
{
auto token = s.substr(0, pos);
tokens.push_back(token);
s.erase(0, pos + delim.length());
}
tokens.push_back(s);
return tokens;
}
inline std::string filename(const std::string& path)
{
if (loggingFormat.printFullFileName)
return path;
auto paths = split(path, "/");
auto final = paths[paths.size() - 1];
if (final == "/")
return paths[paths.size() - 2];
return final;
}
class string_parser
{
private:
std::string _str;
size_t _pos;
public:
explicit string_parser(std::string str): _str(std::move(str)), _pos(0)
{
}
inline char next()
{
return _str[_pos++];
}
[[nodiscard]] inline bool has_next() const
{
return _pos < _str.size();
}
};
std::string stripANSI(const std::string& str)
{
string_parser parser(str);
std::string out;
while (parser.has_next())
{
char c = parser.next();
if (c == '\033')
{
while (parser.has_next() && parser.next() != 'm');
}
else
out += c;
}
return out;
}
void applyCFormatting(const std::string& format, std::string& output, std::va_list& args)
{
// args must be copied because they will be consumed by the first vsnprintf
va_list args_copy;
va_copy(args_copy, args);
auto buffer_size = std::vsnprintf(nullptr, 0, format.c_str(), args_copy) + 1;
auto* buffer = new char[static_cast<unsigned long>(buffer_size)];
vsnprintf(buffer, buffer_size, format.c_str(), args);
output = std::string(buffer);
delete[] buffer;
va_end(args_copy);
}
/**
* Checks if the next character in the parser is a tag opening, if not output the buffer to the out string
*/
inline bool tagOpening(string_parser& parser, std::string& out)
{
char c = ' ';
if (parser.has_next() && (c = parser.next()) == '{')
if (parser.has_next() && (c = parser.next()) == '{')
return true;
else
out += c;
else
out += c;
return false;
}
void parseString(string_parser& parser, std::string& out, const std::string& userStr, log_level level, const char* file, int line)
{
while (parser.has_next())
{
char c = parser.next();
std::string nonTag;
if (c == '$' && tagOpening(parser, nonTag))
{
std::string tag;
while (parser.has_next())
{
c = parser.next();
if (c == '}')
break;
tag += c;
}
c = parser.next();
if (parser.has_next() && c != '}')
{
std::cerr << "Error processing tag, is not closed with two '}'!\n";
break;
}
if (loggingFormat.ensureAlignment && tag == "STR")
{
auto currentOutputWidth = out.size();
auto& longestWidth = loggingFormat.currentWidth;
longestWidth = std::max(longestWidth, currentOutputWidth);
// pad with spaces
if (currentOutputWidth != longestWidth)
{
for (size_t i = currentOutputWidth; i < longestWidth; i++)
out += ' ';
}
}
tag_func_param param{
level, filename({file}), std::to_string(line), userStr, userStr
};
out += (*tagMap)[tag].func(param);
}
else
{
out += c;
out += nonTag;
}
}
}
std::string applyFormatString(const std::string& str, log_level level, const char* file, int line)
{
// this can be speedup by preprocessing the string into an easily callable class
// where all the variables are ready to be substituted in one step
// and all static information already entered
string_parser parser(loggingFormat.logOutputFormat);
std::string out;
parseString(parser, out, str, level, file, line);
return out;
}
void log_internal(const std::string& format, log_level level, const char* file, int line, std::va_list& args)
{
std::string withoutLn = format;
auto len = withoutLn.length();
if (len > 0 && withoutLn[len - 1] == '\n')
withoutLn = withoutLn.substr(0, len - 1);
std::string out;
applyCFormatting(withoutLn, out, args);
if (level == log_level::NONE)
{
std::cout << out << std::endl;
return;
}
std::string finalFormattedOutput = applyFormatString(out, level, file, line);
if (loggingFormat.logToConsole)
std::cout << finalFormattedOutput;
if (loggingFormat.logToFile)
{
string_parser parser(loggingFormat.logFileName);
std::string fileName;
parseString(parser, fileName, withoutLn, level, file, line);
auto path = loggingFormat.logFilePath;
if (!path.empty() && path[path.length() - 1] != '/')
path += '/';
// if the file has changed (new day in default case) we should reset the rollover count
if (loggingFormat.lastFile != fileName)
{
loggingFormat.currentRollover = 0;
loggingFormat.lastFile = fileName;
}
path += fileName;
path += '-';
path += std::to_string(loggingFormat.currentRollover);
path += ".log";
if (std::filesystem::exists(path))
{
auto fileSize = std::filesystem::file_size(path);
// will start on next file
if (fileSize > loggingFormat.logMaxFileSize)
loggingFormat.currentRollover++;
}
writer.writeLine(path, stripANSI(finalFormattedOutput));
}
//std::cout.flush();
}
void log_stream_internal(const std::string& str, const logger& logger)
{
auto& s = loggingStreamLines[std::this_thread::get_id()][logger.level];
// s += str;
for (char c : str)
{
s += c;
if (c == '\n')
{
log(s, logger.level, logger.file, logger.line);
s = "";
}
}
}
void setThreadName(const std::string& name)
{
loggingThreadNames[std::this_thread::get_id()] = name;
}
void setLogFormat(const log_format& format)
{
loggingFormat = format;
}
void setLogColor(log_level level, const std::string& newFormat)
{
loggingFormat.levelColors[(int)level] = newFormat;
}
void setLogName(log_level level, const std::string& newFormat)
{
loggingFormat.levelNames[(int)level] = newFormat;
}
void setLogOutputFormat(const std::string& newFormat)
{
loggingFormat.logOutputFormat = newFormat;
}
void setLogToFile(bool shouldLogToFile)
{
loggingFormat.logToFile = shouldLogToFile;
}
void setLogToConsole(bool shouldLogToConsole)
{
loggingFormat.logToConsole = shouldLogToConsole;
}
void setLogPath(const std::string& path)
{
loggingFormat.logFilePath = path;
}
void setLogFileName(const std::string& fileName)
{
loggingFormat.logFileName = fileName;
}
void setMaxFileSize(const size_t fileSize)
{
loggingFormat.logMaxFileSize = fileSize;
}
void flush()
{
std::cerr.flush();
std::cout.flush();
}
}

View File

@ -15,6 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <blt/logging/logging.h>
#include <blt/std/mmap.h>
#ifdef __unix__
@ -112,7 +113,7 @@ namespace blt
#ifdef __unix__
if (munmap(ptr, bytes))
{
BLT_ERROR_STREAM << "Failed to deallocate\n";
BLT_ERROR("Failed to deallocate");
throw bad_alloc_t(handle_mmap_error());
}
#else

View File

@ -16,7 +16,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <blt/std/simd.h>
#include <blt/std/logging.h>
namespace blt
{

View File

@ -4,7 +4,7 @@
* See LICENSE file for license detail
*/
#include <blt/std/system.h>
#include <blt/std/logging.h>
#include <blt/logging/logging.h>
#if !defined(_MSC_VER) && !defined(WIN32)
#include <sys/time.h> /* for struct timeval */