17 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
9 changed files with 372 additions and 620 deletions

View File

@@ -16,13 +16,8 @@ include(cmake/CPM.cmake)
file(GLOB_RECURSE jlog_HEADERS "include/jlog/*.h" "include/jlog/*.hpp")
if(UNIX AND NOT APPLE)
file(GLOB_RECURSE jlog_SRC "src/jlog/linux/*.c" "src/jlog/linux/*.cpp" "src/jlog/shared/*.c" "src/jlog/shared/*.cpp")
endif()
file(GLOB_RECURSE jlog_SRC "src/jlog/*.cpp")
if(WIN32)
file(GLOB_RECURSE jlog_SRC "src/jlog/windows/*.c" "src/jlog/windows/*.cpp" "src/jlog/shared/*.c" "src/jlog/shared/*.cpp")
endif()
include_directories("include")
@@ -39,6 +34,7 @@ endif()
if (WIN32)
add_library(jlog STATIC ${jlog_SRC})
target_compile_options(jlog PRIVATE /wd4005)
endif()
set_target_properties(jlog PROPERTIES LINKER_LANGUAGE CXX)

View File

@@ -1,52 +1,51 @@
#pragma once
#include <jlog/ansi_escape_codes.hpp>
#include <jlog/nt_color_codes.hpp>
// Platform independent color code mapping
struct colorcode
{
std::string ansi_code;
WORD nt_code;
};
namespace jlog::color_codes
{
static const colorcode FG_BLACK {ansi_escape_codes::FG_BLACK, nt_color_codes::FG_BLACK };
static const colorcode FG_RED {ansi_escape_codes::FG_RED, nt_color_codes::FG_RED };
static const colorcode FG_GREEN {ansi_escape_codes::FG_GREEN, nt_color_codes::FG_GREEN };
static const colorcode FG_YELLOW {ansi_escape_codes::FG_YELLOW, nt_color_codes::FG_YELLOW };
static const colorcode FG_BLUE {ansi_escape_codes::FG_BLUE, nt_color_codes::FG_BLUE };
static const colorcode FG_MAGENTA {ansi_escape_codes::FG_MAGENTA, nt_color_codes::FG_MAGENTA };
static const colorcode FG_CYAN {ansi_escape_codes::FG_CYAN, nt_color_codes::FG_CYAN };
static const colorcode FG_WHITE {ansi_escape_codes::FG_WHITE, nt_color_codes::FG_WHITE };
static const colorcode FG_DEFAULT {ansi_escape_codes::FG_DEFAULT, nt_color_codes::FG_DEFAULT };
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, nt_color_codes::FG_BRIGHT_BLACK};
static const colorcode FG_BRIGHT_RED {ansi_escape_codes::FG_BRIGHT_RED, nt_color_codes::FG_BRIGHT_RED};
static const colorcode FG_BRIGHT_GREEN {ansi_escape_codes::FG_BRIGHT_GREEN, nt_color_codes::FG_BRIGHT_GREEN};
static const colorcode FG_BRIGHT_YELLOW {ansi_escape_codes::FG_BRIGHT_YELLOW, nt_color_codes::FG_BRIGHT_YELLOW};
static const colorcode FG_BRIGHT_BLUE {ansi_escape_codes::FG_BRIGHT_MAGENTA, nt_color_codes::FG_BRIGHT_MAGENTA};
static const colorcode FG_BRIGHT_MAGENTA {ansi_escape_codes::FG_BRIGHT_MAGENTA, nt_color_codes::FG_BRIGHT_MAGENTA};
static const colorcode FG_BRIGHT_CYAN {ansi_escape_codes::FG_BRIGHT_CYAN, nt_color_codes::FG_BRIGHT_CYAN};
static const colorcode FG_BRIGHT_WHITE {ansi_escape_codes::FG_BRIGHT_WHITE, nt_color_codes::FG_BRIGHT_WHITE};
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, nt_color_codes::BG_BLACK};
static const colorcode BG_RED {ansi_escape_codes::BG_RED, nt_color_codes::BG_RED};
static const colorcode BG_GREEN {ansi_escape_codes::BG_GREEN, nt_color_codes::BG_GREEN};
static const colorcode BG_YELLOW {ansi_escape_codes::BG_YELLOW, nt_color_codes::BG_YELLOW};
static const colorcode BG_BLUE {ansi_escape_codes::BG_BLUE, nt_color_codes::BG_BLUE};
static const colorcode BG_MAGENTA {ansi_escape_codes::BG_MAGENTA, nt_color_codes::BG_MAGENTA};
static const colorcode BG_CYAN {ansi_escape_codes::BG_CYAN, nt_color_codes::BG_CYAN};
static const colorcode BG_WHITE {ansi_escape_codes::BG_WHITE, nt_color_codes::BG_WHITE};
static const colorcode BG_DEFAULT {ansi_escape_codes::BG_DEFAULT, nt_color_codes::BG_DEFAULT};
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, nt_color_codes::BG_BRIGHT_BLACK};
static const colorcode BG_BRIGHT_RED {ansi_escape_codes::BG_BRIGHT_RED, nt_color_codes::BG_BRIGHT_RED};
static const colorcode BG_BRIGHT_GREEN {ansi_escape_codes::BG_BRIGHT_GREEN, nt_color_codes::BG_BRIGHT_GREEN};
static const colorcode BG_BRIGHT_YELLOW {ansi_escape_codes::BG_BRIGHT_YELLOW, nt_color_codes::BG_BRIGHT_YELLOW};
static const colorcode BG_BRIGHT_BLUE {ansi_escape_codes::BG_BRIGHT_BLUE, nt_color_codes::BG_BRIGHT_BLUE};
static const colorcode BG_BRIGHT_MAGENTA {ansi_escape_codes::BG_BRIGHT_MAGENTA, nt_color_codes::BG_BRIGHT_MAGENTA};
static const colorcode BG_BRIGHT_CYAN {ansi_escape_codes::BG_BRIGHT_CYAN, nt_color_codes::BG_BRIGHT_CYAN};
static const colorcode BG_BRIGHT_WHITE {ansi_escape_codes::BG_BRIGHT_WHITE, nt_color_codes::BG_BRIGHT_WHITE};
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,6 +3,8 @@
/// Developed & Maintained by Josh O'Leary
/// This work is dedicated to the public domain.
/// Special thanks: Maxine Hayes, William J Tomasine II
#pragma once
#include <string>
@@ -56,6 +58,7 @@ namespace jlog
void set_default_logfile(const std::string& filename);
/// Returns a string timestamp in the format of 'YYYY-MM-DD hh:mm:ss.ms'
std::string get_timestamp();
/// Writes an input string directly to standard output
@@ -72,26 +75,52 @@ namespace jlog
/// @note Does not append a newline to the message.
void log_to_stream(std::ostream stream, const std::string& message);
/// These are helper functions designed to be wrapped around for easier custom logger building.
/// @note This file is implemented differently per-platform to handle differences in console color handling.
/// @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(std::vector<token> tokens);
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
// Generic formatters for building loggers.
#pragma region Generic Formatters
/// 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);
/// Returns a formatted sequence of tokens given a severity and message.
/// @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 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,
@@ -100,54 +129,96 @@ namespace jlog
int line,
const colorcode& severity_cc = color_codes::FG_WHITE);
// Predefined generic loggers for jlog.
/// Returns a token sequence pre-formatted for the INFO log level.
/// @param message The message to send out.
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);
/// Returns a token sequence pre-formatted for the WARNING log level.
/// @param message The message to send out.
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);
/// Returns a token sequence pre-formatted for the ERROR log level.
/// @param message The message to send out.
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);
/// Returns a token sequence pre-formatted for the FATAL log level.
/// @param message The message to send out.
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);
/// Returns a token sequence pre-formatted for the VERBOSE log level.
/// @param message The message to send out.
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);
/// Returns a token sequence pre-formatted for the DEBUG log level.
/// @param message The message to send out.
std::vector<token> debug_format(const std::string& message);
/// 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) if (jlog::loglevel >= jlog::severity::none) { jlog::log(jlog::info_detailed_format(i, FUNCTION, __FILE__, __LINE__)); }
@@ -164,3 +235,5 @@ namespace jlog
#define LOGLEVEL(i) jlog::loglevel = i;
#define LOGTEST(i) if (jlog::loglevel >= jlog::severity::none) { jlog::ltlog(jlog::info_detailed_format(i, FUNCTION, __FILE__, __LINE__)); }

