diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5f9e326 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +example/* +!example/example.cpp +!example/CMakeLists.txt +.ccls-cache/ +compile_commands.json diff --git a/README.md b/README.md index 07289fc..01b5af1 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,17 @@ # YOLO: You Only Log Once +The super simple BLAZING FAST c++ logging library + +```cpp +#include "yolo/yolo.hpp" + +yolo::info("Hello, World! {}", 42); +``` + +The simplest possible form of module logging for super speed + +```cpp +auto mod = yolo::registerModule("MODULE", "\001bansi;m"); +yolo::debug(mod, "This is a debug message {}", "Incredible!"); +``` + diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt new file mode 100644 index 0000000..a017362 --- /dev/null +++ b/example/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.9) + +project(yolo_example) + +add_executable(yolo_example example.cpp) +target_include_directories(yolo_example PRIVATE "../include") + diff --git a/example/example.cpp b/example/example.cpp new file mode 100644 index 0000000..8f663c4 --- /dev/null +++ b/example/example.cpp @@ -0,0 +1,17 @@ +#include "yolo/yolo.hpp" + +int main(int, char**) +{ + int x = 12; + int y = 3; + yolo::info("value for x is {} and value for y is {}", x, y); + + auto mod = yolo::registerModule("COMPONENT", "\u001b[35;1m"); + yolo::info(mod, "value for x is {} and value for y is {}", x, y); + yolo::warn(mod, "value for x is {} and value for y is {}", x, y); + yolo::error(mod, "value for x is {} and value for y is {}", x, y); + yolo::debug(mod, "value for x is {} and value for y is {}", x, y); + + return 0; +} + diff --git a/include/yolo/yolo.hpp b/include/yolo/yolo.hpp new file mode 100644 index 0000000..e1130b6 --- /dev/null +++ b/include/yolo/yolo.hpp @@ -0,0 +1,119 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace yolo { + +namespace detail { + static std::vector> modules; + + template + std::string format(const std::string& format, Args... args) + { + std::ostringstream oss; + size_t start = 0; size_t pos; + ((oss << format.substr(start, (pos = format.find("{}", start)) - start) << args, start = pos + 2), ...); + oss << format.substr(start); + return oss.str(); + } + + std::string formatTime() + { + auto now = std::chrono::system_clock::now(); + std::time_t time = std::chrono::system_clock::to_time_t(now); + std::tm local_time = *std::localtime(&time); + auto ms = std::chrono::duration_cast(now.time_since_epoch()).count() % 1000; + std::ostringstream oss; + oss << std::put_time(&local_time, "%H:%M:%S.") << std::setfill('0') << std::setw(3) << ms; + return oss.str(); + } +} + +template +inline void __log(const std::string& level, const std::string& col, const std::string& message, Args... args) +{ + std::cout + << '[' << detail::formatTime() << "] " + << '[' << col << level << "\033[0m" << "] " + << detail::format(message, args...) << std::endl; +} + +template +inline void __log(uint8_t module, const std::string& level, const std::string& col, const std::string& message, Args... args) +{ + auto mod = detail::modules[module]; + std::cout + << '[' << detail::formatTime() << "] " + << '[' << col << level << "\033[0m" << "] " + << '[' << mod.second << mod.first << "\033[0m" << "] " + << detail::format(message, args...) << std::endl; +} + + +template +inline void info(const std::string& format, Args&&... args) +{ + __log("INFO", "\u001b[32;1m", format, args...); +} + +template +inline void warn(const std::string& format, Args&&... args) +{ + __log("WARN", "\u001b[33;1m", format, args...); +} + +template +inline void error(const std::string& format, Args&&... args) +{ + __log("ERROR", "\u001b[31;1m", format, args...); +} + +template +inline void debug(const std::string& format, Args&&... args) +{ + __log("DEBUG", "\u001b[34;1m", format, args...); +} + + +template +inline void info(uint8_t module, const std::string& format, Args&&... args) +{ + __log(module, "INFO", "\u001b[32;1m", format, args...); +} + +template +inline void warn(uint8_t module, const std::string& format, Args&&... args) +{ + __log(module, "WARN", "\u001b[33;1m", format, args...); +} + +template +inline void error(uint8_t module, const std::string& format, Args&&... args) +{ + __log(module, "ERROR", "\u001b[31;1m", format, args...); +} + +template +inline void debug(uint8_t module, const std::string& format, Args&&... args) +{ + __log(module, "DEBUG", "\u001b[34;1m", format, args...); +} + + +// Registers a module with a name and an optional ANSI colour code.. +// this will return a reference that you can pass for future logs +// which will format the logger correctly to your name and colour +inline uint8_t registerModule(std::string name, std::string ANSI) +{ + detail::modules.push_back(std::make_pair(name, ANSI)); + return detail::modules.size() - 1; +} + +} +