Doing some cleaning up. There is now a Timestamp type used for log formatting.

This commit is contained in:
2024-08-14 12:31:19 -04:00
parent b19e2ea651
commit c5b9d50a2b
8 changed files with 165 additions and 94 deletions

View File

@@ -2,6 +2,29 @@
#include "token.hpp"
namespace jlog {
class Timestamp {
public:
Timestamp();
public:
std::chrono::year Year() {return y;};
std::chrono::month Month() {return m;};
std::chrono::day Day() {return d;}
std::chrono::duration<long, std::ratio<3600>> Hour() {return h;};
std::chrono::duration<long, std::ratio<60>> Minute() {return M;};
std::chrono::duration<long> Second() {return s;};
std::chrono::duration<long, std::ratio<1, 1000>> Millisecond() {return ms;};
private:
std::chrono::year y;
std::chrono::month m;
std::chrono::day d;
std::chrono::duration<long, std::ratio<3600>> h;
std::chrono::duration<long, std::ratio<60>> M;
std::chrono::duration<long> s;
std::chrono::duration<long, std::ratio<1, 1000>> ms;
};
std::vector<token> timestamp_format(Timestamp tstamp);
/// Returns a string timestamp in the format of 'YYYY-MM-DD hh:mm:ss.ms'
std::string get_timestamp();
@@ -38,93 +61,6 @@ namespace jlog {
int line,
const Color4 &severity_cc = Colors::White);
/// Returns a token sequence pre-formatted for the info LogTrace 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 LogTrace 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 LogTrace 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 LogTrace 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 LogTrace 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 LogTrace 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 LogTrace 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 LogTrace 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 LogTrace 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 LogTrace 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 LogTrace 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 LogTrace 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);
// Generic token for line ending
//const token endl = {.content = std::endl, .delimiter = ""};
}

View File

@@ -1,9 +1,23 @@
#pragma once
#include <string>
#include <jlog/token.hpp>
namespace jlog
{
/// Writes a std::vector of tokens directly to standard output
void LogToConsole(const std::vector<token>& ts);
/// Writes a std::string directly to standard output
void LogToConsole(const std::string& s);
/// Writes a std::vector of tokens to the specified logfile
void LogToFile(const std::string& filename, const std::vector<token>& ts);
/// Writes a std::string to the specified logfile
void LogToFile(const std::string& filename, const std::string& s);
/*
/// 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);
@@ -11,4 +25,5 @@ namespace jlog
/// 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);
*/
}

View File

@@ -16,6 +16,56 @@ namespace jlog {
std::string delimiter = "[]";
};
//class TokenStringer {
//public:
// virtual std::string Stringer(std::vector<token> ts) = 0;
//};
// I did these after reading the Bjarne book.
// May or may not be a good idea, but it looks cool(?)
class WithColor {
public:
static std::string Stringer(std::vector<token> ts) {
std::string msg;
for (const token &t: ts) {
if (!t.delimiter.empty()) {
msg += std::format("{}{}{}{}{} ",
mcolor::toEscapeCode(t.colorCode),
t.delimiter[0], t.content,
t.delimiter[1],
mcolor::toEscapeCode(AnsiColor::RESET));
} else {
msg += std::format("{}{}{} ",
mcolor::toEscapeCode(t.colorCode),
t.content,
mcolor::toEscapeCode(AnsiColor::RESET));
}
}
return msg;
};
};
class WithoutColor {
public:
static std::string Stringer(std::vector<token> ts) {
std::string msg;
for (const token &t: ts) {
if (!t.delimiter.empty())
msg += std::format("{}{}{} ", t.delimiter[0], t.content, t.delimiter[1]);
else
msg += t.content + " ";
}
return msg;
}
};
// By default we use the WithColor token stringer
template<class S = WithColor>
std::string TokensToString(std::vector<token> ts) {
return S::Stringer(ts);
}
/// These are helper functions designed to be wrapped around for easier custom logger building.
std::string toks2msg(std::vector<token> tokens, std::function<std::string(token)>);
std::string consoleMsgFormatter(token t);

View File

@@ -74,7 +74,8 @@ int main()
demo.OnLogEvent += [](std::vector<jlog::token> t) {
jlog::token dbg = {.colorCode = jlog::debug.GetColorCode(), .content = "This message is only seen when the event hook is added."};
jlog::log_to_console(jlog::toks2consoleMsg(std::vector<jlog::token>{dbg}));
//jlog::log_to_console(jlog::toks2consoleMsg(std::vector<jlog::token>{dbg}));
jlog::LogToConsole(std::vector<jlog::token>{dbg});
};
demo("After event hook");

