84 Commits

Author SHA1 Message Date
6836cab537 Re-enable color output on Windows. 2025-06-04 13:54:50 -05:00
e618fd9b31 Update mcolor package. 2025-04-22 17:28:48 -04:00
884f23f79e Add OnLog event to CompoundLogger 2025-04-04 14:29:31 -04:00
cf4e19e340 Merge remote-tracking branch 'origin/main' 2024-12-25 16:24:50 -05:00
12d3714eda Upgrade to latest Event and mcolor 2024-12-25 16:24:44 -05:00
f3cec87518 LibraryLogger for implementing an easy generic logger that can be toggled for libraries 2024-09-17 23:39:14 -04:00
7c9a3bddc8 Update Token.cpp
fix msvc being stupid
2024-09-14 21:50:46 -04:00
16a2b8ead0 event update 2024-09-12 20:48:09 -04:00
82fb6c64ca Fix cmake_minimum_required using rebitch 2024-08-26 19:45:27 -04:00
b3dbd1b556 It builds now :/ 2024-08-26 12:31:00 -04:00
22a4e02b95 Update CMakeLists.txt
Update components
2024-08-22 11:58:57 -04:00
maxine
e89b7acb00 Merge pull request 'anotherrewrite' (#18) from anotherrewrite into main
Reviewed-on: #18
2024-08-21 13:26:24 -04:00
d62935e72e Updated Event release in cmake file 2024-08-21 13:27:09 -04:00
d704b6c74d Doing some fancying up 2024-08-21 09:23:02 -04:00
d8133772de Another rewrite and total restructure 2024-08-20 20:08:34 -04:00
c65cc4f965 LogEntry class, prettied up code and log output more, OnLogEvent now takes a LogEntry instead of a vector<token> 2024-08-14 15:12:32 -04:00
7aa30a4966 FUCK YOU C++2 2024-08-14 14:44:33 -04:00
b69ba9650b FUCK YOU C++ 2024-08-14 14:36:06 -04:00
maxine
cde1aa507b Merge pull request 'Doing some cleaning up. There is now a Timestamp type used for log formatting.' (#17) from nomacros into main
Reviewed-on: #17
2024-08-14 12:31:10 -04:00
c5b9d50a2b Doing some cleaning up. There is now a Timestamp type used for log formatting. 2024-08-14 12:31:19 -04:00
maxine
bfb6fc0702 Merge pull request 'nomacros' (#16) from nomacros into main
Reviewed-on: #16
2024-08-13 16:21:49 -04:00
b19e2ea651 Added TODO 2024-08-13 16:16:09 -04:00
18dd697470 Disable color output on Windows for now. 2024-08-13 16:14:48 -04:00
ae46df7006 small fix for windows 2024-08-13 16:08:49 -04:00
eb9a2b26b9 Updated README.md 2024-08-13 16:05:40 -04:00
758925c837 Added "No more macros for traceback!" to README.md 2024-08-13 16:04:18 -04:00
d8439efcaf Updated README. New demo image. Fixed typo in demo. 2024-08-13 16:01:38 -04:00
7b25a097cd Made main.cpp more professional 2024-08-13 15:43:05 -04:00
fe158ab88e Make sure we're all up to date 2024-08-13 15:03:15 -04:00
633bee1e9f Using Color4 for logger color codes now. It's 2024 if your terminal doesn't support 16 million colors your terminal sucks 2024-08-13 14:50:39 -04:00
c735e4baa1 Added OnLogEvent 2024-08-13 14:25:54 -04:00
168af78441 Smoothing it out 2024-08-13 13:40:20 -04:00
96b759d54e Decent-size refactor pt1 2024-08-12 23:21:33 -04:00
1ae346304e Stylistic adjustments 2024-08-12 14:08:15 -04:00
2795756235 parent tracing plus other nice stuff 2024-08-12 13:54:20 -04:00
c17a34f0f1 Rewrote logging class/interface bullshit. Anyway it took a while and there's a lot of cool shit. 2024-08-09 16:01:48 -04:00
404c3dceba Rewrote jlog entirely. Macros are no longer needed thanks to C++ builtin shit. There's a lot to cover, so just read the source code if you actually care. 2024-08-08 14:25:34 -04:00
e0b6879ec5 Confirmed setting default log file to NUL on Windows works the same as /dev/null on Linux. Also placed a forgotten semicolon 2024-07-18 11:00:16 -04:00
73f92d0c1a Default logfile can be set to /dev/null on Linux to disable file logging. Supposedly NUL on Windows will work the same way. 2024-07-18 10:58:32 -04:00
maxine
f7ee1a347e Merge pull request 'Allow disabling of console output for logging. New macro CONSOLELOGGING set to true/false to enable/disable.' (#13) from mcolortest into main
Reviewed-on: #13
2024-07-18 10:49:39 -04:00
aace84af52 Allow disabling of console output for logging. New macro CONSOLELOGGING set to true/false to enable/disable. 2024-07-18 10:48:27 -04:00
maxine
47e06dd8ed Merge pull request 'mcolortest merge' (#12) from mcolortest into main
Reviewed-on: #12
2024-07-18 10:05:45 -04:00
cad79a474a Make jlog log_to_console use mcolor windowsSaneify for Windows platform 2024-07-02 13:33:52 -04:00
67a83bbac4 Removed need for jlog to handle colors. Using mcolor library now. 2024-07-02 13:28:00 -04:00
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
maxbyte9p
f22b869335 Added short and ultra short logger messages. 2024-06-15 21:09:28 -04:00
8df5a62597 Fixing more typos in README.md 2024-06-14 13:01:32 -04:00
cd756f7e61 Attempt to publicly expose Event subdependency 2024-06-14 12:54:13 -04:00
24de473770 Add sample output image 2024-06-14 12:48:25 -04:00
17bd6b17ff Fix up README 2024-06-14 12:47:46 -04:00
14 changed files with 419 additions and 382 deletions

2
.gitignore vendored Normal file
View File

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

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.18..27)
cmake_minimum_required(VERSION 3.18..3.27)
PROJECT(jlog
VERSION 1.0
LANGUAGES CXX
@@ -14,18 +14,22 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(cmake/CPM.cmake)
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")
CPMAddPackage(
NAME Event
URL https://git.redacted.cc/josh/Event/archive/Release-6.zip
URL https://git.redacted.cc/josh/Event/archive/Release-12.zip
)
include_directories(${Event_SOURCE_DIR}/include)
CPMAddPackage(
NAME mcolor
URL https://git.redacted.cc/maxine/mcolor/archive/Release-1.zip
)
if (UNIX)
add_library(jlog SHARED ${jlog_SRC})
@@ -33,8 +37,11 @@ endif()
if (WIN32)
add_library(jlog STATIC ${jlog_SRC})
target_compile_options(jlog PRIVATE /wd4005)
endif()
target_include_directories(jlog PUBLIC ${Event_SOURCE_DIR}/include ${mcolor_SOURCE_DIR}/include)
set_target_properties(jlog PROPERTIES LINKER_LANGUAGE CXX)
install(TARGETS ${PROJECT_NAME} DESTINATION lib/${PROJECT_NAME})
@@ -42,5 +49,7 @@ install(FILES ${jlog_HEADERS} DESTINATION include/${PROJECT_NAME})
#add_subdirectory(tests)
target_link_libraries(jlog PUBLIC Event mcolor)
add_executable(LoggerDemo main.cpp)
target_link_libraries(LoggerDemo ${PROJECT_NAME} Event)
target_link_libraries(LoggerDemo PUBLIC jlog)

View File

@@ -8,53 +8,59 @@ jlog is a C++ library for logging to file, console, and event callbacks.
* Modern (C++20)
* Static Library
* Color Output
* Color Output (Now in RGB!)
* Logs to file AND console!
* Idiomatic Event callback for hooking into your game engine gui!
* GCC and MSVC support
* No more macros for traceback!
## Installation
Include this repository as a CPM dependency, and link against the library.
(TODO: Show the relevant CMake script lines.)
```cmake
CPMAddPackage(
NAME Event
URL https://git.redacted.cc/josh/Event/archive/Release-6.zip
NAME jlog
URL https://git.redacted.cc/josh/jlog/archive/Prerelease-7.zip
)
# ...
include_directories(${jlog_SOURCE_DIR}/include)
# ...
target_link_libraries(YourProgram ${PROJECT_NAME} jlog)
target_link_libraries(YourProgram ... jlog)
```
# Usage
Using jlog is straightforward:
```cpp
#include <jlog.h>
#include <jlog/jlog.hpp>
int main() {
jlog::info("This is barely useful information.");
jlog::debug("Debugging Information");
jlog::verbose("Yadda Yadda Yadda");
jlog::warning("Slight miscalculation!");
jlog::error("Oops, something went wrong.");
jlog::fatal("Unrecoverable Error!!!");
return 0;
}
```
## Output
![Should be sample output...](img.png)
## TODO
* Custom Contexts: Allow users to specify custom logging contexts for better organization.
* Disable & sort by context (other categories?)
* Custom Formats: Add support for custom log message formats.
* Documentation
* Thread Safety
* Memory Safety
* Stream Support
* Identify File, Line, Function name via macros (I hate macros!!!)
## License

BIN
img.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

223
include/jlog/Logger.hpp Normal file
View File

@@ -0,0 +1,223 @@
#pragma once
#include <fstream>
#include <iostream>
#include <source_location>
#include <jlog/Token.hpp>
#include <jlog/Timestamp.hpp>
#include <Event.h>
namespace jlog {
class Logger {
public:
Logger(std::ostream &stream = std::cout) : os{stream} {};
public:
void operator()(const std::string &message, const std::source_location &location = std::source_location::current(),
const Timestamp &ts = Timestamp()) {
if (Enable)
Log(message, location, ts);
};
protected:
virtual void
Log(const std::string &message, const std::source_location &location = std::source_location::current(),
const Timestamp &ts = Timestamp()) = 0;
public:
bool Enable = true;
bool IncludeLocation = true;
bool IncludeTimestamp = true;
protected:
std::ostream &os = std::cout;
};
class ColorLogger : public Logger {
public:
ColorLogger(std::ostream &stream = std::cout) : Logger(stream) {};
public:
bool IncludeColor = true;
};
class ConsoleLogger : public ColorLogger {
public:
//explicit ConsoleLogger();
explicit ConsoleLogger(const std::string &context) : ColorLogger() { this->context = context; };
protected:
virtual void
Log(const std::string &message, const std::source_location &location = std::source_location::current(),
const Timestamp &ts = Timestamp()) {
if (!Enable)
return;
if (IncludeTimestamp) {
Timestamp ts;
os << token{std::format(
"{}-{}-{} {}:{}:{}.{}",
ts.Year(),
ts.Month(),
ts.Day(),
ts.Hour().count(),
ts.Minute().count(),
ts.Second().count(),
ts.Millisecond().count()), "[]", timestampColor}.Stringer(IncludeColor);
}
os << token(context, "[]", contextColor).Stringer(IncludeColor);
if (IncludeLocation) {
os << token{location.function_name(), "[]", locationColor}.Stringer(IncludeColor);
os << token{std::format("{}:{}", location.file_name(), location.line()), "[]", locationColor}.Stringer(
IncludeColor);
}
os << token{">>", "", pointerColor}.Stringer(IncludeColor)
<< token(message, "", messageColor).Stringer(IncludeColor) << "\n";
}
protected:
std::string context = "CONSOLE";
protected:
Color4 timestampColor = Colors::Purples::Fuchsia;
Color4 contextColor = Colors::White;
Color4 locationColor = Colors::Pinks::Pink;
Color4 pointerColor = Colors::Pinks::LightPink;
Color4 messageColor = Colors::Greens::LightGreen;
};
class FileLogger : public Logger {
public:
//explicit FileLogger();
explicit FileLogger(const std::string &context, std::ofstream &file) : Logger(
file) { this->context = context; };
protected:
virtual void
Log(const std::string &message, const std::source_location &location = std::source_location::current(),
const Timestamp &ts = Timestamp()) {
if (!Enable)
return;
if (IncludeTimestamp) {
Timestamp ts;
os << token{std::format(
"{}-{}-{} {}:{}:{}.{}",
ts.Year(),
ts.Month(),
ts.Day(),
ts.Hour().count(),
ts.Minute().count(),
ts.Second().count(),
ts.Millisecond().count()), "[]"}.Stringer(false);
}
os << token(context, "[]").Stringer(false);
if (IncludeLocation) {
os << token{location.function_name(), "[]"}.Stringer(false);
os << token{std::format("{}:{}", location.file_name(), location.line()), "[]"}.Stringer(false);
}
os << token{">>", ""}.Stringer(false) << token(message, "").Stringer(false) << "\n";
}
protected:
std::string context = "FILE";
};
class CompoundLogger : protected ConsoleLogger, protected FileLogger {
public:
Event<std::string, Color4> OnLog;
explicit CompoundLogger(const std::string &context, std::ofstream &file) : ConsoleLogger(context),
FileLogger(context, file) {};
public:
void
operator()(const std::string &message, const std::source_location &location = std::source_location::current(),
const Timestamp &ts = Timestamp()) { Log(message, location, ts); };
virtual void
Log(const std::string &message, const std::source_location &location = std::source_location::current(),
const Timestamp &ts = Timestamp()) {
OnLog.Invoke(message, messageColor);
ConsoleLogger::Log(message, location, ts);
FileLogger::Log(message, location, ts);
}
public:
void EnableConsole(bool b) { ConsoleLogger::Enable = b; };
void EnableFile(bool b) { FileLogger::Enable = b; };
void IncludeTimestamp(bool b) {
ConsoleLogger::IncludeTimestamp = b;
FileLogger::IncludeTimestamp = b;
};
void IncludeLocation(bool b) {
ConsoleLogger::IncludeLocation = b;
FileLogger::IncludeLocation = b;
};
void IncludeColor(bool b) { ConsoleLogger::IncludeColor = b; };
};
class GenericLogger : public CompoundLogger {
public:
GenericLogger(const std::string &context,
std::ofstream &file,
Color4 contextColor = Colors::White,
Color4 timestampColor = Colors::Purples::Fuchsia,
Color4 locationColor = Colors::Pinks::Pink,
Color4 pointerColor = Colors::Pinks::LightPink,
Color4 messageColor = Colors::Greens::LightGreen)
: CompoundLogger(context, file) {
this->contextColor = contextColor;
this->timestampColor = timestampColor;
this->locationColor = locationColor;
this->pointerColor = pointerColor;
this->messageColor = messageColor;
}
};
extern std::ofstream GlobalLogFile;
extern GenericLogger Info;
extern GenericLogger Warning;
extern GenericLogger Error;
extern GenericLogger Fatal;
extern GenericLogger Verbose;
extern GenericLogger Debug;
class LibraryLogger {
public:
LibraryLogger(const std::string libname) :
Info {libname + "::" + "info", GlobalLogFile, Colors::Green, Colors::Gray, Colors::Gray, Colors::Green, Colors::White},
Warning {libname + "::" + "warning", GlobalLogFile, Colors::Yellow, Colors::Gray, Colors::Gray, Colors::Yellow, Colors::White},
Error {libname + "::" + "error", GlobalLogFile, Colors::Red, Colors::Gray, Colors::Gray, Colors::Red, Colors::White},
Fatal {libname + "::" + "fatal", GlobalLogFile, Colors::Reds::Crimson, Colors::Gray, Colors::Gray, Colors::Reds::Crimson, Colors::White},
Verbose {libname + "::" + "verbose", GlobalLogFile, Colors::Blue, Colors::Gray, Colors::Gray, Colors::Blue, Colors::White},
Debug {libname + "::" + "debug", GlobalLogFile, Colors::Purples::Purple, Colors::Gray, Colors::Gray, Colors::Purples::Purple, Colors::White}
{}
public:
GenericLogger Info;// {"info", GlobalLogFile, Colors::Green, Colors::Gray, Colors::Gray, Colors::Green, Colors::White};
GenericLogger Warning;// {"warning", GlobalLogFile, Colors::Yellow, Colors::Gray, Colors::Gray, Colors::Yellow, Colors::White};
GenericLogger Error;// {"error", GlobalLogFile, Colors::Red, Colors::Gray, Colors::Gray, Colors::Red, Colors::White};
GenericLogger Fatal;// {"fatal", GlobalLogFile, Colors::Reds::Crimson, Colors::Gray, Colors::Gray, Colors::Reds::Crimson, Colors::White};
GenericLogger Verbose;// {"verbose", GlobalLogFile, Colors::Blue, Colors::Gray, Colors::Gray, Colors::Blue, Colors::White};
GenericLogger Debug;// {"debug", GlobalLogFile, Colors::Purples::Purple, Colors::Gray, Colors::Gray, Colors::Purples::Purple, Colors::White};
public:
void EnableAll(bool b) {
Info.EnableConsole(b);
Info.EnableFile(b);
Warning.EnableConsole(b);
Warning.EnableFile(b);
Error.EnableConsole(b);
Error.EnableFile(b);
Fatal.EnableConsole(b);
Fatal.EnableFile(b);
Verbose.EnableConsole(b);
Verbose.EnableFile(b);
Debug.EnableConsole(b);
Debug.EnableFile(b);
}
};
}

View File

@@ -0,0 +1,26 @@
#pragma once
#include <chrono>
namespace jlog {
class Timestamp {
public:
Timestamp();
public:
[[nodiscard]] std::chrono::year Year() const {return y;};
[[nodiscard]] std::chrono::month Month() const {return m;};
[[nodiscard]] std::chrono::day Day() const {return d;}
[[nodiscard]] std::chrono::duration<long, std::ratio<3600>> Hour() const {return h;};
[[nodiscard]] std::chrono::duration<long, std::ratio<60>> Minute() const {return M;};
[[nodiscard]] std::chrono::duration<long> Second() const {return s;};
[[nodiscard]] std::chrono::duration<long, std::ratio<1, 1000>> Millisecond() const {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;
};
}

30
include/jlog/Token.hpp Normal file
View File

@@ -0,0 +1,30 @@
#pragma once
#include <functional>
#include <string>
#include <ostream>
#include <mcolor.h>
#include <Colors.hpp>
namespace jlog {
using namespace mcolor;
class token {
public:
token(std::string content = "", std::string delimiter = "[]", Color4 colorCode = Colors::White) {
this->colorCode = colorCode;
this->content = content;
this->delimiter = delimiter;
}
public:
std::string Stringer(bool includeColor = true);
std::string StringerWithColor();
std::string StringerWithoutColor();
public:
Color4 colorCode = Colors::White;
std::string content = "";
std::string delimiter = "[]";
};
std::ostream& operator<<(std::ostream& os, token t);
}

View File

@@ -1,109 +0,0 @@
#pragma once
#include <string>
#include <cstdint>
#include <format>
#define ESC "\033["
namespace jlog::ansi_escape_codes
{
static const std::string CURSOR_HOME = "\033[H";
static const std::string ERASE_SCREEN_AFTER_CURSOR = "\033[0J";
static const std::string ERASE_SCREEN_BEFORE_CURSOR = "\033[1J";
static const std::string ERASE_SCREEN_ALL = "\033[2J";
static const std::string ERASE_LINE_AFTER_CURSOR = "\033[0K";
static const std::string ERASE_LINE_BEFORE_CURSOR = "\033[1K";
static const std::string ERASE_LINE_ALL = "\033[2K";
static const std::string RESET = "\033[0m";
static const std::string BOLD = "\033[1m";
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.
/// @see xterm control sequences for a more in-depth list.
/// 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.
static const std::string CURSOR_INVISIBLE = "\033[?25l";
static const std::string CURSOR_VISIBLE = "\033[?25h";
static const std::string RESTORE_SCREEN = "\033[?47l";
static const std::string SAVE_SCREEN = "\033[?47h";
static const std::string FG_BLACK = "\033[30m";
static const std::string FG_RED = "\033[31m";
static const std::string FG_GREEN = "\033[32m";
static const std::string FG_YELLOW = "\033[33m";
static const std::string FG_BLUE = "\033[34m";
static const std::string FG_MAGENTA = "\033[35m";
static const std::string FG_CYAN = "\033[36m";
static const std::string FG_WHITE = "\033[37m";
static const std::string FG_DEFAULT = "\033[39m";
static const std::string FG_BRIGHT_BLACK = "\033[90m";
static const std::string FG_BRIGHT_RED = "\033[91m";
static const std::string FG_BRIGHT_GREEN = "\033[92m";
static const std::string FG_BRIGHT_YELLOW = "\033[93m";
static const std::string FG_BRIGHT_BLUE = "\033[94m";
static const std::string FG_BRIGHT_MAGENTA = "\033[95m";
static const std::string FG_BRIGHT_CYAN = "\033[96m";
static const std::string FG_BRIGHT_WHITE = "\033[97m";
static const std::string BG_BLACK = "\033[40m";
static const std::string BG_RED = "\033[41m";
static const std::string BG_GREEN = "\033[42m";
static const std::string BG_YELLOW = "\033[43m";
static const std::string BG_BLUE = "\033[44m";
static const std::string BG_MAGENTA = "\033[45m";
static const std::string BG_CYAN = "\033[46m";
static const std::string BG_WHITE = "\033[47m";
static const std::string BG_DEFAULT = "\033[49m";
static const std::string BG_BRIGHT_BLACK = "\033[100m";
static const std::string BG_BRIGHT_RED = "\033[101m";
static const std::string BG_BRIGHT_GREEN = "\033[102m";
static const std::string BG_BRIGHT_YELLOW = "\033[103m";
static const std::string BG_BRIGHT_BLUE = "\033[104m";
static const std::string BG_BRIGHT_MAGENTA = "\033[105m";
static const std::string BG_BRIGHT_CYAN = "\033[106m";
static const std::string BG_BRIGHT_WHITE = "\033[107m";
std::string true_color(uint8_t r, uint8_t g, uint8_t b)
{
return std::format("\033[38;2;{};{};{}m", r, g, b);
}
std::string cursor_to(int line, int col)
{
}
std::string cursor_up(int lines)
{
}
std::string cursor_down(int lines)
{
}
std::string cursor_left(int cols)
{
}
std::string cursor_right(int cols)
{
}
std::string cursor_to_col(int col)
{
}
}

View File

@@ -1,78 +0,0 @@
/// Josh's Logger
/// A Redacted Software Product
/// Developed & Maintained by Josh O'Leary
/// This work is dedicated to the public domain.
#pragma once
#include <format>
#include <string>
#include <iostream>
#include <chrono>
#include <Event.h>
#include <fstream>
namespace jlog
{
enum class severity
{
none,
verbose,
debug,
warning,
error,
fatal
};
struct LogEntry
{
severity level;
std::string content;
std::string timestamp;
};
static Event<LogEntry> on_log = Event<LogEntry>();
std::vector<LogEntry> log_history;
struct token
{
std::string colorCode = "";
std::string content = "";
std::string delimiter = "[]";
};
void log(std::vector<token> tokens);
void info (const std::string& message);
void verbose(const std::string& message);
void debug (const std::string& message);
void warning(const std::string& message);
void error (const std::string& message);
void fatal (const std::string& message);
void info_spec(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);
void debug_spec(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);
void error_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);
}
#define INFO(i) jlog::info_spec(i, __PRETTY_FUNCTION__, __FILE__, __LINE__);
#define VERBOSE(i) jlog::verbose_spec(i, __PRETTY_FUNCTION__, __FILE__, __LINE__);
#define DEBUG(i) jlog::debug_spec(i, __PRETTY_FUNCTION__, __FILE__, __LINE__);
#define WARNING(i) jlog::warning_spec(i, __PRETTY_FUNCTION__, __FILE__, __LINE__);
#define ERROR(i) jlog::error_spec(i, __PRETTY_FUNCTION__, __FILE__, __LINE__);
#define FATAL(i) jlog::fatal_spec(i, __PRETTY_FUNCTION__, __FILE__, __LINE__);

View File

@@ -1,15 +1,45 @@
#include <jlog/ansi_escape_codes.hpp>
#include <jlog/jlog.hpp>
// 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/Logger.hpp"
int main()
{
INFO("Do the needful!");
DEBUG("Debugging Message 123");
ERROR("Big problem!");
VERBOSE("Irrelevant message...");
WARNING("Our software suite is only supported on C++20! Get with it grampa.");
mcolor::windowsSaneify();
jlog::GenericLogger Demo("demo", jlog::GlobalLogFile);
Demo("No new demo yet");
jlog::Info("dsadsd");
jlog::Warning("dsadsd");
jlog::Error("dsadsd");
jlog::Fatal("dsadsd");
jlog::Verbose("dsadsd");
jlog::Debug("dsadsd");
jlog::LibraryLogger libtest("JLog");
libtest.Info("A");
libtest.Warning("B");
libtest.Debug("C");
libtest.Error("D");
libtest.Fatal("E");
libtest.Verbose("G");
libtest.EnableAll(false);
libtest.Info("A2");
libtest.Warning("B2");
libtest.Debug("C2");
libtest.Error("D2");
libtest.Fatal("E2");
libtest.Verbose("G2");
FATAL("Real Fuckin Error");
return 0;
///
}
}
//Windows :(
#ifdef _WIN32
extern "C" {
int wmain(int argc, wchar_t* argv[]) {
return main();
}
}
#endif

13
src/jlog/Logger.cpp Normal file
View File

@@ -0,0 +1,13 @@
#include "jlog/Logger.hpp"
#include <fstream>
namespace jlog {
std::ofstream GlobalLogFile("latest.log", std::ios_base::app);
GenericLogger Info {"info", GlobalLogFile, Colors::Green, Colors::Gray, Colors::Gray, Colors::Green, Colors::White};
GenericLogger Warning {"warning", GlobalLogFile, Colors::Yellow, Colors::Gray, Colors::Gray, Colors::Yellow, Colors::White};
GenericLogger Error {"error", GlobalLogFile, Colors::Red, Colors::Gray, Colors::Gray, Colors::Red, Colors::White};
GenericLogger Fatal {"fatal", GlobalLogFile, Colors::Reds::Crimson, Colors::Gray, Colors::Gray, Colors::Reds::Crimson, Colors::White};
GenericLogger Verbose {"verbose", GlobalLogFile, Colors::Blue, Colors::Gray, Colors::Gray, Colors::Blue, Colors::White};
GenericLogger Debug {"debug", GlobalLogFile, Colors::Purples::Purple, Colors::Gray, Colors::Gray, Colors::Purples::Purple, Colors::White};
}

17
src/jlog/Timestamp.cpp Normal file
View File

@@ -0,0 +1,17 @@
#include "jlog/Timestamp.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();
}
}

37
src/jlog/Token.cpp Normal file
View File

@@ -0,0 +1,37 @@
#include <jlog/Token.hpp>
#include <ostream>
namespace jlog {
std::string token::Stringer(bool includeColor) {
std::string msg;
if (!includeColor)
return StringerWithoutColor();
return StringerWithColor();
}
std::string token::StringerWithColor() {
std::string msg;
if (!delimiter.empty()) {
return std::format("{}{}{}{}{} ",
mcolor::toEscapeCode(colorCode),
delimiter[0], content,
delimiter[1],
mcolor::toEscapeCode(AnsiColor::RESET));
}
return std::format("{}{}{} ",
mcolor::toEscapeCode(colorCode),
content,
mcolor::toEscapeCode(AnsiColor::RESET));
}
std::string token::StringerWithoutColor() {
if (!delimiter.empty())
return std::format("{}{}{} ", delimiter[0], content, delimiter[1]);
return content + " ";
}
std::ostream& operator<<(std::ostream& os, token t) {
os << t.Stringer();
return os;
}
}

View File

@@ -1,169 +0,0 @@
#include <source_location>
#include <jlog/ansi_escape_codes.hpp>
#include <jlog/jlog.hpp>
#include <string>
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()
{
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("latest.log", std::ios_base::app);
latest_log << message;
latest_log.close();
}
void log(std::vector<token> tokens) {
for (token t : tokens) {
if (t.delimiter != "") {
log_to_console(std::format("{}{}{}{}{} ", t.colorCode, 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, t.content, ansi_escape_codes::RESET));
log_to_file(t.content + " ");
}
}
log_to_console("\n");
log_to_file("\n");
}
void direct(const std::string &message) { log({{.content = message, .delimiter=""}});}
void info(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({timestamp, severity, content});
}
void verbose(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({timestamp, 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 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 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 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 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 filedata = token{.content = std::format("{}:{}", file, line)};
log({timestamp, trace, filedata, severity, content});
}
void verbose_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_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 debug_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_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 warning_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_YELLOW, .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 error_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_RED, .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 fatal_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({timestamp, trace, filedata, severity, content});
}
}