
6 changed files with 307 additions and 0 deletions
@ -0,0 +1,170 @@ |
|||||
|
#include "valog.h" |
||||
|
#include "valog.hh" |
||||
|
#include <iostream> |
||||
|
#include <sstream> |
||||
|
#include <cstdarg> |
||||
|
#include <unistd.h> |
||||
|
#include <thread> |
||||
|
#include <cmath> |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
const char* _orca_log_level_to_string(const ORCA_LOG_LEVEL* level) |
||||
|
{ |
||||
|
switch (*level) { |
||||
|
case ORCA_LOG_LEVEL_ERROR: |
||||
|
return "ERROR"; |
||||
|
case ORCA_LOG_LEVEL_WARNING: |
||||
|
return "WARN"; |
||||
|
case ORCA_LOG_LEVEL_TRACE: |
||||
|
return "TRACE"; |
||||
|
default: |
||||
|
return "invalid log level"; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void _orca_log( |
||||
|
ORCA_LOG_LEVEL level, |
||||
|
const char* file, |
||||
|
int line, |
||||
|
const char* funcname, |
||||
|
const char* fmt, |
||||
|
...) |
||||
|
{ |
||||
|
std::string msg{ "orca log subsystem error" }; |
||||
|
va_list var_args; |
||||
|
va_start(var_args, fmt); |
||||
|
|
||||
|
char* msg_fmtd = nullptr; |
||||
|
int size = vasprintf(&msg_fmtd, fmt, var_args); |
||||
|
if (size >= 0) { |
||||
|
std::stringstream header{}; |
||||
|
header << _orca_log_level_to_string(&level) << " "; |
||||
|
header << getpid() << " "; |
||||
|
header << std::this_thread::get_id() << " "; |
||||
|
header << file << ":"; |
||||
|
header << line << " "; |
||||
|
header << funcname << " "; |
||||
|
msg = header.str() + " - " + std::string(msg_fmtd); |
||||
|
} |
||||
|
free(msg_fmtd); |
||||
|
Orca::Log::log(msg); |
||||
|
va_end(var_args); |
||||
|
} |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
std::ostream& operator<<(std::ostream& o, const ORCA_LOG_LEVEL* level) |
||||
|
{ |
||||
|
return o << std::string(_orca_log_level_to_string(level)); |
||||
|
} |
||||
|
|
||||
|
namespace Orca { |
||||
|
namespace Utils { |
||||
|
std::string to_termcol(const Color& col) |
||||
|
{ |
||||
|
switch (col) { |
||||
|
case Color::RESET: |
||||
|
return "\033[0m"; |
||||
|
case Color::BLACK: |
||||
|
return "\033[30m"; |
||||
|
case Color::RED: |
||||
|
return "\033[31m"; |
||||
|
case Color::GREEN: |
||||
|
return "\033[32m"; |
||||
|
case Color::YELLOW: |
||||
|
return "\033[33m"; |
||||
|
case Color::BLUE: |
||||
|
return "\033[34m"; |
||||
|
case Color::MAGENTA: |
||||
|
return "\033[35m"; |
||||
|
case Color::CYAN: |
||||
|
return "\033[36m"; |
||||
|
case Color::WHITE: |
||||
|
return "\033[37m"; |
||||
|
default: |
||||
|
return "\033[0m"; |
||||
|
} |
||||
|
} |
||||
|
} // namespace Utils
|
||||
|
} // namespace Orca
|
||||
|
|
||||
|
namespace Orca { |
||||
|
namespace Log { |
||||
|
int line_width = 120; |
||||
|
|
||||
|
// NON CLASS
|
||||
|
std::mutex mtx; |
||||
|
std::atomic_bool is_enabled{ false }; |
||||
|
|
||||
|
void set_enabled(const bool& enabled) |
||||
|
{ |
||||
|
is_enabled.store(enabled); |
||||
|
} |
||||
|
|
||||
|
bool get_enabled() |
||||
|
{ |
||||
|
return is_enabled.load(); |
||||
|
} |
||||
|
|
||||
|
// Common "print" function implementing the actual "backends"
|
||||
|
void _log(const std::string& msg, Utils::Color col = Utils::Color::WHITE) |
||||
|
{ |
||||
|
std::lock_guard<std::mutex> l(mtx); |
||||
|
std::cerr << Utils::to_termcol(col) << msg << Utils::to_termcol(Utils::Color::RESET) |
||||
|
<< std::endl; //endl also flushes, but cerr is unbuffered anyways
|
||||
|
} |
||||
|
|
||||
|
void log(const std::string& msg, Utils::Color col) |
||||
|
{ |
||||
|
_log(msg, col); |
||||
|
} |
||||
|
|
||||
|
void logH1(const std::string& msg, Utils::Color col) |
||||
|
{ |
||||
|
log(decorate_three_lines(msg, '='), col); |
||||
|
} |
||||
|
|
||||
|
void logH2(const std::string& msg, Utils::Color col) |
||||
|
{ |
||||
|
log("\n" + decorate_centered(msg, '='), col); |
||||
|
} |
||||
|
|
||||
|
void logH3(const std::string& msg, Utils::Color col) |
||||
|
{ |
||||
|
log(decorate_centered(msg, '-'), col); |
||||
|
} |
||||
|
|
||||
|
std::string decorate_three_lines(const std::string& msg, char decoration) |
||||
|
{ |
||||
|
std::stringstream tmp; |
||||
|
tmp << std::string(line_width, decoration) << std::endl |
||||
|
<< msg << std::endl |
||||
|
<< std::string(line_width, decoration); |
||||
|
return tmp.str(); |
||||
|
} |
||||
|
|
||||
|
std::string decorate_centered(const std::string& msg, char decoration) |
||||
|
{ |
||||
|
std::stringstream tmp; |
||||
|
size_t max_len = line_width - 10; |
||||
|
// truncate msg
|
||||
|
std::string msg_truncated = msg; |
||||
|
if (msg.length() >= max_len) { |
||||
|
msg_truncated = msg.substr(0, max_len); |
||||
|
msg_truncated += "..."; |
||||
|
} |
||||
|
|
||||
|
// define decolen
|
||||
|
int decolen = static_cast<int>(floor((double(line_width - msg_truncated.length()))) / 2.0); |
||||
|
|
||||
|
tmp << std::string(decolen, decoration) << ' ' << msg_truncated << ' ' |
||||
|
<< std::string(decolen, decoration); |
||||
|
return tmp.str(); |
||||
|
} |
||||
|
} // namespace Log
|
||||
|
} // namespace Orca
|
@ -0,0 +1,17 @@ |
|||||
|
#ifndef _ORCA_VALOG_H |
||||
|
#define _ORCA_VALOG_H |
||||
|
|
||||
|
#include "valog_internal.h" |
||||
|
|
||||
|
#define ORCA_LOG_ERR(...) ORCA_LOG(ORCA_LOG_LEVEL_ERROR, __VA_ARGS__) |
||||
|
|
||||
|
#define ORCA_LOG_WARN(...) ORCA_LOG(ORCA_LOG_LEVEL_WARN, __VA_ARGS__) |
||||
|
|
||||
|
#define ORCA_LOG_TRACE(...) ORCA_LOG(ORCA_LOG_LEVEL_TRACE, __VA_ARGS__) |
||||
|
|
||||
|
#define ORCA_LOG(level, ...) \ |
||||
|
do { \ |
||||
|
_orca_log(level, __FILE__, __LINE__, ORCA_MACRO_FUNCNAME, "" __VA_ARGS__); \ |
||||
|
} while (0) |
||||
|
|
||||
|
#endif |
@ -0,0 +1,49 @@ |
|||||
|
#ifndef _ORCA_VALOG_HH |
||||
|
#define _ORCA_VALOG_HH |
||||
|
|
||||
|
#include <string> |
||||
|
#include "valog_internal.h" |
||||
|
|
||||
|
#define ORCA_LOG_ERR(...) ORCA_LOG(ORCA_LOG_LEVEL_ERROR, __VA_ARGS__) |
||||
|
|
||||
|
#define ORCA_LOG_WARN(...) ORCA_LOG(ORCA_LOG_LEVEL_WARN, __VA_ARGS__) |
||||
|
|
||||
|
#define ORCA_LOG_TRACE(...) ORCA_LOG(ORCA_LOG_LEVEL_TRACE, __VA_ARGS__) |
||||
|
|
||||
|
#define ORCA_LOG(level, ...) \ |
||||
|
do { \ |
||||
|
_orca_log(level, __FILE__, __LINE__, ORCA_MACRO_FUNCNAME, "" __VA_ARGS__); \ |
||||
|
} while (0) |
||||
|
|
||||
|
|
||||
|
namespace Orca { |
||||
|
namespace Utils { |
||||
|
enum class Color { |
||||
|
RESET, |
||||
|
BLACK, |
||||
|
RED, |
||||
|
GREEN, |
||||
|
YELLOW, |
||||
|
BLUE, |
||||
|
MAGENTA, |
||||
|
CYAN, |
||||
|
WHITE, |
||||
|
}; |
||||
|
std::string to_termcol(const Color& col); |
||||
|
} // namespace Utils
|
||||
|
|
||||
|
namespace Log { |
||||
|
void set_enabled(const bool& is_enabled); |
||||
|
bool get_enabled(); |
||||
|
void log(const std::string& msg, Utils::Color col = Utils::Color::WHITE); |
||||
|
void logH1(const std::string& msg, Utils::Color col = Utils::Color::WHITE); |
||||
|
void logH2(const std::string& msg, Utils::Color col = Utils::Color::WHITE); |
||||
|
void logH3(const std::string& msg, Utils::Color col = Utils::Color::WHITE); |
||||
|
std::string decorate_three_lines(const std::string& msg, char decoration = '-'); |
||||
|
std::string decorate_centered(const std::string& msg, char decoration = '-'); |
||||
|
} // namespace Log
|
||||
|
} // namespace Orca
|
||||
|
|
||||
|
std::ostream& operator<<(std::ostream& o, const ORCA_LOG_LEVEL* level); |
||||
|
|
||||
|
#endif |
@ -0,0 +1,35 @@ |
|||||
|
#ifndef _ORCA_VALOG_INTERNAL_H |
||||
|
#define _ORCA_VALOG_INTERNAL_H |
||||
|
|
||||
|
#define ORCA_HAVE_PRETTY_FUNCTION 1 |
||||
|
#ifdef ORCA_HAVE_PRETTY_FUNCTION |
||||
|
#define ORCA_MACRO_FUNCNAME __PRETTY_FUNCTION__ |
||||
|
#else |
||||
|
#define ORCA_func_OR_PRETTY_FUNCTION __func__ |
||||
|
#endif |
||||
|
|
||||
|
typedef enum { |
||||
|
ORCA_LOG_LEVEL_ERROR = 100, |
||||
|
ORCA_LOG_LEVEL_WARNING = 200, |
||||
|
ORCA_LOG_LEVEL_TRACE = 300, |
||||
|
} ORCA_LOG_LEVEL; |
||||
|
|
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
void _orca_log( |
||||
|
ORCA_LOG_LEVEL level, |
||||
|
const char* file, |
||||
|
int line, |
||||
|
const char* funcname, |
||||
|
const char* fmt, |
||||
|
...); |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
|
||||
|
#endif |
@ -0,0 +1,17 @@ |
|||||
|
//#include <iostream>
|
||||
|
#include <stdio.h> |
||||
|
#include <stdlib.h> |
||||
|
#include <string.h> |
||||
|
#include "../src/valog.h" |
||||
|
|
||||
|
|
||||
|
int main() |
||||
|
{ |
||||
|
// C usage
|
||||
|
ORCA_LOG_ERR(); |
||||
|
ORCA_LOG_ERR("HELLO"); |
||||
|
char *str = strdup("fds"); |
||||
|
ORCA_LOG_ERR("string: %s", str); |
||||
|
|
||||
|
free(str); |
||||
|
} |
@ -0,0 +1,19 @@ |
|||||
|
//#include <iostream>
|
||||
|
//#include <stdio.h>
|
||||
|
#include <iostream> |
||||
|
#include <cstring> |
||||
|
#include "../src/valog.h" |
||||
|
#include <string> |
||||
|
|
||||
|
int main() |
||||
|
{ |
||||
|
// C++ usage
|
||||
|
ORCA_LOG_ERR(); |
||||
|
ORCA_LOG_ERR("HELLO"); |
||||
|
std::string str{ "fds" }; |
||||
|
ORCA_LOG_ERR("string: %s", str.c_str()); |
||||
|
// {
|
||||
|
// // C++ usage
|
||||
|
// ORCA_LOG_ERR("%s",std::string("test: " + std::string(str) + "end").c_str());
|
||||
|
// }
|
||||
|
} |
Loading…
Reference in new issue