35 Commits

Author SHA1 Message Date
e553c74ade Cleanup 2024-07-01 14:48:56 -04:00
9d36f07717 Beating Windows and MSVC further into submission. 2024-07-01 14:28:18 -04:00
47caaba587 Forcing abstraction to work with windows and beating windows into submission to work like a good boy 2024-07-01 14:05:12 -04:00
f2651b58df FIx bug causing std::max to be an error in j3ml QuaternionTests 2024-06-28 18:19:22 -04:00
83df783e7c Unfortunate regression to get Windows ColorCodes working again. Will clean up shortly. (Test On Linux Also) 2024-06-28 14:45:04 -04:00
99c1fe9f4c Color output currently broken, see notes. 2024-06-28 14:09:31 -04:00
e0355d2a32 Merge remote-tracking branch 'origin/main' 2024-06-28 13:57:42 -04:00
8e0d99ce75 forgot semiclon 2024-06-28 13:57:42 -04:00
2394f51240 Fix syntax error 2024-06-28 13:57:27 -04:00
e83dd27d31 Made logger more platform agnostic. Hopefully supporting Windows properly for the message formatter functions. 2024-06-28 13:54:11 -04:00
623b9efc26 Accreditations 2024-06-28 13:16:25 -04:00
f74b97ac11 const-ref tokens in loop since they aren't modified here 2024-06-28 13:09:26 -04:00
abb9eed60f use std::function signature in argument? 2024-06-28 13:06:43 -04:00
5675480499 Merge remote-tracking branch 'origin/main' 2024-06-28 12:59:15 -04:00
3e414abc8d Implemented ability to specify custom logfile globally and per-function. Wrote helper functions to make writing custom loggers easier. Still need to work on the windows side of things, but that should be easy. 2024-06-28 12:59:07 -04:00
69ef213d85 More documentation 2024-06-28 12:57:33 -04:00
22e75476f3 Remove several now-unused functions 2024-06-28 12:30:04 -04:00
e5d8ea5faa Removed unused include "format" 2024-06-28 09:43:31 -04:00
e870007004 Beginning documentation effort. 2024-06-27 15:09:10 -04:00
4138b45404 Implement basic capability to log to specified file. 2024-06-27 14:57:14 -04:00
f0ccdf00c0 consolidate as much as possible 2024-06-26 21:19:04 -04:00
Redacted
9f0ccef302 Refactor to abstract platform-specific colorcodes away from the higher-level API 2024-06-26 19:17:12 -04:00
c5d3f7dc82 Updated README.md 2024-06-19 11:26:53 -04:00
aaa7318672 Merge remote-tracking branch 'origin/main' 2024-06-19 11:25:01 -04:00
95f2c761c7 Rewritten most functionality to be more generic and flexible. Cleaned up code as well. Implemented formatter system for easier wrapping. Made it easier for custom loggers to be built from jlog generics and primitives. Removed unused ultra short and short loggers to remove clutter. 2024-06-19 11:23:57 -04:00
Redacted
16d1eaa1ee Update README.md 2024-06-18 21:49:22 -04:00
Redacted
80d9bcd240 Update include/jlog/jlog.hpp
Fix definition clash when using in multiple projects.
2024-06-18 14:40:31 -04:00
2799c918b8 Implemented log level handling/switching. Use LOGLEVEL macro for setting level/severity. See jlog::severity in jlog.hpp for more information. 2024-06-18 12:11:41 -04:00
a86e70a055 Merge remote-tracking branch 'origin/main' 2024-06-18 11:10:20 -04:00
3cf70f5f4f removed todo from README 2024-06-18 11:10:13 -04:00
3a28d4e43b Update ansi_escape_codes.hpp
Fix problem that'd sometimes cause errors when using the macros in a lot of different files.
2024-06-18 00:44:07 -04:00
e5cfd25fcc Merge remote-tracking branch 'origin/main' 2024-06-17 13:51:29 -04:00
b0793828f6 Try to make dependency private 2024-06-17 13:51:18 -04:00
4b512df77a Windows color codes. 2024-06-16 18:52:05 -04:00
eb21b8a81f Windows 2024-06-16 11:07:24 -07:00
8 changed files with 527 additions and 459 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/cmake-build-debug
/.idea

View File

@@ -14,9 +14,10 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(cmake/CPM.cmake) include(cmake/CPM.cmake)
file(GLOB_RECURSE jlog_HEADERS "include/jlog/*.h" "include/jlog/*.hpp") file(GLOB_RECURSE jlog_HEADERS "include/jlog/*.h" "include/jlog/*.hpp")
file(GLOB_RECURSE jlog_SRC "src/jlog/*.c" "src/jlog/*.cpp")
file(GLOB_RECURSE jlog_SRC "src/jlog/*.cpp")
include_directories("include") include_directories("include")
@@ -33,6 +34,7 @@ endif()
if (WIN32) if (WIN32)
add_library(jlog STATIC ${jlog_SRC}) add_library(jlog STATIC ${jlog_SRC})
target_compile_options(jlog PRIVATE /wd4005)
endif() endif()
set_target_properties(jlog PROPERTIES LINKER_LANGUAGE CXX) set_target_properties(jlog PROPERTIES LINKER_LANGUAGE CXX)
@@ -42,7 +44,7 @@ install(FILES ${jlog_HEADERS} DESTINATION include/${PROJECT_NAME})
#add_subdirectory(tests) #add_subdirectory(tests)
target_link_libraries(jlog PUBLIC Event) target_link_libraries(jlog PRIVATE Event)
add_executable(LoggerDemo main.cpp) add_executable(LoggerDemo main.cpp)
target_link_libraries(LoggerDemo PUBLIC ${PROJECT_NAME}) target_link_libraries(LoggerDemo PUBLIC jlog)

View File