View File

@@ -7,6 +7,22 @@
#include "jlog/token.hpp"
namespace jlog {
Timestamp::Timestamp() {
auto const timestamp = std::chrono::current_zone()->to_local(std::chrono::system_clock::now());
auto dp = floor<std::chrono::days>(timestamp);
std::chrono::year_month_day ymd{floor<std::chrono::days>(timestamp)};
std::chrono::hh_mm_ss time{floor<std::chrono::milliseconds>(timestamp - dp)};
y = ymd.year();
m = ymd.month();
d = ymd.day();
h = time.hours();
M = time.minutes();
s = time.seconds();
ms = time.subseconds();
}
// [2024-Aug-14 12:0:58.815]
std::string get_timestamp() {
using namespace std::chrono;
auto const timestamp = current_zone()->to_local(system_clock::now());
@@ -22,6 +38,10 @@ namespace jlog {
auto ms = time.subseconds();
return std::format("{}-{}-{} {}:{}:{}.{}", y, m, d, h.count(), M.count(), s.count(), ms.count());
}
//[2024-Aug-14 12:0:58.815]
std::vector<token> timestamp_format(Timestamp tstamp) {
return std::vector<token>{{.content = std::format("{}-{}-{} {}:{}:{}.{}", tstamp.Year(), tstamp.Month(), tstamp.Day(), tstamp.Hour().count(), tstamp.Minute().count(), tstamp.Second().count(), tstamp.Millisecond().count())}};
}
std::vector<token> trace_format(
const std::string& func,
@@ -52,12 +72,16 @@ namespace jlog {
const Color4& severity_cc)
{
std::vector<token> tokens;
auto timestamp = token{.content = jlog::get_timestamp()};
//auto timestamp = token{.content = jlog::get_timestamp()};
auto tsf_tokens = jlog::timestamp_format(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.push_back(timestamp);
tokens.insert(tokens.end(), tsf_tokens.begin(), tsf_tokens.end());
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,4 +1,5 @@
#include <mcolor.h>
#include <jlog/token.hpp>
#include <jlog/io.hpp>
#include <fstream>
#include <iostream>
@@ -6,6 +7,34 @@
namespace jlog
{
// Is there really a need for this? No, I'm just being consistent.
void LogToConsole(const std::string& s) {
std::cout << s;
}
void LogToConsole(const std::vector<token>& ts) {
// Disable color output on Windows for now.
#ifdef WIN32
//std::cout << TokensToString<WithoutColor>(ts);
LogToConsole(TokensToString<WithoutColor>(ts));
#else
//std::cout << TokensToString(ts);//<< std::endl;
LogToConsole(TokensToString(ts));
#endif
}
void LogToFile(const std::string& filename, const std::string& s) {
std::ofstream logfile(filename, std::ios_base::app);
logfile << s;// << std::endl;
logfile.close();
}
void LogToFile(const std::string& filename, const std::vector<token>& ts) {
LogToFile(filename, TokensToString<WithoutColor>(ts));
}
/*
void log_to_console(const std::string& message)
{
#ifdef WIN32
@@ -20,4 +49,5 @@ namespace jlog
latest_log << message;
latest_log.close();
}
*/
}

View File

@@ -24,8 +24,15 @@ namespace jlog
OnLogEvent(fmt);
jlog::log_to_console(jlog::toks2consoleMsg(fmt) + '\n');
jlog::log_to_file(this->logfile, jlog::toks2logfileMsg(fmt) + '\n');
//jlog::log_to_console(jlog::toks2consoleMsg(fmt) + '\n');
//jlog::log_to_file(this->logfile, jlog::toks2logfileMsg(fmt) + '\n');
//jlog::log_to_console(jlog::TokensToString(fmt) + '\n');
//jlog::log_to_file(logfile, jlog::TokensToString<WithoutColor>(fmt) + '\n');
LogToConsole(fmt);
LogToConsole("\n");
//LogToConsole(std::vector<token>{jlog::endl});
LogToFile(logfile, fmt);
LogToFile(logfile, "\n");
}
void Logger::SetEnabled(bool state) {

View File

@@ -6,6 +6,14 @@
#include <jlog/token.hpp>
namespace jlog {
//template<class S = WithColor>
//template<class S>
//std::string TokensToString(std::vector<token> ts) {
// return S::Stringer(ts);
//}
std::string toks2msg(std::vector <token> tokens, std::function<std::string(token)> formatter) {
std::string msg;
for (const token &t: tokens) {