header-only, easy to use, C++ logging library minimum C++17
clone the repo with --recursive, it will clone:
kqlog,
fmt,
magic_enum,
Catch2.
- Linux: clang 15.0.7
- Windows: clang 15.0.7
- Header only
- Allows user defined log types(/levels)
- Log filtering
- Log color
- Custom formtting for log pattern
- Rich formatting, by fmt
- Thread safe
- Backup
- xml for .npp log files (in progress)
by default the logger will output into ./logs.txt (filename="logs.txt", directory="./")
you can change it by providing a filename and directory in the constructor
e.g
kq::logger logger("myfile.txt", "myDirectory/myOutputDirectory/");
Make sure to include any / in your directory
enum class myTypes { /* your types here */ };
kq::logger<myTypes> loggers;
if no template argument is provided, kq::default_symbols is used as a default, containing: (macros)
- KQDEBUG
- KQINFO
- KQWARNING
- KQERROR
- KQCRITICAL
call .out() with an enum type and a format string with all it's argument wrapped in {} e.g
logger.out( KQINFO, { "{} is a nice {}", "Today", "day" } );
output: `[2023-02-27 06:38:11] [INFO] [main@07] Today is a nice day`
by default the logger will have the following pattern:
[{%Y}-{%M}-{%D} {%H}:{%N}:{%S}] [{%T}] [{%F}@{%L}] {%V}
see Pattern Flags for reference you can change this pattern with .set_pattern() and provide a string containing the new pattern to reset to the default pattern call the function with no arguments
kq::logger Logger("logs.txt", "output/");
for(int i = 0; i < 10; ++i)
{
Logger.set_pattern("{%R}[{%Y}-{%M}-{%D}{%y} {%H}:{%N}:{%S}] {%G}[{%T}] {%E}[{%F}@{%L}] {%V}\n");
Logger.out(KQINFO, {"{%C} {0:5} {%g}START", i + 10});
Logger.set_pattern("{%y}[{%Y}-{%M}-{%D}{%G} {%H}:{%N}:{%S}] {%C}[{%T}] [{%F}@{%L}] {%V}\n");
Logger.out(KQDEBUG, {"{%g} {0:5} {%R}CONTINUE", i + 10});
Logger.set_pattern("{%G}[{%Y}-{%M}-{%D}{%C} {%H}:{%N}:{%S}] {%E}[{%T}] [{%F}@{%L}] {%V}\n");
Logger.out(KQCRITICAL, {"{%R} {0:5} {%E}END", i + 10});
}
the .set_filter() function takes as parameters:
a vector containing values from the enum of choice
a bool which if true, will only print the values found in the vector, if false, will only print the values NOT found in the vector
(basically filter in/out)
example:
kq::logger logger;
// logger.set_filter(.....)
logger.out( KQINFO, { "Some info message\n" } );
logger.out( KQDEBUG, { "Some debug message\n" } );
logger.out( KQCRITICAL, { "Some critical message\n" } );with .set_filter({KQINFO}, true), we get the folloiwng console output:
[2023-03-01 20:32:43] [INFO] [main@08] Some info message
with .set_filter({KQINFO}, false), we get the following console output:
[2023-03-01 20:33:35] [DEBUG] [main@09] Some debug message
[2023-03-01 20:33:35] [CRITICAL] [main@10] Some critical message
the file output does not experience any changes
simply call .backup()
it will create backup/ in the directory specified at construction
and will make a copy of the log file with the following pattern name:
{year}-{month}-{day}_{hour}:{min}:{sec}-{filename}
this project was made by me and norctus
we took inspiration from other loggers like spdlog and plog
but we've added our on twist and took a more flexible and different approach on our logger








