Compare commits
10 Commits
Prerelease
...
Prerelease
Author | SHA1 | Date | |
---|---|---|---|
623b9efc26 | |||
f74b97ac11 | |||
abb9eed60f | |||
5675480499 | |||
3e414abc8d | |||
69ef213d85 | |||
22e75476f3 | |||
e5d8ea5faa | |||
e870007004 | |||
4138b45404 |
@@ -3,10 +3,10 @@
|
||||
/// 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 <format>
|
||||
#include <string>
|
||||
#include <Event.h>
|
||||
#include <jlog/color_codes.hpp>
|
||||
@@ -21,14 +21,16 @@
|
||||
|
||||
namespace jlog
|
||||
{
|
||||
/// Severity levels for logging. Higher numbers filter less messages out.
|
||||
/// @see LOG_LEVEL macro
|
||||
enum class severity : uint8_t
|
||||
{
|
||||
none,
|
||||
warning,
|
||||
error,
|
||||
fatal,
|
||||
verbose,
|
||||
debug,
|
||||
none, // Show no output
|
||||
fatal, // Show only fatal errors
|
||||
error, // Show fatal and not-necessarily-fatal errors
|
||||
warning, // Show warnings additionally
|
||||
verbose, // Show errors, warnings, and 'verbose' output (i.e. extra information)
|
||||
debug, // Show debugging messages (Basically everything).
|
||||
};
|
||||
|
||||
inline severity loglevel = severity::debug; // Default log level always debug
|
||||
@@ -40,10 +42,13 @@ namespace jlog
|
||||
std::string timestamp;
|
||||
};
|
||||
|
||||
// TODO: Fully implement logging callback.
|
||||
static Event<LogEntry> on_log = Event<LogEntry>();
|
||||
|
||||
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
|
||||
{
|
||||
colorcode colorCode = color_codes::FG_DEFAULT;
|
||||
@@ -51,23 +56,71 @@ namespace jlog
|
||||
std::string delimiter = "[]";
|
||||
};
|
||||
|
||||
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
|
||||
/// @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);
|
||||
|
||||
/// 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, const std::string& filename);
|
||||
void log(std::vector<token> tokens);
|
||||
void ltlog(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,
|
||||
@@ -76,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__)); }
|
||||
@@ -140,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__)); }
|
||||
|
||||
|
3
main.cpp
3
main.cpp
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -1,17 +1,31 @@
|
||||
#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 + " ");
|
||||
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(std::vector<token> tokens, const std::string& filename)
|
||||
{
|
||||
log_to_console(toks2consoleMsg(tokens));
|
||||
log_to_console("\n");
|
||||
log_to_file("\n");
|
||||
log_to_file(filename, toks2logfileMsg(tokens));
|
||||
log_to_file(filename, "\n");
|
||||
}
|
||||
}
|
@@ -5,6 +5,15 @@
|
||||
|
||||
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;
|
||||
@@ -29,11 +38,55 @@ namespace jlog
|
||||
|
||||
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.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);
|
||||
}
|
||||
|
||||
void log(std::vector<token> tokens)
|
||||
{
|
||||
log(tokens, default_logfile);
|
||||
}
|
||||
|
||||
// Mainly for debug purposes
|
||||
void ltlog(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,
|
||||
@@ -78,145 +131,6 @@ namespace jlog
|
||||
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,
|
||||
|
@@ -1,3 +1,5 @@
|
||||
|
||||
|
||||
#include <jlog/jlog.hpp>
|
||||
#include <string>
|
||||
|
||||
|
Reference in New Issue
Block a user