View File

@@ -1,55 +0,0 @@
#pragma once
// NT color codes taken from windows.h / consoleapi2.h
#ifdef WIN32
#include <windows.h>
#endif
#ifndef WORD
#define WORD short
#endif
namespace jlog::nt_color_codes
{
const WORD FG_BLACK = 0x0000;
const WORD FG_BLUE = 0x0001;
const WORD FG_GREEN = 0x0002;
const WORD FG_RED = 0x0004;
const WORD FG_YELLOW = FG_RED | FG_GREEN;
const WORD FG_MAGENTA = FG_RED | FG_BLUE;
const WORD FG_CYAN = FG_GREEN | FG_BLUE;
const WORD FG_WHITE = FG_RED | FG_GREEN | FG_BLUE;
const WORD FG_DEFAULT = FG_WHITE;
const WORD FG_BRIGHT_BLACK = 0 | 0x0008;
const WORD FG_BRIGHT_RED = FG_RED | 0x0008;
const WORD FG_BRIGHT_GREEN = FG_GREEN | 0x0008;
const WORD FG_BRIGHT_YELLOW = FG_RED | FG_GREEN | 0x0008;
const WORD FG_BRIGHT_BLUE = FG_BLUE | 0x0008;
const WORD FG_BRIGHT_MAGENTA = FG_RED | FG_BLUE | 0x0008;
const WORD FG_BRIGHT_CYAN = FG_GREEN | FG_BLUE | 0x0008;
const WORD FG_BRIGHT_WHITE = FG_RED | FG_GREEN | FG_BLUE | 0x0008;
const WORD BG_BLACK = 0x0000;
const WORD BG_BLUE = 0x0010;
const WORD BG_GREEN = 0x0020;
const WORD BG_RED = 0x0040;
const WORD BG_YELLOW = BG_RED | BG_GREEN;
const WORD BG_MAGENTA = BG_RED | BG_BLUE;
const WORD BG_CYAN = BG_GREEN | BG_BLUE;
const WORD BG_WHITE = BG_RED | BG_GREEN | BG_BLUE;
const WORD BG_BRIGHT_BLACK = 0 | 0x0080;
const WORD BG_BRIGHT_RED = BG_RED | 0x0080;
const WORD BG_BRIGHT_GREEN = BG_GREEN | 0x0080;
const WORD BG_BRIGHT_YELLOW = BG_YELLOW | 0x0080;
const WORD BG_BRIGHT_BLUE = BG_BLUE | 0x0080;
const WORD BG_BRIGHT_MAGENTA = BG_RED | BG_BLUE | 0x0080;
const WORD BG_BRIGHT_CYAN = BG_GREEN | BG_BLUE | 0x0080;
const WORD BG_BRIGHT_WHITE = BG_RED | BG_GREEN | BG_BLUE | 0x0080;
const WORD BG_DEFAULT = BG_WHITE;
}

