
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