@@ -11,16 +11,16 @@ jlog is a C++ library for logging to file, console, and event callbacks.
* Color Output * Color Output
* Logs to file AND console! * Logs to file AND console!
* Idiomatic Event callback for hooking into your game engine gui! * Idiomatic Event callback for hooking into your game engine gui!
* GCC and MSVC support
## Installation ## Installation
Include this repository as a CPM dependency, and link against the library. Include this repository as a CPM dependency, and link against the library.
(TODO: Show the relevant CMake script lines.)
```cmake ```cmake
CPMAddPackage( CPMAddPackage(
NAME jlog NAME jlog
URL https://git.redacted.cc/josh/jlog/archive/Prerelease-2.zip URL https://git.redacted.cc/josh/jlog/archive/Prerelease-7.zip
) )
# ... # ...
include_directories(${jlog_SOURCE_DIR}/include) include_directories(${jlog_SOURCE_DIR}/include)
@@ -30,6 +30,7 @@ target_link_libraries(YourProgram ... jlog)
``` ```
# Usage
Using jlog is straightforward: Using jlog is straightforward:
```cpp ```cpp
@@ -37,6 +38,8 @@ Using jlog is straightforward:
#include <jlog.h> #include <jlog.h>
int main() { int main() {
LOGLEVEL(jlog::severity::debug); // <- see jlog::severity for full list of log levels
INFO("This is barely useful information."); INFO("This is barely useful information.");
DEBUG("Debugging Information"); DEBUG("Debugging Information");
VERBOSE("Yadda Yadda Yadda"); VERBOSE("Yadda Yadda Yadda");
@@ -57,12 +60,10 @@ int main() {
* Custom Contexts: Allow users to specify custom logging contexts for better organization. * Custom Contexts: Allow users to specify custom logging contexts for better organization.
* Disable & sort by context (other categories?) * Disable & sort by context (other categories?)
* Custom Formats: Add support for custom log message formats.
* Documentation * Documentation
* Thread Safety * Thread Safety
* Memory Safety * Memory Safety
* Stream Support * Stream Support
* Identify File, Line, Function name via macros (I hate macros!!!)
## License ## License

View File

@@ -4,106 +4,105 @@
#include <cstdint> #include <cstdint>
#include <format> #include <format>
#define ESC "\033["
namespace jlog::ansi_escape_codes namespace jlog::ansi_escape_codes
{ {
static const std::string CURSOR_HOME = "\033[H"; inline static const std::string CURSOR_HOME = "\033[H";
static const std::string ERASE_SCREEN_AFTER_CURSOR = "\033[0J"; inline static const std::string ERASE_SCREEN_AFTER_CURSOR = "\033[0J";
static const std::string ERASE_SCREEN_BEFORE_CURSOR = "\033[1J"; inline static const std::string ERASE_SCREEN_BEFORE_CURSOR = "\033[1J";
static const std::string ERASE_SCREEN_ALL = "\033[2J"; inline static const std::string ERASE_SCREEN_ALL = "\033[2J";
static const std::string ERASE_LINE_AFTER_CURSOR = "\033[0K"; inline static const std::string ERASE_LINE_AFTER_CURSOR = "\033[0K";
static const std::string ERASE_LINE_BEFORE_CURSOR = "\033[1K"; inline static const std::string ERASE_LINE_BEFORE_CURSOR = "\033[1K";
static const std::string ERASE_LINE_ALL = "\033[2K"; inline static const std::string ERASE_LINE_ALL = "\033[2K";
static const std::string RESET = "\033[0m"; inline static const std::string RESET = "\033[0m";
static const std::string BOLD = "\033[1m"; inline static const std::string BOLD = "\033[1m";
static const std::string DIM = "\033[2m"; inline static const std::string DIM = "\033[2m";
/// These are some examples of private modes, which are not defined by the spec, but are implemented in most terminals. /// These are some examples of private modes, which are not defined by the spec, but are implemented in most terminals.
/// @see xterm control sequences for a more in-depth list. /// @see xterm control sequences for a more in-depth list.
/// https://invisible-island.net/xterm/ctlseqs/ctlseqs.html /// https://invisible-island.net/xterm/ctlseqs/ctlseqs.html
/// @note While these modes may be supported by most terminals, some may not work in multiplexers like tmux. /// @note While these modes may be supported by most terminals, some may not work in multiplexers like tmux.
static const std::string CURSOR_INVISIBLE = "\033[?25l"; inline static const std::string CURSOR_INVISIBLE = "\033[?25l";
static const std::string CURSOR_VISIBLE = "\033[?25h"; inline static const std::string CURSOR_VISIBLE = "\033[?25h";
static const std::string RESTORE_SCREEN = "\033[?47l"; inline static const std::string RESTORE_SCREEN = "\033[?47l";
static const std::string SAVE_SCREEN = "\033[?47h"; inline static const std::string SAVE_SCREEN = "\033[?47h";
static const std::string FG_BLACK = "\033[30m"; inline static const std::string FG_BLACK = "\033[30m";
static const std::string FG_RED = "\033[31m"; inline static const std::string FG_RED = "\033[31m";
static const std::string FG_GREEN = "\033[32m"; inline static const std::string FG_GREEN = "\033[32m";
static const std::string FG_YELLOW = "\033[33m"; inline static const std::string FG_YELLOW = "\033[33m";
static const std::string FG_BLUE = "\033[34m"; inline static const std::string FG_BLUE = "\033[34m";
static const std::string FG_MAGENTA = "\033[35m"; inline static const std::string FG_MAGENTA = "\033[35m";
static const std::string FG_CYAN = "\033[36m"; inline static const std::string FG_CYAN = "\033[36m";
static const std::string FG_WHITE = "\033[37m"; inline static const std::string FG_WHITE = "\033[37m";
static const std::string FG_DEFAULT = "\033[39m"; inline static const std::string FG_DEFAULT = "\033[39m";
static const std::string FG_BRIGHT_BLACK = "\033[90m"; inline static const std::string FG_BRIGHT_BLACK = "\033[90m";
static const std::string FG_BRIGHT_RED = "\033[91m"; inline static const std::string FG_BRIGHT_RED = "\033[91m";
static const std::string FG_BRIGHT_GREEN = "\033[92m"; inline static const std::string FG_BRIGHT_GREEN = "\033[92m";
static const std::string FG_BRIGHT_YELLOW = "\033[93m"; inline static const std::string FG_BRIGHT_YELLOW = "\033[93m";
static const std::string FG_BRIGHT_BLUE = "\033[94m"; inline static const std::string FG_BRIGHT_BLUE = "\033[94m";
static const std::string FG_BRIGHT_MAGENTA = "\033[95m"; inline static const std::string FG_BRIGHT_MAGENTA = "\033[95m";
static const std::string FG_BRIGHT_CYAN = "\033[96m"; inline static const std::string FG_BRIGHT_CYAN = "\033[96m";
static const std::string FG_BRIGHT_WHITE = "\033[97m"; inline static const std::string FG_BRIGHT_WHITE = "\033[97m";
static const std::string BG_BLACK = "\033[40m"; inline static const std::string BG_BLACK = "\033[40m";
static const std::string BG_RED = "\033[41m"; inline static const std::string BG_RED = "\033[41m";
static const std::string BG_GREEN = "\033[42m"; inline static const std::string BG_GREEN = "\033[42m";
static const std::string BG_YELLOW = "\033[43m"; inline static const std::string BG_YELLOW = "\033[43m";
static const std::string BG_BLUE = "\033[44m"; inline static const std::string BG_BLUE = "\033[44m";
static const std::string BG_MAGENTA = "\033[45m"; inline static const std::string BG_MAGENTA = "\033[45m";
static const std::string BG_CYAN = "\033[46m"; inline static const std::string BG_CYAN = "\033[46m";
static const std::string BG_WHITE = "\033[47m"; inline static const std::string BG_WHITE = "\033[47m";
static const std::string BG_DEFAULT = "\033[49m"; inline static const std::string BG_DEFAULT = "\033[49m";
static const std::string BG_BRIGHT_BLACK = "\033[100m"; inline static const std::string BG_BRIGHT_BLACK = "\033[100m";
static const std::string BG_BRIGHT_RED = "\033[101m"; inline static const std::string BG_BRIGHT_RED = "\033[101m";
static const std::string BG_BRIGHT_GREEN = "\033[102m"; inline static const std::string BG_BRIGHT_GREEN = "\033[102m";
static const std::string BG_BRIGHT_YELLOW = "\033[103m"; inline static const std::string BG_BRIGHT_YELLOW = "\033[103m";
static const std::string BG_BRIGHT_BLUE = "\033[104m"; inline static const std::string BG_BRIGHT_BLUE = "\033[104m";
static const std::string BG_BRIGHT_MAGENTA = "\033[105m"; inline static const std::string BG_BRIGHT_MAGENTA = "\033[105m";
static const std::string BG_BRIGHT_CYAN = "\033[106m"; inline static const std::string BG_BRIGHT_CYAN = "\033[106m";
static const std::string BG_BRIGHT_WHITE = "\033[107m"; inline static const std::string BG_BRIGHT_WHITE = "\033[107m";
std::string true_color(uint8_t r, uint8_t g, uint8_t b) inline std::string true_color(uint8_t r, uint8_t g, uint8_t b)
{ {
return std::format("\033[38;2;{};{};{}m", r, g, b); return std::format("\033[38;2;{};{};{}m", r, g, b);
} }
std::string cursor_to(int line, int col) inline std::string cursor_to(int line, int col)
{ {
return "";
} }
std::string cursor_up(int lines) inline std::string cursor_up(int lines)
{ {
return "";
} }
std::string cursor_down(int lines) inline std::string cursor_down(int lines)
{ {
return "";
} }
std::string cursor_left(int cols) inline std::string cursor_left(int cols)
{ {
return "";
} }
std::string cursor_right(int cols) inline std::string cursor_right(int cols)
{ {
return "";
} }
std::string cursor_to_col(int col) inline std::string cursor_to_col(int col)
{ {
return "";
} }
} }

View File

@@ -0,0 +1,51 @@
#pragma once
#include <jlog/ansi_escape_codes.hpp>
// Platform independent color code mapping
struct colorcode
{
std::string ansi_code;
};
namespace jlog::color_codes
{
static const colorcode FG_BLACK {ansi_escape_codes::FG_BLACK};
static const colorcode FG_RED {ansi_escape_codes::FG_RED};
static const colorcode FG_GREEN {ansi_escape_codes::FG_GREEN };
static const colorcode FG_YELLOW {ansi_escape_codes::FG_YELLOW};
static const colorcode FG_BLUE {ansi_escape_codes::FG_BLUE};
static const colorcode FG_MAGENTA {ansi_escape_codes::FG_MAGENTA};
static const colorcode FG_CYAN {ansi_escape_codes::FG_CYAN};
static const colorcode FG_WHITE {ansi_escape_codes::FG_WHITE};
static const colorcode FG_DEFAULT {ansi_escape_codes::FG_DEFAULT};
static const colorcode FG_BRIGHT_BLACK {ansi_escape_codes::FG_BRIGHT_BLACK};
static const colorcode FG_BRIGHT_RED {ansi_escape_codes::FG_BRIGHT_RED};
static const colorcode FG_BRIGHT_GREEN {ansi_escape_codes::FG_BRIGHT_GREEN};
static const colorcode FG_BRIGHT_YELLOW {ansi_escape_codes::FG_BRIGHT_YELLOW};
static const colorcode FG_BRIGHT_BLUE {ansi_escape_codes::FG_BRIGHT_MAGENTA};
static const colorcode FG_BRIGHT_MAGENTA {ansi_escape_codes::FG_BRIGHT_MAGENTA};
static const colorcode FG_BRIGHT_CYAN {ansi_escape_codes::FG_BRIGHT_CYAN};
static const colorcode FG_BRIGHT_WHITE {ansi_escape_codes::FG_BRIGHT_WHITE};
static const colorcode BG_BLACK {ansi_escape_codes::BG_BLACK};
static const colorcode BG_RED {ansi_escape_codes::BG_RED};
static const colorcode BG_GREEN {ansi_escape_codes::BG_GREEN};
static const colorcode BG_YELLOW {ansi_escape_codes::BG_YELLOW};
static const colorcode BG_BLUE {ansi_escape_codes::BG_BLUE};
static const colorcode BG_MAGENTA {ansi_escape_codes::BG_MAGENTA};
static const colorcode BG_CYAN {ansi_escape_codes::BG_CYAN};
static const colorcode BG_WHITE {ansi_escape_codes::BG_WHITE};
static const colorcode BG_DEFAULT {ansi_escape_codes::BG_DEFAULT};
static const colorcode BG_BRIGHT_BLACK {ansi_escape_codes::BG_BRIGHT_BLACK};
static const colorcode BG_BRIGHT_RED {ansi_escape_codes::BG_BRIGHT_RED};
static const colorcode BG_BRIGHT_GREEN {ansi_escape_codes::BG_BRIGHT_GREEN};
static const colorcode BG_BRIGHT_YELLOW {ansi_escape_codes::BG_BRIGHT_YELLOW};
static const colorcode BG_BRIGHT_BLUE {ansi_escape_codes::BG_BRIGHT_BLUE};
static const colorcode BG_BRIGHT_MAGENTA {ansi_escape_codes::BG_BRIGHT_MAGENTA};
static const colorcode BG_BRIGHT_CYAN {ansi_escape_codes::BG_BRIGHT_CYAN};
static const colorcode BG_BRIGHT_WHITE {ansi_escape_codes::BG_BRIGHT_WHITE};
}

View File

@@ -3,28 +3,38 @@
/// Developed & Maintained by Josh O'Leary /// Developed & Maintained by Josh O'Leary
/// This work is dedicated to the public domain. /// This work is dedicated to the public domain.
/// Special thanks: Maxine Hayes, William J Tomasine II
#pragma once #pragma once
#include <format>
#include <string> #include <string>
#include <iostream>
#include <chrono>
#include <Event.h> #include <Event.h>
#include <fstream> #include <jlog/color_codes.hpp>
#ifdef __linux__
#define FUNCTION __PRETTY_FUNCTION__
#endif
#ifdef _WIN32
#define FUNCTION __FUNCSIG__
#endif
namespace jlog namespace jlog
{ {
enum class severity /// Severity levels for logging. Higher numbers filter less messages out.
/// @see LOG_LEVEL macro
enum class severity : uint8_t
{ {
none, none, // Show no output
verbose, fatal, // Show only fatal errors
debug, error, // Show fatal and not-necessarily-fatal errors
warning, warning, // Show warnings additionally
error, verbose, // Show errors, warnings, and 'verbose' output (i.e. extra information)
fatal debug, // Show debugging messages (Basically everything).
}; };
inline severity loglevel = severity::debug; // Default log level always debug
struct LogEntry struct LogEntry
{ {
severity level; severity level;
@@ -32,108 +42,198 @@ namespace jlog
std::string timestamp; std::string timestamp;
}; };
// TODO: Fully implement logging callback.
static Event<LogEntry> on_log = Event<LogEntry>(); static Event<LogEntry> on_log = Event<LogEntry>();
std::vector<LogEntry> log_history; inline std::vector<LogEntry> log_history;
/// A single piece of a logging message, with color code, content, and delimiter
/// These are strung together to build full logger messages in a flexible manner.
struct token struct token
{ {
std::string colorCode = ""; colorcode colorCode = color_codes::FG_DEFAULT;
std::string content = ""; std::string content = "";
std::string delimiter = "[]"; std::string delimiter = "[]";
}; };
void log(std::vector<token> tokens); void set_default_logfile(const std::string& filename);
void info (const std::string& message); /// Returns a string timestamp in the format of 'YYYY-MM-DD hh:mm:ss.ms'
void sinfo (const std::string& message); std::string get_timestamp();
void usinfo (const std::string& message);
/// Writes an input string directly to standard output
/// @note Does not append a newline to the message.
void log_to_console(const std::string& message);
/// Writes an input string directly to the default destination logfile
/// @note Does not append a newline to the message.
/// @see set_default_logfile()
void log_to_file(const std::string& message);
/// Writes an input string directly to the specified destination logfile
/// @note Does not append a newline to the message.
void log_to_file(const std::string& filename, const std::string& message);
/// Writes an input string directly to the specified output stream
/// @note Does not append a newline to the message.
void log_to_stream(std::ostream stream, const std::string& message);
void verbose(const std::string& message); /// These are helper functions designed to be wrapped around for easier custom logger building.
void sverbose(const std::string& message); /// @note This file is implemented differently per-platform to handle differences in console color handling.
void usverbose(const std::string& message); /// @see windows/jlog.cpp linux/jlog.cpp
std::string toks2msg(std::vector<token> tokens, std::function<std::string(token)> formatter);
std::string consoleMsgFormatter(token t);
std::string logfileMsgFormatter(token t);
std::string toks2consoleMsg(std::vector<token> tokens);
std::string toks2logfileMsg(std::vector<token> tokens);
/// Parses a sequence of tokens into a printable message, and logs to the following destinations:
/// standard output (console)
/// output file (default)
/// logging callback (Event)
/// @note This file is implemented differently per-platform to handle differences in console color handling.
/// @see windows/jlog.cpp linux/jlog.cpp
void log(const std::vector<token>& tokens, const std::string& filename);
void log(const std::vector<token>& tokens);
void ltlog(const std::vector<token>& tokens); // Just for debug purposes
void debug (const std::string& message); #pragma region Generic Formatters
void sdebug (const std::string& message);
void usdebug (const std::string& message);
/// Returns a pseudo-"stacktrace" formatted sequence of tokens.
/// @param func The function name/signature to trace back to. Should be provided by a __FUNCTION__ macro variant.
/// @param file The file name to trace back to. Should be provided by a __FILE__ macro variant.
/// @param line The source-code line to trace back to. Should be provided by a __LINE__ macro variant.
std::vector<token> trace_format(
const std::string& func,
const std::string& file,
int line);
void warning(const std::string& message); /// Returns a formatted sequence of tokens given a severity and message.
void swarning(const std::string& message); /// @param severity_name The severity tag to prefix to the message. Could theoretically also be a context.
void uswarning(const std::string& message); /// @param message The actual message to include
/// @param severity_cc The colorcode to assign to the severity. See color_codes.hpp
std::vector<token> log_format(
const std::string& severity_name,
const std::string& message,
const colorcode& severity_cc = color_codes::FG_WHITE);
/// Returns a more detailed formatted sequence of tokens.
/// @param severity_name The severity tag to prefix to the message. Could theoretically also be a context.
/// @param message The actual message to include
/// @param func The function name/signature to trace back to. Should be provided by a __FUNCTION__ macro variant.
/// @param file The file name to trace back to. Should be provided by a __FILE__ macro variant.
/// @param line The source-code line to trace back to. Should be provided by a __LINE__ macro variant.
/// @param severity_cc The colorcode to assign to the severity. See color_codes.hpp
std::vector<token> log_detailed_format(
const std::string& severity_name,
const std::string& message,
const std::string& func,
const std::string& file,
int line,
const colorcode& severity_cc = color_codes::FG_WHITE);
void error (const std::string& message); /// Returns a token sequence pre-formatted for the INFO log level.
void serror (const std::string& message); /// @param message The message to send out.
void userror (const std::string& message); std::vector<token> info_format(const std::string& message);
/// Returns a token sequence pre-formatted for the INFO log level.
/// @param message The message to send out.
/// @param func The function name/signature to trace back to. Should be provided by a __FUNCTION__ macro variant.
/// @param file The file name to trace back to. Should be provided by a __FILE__ macro variant.
/// @param line The source-code line to trace back to. Should be provided by a __LINE__ macro variant.
std::vector<token> info_detailed_format(
const std::string &message,
const std::string &func,
const std::string &file,
int line);
void fatal (const std::string& message); /// Returns a token sequence pre-formatted for the WARNING log level.
void sfatal (const std::string& message); /// @param message The message to send out.
void usfatal (const std::string& message); std::vector<token> warning_format(const std::string& message);
/// Returns a token sequence pre-formatted for the WARNING log level.
/// @param message The message to send out.
/// @param func The function name/signature to trace back to. Should be provided by a __FUNCTION__ macro variant.
/// @param file The file name to trace back to. Should be provided by a __FILE__ macro variant.
/// @param line The source-code line to trace back to. Should be provided by a __LINE__ macro variant.
std::vector<token> warning_detailed_format(
const std::string &message,
const std::string &func,
const std::string &file,
int line);
void info_spec(const std::string& message, const std::string& func, const std::string& file, int line); /// Returns a token sequence pre-formatted for the ERROR log level.
void sinfo_spec(const std::string& message, const std::string& func, const std::string& file, int line); /// @param message The message to send out.
void usinfo_spec(const std::string& message, const std::string& func, const std::string& file, int line); std::vector<token> error_format(const std::string& message);
/// Returns a token sequence pre-formatted for the ERROR log level.
/// @param message The message to send out.
/// @param func The function name/signature to trace back to. Should be provided by a __FUNCTION__ macro variant.
/// @param file The file name to trace back to. Should be provided by a __FILE__ macro variant.
/// @param line The source-code line to trace back to. Should be provided by a __LINE__ macro variant.
std::vector<token> error_detailed_format(
const std::string &message,
const std::string &func,
const std::string &file,
int line);
void verbose_spec(const std::string& message, const std::string& func, const std::string& file, int line); /// Returns a token sequence pre-formatted for the FATAL log level.
void sverbose_spec(const std::string& message, const std::string& func, const std::string& file, int line); /// @param message The message to send out.
void usverbose_spec(const std::string& message, const std::string& func, const std::string& file, int line); std::vector<token> fatal_format(const std::string& message);
/// Returns a token sequence pre-formatted for the FATAL log level.
/// @param message The message to send out.
/// @param func The function name/signature to trace back to. Should be provided by a __FUNCTION__ macro variant.
/// @param file The file name to trace back to. Should be provided by a __FILE__ macro variant.
/// @param line The source-code line to trace back to. Should be provided by a __LINE__ macro variant.
std::vector<token> fatal_detailed_format(
const std::string &message,
const std::string &func,
const std::string &file,
int line);
void debug_spec(const std::string& message, const std::string& func, const std::string& file, int line); /// Returns a token sequence pre-formatted for the VERBOSE log level.
void sdebug_spec(const std::string& message, const std::string& func, const std::string& file, int line); /// @param message The message to send out.
void usdebug_spec(const std::string& message, const std::string& func, const std::string& file, int line); std::vector<token> verbose_format(const std::string& message);
/// Returns a token sequence pre-formatted for the VERBOSE log level.
/// @param message The message to send out.
/// @param func The function name/signature to trace back to. Should be provided by a __FUNCTION__ macro variant.
/// @param file The file name to trace back to. Should be provided by a __FILE__ macro variant.
/// @param line The source-code line to trace back to. Should be provided by a __LINE__ macro variant.
std::vector<token> verbose_detailed_format(
const std::string &message,
const std::string &func,
const std::string &file,
int line);
void warning_spec(const std::string& message, const std::string& func, const std::string& file, int line); /// Returns a token sequence pre-formatted for the DEBUG log level.
void swarning_spec(const std::string& message, const std::string& func, const std::string& file, int line); /// @param message The message to send out.
void uswarning_spec(const std::string& message, const std::string& func, const std::string& file, int line); std::vector<token> debug_format(const std::string& message);
void error_spec(const std::string& message, const std::string& func, const std::string& file, int line);
void serror_spec(const std::string& message, const std::string& func, const std::string& file, int line);
void userror_spec(const std::string& message, const std::string& func, const std::string& file, int line);
void fatal_spec(const std::string& message, const std::string& func, const std::string& file, int line);
void sfatal_spec(const std::string& message, const std::string& func, const std::string& file, int line);
void usfatal_spec(const std::string& message, const std::string& func, const std::string& file, int line);
/// Returns a token sequence pre-formatted for the DEBUG log level.
/// @param message The message to send out.
/// @param func The function name/signature to trace back to. Should be provided by a __FUNCTION__ macro variant.
/// @param file The file name to trace back to. Should be provided by a __FILE__ macro variant.
/// @param line The source-code line to trace back to. Should be provided by a __LINE__ macro variant.
std::vector<token> debug_detailed_format(
const std::string &message,
const std::string &func,
const std::string &file,
int line);
#pragma endregion
} }
#define INFO(i) jlog::info_spec(i, __PRETTY_FUNCTION__, __FILE__, __LINE__); #define INFO(i) if (jlog::loglevel >= jlog::severity::none) { jlog::log(jlog::info_detailed_format(i, FUNCTION, __FILE__, __LINE__)); }
#define SINFO(i) jlog::sinfo_spec(i, __PRETTY_FUNCTION__, __FILE__, __LINE__);
#define USINFO(i) jlog::usinfo_spec(i, __PRETTY_FUNCTION__, __FILE__, __LINE__);
#define VERBOSE(i) if (jlog::loglevel >= jlog::severity::verbose) { jlog::log(jlog::verbose_detailed_format(i, FUNCTION, __FILE__, __LINE__)); }
#define VERBOSE(i) jlog::verbose_spec(i, __PRETTY_FUNCTION__, __FILE__, __LINE__); #define DEBUG(i) if (jlog::loglevel >= jlog::severity::debug) { jlog::log(jlog::debug_detailed_format(i, FUNCTION, __FILE__, __LINE__)); }
#define SVERBOSE(i) jlog::sverbose_spec(i, __PRETTY_FUNCTION__, __FILE__, __LINE__);
#define USVERBOSE(i) jlog::usverbose_spec(i, __PRETTY_FUNCTION__, __FILE__, __LINE__);
#define WARNING(i) if (jlog::loglevel >= jlog::severity::warning) { jlog::log(jlog::warning_detailed_format(i, FUNCTION, __FILE__, __LINE__)); }
#define DEBUG(i) jlog::debug_spec(i, __PRETTY_FUNCTION__, __FILE__, __LINE__); #define ERROR(i) if (jlog::loglevel >= jlog::severity::error) { jlog::log(jlog::error_detailed_format(i, FUNCTION, __FILE__, __LINE__)); }
#define SDEBUG(i) jlog::sdebug_spec(i, __PRETTY_FUNCTION__, __FILE__, __LINE__);
#define USDEBUG(i) jlog::usdebug_spec(i, __PRETTY_FUNCTION__, __FILE__, __LINE__);
#define FATAL(i) if (jlog::loglevel >= jlog::severity::fatal) { jlog::log(jlog::fatal_detailed_format(i, FUNCTION, __FILE__, __LINE__)); }
#define WARNING(i) jlog::warning_spec(i, __PRETTY_FUNCTION__, __FILE__, __LINE__); #define LOGLEVEL(i) jlog::loglevel = i;
#define SWARNING(i) jlog::swarning_spec(i, __PRETTY_FUNCTION__, __FILE__, __LINE__);
#define USWARNING(i) jlog::uswarning_spec(i, __PRETTY_FUNCTION__, __FILE__, __LINE__);
#define LOGTEST(i) if (jlog::loglevel >= jlog::severity::none) { jlog::ltlog(jlog::info_detailed_format(i, FUNCTION, __FILE__, __LINE__)); }
#define ERROR(i) jlog::error_spec(i, __PRETTY_FUNCTION__, __FILE__, __LINE__);
#define SERROR(i) jlog::serror_spec(i, __PRETTY_FUNCTION__, __FILE__, __LINE__);
#define USERROR(i) jlog::userror_spec(i, __PRETTY_FUNCTION__, __FILE__, __LINE__);
#define FATAL(i) jlog::fatal_spec(i, __PRETTY_FUNCTION__, __FILE__, __LINE__);
#define SFATAL(i) jlog::sfatal_spec(i, __PRETTY_FUNCTION__, __FILE__, __LINE__);
#define USFATAL(i) jlog::usfatal_spec(i, __PRETTY_FUNCTION__, __FILE__, __LINE__);

View File

@@ -1,7 +1,29 @@
// Josh's Logger
// Minimal, robust, Modern (C++20) Logging Framework
// Created by Joshua O'Leary @ Redacted Software, June 2024
// Contact: josh@redacted.cc
// Contributors: william@redacted.cc maxi@redacted.cc
// This work is dedicated to the public domain.
#include <jlog/jlog.hpp> #include <jlog/jlog.hpp>
// Writing custom wrappers for jlog is super easy!
/*void coollog(std::vector<jlog::token> tokens) {
std::vector<jlog::token> wtokens;
auto group = jlog::token{.content = "COOLLOGGER"};
wtokens.push_back(group);
wtokens.insert(wtokens.end(), tokens.begin(), tokens.end());
jlog::log(wtokens);
}*/
// We can either define custom logging macros or redefine jlog's builtin macros.
//#define COOLINFO(i) coollog(jlog::info_format(i));
//#define COOLINFOTRACE(i) coollog(jlog::info_detailed_format(i, FUNCTION, __FILE__, __LINE__));
int main() int main()
{ {
LOGLEVEL(jlog::severity::debug); // <- see jlog::severity for full list of log levels
INFO("This is barely useful information."); INFO("This is barely useful information.");
DEBUG("Debugging Information"); DEBUG("Debugging Information");
VERBOSE("Yadda Yadda Yadda"); VERBOSE("Yadda Yadda Yadda");
@@ -9,20 +31,20 @@ int main()
ERROR("Oops, something went wrong."); ERROR("Oops, something went wrong.");
FATAL("Unrecoverable Error!!!"); FATAL("Unrecoverable Error!!!");
SINFO("This is even less useful information."); //COOLINFO("This is really cool!!!");
SDEBUG("Shorter Debugging Information"); //COOLINFOTRACE("THIS IS EVEN COOLER!!!");
SVERBOSE("Yadda Yadda");
SWARNING("Minute miscalculation!");
SERROR("Oops, something went wrong, but the programmer used the short error logger so you're fucked!");
SFATAL("Unrecoverable Error, but the programmer used the short fatal logger so you're even more fucked!!!");
USINFO("This is EVEN less useful information."); LOGTEST("This is a really cool test man :3");
USDEBUG("Ultra compact debugging information."); LOGTEST("Go check cmake-build-debug/logtest.log and cmake-build-debug/latest.log");
USVERBOSE("Isn't this an oxymoron?");
USWARNING("Captain Quark grade miscalculation!");
USERROR("You're fucked!");
USFATAL("You're super fucked!!!");
return 0; return 0;
///
} }
//Windows :(
#ifdef _WIN32
extern "C" {
int wmain(int argc, wchar_t* argv[]) {
return main();
}
}
#endif

View File

@@ -1,12 +1,22 @@
#include <source_location>
#include <jlog/ansi_escape_codes.hpp>
#include <jlog/jlog.hpp> #include <jlog/jlog.hpp>
#include <string> #include <fstream>
#include <iostream>
#include <chrono>
#ifdef WIN32
#define NOMINMAX
#include <windows.h>
#endif
namespace jlog
{
static std::string default_logfile = "latest.log";
void set_default_logfile(const std::string& filename)
{
default_logfile = filename;
}
namespace jlog {
static std::string get_timestamp();
static void log_to_console(const std::string& message);
static void log_to_file(const std::string& message);
std::string get_timestamp() std::string get_timestamp()
{ {
@@ -14,7 +24,7 @@ namespace jlog {
auto const timestamp = current_zone()->to_local(system_clock::now()); auto const timestamp = current_zone()->to_local(system_clock::now());
auto dp = floor<days>(timestamp); auto dp = floor<days>(timestamp);
year_month_day ymd{floor<days>(timestamp)}; year_month_day ymd{floor<days>(timestamp)};
hh_mm_ss time{floor<milliseconds>(timestamp-dp)}; hh_mm_ss time{floor<milliseconds>(timestamp - dp)};
auto y = ymd.year(); auto y = ymd.year();
auto m = ymd.month(); auto m = ymd.month();
auto d = ymd.day(); auto d = ymd.day();
@@ -25,341 +35,222 @@ namespace jlog {
return std::format("{}-{}-{} {}:{}:{}.{}", y, m, d, h.count(), M.count(), s.count(), ms.count()); return std::format("{}-{}-{} {}:{}:{}.{}", y, m, d, h.count(), M.count(), s.count(), ms.count());
} }
void log_to_console(const std::string &message) void log_to_console(const std::string& message)
{ {
// Beat windows into submission and make it use ANSI color codes
// This also looks fugly, but it works
#ifdef WIN32
HANDLE handleOut = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD consoleMode;
GetConsoleMode( handleOut, &consoleMode);
consoleMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
consoleMode |= DISABLE_NEWLINE_AUTO_RETURN;
SetConsoleMode( handleOut , consoleMode );
SetConsoleOutputCP(CP_UTF8);
#endif
std::cout << message; std::cout << message;
} }
void log_to_file(const std::string &message) void log_to_file(const std::string& message)
{ {
std::ofstream latest_log("latest.log", std::ios_base::app); std::ofstream latest_log(default_logfile, std::ios_base::app);
latest_log << message; latest_log << message;
latest_log.close(); latest_log.close();
} }
void log(std::vector<token> tokens) { void log_to_file(const std::string& filename, const std::string& message)
for (token t : tokens) { {
if (t.delimiter != "") { std::ofstream latest_log(filename, std::ios_base::app);
log_to_console(std::format("{}{}{}{}{} ", t.colorCode, t.delimiter[0], t.content, t.delimiter[1], ansi_escape_codes::RESET)); latest_log << message;
log_to_file(std::format("{}{}{} ", t.delimiter[0], t.content, t.delimiter[1])); latest_log.close();
} else { }
log_to_console(std::format("{}{}{} ", t.colorCode, t.content, ansi_escape_codes::RESET));
log_to_file(t.content + " "); void log_to_stream(std::ostream stream, const std::string& message)
} {
stream << message;
}
std::string toks2msg(std::vector<token> tokens, std::function<std::string(token)> formatter)
{
std::string msg;
for (const token& t: tokens)
{
msg += formatter(t);
} }
return msg;
}
std::string toks2consoleMsg(std::vector<token> tokens)
{
return toks2msg(tokens, consoleMsgFormatter);
}
std::string toks2logfileMsg(std::vector<token> tokens)
{
return toks2msg(tokens, logfileMsgFormatter);
}
std::string consoleMsgFormatter(token t)
{
if (!t.delimiter.empty())
{
return std::format("{}{}{}{}{} ", t.colorCode.ansi_code, t.delimiter[0], t.content, t.delimiter[1], ansi_escape_codes::RESET);
}
return std::format("{}{}{} ", t.colorCode.ansi_code, t.content, ansi_escape_codes::RESET);
}
std::string logfileMsgFormatter(token t)
{
if (!t.delimiter.empty())
{
return std::format("{}{}{} ", t.delimiter[0], t.content, t.delimiter[1]);
}
return t.content + " ";
}
void log(const std::vector<token>& tokens, const std::string& filename)
{
log_to_console(toks2consoleMsg(tokens));
log_to_console("\n"); log_to_console("\n");
log_to_file("\n"); log_to_file(filename, toks2logfileMsg(tokens));
log_to_file(filename, "\n");
} }
void direct(const std::string &message) { log({{.content = message, .delimiter=""}});} void log(const std::vector<token>& tokens)
{
void info(const std::string &message) { log(tokens, default_logfile);
auto timestamp = token{.content = get_timestamp()};
auto severity = token{.colorCode = ansi_escape_codes::FG_WHITE, .content = "INFO"};
auto content = token{.content = message, .delimiter = ""};
//auto trace = token{.content = };
log({timestamp, severity, content});
} }
void sinfo(const std::string &message) { // Mainly for debug purposes
//auto timestamp = token{.content = get_timestamp()}; void ltlog(const std::vector<token>& tokens)
auto severity = token{.colorCode = ansi_escape_codes::FG_WHITE, .content = "INFO"}; {
auto content = token{.content = message, .delimiter = ""}; log(tokens);
//auto trace = token{.content = }; log_to_file("logtest.log", toks2logfileMsg(tokens) + "\n");
log({severity, content});
}
void usinfo(const std::string &message) {
//auto timestamp = token{.content = get_timestamp()};
auto severity = token{.colorCode = ansi_escape_codes::FG_WHITE, .content = "INFO"};
auto content = token{.content = message, .delimiter = ""};
//auto trace = token{.content = };
log({severity, content});
} }
void verbose(const std::string &message) { std::vector<token> trace_format(
auto timestamp = token{.content = get_timestamp()}; const std::string& func,
auto severity = token{.colorCode = ansi_escape_codes::FG_CYAN, .content = "VERBOSE"}; const std::string& file,
auto content = token{.content = message, .delimiter = ""}; int line)
//auto trace = token{.content = }; {
log({timestamp, severity, content});
//log(ansi_escape_codes::FG_CYAN, "VERBOSE", message);
}
void sverbose(const std::string &message) {
//auto timestamp = token{.content = get_timestamp()};
auto severity = token{.colorCode = ansi_escape_codes::FG_CYAN, .content = "VERBOSE"};
auto content = token{.content = message, .delimiter = ""};
//auto trace = token{.content = };
log({severity, content});
//log(ansi_escape_codes::FG_CYAN, "VERBOSE", message);
}
void usverbose(const std::string &message) {
//auto timestamp = token{.content = get_timestamp()};
auto severity = token{.colorCode = ansi_escape_codes::FG_CYAN, .content = "VERBOSE"};
auto content = token{.content = message, .delimiter = ""};
//auto trace = token{.content = };
log({severity, content});
//log(ansi_escape_codes::FG_CYAN, "VERBOSE", message);
}
void debug(const std::string &message) {
auto timestamp = token{.content = get_timestamp()};
auto severity = token{.colorCode = ansi_escape_codes::FG_GREEN, .content = "DEBUG"};
auto content = token{.content = message, .delimiter = ""};
//auto trace = token{.content = };
log({timestamp, severity, content});
}
void sdebug(const std::string &message) {
//auto timestamp = token{.content = get_timestamp()};
auto severity = token{.colorCode = ansi_escape_codes::FG_GREEN, .content = "DEBUG"};
auto content = token{.content = message, .delimiter = ""};
//auto trace = token{.content = };
log({severity, content});
}
void usdebug(const std::string &message) {
//auto timestamp = token{.content = get_timestamp()};
auto severity = token{.colorCode = ansi_escape_codes::FG_GREEN, .content = "DEBUG"};
auto content = token{.content = message, .delimiter = ""};
//auto trace = token{.content = };
log({severity, content});
}
void warning(const std::string &message) {
auto timestamp = token{.content = get_timestamp()};
auto severity = token{.colorCode = ansi_escape_codes::FG_YELLOW, .content = "WARNING"};
auto content = token{.content = message, .delimiter = ""};
//auto trace = token{.content = };
log({timestamp, severity, content});
//log(ansi_escape_codes::FG_YELLOW, "WARNING", message);
}
void uswarning(const std::string &message) {
//auto timestamp = token{.content = get_timestamp()};
auto severity = token{.colorCode = ansi_escape_codes::FG_YELLOW, .content = "WARNING"};
auto content = token{.content = message, .delimiter = ""};
//auto trace = token{.content = };
log({severity, content});
//log(ansi_escape_codes::FG_YELLOW, "WARNING", message);
}
void error(const std::string &message) {
auto timestamp = token{.content = get_timestamp()};
auto severity = token{.colorCode = ansi_escape_codes::FG_RED, .content = "ERROR"};
auto content = token{.content = message, .delimiter = ""};
//auto trace = token{.content = };
log({timestamp, severity, content});
//log(ansi_escape_codes::FG_RED, "ERROR", message);
}
void userror(const std::string &message) {
//auto timestamp = token{.content = get_timestamp()};
auto severity = token{.colorCode = ansi_escape_codes::FG_RED, .content = "ERROR"};
auto content = token{.content = message, .delimiter = ""};
//auto trace = token{.content = };
log({severity, content});
//log(ansi_escape_codes::FG_RED, "ERROR", message);
}
void fatal(const std::string &message) {
auto timestamp = token{.content = get_timestamp()};
auto severity = token{.colorCode = ansi_escape_codes::FG_BRIGHT_RED, .content = "FATAL"};
auto content = token{.content = message, .delimiter = ""};
log({timestamp, severity, content});
}
void usfatal(const std::string &message) {
//auto timestamp = token{.content = get_timestamp()};
auto severity = token{.colorCode = ansi_escape_codes::FG_BRIGHT_RED, .content = "FATAL"};
auto content = token{.content = message, .delimiter = ""};
log({severity, content});
}
void info_spec(const std::string &message, const std::string &func, const std::string &file,
int line) {
auto timestamp = token{.content = get_timestamp()};
auto severity = token{.colorCode = ansi_escape_codes::FG_WHITE, .content = "INFO"};
auto content = token{.content = message, .delimiter = ""};
auto trace = token{.content = func}; auto trace = token{.content = func};
auto filedata = token{.content = std::format("{}:{}", file, line)}; auto filedata = token{.content = std::format("{}:{}", file, line)};
log({timestamp, trace, filedata, severity, content}); return {trace, filedata};
} }
void sinfo_spec(const std::string &message, const std::string &func, const std::string &file, std::vector<token> info_format(const std::string& message)
int line) { {
//auto timestamp = token{.content = get_timestamp()}; return log_format("INFO", message);
auto severity = token{.colorCode = ansi_escape_codes::FG_WHITE, .content = "INFO"};
auto content = token{.content = message, .delimiter = ""};
auto trace = token{.content = func};
auto filedata = token{.content = std::format("{}:{}", file, line)};
log({trace, filedata, severity, content});
//log({severity, content});
} }
void usinfo_spec(const std::string &message, const std::string &func, const std::string &file, std::vector<token> warning_format(const std::string& message)
int line) { {
//auto timestamp = token{.content = get_timestamp()}; return log_format("INFO", message, color_codes::FG_YELLOW);
auto severity = token{.colorCode = ansi_escape_codes::FG_WHITE, .content = "INFO"};
auto content = token{.content = message, .delimiter = ""};
//auto trace = token{.content = func};
//auto filedata = token{.content = std::format("{}:{}", file, line)};
//log({trace, filedata, severity, content});
log({severity, content});
} }
void verbose_spec(const std::string &message, const std::string &func, const std::string &file, std::vector<token> error_format(const std::string& message)
int line) { {
auto timestamp = token{.content = get_timestamp()}; return log_format("ERROR", message, color_codes::FG_RED);
auto severity = token{.colorCode = ansi_escape_codes::FG_CYAN, .content = "VERBOSE"};
auto content = token{.content = message, .delimiter = ""};
auto trace = token{.content = func};
auto filedata = token{.content = std::format("{}:{}", file, line)};
log({timestamp, trace, filedata, severity, content});
} }
void sverbose_spec(const std::string &message, const std::string &func, const std::string &file, std::vector<token> verbose_format(const std::string& message)
int line) { {
//auto timestamp = token{.content = get_timestamp()}; return log_format("VERBOSE", message, color_codes::FG_CYAN);
auto severity = token{.colorCode = ansi_escape_codes::FG_CYAN, .content = "VERBOSE"};
auto content = token{.content = message, .delimiter = ""};
auto trace = token{.content = func};
auto filedata = token{.content = std::format("{}:{}", file, line)};
log({trace, filedata, severity, content});
} }
void usverbose_spec(const std::string &message, const std::string &func, const std::string &file, std::vector<token> debug_format(const std::string& message)
int line) { {
//auto timestamp = token{.content = get_timestamp()}; return log_format("DEBUG", message, color_codes::FG_GREEN);
auto severity = token{.colorCode = ansi_escape_codes::FG_CYAN, .content = "VERBOSE"};
auto content = token{.content = message, .delimiter = ""};
//auto trace = token{.content = func};
//auto filedata = token{.content = std::format("{}:{}", file, line)};
log({severity, content});
} }
void debug_spec(const std::string &message, const std::string &func, const std::string &file, std::vector<token> debug_detailed_format(
int line) { const std::string& message,
auto timestamp = token{.content = get_timestamp()}; const std::string& func,
auto severity = token{.colorCode = ansi_escape_codes::FG_GREEN, .content = "DEBUG"}; const std::string& file,
auto content = token{.content = message, .delimiter = ""}; int line)
auto trace = token{.content = func}; {
auto filedata = token{.content = std::format("{}:{}", file, line)}; return log_detailed_format("DEBUG", message, func, file, line, color_codes::FG_GREEN);
log({timestamp, trace, filedata, severity, content});
} }
void sdebug_spec(const std::string &message, const std::string &func, const std::string &file, std::vector<token> info_detailed_format(
int line) { const std::string& message,
//auto timestamp = token{.content = get_timestamp()}; const std::string& func,
auto severity = token{.colorCode = ansi_escape_codes::FG_GREEN, .content = "DEBUG"}; const std::string& file,
auto content = token{.content = message, .delimiter = ""}; int line)
auto trace = token{.content = func}; {
auto filedata = token{.content = std::format("{}:{}", file, line)}; return log_detailed_format("INFO", message, func, file, line);
log({trace, filedata, severity, content});
} }
void usdebug_spec(const std::string &message, const std::string &func, const std::string &file, std::vector<token> warning_detailed_format(
int line) { const std::string& message,
//auto timestamp = token{.content = get_timestamp()}; const std::string& func,
auto severity = token{.colorCode = ansi_escape_codes::FG_GREEN, .content = "DEBUG"}; const std::string& file,
auto content = token{.content = message, .delimiter = ""}; int line)
//auto trace = token{.content = func}; {
//auto filedata = token{.content = std::format("{}:{}", file, line)}; return log_detailed_format("WARNING", message, func, file, line, color_codes::FG_YELLOW);
log({severity, content});
} }
void warning_spec(const std::string &message, const std::string &func, const std::string &file, std::vector<token> error_detailed_format(
int line) { const std::string& message,
auto timestamp = token{.content = get_timestamp()}; const std::string& func,
auto severity = token{.colorCode = ansi_escape_codes::FG_YELLOW, .content = "WARNING"}; const std::string& file,
auto content = token{.content = message, .delimiter = ""}; int line)
auto trace = token{.content = func}; {
auto filedata = token{.content = std::format("{}:{}", file, line)}; return log_detailed_format("ERROR", message, func, file, line, color_codes::FG_RED);
log({timestamp, trace, filedata, severity, content});
} }
void swarning_spec(const std::string &message, const std::string &func, const std::string &file, std::vector<token> fatal_format(const std::string& message)
int line) { {
//auto timestamp = token{.content = get_timestamp()}; return log_format("FATAL", message, color_codes::FG_BRIGHT_RED);
auto severity = token{.colorCode = ansi_escape_codes::FG_YELLOW, .content = "WARNING"};
auto content = token{.content = message, .delimiter = ""};
auto trace = token{.content = func};
auto filedata = token{.content = std::format("{}:{}", file, line)};
log({trace, filedata, severity, content});
} }
void uswarning_spec(const std::string &message, const std::string &func, const std::string &file, std::vector<token> verbose_detailed_format(
int line) { const std::string& message,
//auto timestamp = token{.content = get_timestamp()}; const std::string& func,
auto severity = token{.colorCode = ansi_escape_codes::FG_YELLOW, .content = "WARNING"}; const std::string& file,
auto content = token{.content = message, .delimiter = ""}; int line)
//auto trace = token{.content = func}; {
//auto filedata = token{.content = std::format("{}:{}", file, line)}; return log_detailed_format("VERBOSE", message, func, file, line, color_codes::FG_CYAN);
log({severity, content});
} }
void error_spec(const std::string &message, const std::string &func, const std::string &file, std::vector<token> fatal_detailed_format(
int line) { const std::string& message,
auto timestamp = token{.content = get_timestamp()}; const std::string& func,
auto severity = token{.colorCode = ansi_escape_codes::FG_RED, .content = "ERROR"}; const std::string& file,
auto content = token{.content = message, .delimiter = ""}; int line)
auto trace = token{.content = func}; {
auto filedata = token{.content = std::format("{}:{}", file, line)}; return log_detailed_format("FATAL", message, func, file, line, color_codes::FG_BRIGHT_RED);
log({timestamp, trace, filedata, severity, content});
} }
void serror_spec(const std::string &message, const std::string &func, const std::string &file, std::vector<token> log_format(
int line) { const std::string& severity_name,
//auto timestamp = token{.content = get_timestamp()}; const std::string& message,
auto severity = token{.colorCode = ansi_escape_codes::FG_RED, .content = "ERROR"}; const colorcode& severity_cc)
{
auto severity = token{.colorCode = severity_cc, .content = severity_name};
auto content = token{.content = message, .delimiter = ""}; auto content = token{.content = message, .delimiter = ""};
auto trace = token{.content = func}; return {severity, content};
auto filedata = token{.content = std::format("{}:{}", file, line)};
log({trace, filedata, severity, content});
} }
void userror_spec(const std::string &message, const std::string &func, const std::string &file, std::vector<token> log_detailed_format(
int line) { const std::string& severity_name,
//auto timestamp = token{.content = get_timestamp()}; const std::string& message,
auto severity = token{.colorCode = ansi_escape_codes::FG_RED, .content = "ERROR"}; const std::string& func,
auto content = token{.content = message, .delimiter = ""}; const std::string& file,
//auto trace = token{.content = func}; int line,
//auto filedata = token{.content = std::format("{}:{}", file, line)}; const colorcode& severity_cc)
log({severity, content}); {
} std::vector<token> tokens;
auto timestamp = token{.content = jlog::get_timestamp()};
void fatal_spec(const std::string &message, const std::string &func, const std::string &file, auto tf_tokens = jlog::trace_format(func, file, line);
int line) { auto lf_tokens = jlog::log_format(severity_name, message, severity_cc);
auto timestamp = token{.content = get_timestamp()}; tokens.push_back(timestamp);
auto severity = token{.colorCode = ansi_escape_codes::FG_BRIGHT_RED, .content = "FATAL"}; tokens.insert(tokens.end(), tf_tokens.begin(), tf_tokens.end());
auto content = token{.content = message, .delimiter = ""}; tokens.insert(tokens.end(), lf_tokens.begin(), lf_tokens.end());
auto trace = token{.content = func}; return tokens;
auto filedata = token{.content = std::format("{}:{}", file, line)};
log({timestamp, trace, filedata, severity, content});
}
void sfatal_spec(const std::string &message, const std::string &func, const std::string &file,
int line) {
auto timestamp = token{.content = get_timestamp()};
auto severity = token{.colorCode = ansi_escape_codes::FG_BRIGHT_RED, .content = "FATAL"};
auto content = token{.content = message, .delimiter = ""};
auto trace = token{.content = func};
auto filedata = token{.content = std::format("{}:{}", file, line)};
log({trace, filedata, severity, content});
}
void usfatal_spec(const std::string &message, const std::string &func, const std::string &file,
int line) {
auto timestamp = token{.content = get_timestamp()};
auto severity = token{.colorCode = ansi_escape_codes::FG_BRIGHT_RED, .content = "FATAL"};
auto content = token{.content = message, .delimiter = ""};
//auto trace = token{.content = func};
//auto filedata = token{.content = std::format("{}:{}", file, line)};
log({severity, content});
} }
} }