View File

@@ -34,6 +34,9 @@ int main()
//COOLINFO("This is really cool!!!");
//COOLINFOTRACE("THIS IS EVEN COOLER!!!");
LOGTEST("This is a really cool test man :3");
LOGTEST("Go check cmake-build-debug/logtest.log and cmake-build-debug/latest.log");
return 0;
}

256
src/jlog/jlog.cpp Normal file
View File

@@ -0,0 +1,256 @@
#include <jlog/jlog.hpp>
#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;
}
std::string get_timestamp()
{
using namespace std::chrono;
auto const timestamp = current_zone()->to_local(system_clock::now());
auto dp = floor<days>(timestamp);
year_month_day ymd{floor<days>(timestamp)};
hh_mm_ss time{floor<milliseconds>(timestamp - dp)};
auto y = ymd.year();
auto m = ymd.month();
auto d = ymd.day();
auto h = time.hours();
auto M = time.minutes();
auto s = time.seconds();
auto ms = time.subseconds();
return std::format("{}-{}-{} {}:{}:{}.{}", y, m, d, h.count(), M.count(), s.count(), ms.count());
}
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;
}
void log_to_file(const std::string& message)
{
std::ofstream latest_log(default_logfile, std::ios_base::app);
latest_log << message;
latest_log.close();
}
void log_to_file(const std::string& filename, const std::string& message)
{
std::ofstream latest_log(filename, std::ios_base::app);
latest_log << message;
latest_log.close();
}
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_file(filename, toks2logfileMsg(tokens));
log_to_file(filename, "\n");
}
void log(const std::vector<token>& tokens)
{
log(tokens, default_logfile);
}
// Mainly for debug purposes
void ltlog(const std::vector<token>& tokens)
{
log(tokens);
log_to_file("logtest.log", toks2logfileMsg(tokens) + "\n");
}
std::vector<token> trace_format(
const std::string& func,
const std::string& file,
int line)
{
auto trace = token{.content = func};
auto filedata = token{.content = std::format("{}:{}", file, line)};
return {trace, filedata};
}
std::vector<token> info_format(const std::string& message)
{
return log_format("INFO", message);
}
std::vector<token> warning_format(const std::string& message)
{
return log_format("INFO", message, color_codes::FG_YELLOW);
}
std::vector<token> error_format(const std::string& message)
{
return log_format("ERROR", message, color_codes::FG_RED);
}
std::vector<token> verbose_format(const std::string& message)
{
return log_format("VERBOSE", message, color_codes::FG_CYAN);
}
std::vector<token> debug_format(const std::string& message)
{
return log_format("DEBUG", message, color_codes::FG_GREEN);
}
std::vector<token> debug_detailed_format(
const std::string& message,
const std::string& func,
const std::string& file,
int line)
{
return log_detailed_format("DEBUG", message, func, file, line, color_codes::FG_GREEN);
}
std::vector<token> info_detailed_format(
const std::string& message,
const std::string& func,
const std::string& file,
int line)
{
return log_detailed_format("INFO", message, func, file, line);
}
std::vector<token> warning_detailed_format(
const std::string& message,
const std::string& func,
const std::string& file,
int line)
{
return log_detailed_format("WARNING", message, func, file, line, color_codes::FG_YELLOW);
}
std::vector<token> error_detailed_format(
const std::string& message,
const std::string& func,
const std::string& file,
int line)
{
return log_detailed_format("ERROR", message, func, file, line, color_codes::FG_RED);
}
std::vector<token> fatal_format(const std::string& message)
{
return log_format("FATAL", message, color_codes::FG_BRIGHT_RED);
}
std::vector<token> verbose_detailed_format(
const std::string& message,
const std::string& func,
const std::string& file,
int line)
{
return log_detailed_format("VERBOSE", message, func, file, line, color_codes::FG_CYAN);
}
std::vector<token> fatal_detailed_format(
const std::string& message,
const std::string& func,
const std::string& file,
int line)
{
return log_detailed_format("FATAL", message, func, file, line, color_codes::FG_BRIGHT_RED);
}
std::vector<token> log_format(
const std::string& severity_name,
const std::string& message,
const colorcode& severity_cc)
{
auto severity = token{.colorCode = severity_cc, .content = severity_name};
auto content = token{.content = message, .delimiter = ""};
return {severity, content};
}
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)
{
std::vector<token> tokens;
auto timestamp = token{.content = jlog::get_timestamp()};
auto tf_tokens = jlog::trace_format(func, file, line);
auto lf_tokens = jlog::log_format(severity_name, message, severity_cc);
tokens.push_back(timestamp);
tokens.insert(tokens.end(), tf_tokens.begin(), tf_tokens.end());
tokens.insert(tokens.end(), lf_tokens.begin(), lf_tokens.end());
return tokens;
}
}

View File

@@ -1,17 +0,0 @@
#include <jlog/jlog.hpp>
namespace jlog {
void log(std::vector<token> tokens) {
for (token t: tokens) {
if (!t.delimiter.empty())
log_to_console(std::format("{}{}{}{}{} ", t.colorCode.ansi_code, t.delimiter[0], t.content, t.delimiter[1], ansi_escape_codes::RESET)),
log_to_file(std::format("{}{}{} ", t.delimiter[0], t.content, t.delimiter[1]));
else
log_to_console(std::format("{}{}{} ", t.colorCode.ansi_code, t.content, ansi_escape_codes::RESET)),
log_to_file(t.content + " ");
}
log_to_console("\n");
log_to_file("\n");
}
}

View File

@@ -1,475 +0,0 @@
#include <jlog/jlog.hpp>
#include <fstream>
#include <iostream>
#include <chrono>
namespace jlog
{
static std::string default_logfile = "latest.log";
void set_default_logfile(const std::string& filename)
{
default_logfile = filename;
}
std::string get_timestamp()
{
using namespace std::chrono;
auto const timestamp = current_zone()->to_local(system_clock::now());
auto dp = floor<days>(timestamp);
year_month_day ymd{floor<days>(timestamp)};
hh_mm_ss time{floor<milliseconds>(timestamp - dp)};
auto y = ymd.year();
auto m = ymd.month();
auto d = ymd.day();
auto h = time.hours();
auto M = time.minutes();
auto s = time.seconds();
auto ms = time.subseconds();
return std::format("{}-{}-{} {}:{}:{}.{}", y, m, d, h.count(), M.count(), s.count(), ms.count());
}
void log_to_console(const std::string& message)
{
std::cout << message;
}
void log_to_file(const std::string& message)
{
std::ofstream latest_log(default_logfile, std::ios_base::app);
latest_log << message;
latest_log.close();
}
void log_to_file(const std::string& filename, const std::string& message)
{
std::ofstream latest_log(filename, std::ios_base::app);
latest_log << message;
latest_log.close();
}
void log_to_stream(std::ostream stream, const std::string& message)
{
stream << message;
}
std::vector<token> trace_format(
const std::string& func,
const std::string& file,
int line)
{
auto trace = token{.content = func};
auto filedata = token{.content = std::format("{}:{}", file, line)};
return {trace, filedata};
}
std::vector<token> info_format(const std::string& message)
{
return log_format("INFO", message);
}
std::vector<token> warning_format(const std::string& message)
{
return log_format("INFO", message, color_codes::FG_YELLOW);
}
std::vector<token> error_format(const std::string& message)
{
return log_format("ERROR", message, color_codes::FG_RED);
}
std::vector<token> verbose_format(const std::string& message)
{
return log_format("VERBOSE", message, color_codes::FG_CYAN);
}
std::vector<token> debug_format(const std::string& message)
{
return log_format("DEBUG", message, color_codes::FG_GREEN);
}
std::vector<token> debug_detailed_format(
const std::string& message,
const std::string& func,
const std::string& file,
int line)
{
return log_detailed_format("DEBUG", message, func, file, line, color_codes::FG_GREEN);
}
void direct(const std::string& message)
{
log({{.content = message, .delimiter = ""}});
}
void info(const std::string& message)
{
auto timestamp = token{.content = jlog::get_timestamp()};
auto severity = token{.colorCode = color_codes::FG_WHITE, .content = "INFO"};
auto content = token{.content = message, .delimiter = ""};
log({timestamp, severity, content});
}
void sinfo(const std::string& message)
{
auto severity = token{.colorCode = color_codes::FG_WHITE, .content = "INFO"};
auto content = token{.content = message, .delimiter = ""};
log({severity, content});
}
void usinfo(const std::string& message)
{
auto severity = token{.colorCode = color_codes::FG_WHITE, .content = "INFO"};
auto content = token{.content = message, .delimiter = ""};
log({severity, content});
}
void verbose(const std::string& message)
{
auto timestamp = token{.content = jlog::get_timestamp()};
auto severity = token{.colorCode = color_codes::FG_CYAN, .content = "VERBOSE"};
auto content = token{.content = message, .delimiter = ""};
log({timestamp, severity, content});
}
void sverbose(const std::string& message)
{
auto severity = token{.colorCode = color_codes::FG_CYAN, .content = "VERBOSE"};
auto content = token{.content = message, .delimiter = ""};
log({severity, content});
}
void usverbose(const std::string& message)
{
auto severity = token{.colorCode = color_codes::FG_CYAN, .content = "VERBOSE"};
auto content = token{.content = message, .delimiter = ""};
log({severity, content});
}
void debug(const std::string& message)
{
auto timestamp = token{.content = jlog::get_timestamp()};
auto severity = token{.colorCode = color_codes::FG_GREEN, .content = "DEBUG"};
auto content = token{.content = message, .delimiter = ""};
log({timestamp, severity, content});
}
void sdebug(const std::string& message)
{
auto severity = token{.colorCode = color_codes::FG_GREEN, .content = "DEBUG"};
auto content = token{.content = message, .delimiter = ""};
log({severity, content});
}
void usdebug(const std::string& message)
{
auto severity = token{.colorCode = color_codes::FG_GREEN, .content = "DEBUG"};
auto content = token{.content = message, .delimiter = ""};
log({severity, content});
}
void warning(const std::string& message)
{
auto timestamp = token{.content = jlog::get_timestamp()};
auto severity = token{.colorCode = color_codes::FG_YELLOW, .content = "WARNING"};
auto content = token{.content = message, .delimiter = ""};
log({timestamp, severity, content});
}
void swarning(const std::string& message)
{
auto severity = token{.colorCode = color_codes::FG_YELLOW, .content = "WARNING"};
auto content = token{.content = message, .delimiter = ""};
log({severity, content});
}
void uswarning(const std::string& message)
{
auto severity = token{.colorCode = color_codes::FG_YELLOW, .content = "WARNING"};
auto content = token{.content = message, .delimiter = ""};
log({severity, content});
}
void error(const std::string& message)
{
auto timestamp = token{.content = jlog::get_timestamp()};
auto severity = token{.colorCode = color_codes::FG_RED, .content = "ERROR"};
auto content = token{.content = message, .delimiter = ""};
log({timestamp, severity, content});
}
void serror(const std::string& message)
{
auto severity = token{.colorCode = color_codes::FG_RED, .content = "ERROR"};
auto content = token{.content = message, .delimiter = ""};
log({severity, content});
}
void userror(const std::string& message)
{
auto severity = token{.colorCode = color_codes::FG_RED, .content = "ERROR"};
auto content = token{.content = message, .delimiter = ""};
log({severity, content});
}
void fatal(const std::string& message)
{
auto timestamp = token{.content = jlog::get_timestamp()};
auto severity = token{.colorCode = color_codes::FG_BRIGHT_RED, .content = "FATAL"};
auto content = token{.content = message, .delimiter = ""};
log({timestamp, severity, content});
}
void sfatal(const std::string& message)
{
auto timestamp = token{.content = jlog::get_timestamp()};
auto severity = token{.colorCode = color_codes::FG_BRIGHT_RED, .content = "FATAL"};
auto content = token{.content = message, .delimiter = ""};
log({severity, content});
}
void usfatal(const std::string& message)
{
auto timestamp = token{.content = jlog::get_timestamp()};
auto severity = token{.colorCode = color_codes::FG_BRIGHT_RED, .content = "FATAL"};
auto content = token{.content = message, .delimiter = ""};
log({severity, content});
}
std::vector<token> info_detailed_format(
const std::string& message,
const std::string& func,
const std::string& file,
int line)
{
return log_detailed_format("INFO", message, func, file, line);
}
std::vector<token> warning_detailed_format(
const std::string& message,
const std::string& func,
const std::string& file,
int line)
{
return log_detailed_format("WARNING", message, func, file, line, color_codes::FG_YELLOW);
}
std::vector<token> error_detailed_format(
const std::string& message,
const std::string& func,
const std::string& file,
int line)
{
return log_detailed_format("ERROR", message, func, file, line, color_codes::FG_RED);
}
std::vector<token> fatal_format(const std::string& message)
{
return log_format("FATAL", message, color_codes::FG_BRIGHT_RED);
}
std::vector<token> verbose_detailed_format(
const std::string& message,
const std::string& func,
const std::string& file,
int line)
{
return log_detailed_format("VERBOSE", message, func, file, line, color_codes::FG_CYAN);
}
std::vector<token> fatal_detailed_format(
const std::string& message,
const std::string& func,
const std::string& file,
int line)
{
return log_detailed_format("FATAL", message, func, file, line, color_codes::FG_BRIGHT_RED);
}
std::vector<token> log_format(
const std::string& severity_name,
const std::string& message,
const colorcode& severity_cc)
{
auto severity = token{.colorCode = severity_cc, .content = severity_name};
auto content = token{.content = message, .delimiter = ""};
return {severity, content};
}
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)
{
std::vector<token> tokens;
auto timestamp = token{.content = jlog::get_timestamp()};
auto tf_tokens = jlog::trace_format(func, file, line);
auto lf_tokens = jlog::log_format(severity_name, message, severity_cc);
tokens.push_back(timestamp);
tokens.insert(tokens.end(), tf_tokens.begin(), tf_tokens.end());
tokens.insert(tokens.end(), lf_tokens.begin(), lf_tokens.end());
return tokens;
}
void info_spec(const std::string& message, const std::string& func, const std::string& file, int line)
{
auto timestamp = token{.content = jlog::get_timestamp()};
auto severity = token{.colorCode = color_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({timestamp, trace, filedata, severity, content});
}
void sinfo_spec(const std::string& message, const std::string& func, const std::string& file, int line)
{
auto severity = token{.colorCode = color_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});
}
void usinfo_spec(const std::string& message, const std::string& func, const std::string& file, int line)
{
auto severity = token{.colorCode = color_codes::FG_WHITE, .content = "INFO"};
auto content = token{.content = message, .delimiter = ""};
log({severity, content});
}
void verbose_spec(const std::string& message, const std::string& func, const std::string& file, int line)
{
auto timestamp = token{.content = jlog::get_timestamp()};
auto severity = token{.colorCode = color_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, int line)
{
auto severity = token{.colorCode = color_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, int line)
{
auto severity = token{.colorCode = color_codes::FG_CYAN, .content = "VERBOSE"};
auto content = token{.content = message, .delimiter = ""};
log({severity, content});
}
void debug_spec(const std::string& message, const std::string& func, const std::string& file, int line)
{
auto timestamp = token{.content = jlog::get_timestamp()};
auto severity = token{.colorCode = color_codes::FG_GREEN, .content = "DEBUG"};
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 sdebug_spec(const std::string& message, const std::string& func, const std::string& file, int line)
{
auto severity = token{.colorCode = color_codes::FG_GREEN, .content = "DEBUG"};
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 usdebug_spec(const std::string& message, const std::string& func, const std::string& file, int line)
{
auto severity = token{.colorCode = color_codes::FG_GREEN, .content = "DEBUG"};
auto content = token{.content = message, .delimiter = ""};
log({severity, content});
}
void warning_spec(const std::string& message, const std::string& func, const std::string& file, int line)
{
auto timestamp = token{.content = jlog::get_timestamp()};
auto severity = token{.colorCode = color_codes::FG_GREEN, .content = "WARNING"};
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 swarning_spec(const std::string& message, const std::string& func, const std::string& file, int line)
{
auto severity = token{.colorCode = color_codes::FG_GREEN, .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, int line)
{
auto severity = token{.colorCode = color_codes::FG_GREEN, .content = "WARNING"};
auto content = token{.content = message, .delimiter = ""};
log({severity, content});
}
void error_spec(const std::string& message, const std::string& func, const std::string& file, int line)
{
auto timestamp = token{.content = jlog::get_timestamp()};
auto severity = token{.colorCode = color_codes::FG_GREEN, .content = "ERROR"};
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 serror_spec(const std::string& message, const std::string& func, const std::string& file, int line)
{
auto severity = token{.colorCode = color_codes::FG_RED, .content = "ERROR"};
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 userror_spec(const std::string& message, const std::string& func, const std::string& file, int line)
{
auto severity = token{.colorCode = color_codes::FG_RED, .content = "ERROR"};
auto content = token{.content = message, .delimiter = ""};
log({severity, content});
}
void fatal_spec(const std::string& message, const std::string& func, const std::string& file, int line)
{
auto timestamp = token{.content = jlog::get_timestamp()};
auto severity = token{.colorCode = color_codes::FG_RED, .content = "FATAL"};
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 sfatal_spec(const std::string& message, const std::string& func, const std::string& file, int line)
{
auto timestamp = token{.content = jlog::get_timestamp()};
auto severity = token{.colorCode = color_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 severity = token{.colorCode = color_codes::FG_BRIGHT_RED, .content = "FATAL"};
auto content = token{.content = message, .delimiter = ""};
log({severity, content});
}
}

View File

@@ -1,28 +0,0 @@
#include <jlog/jlog.hpp>
#include <string>
inline void SetConsoleTextColor(WORD color) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
}
namespace jlog
{
void log(const std::vector<token> tokens) {
for (const token& t : tokens) {
if (!t.delimiter.empty()) {
SetConsoleTextColor(t.colorCode.nt_code);
log_to_console(std::string(1, t.delimiter[0]) + t.content + std::string(1, t.delimiter[1]) + " ");
log_to_file(std::string(1, t.delimiter[0]) + t.content + std::string(1, t.delimiter[1]) + " ");
} else {
SetConsoleTextColor(t.colorCode.nt_code);
log_to_console(t.content + " ");
log_to_file(t.content + " ");
}
}
SetConsoleTextColor(color_codes::FG_DEFAULT.nt_code);
log_to_console("\n");
log_to_file("\n");
}
}