[DEV] basic simple log lib
This commit is contained in:
parent
818ede7c21
commit
31bdec208d
15
elog/debug.cpp
Normal file
15
elog/debug.cpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/**
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
*
|
||||||
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||||
|
*
|
||||||
|
* @license APACHE v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <elog/debug.h>
|
||||||
|
|
||||||
|
int32_t elog::getLogId() {
|
||||||
|
static int32_t g_val = elog::registerInstance("elog");
|
||||||
|
return g_val;
|
||||||
|
}
|
||||||
|
|
45
elog/debug.h
Normal file
45
elog/debug.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/**
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
*
|
||||||
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||||
|
*
|
||||||
|
* @license APACHE v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <elog/log.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
namespace elog {
|
||||||
|
int32_t getLogId();
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ELOG_BASIC(info,data) ELOG_BASE(elog::getLogId(),info,data)
|
||||||
|
|
||||||
|
#define ELOG_PRINT(data) ELOG_BASIC(-1, data)
|
||||||
|
#define ELOG_CRITICAL(data) ELOG_BASIC(1, data)
|
||||||
|
#define ELOG_ERROR(data) ELOG_BASIC(2, data)
|
||||||
|
#define ELOG_WARNING(data) ELOG_BASIC(3, data)
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define ELOG_INFO(data) ELOG_BASIC(4, data)
|
||||||
|
#define ELOG_DEBUG(data) ELOG_BASIC(5, data)
|
||||||
|
#define ELOG_VERBOSE(data) ELOG_BASIC(6, data)
|
||||||
|
#define ELOG_TODO(data) ELOG_BASIC(4, "TODO : " << data)
|
||||||
|
#else
|
||||||
|
#define ELOG_INFO(data) do { } while(false)
|
||||||
|
#define ELOG_DEBUG(data) do { } while(false)
|
||||||
|
#define ELOG_VERBOSE(data) do { } while(false)
|
||||||
|
#define ELOG_TODO(data) do { } while(false)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ELOG_HIDDEN(data) do { } while(false)
|
||||||
|
|
||||||
|
#define ELOG_ASSERT(cond,data) \
|
||||||
|
do { \
|
||||||
|
if (!(cond)) { \
|
||||||
|
ELOG_CRITICAL(data); \
|
||||||
|
assert(!#cond); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
523
elog/log.cpp
Normal file
523
elog/log.cpp
Normal file
@ -0,0 +1,523 @@
|
|||||||
|
/**
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
*
|
||||||
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||||
|
*
|
||||||
|
* @license APACHE v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <elog/log.h>
|
||||||
|
#include <elog/debug.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
|
#include <map>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#ifdef ELOG_BUILD_ETHREAD
|
||||||
|
#include <ethread/tools.h>
|
||||||
|
#endif
|
||||||
|
#include <elog/debug.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#if defined(__TARGET_OS__Android)
|
||||||
|
# include <android/log.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <elog/logIOs.h>
|
||||||
|
|
||||||
|
#if !defined(__STDCPP_LLVM__) && defined(__TARGET_OS__Linux) && defined(DEBUG)
|
||||||
|
#include <execinfo.h>
|
||||||
|
#include <cxxabi.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#define MAX_DEPTH (256)
|
||||||
|
void elog::displayBacktrace(bool _breakAtEnd, int32_t _removeElement) {
|
||||||
|
// retrieve call-stack
|
||||||
|
void * trace[MAX_DEPTH];
|
||||||
|
int stack_depth = backtrace(trace, MAX_DEPTH);
|
||||||
|
|
||||||
|
ELOG_ERROR("Back-trace : ");
|
||||||
|
for (int32_t i = 1; i < stack_depth; i++) {
|
||||||
|
Dl_info dlinfo;
|
||||||
|
if(!dladdr(trace[i], &dlinfo)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const char * symname = dlinfo.dli_sname;
|
||||||
|
int status;
|
||||||
|
char * demangled = abi::__cxa_demangle(symname, nullptr, 0, &status);
|
||||||
|
if(status == 0 && demangled) {
|
||||||
|
symname = demangled;
|
||||||
|
}
|
||||||
|
if (_removeElement <= 0) {
|
||||||
|
ELOG_WARNING(" " << dlinfo.dli_fname << ": ");
|
||||||
|
ELOG_ERROR(" " << symname);
|
||||||
|
}
|
||||||
|
_removeElement--;
|
||||||
|
if(demangled != nullptr) {
|
||||||
|
free(demangled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_breakAtEnd == true) {
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void elog::displayBacktrace(bool _breakAtEnd, int32_t _removeElement) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
assert(false);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define DEFAULT_LOG_LEVEL elog::logLevelInfo
|
||||||
|
#define DEFAULT_LOG_COLOR true
|
||||||
|
#define DEFAULT_LOG_LINE true
|
||||||
|
#define DEFAULT_LOG_THREAD_ID true
|
||||||
|
#define DEFAULT_LOG_THREAD_NAME true
|
||||||
|
#define DEFAULT_LOG_CLASS true
|
||||||
|
#define DEFAULT_LOG_TIME true
|
||||||
|
#define DEFAULT_LOG_LIB_NAME true
|
||||||
|
#else
|
||||||
|
#define DEFAULT_LOG_LEVEL elog::logLevelNone
|
||||||
|
#define DEFAULT_LOG_COLOR false
|
||||||
|
#define DEFAULT_LOG_LINE false
|
||||||
|
#define DEFAULT_LOG_THREAD_ID false
|
||||||
|
#define DEFAULT_LOG_THREAD_NAME false
|
||||||
|
#define DEFAULT_LOG_CLASS false
|
||||||
|
#define DEFAULT_LOG_TIME true
|
||||||
|
#define DEFAULT_LOG_LIB_NAME true
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum elog::level& getDefaultLevel() {
|
||||||
|
static enum elog::level g_val = DEFAULT_LOG_LEVEL;
|
||||||
|
return g_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t& getFunctionSizeLog() {
|
||||||
|
static size_t g_val = 5;
|
||||||
|
return g_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t& getThreadSizeLog() {
|
||||||
|
static size_t g_val = 5;
|
||||||
|
return g_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t& getNameSizeLog() {
|
||||||
|
static size_t g_val = 5;
|
||||||
|
return g_val;
|
||||||
|
}
|
||||||
|
static std::vector<std::pair<std::string, enum elog::level> >& getList() {
|
||||||
|
static std::vector<std::pair<std::string, enum elog::level> > g_val;
|
||||||
|
return g_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t elog::registerInstance(const std::string& _name) {
|
||||||
|
for (size_t iii = 0; iii < getList().size(); ++iii) {
|
||||||
|
if (getList()[iii].first == _name) {
|
||||||
|
return iii;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getList().push_back(std::make_pair(_name, getDefaultLevel()));
|
||||||
|
if (_name.size() >= getNameSizeLog()) {
|
||||||
|
getNameSizeLog() = _name.size()+1;
|
||||||
|
}
|
||||||
|
//std::cout << "register log : '" << _name << "'=" << getList().size()-1 << std::endl;
|
||||||
|
return getList().size()-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void elog::setLevel(const std::string& _name, enum level _level) {
|
||||||
|
for (size_t iii = 0; iii < getList().size(); ++iii) {
|
||||||
|
if (getList()[iii].first == _name) {
|
||||||
|
getList()[iii].second = _level;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getList().push_back(std::make_pair(_name, _level));
|
||||||
|
}
|
||||||
|
|
||||||
|
void elog::setLevel(enum level _level) {
|
||||||
|
getDefaultLevel() = _level;
|
||||||
|
for (size_t iii = 0; iii < getList().size(); ++iii) {
|
||||||
|
getList()[iii].second = _level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void elog::setLevel(int32_t _id, enum level _level) {
|
||||||
|
if (_id < 0 || _id > (int32_t)getList().size()) {
|
||||||
|
// ERROR...
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
getList()[_id].second = _level;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t elog::getLevel(int32_t _id) {
|
||||||
|
if (_id < 0 || _id > (int32_t)getList().size()) {
|
||||||
|
// ERROR...
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (int32_t)getList()[_id].second;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> elog::getListInstance() {
|
||||||
|
std::vector<std::string> out;
|
||||||
|
for (size_t iii = 0; iii < getList().size(); ++iii) {
|
||||||
|
out.push_back(getList()[iii].first);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
void elog::logStream(int32_t _id, int32_t _level, int32_t _ligne, const char* _className, const char* _funcName, const std::ostream& _log) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << _log.rdbuf();
|
||||||
|
std::string sss =oss.str();
|
||||||
|
elog::logChar(_id, _level, _ligne, _className, _funcName, sss.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void elog::logChar1(int32_t _id, int32_t _level, const char* _log) {
|
||||||
|
elog::logChar(_id, _level, -1, nullptr, nullptr, _log);
|
||||||
|
}
|
||||||
|
|
||||||
|
void elog::logStream1(int32_t _id, int32_t _level, const std::ostream& _log) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << _log.rdbuf();
|
||||||
|
std::string sss =oss.str();
|
||||||
|
elog::logChar(_id, _level, -1, nullptr, nullptr, sss.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool& getColor() {
|
||||||
|
static bool g_val = DEFAULT_LOG_COLOR;
|
||||||
|
return g_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void elog::setColor(bool _status) {
|
||||||
|
getColor() = _status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool& getTime() {
|
||||||
|
static bool g_val = DEFAULT_LOG_TIME;
|
||||||
|
return g_val;
|
||||||
|
}
|
||||||
|
void elog::setTime(bool _status) {
|
||||||
|
getTime() = _status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool& getLine() {
|
||||||
|
static bool g_val = DEFAULT_LOG_LINE;
|
||||||
|
return g_val;
|
||||||
|
}
|
||||||
|
void elog::setLine(bool _status) {
|
||||||
|
getLine() = _status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool& getThreadId() {
|
||||||
|
static bool g_val = DEFAULT_LOG_THREAD_ID;
|
||||||
|
return g_val;
|
||||||
|
}
|
||||||
|
void elog::setThreadId(bool _status) {
|
||||||
|
getThreadId() = _status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool& getThreadNameEnable() {
|
||||||
|
static bool g_val = DEFAULT_LOG_THREAD_NAME;
|
||||||
|
return g_val;
|
||||||
|
}
|
||||||
|
void elog::setThreadNameEnable(bool _status) {
|
||||||
|
getThreadNameEnable() = _status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool& getFunction() {
|
||||||
|
static bool g_val = DEFAULT_LOG_CLASS;
|
||||||
|
return g_val;
|
||||||
|
}
|
||||||
|
void elog::setFunction(bool _status) {
|
||||||
|
getFunction() = _status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool& getLibName() {
|
||||||
|
static bool g_val = DEFAULT_LOG_LIB_NAME;
|
||||||
|
return g_val;
|
||||||
|
}
|
||||||
|
void elog::setLibName(bool _status) {
|
||||||
|
getLibName() = _status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void getDisplayTime(char* data) {
|
||||||
|
#ifdef __TARGET_OS__Android
|
||||||
|
struct timeval now;
|
||||||
|
gettimeofday(&now, nullptr);
|
||||||
|
sprintf(data, " %2dh%2d'%2d ", (int32_t)(now.tv_sec/3600)%24, (int32_t)(now.tv_sec/60)%60, (int32_t)(now.tv_sec%60));
|
||||||
|
#else
|
||||||
|
time_t rawtime;
|
||||||
|
struct tm * timeinfo;
|
||||||
|
time(&rawtime);
|
||||||
|
timeinfo = localtime(&rawtime);
|
||||||
|
sprintf(data, " %2dh%2d'%2d ", (timeinfo->tm_hour)%24, timeinfo->tm_min, timeinfo->tm_sec);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//regular colors
|
||||||
|
#define ETK_BASH_COLOR_BLACK "\e[0;30m"
|
||||||
|
#define ETK_BASH_COLOR_RED "\e[0;31m"
|
||||||
|
#define ETK_BASH_COLOR_GREEN "\e[0;32m"
|
||||||
|
#define ETK_BASH_COLOR_YELLOW "\e[0;33m"
|
||||||
|
#define ETK_BASH_COLOR_BLUE "\e[0;34m"
|
||||||
|
#define ETK_BASH_COLOR_MAGENTA "\e[0;35m"
|
||||||
|
#define ETK_BASH_COLOR_CYAN "\e[0;36m"
|
||||||
|
#define ETK_BASH_COLOR_WHITE "\e[0;37m"
|
||||||
|
//emphasized (bolded) colors
|
||||||
|
#define ETK_BASH_COLOR_BOLD_BLACK "\e[1;30m"
|
||||||
|
#define ETK_BASH_COLOR_BOLD_RED "\e[1;31m"
|
||||||
|
#define ETK_BASH_COLOR_BOLD_GREEN "\e[1;32m"
|
||||||
|
#define ETK_BASH_COLOR_BOLD_YELLOW "\e[1;33m"
|
||||||
|
#define ETK_BASH_COLOR_BOLD_BLUE "\e[1;34m"
|
||||||
|
#define ETK_BASH_COLOR_BOLD_MAGENTA "\e[1;35m"
|
||||||
|
#define ETK_BASH_COLOR_BOLD_CYAN "\e[1;36m"
|
||||||
|
#define ETK_BASH_COLOR_BOLD_WHITE "\e[1;37m"
|
||||||
|
//background colors
|
||||||
|
#define ETK_BASH_COLOR_BG_BLACK "\e[40m"
|
||||||
|
#define ETK_BASH_COLOR_BG_RED "\e[41m"
|
||||||
|
#define ETK_BASH_COLOR_BG_GREEN "\e[42m"
|
||||||
|
#define ETK_BASH_COLOR_BG_YELLOW "\e[43m"
|
||||||
|
#define ETK_BASH_COLOR_BG_BLUE "\e[44m"
|
||||||
|
#define ETK_BASH_COLOR_BG_MAGENTA "\e[45m"
|
||||||
|
#define ETK_BASH_COLOR_BG_CYAN "\e[46m"
|
||||||
|
#define ETK_BASH_COLOR_BG_WHITE "\e[47m"
|
||||||
|
// Return to the normal color setings
|
||||||
|
#define ETK_BASH_COLOR_NORMAL "\e[0m"
|
||||||
|
//go to the Top of bash
|
||||||
|
#define ETK_BASH_GO_TOP "\e[0;0f"
|
||||||
|
|
||||||
|
#define LENGHT_MAX_LOG (2048)
|
||||||
|
|
||||||
|
void elog::logChar(int32_t _id, int32_t _level, int32_t _ligne, const char* _className, const char* _funcName, const char* _log) {
|
||||||
|
static std::mutex g_lock;
|
||||||
|
char handle[LENGHT_MAX_LOG] = "";
|
||||||
|
memset(handle, ' ', LENGHT_MAX_LOG);
|
||||||
|
handle[0] = '\0';
|
||||||
|
char* pointer = handle;
|
||||||
|
if(getColor() == true) {
|
||||||
|
switch(_level) {
|
||||||
|
default:
|
||||||
|
// nothing to do ...
|
||||||
|
break;
|
||||||
|
case logLevelCritical:
|
||||||
|
strcat(pointer, ETK_BASH_COLOR_BOLD_RED);
|
||||||
|
break;
|
||||||
|
case logLevelError:
|
||||||
|
strcat(pointer, ETK_BASH_COLOR_RED);
|
||||||
|
break;
|
||||||
|
case logLevelWarning:
|
||||||
|
strcat(pointer, ETK_BASH_COLOR_MAGENTA);
|
||||||
|
break;
|
||||||
|
case logLevelInfo:
|
||||||
|
strcat(pointer, ETK_BASH_COLOR_CYAN);
|
||||||
|
break;
|
||||||
|
case logLevelDebug:
|
||||||
|
strcat(pointer, ETK_BASH_COLOR_YELLOW);
|
||||||
|
break;
|
||||||
|
case logLevelVerbose:
|
||||||
|
strcat(pointer, ETK_BASH_COLOR_WHITE);
|
||||||
|
break;
|
||||||
|
case logLevelPrint:
|
||||||
|
strcat(pointer, ETK_BASH_COLOR_WHITE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pointer = handle+strlen(handle);
|
||||||
|
}
|
||||||
|
if(getTime() == true) {
|
||||||
|
getDisplayTime(pointer);
|
||||||
|
pointer = handle+strlen(handle);
|
||||||
|
}
|
||||||
|
#ifndef __TARGET_OS__Android
|
||||||
|
switch(_level) {
|
||||||
|
default:
|
||||||
|
strcat(pointer, "[?] ");
|
||||||
|
break;
|
||||||
|
case logLevelPrint:
|
||||||
|
strcat(pointer, "[P] ");
|
||||||
|
break;
|
||||||
|
case logLevelCritical:
|
||||||
|
strcat(pointer, "[C] ");
|
||||||
|
break;
|
||||||
|
case logLevelError:
|
||||||
|
strcat(pointer, "[E] ");
|
||||||
|
break;
|
||||||
|
case logLevelWarning:
|
||||||
|
strcat(pointer, "[W] ");
|
||||||
|
break;
|
||||||
|
case logLevelInfo:
|
||||||
|
strcat(pointer, "[I] ");
|
||||||
|
break;
|
||||||
|
case logLevelDebug:
|
||||||
|
strcat(pointer, "[D] ");
|
||||||
|
break;
|
||||||
|
case logLevelVerbose:
|
||||||
|
strcat(pointer, "[V] ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pointer = handle+strlen(handle);
|
||||||
|
#endif
|
||||||
|
if (getLibName() == true) {
|
||||||
|
if (_id >= 0) {
|
||||||
|
int32_t len = strlen(handle);
|
||||||
|
strcat(pointer, getList()[_id].first.c_str());
|
||||||
|
pointer = handle+strlen(handle);
|
||||||
|
while (strlen(handle) - len < getNameSizeLog()) {
|
||||||
|
*pointer++ = ' ';
|
||||||
|
*pointer = '\0';
|
||||||
|
}
|
||||||
|
*pointer++ = '|';
|
||||||
|
*pointer++ = ' ';
|
||||||
|
*pointer = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef ELOG_BUILD_ETHREAD
|
||||||
|
if(getThreadId() == true) {
|
||||||
|
// display thread ID
|
||||||
|
uint32_t iddd = ethread::getId();
|
||||||
|
sprintf(pointer, "%3d", iddd);
|
||||||
|
pointer = handle+strlen(handle);
|
||||||
|
*pointer++ = ' ';
|
||||||
|
*pointer++ = '|';
|
||||||
|
*pointer++ = ' ';
|
||||||
|
*pointer = '\0';
|
||||||
|
}
|
||||||
|
if(getThreadNameEnable() == true) {
|
||||||
|
// display thread ID
|
||||||
|
std::string name = ethread::getName();
|
||||||
|
if (name.size() >= getThreadSizeLog() ) {
|
||||||
|
getThreadSizeLog() = name.size() + 1;
|
||||||
|
}
|
||||||
|
sprintf(pointer, "%s", name.c_str());
|
||||||
|
pointer = handle+strlen(handle);
|
||||||
|
size_t nbSpaceToAdd = getThreadSizeLog()-name.size();
|
||||||
|
for (size_t iii=0; iii<nbSpaceToAdd; ++iii) {
|
||||||
|
*pointer++ = ' ';
|
||||||
|
*pointer = '\0';
|
||||||
|
}
|
||||||
|
*pointer++ = '|';
|
||||||
|
*pointer++ = ' ';
|
||||||
|
*pointer = '\0';
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if(getLine() == true) {
|
||||||
|
if (_ligne >= 0) {
|
||||||
|
sprintf(pointer, "(l=%5d)", _ligne);
|
||||||
|
pointer = handle+strlen(handle);
|
||||||
|
*pointer++ = ' ';
|
||||||
|
*pointer = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO :Maybe optimize this one ...
|
||||||
|
if(getFunction() == true) {
|
||||||
|
int32_t len = strlen(handle);
|
||||||
|
char tmpName[1024];
|
||||||
|
char *tmpPointer = tmpName;
|
||||||
|
#ifndef __TARGET_OS__Android
|
||||||
|
if (_className != nullptr) {
|
||||||
|
snprintf(tmpPointer, 1024, "%s::", _className);
|
||||||
|
tmpPointer = tmpPointer+strlen(tmpPointer);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (_funcName != nullptr) {
|
||||||
|
#if defined(__TARGET_OS__Android)
|
||||||
|
// cleen for android :
|
||||||
|
char* startPos = strchr(_funcName, ' ');
|
||||||
|
char* stopPos = strchr(_funcName, '(');
|
||||||
|
if (startPos != nullptr) {
|
||||||
|
if (stopPos != nullptr) {
|
||||||
|
if(stopPos < startPos) {
|
||||||
|
snprintf(tmpPointer, std::min(1024, int32_t(stopPos-_funcName)), "%s", _funcName);
|
||||||
|
} else {
|
||||||
|
snprintf(tmpPointer, std::min(1024, int32_t(stopPos-startPos)), "%s", startPos+1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
snprintf(tmpPointer, 1024, "%s", startPos);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (stopPos != nullptr) {
|
||||||
|
snprintf(tmpPointer, std::min(1024, int32_t(stopPos-_funcName)), "%s", _funcName);
|
||||||
|
} else {
|
||||||
|
snprintf(tmpPointer, 1024, "%s", _funcName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
snprintf(tmpPointer, 1024, "%s", _funcName);
|
||||||
|
#endif
|
||||||
|
tmpPointer = tmpPointer+strlen(tmpPointer);
|
||||||
|
}
|
||||||
|
size_t lenFunc = strlen(tmpName);
|
||||||
|
if (lenFunc >= getFunctionSizeLog()) {
|
||||||
|
getFunctionSizeLog() = lenFunc+1;
|
||||||
|
}
|
||||||
|
size_t nbSpaceToAdd = getFunctionSizeLog() - lenFunc;
|
||||||
|
for (size_t iii=0; iii<nbSpaceToAdd; ++iii) {
|
||||||
|
*tmpPointer++ = ' ';
|
||||||
|
*tmpPointer = '\0';
|
||||||
|
}
|
||||||
|
*tmpPointer++ = '|';
|
||||||
|
*tmpPointer++ = ' ';
|
||||||
|
*tmpPointer = '\0';
|
||||||
|
strcat(pointer, tmpName);
|
||||||
|
pointer += strlen(tmpName);
|
||||||
|
}
|
||||||
|
if (strlen(_log) > LENGHT_MAX_LOG - strlen(handle)-20) {
|
||||||
|
memcpy(pointer, _log, LENGHT_MAX_LOG - strlen(handle)-21);
|
||||||
|
handle[1024-25] = ' ';
|
||||||
|
handle[1024-24] = '.';
|
||||||
|
handle[1024-23] = '.';
|
||||||
|
handle[1024-22] = '.';
|
||||||
|
handle[1024-21] = '\0';
|
||||||
|
} else {
|
||||||
|
strcat(pointer, _log);
|
||||||
|
}
|
||||||
|
pointer = handle+strlen(handle);
|
||||||
|
if(getColor() == true) {
|
||||||
|
strcat(pointer, ETK_BASH_COLOR_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_lock.lock();
|
||||||
|
#if defined(__TARGET_OS__Android)
|
||||||
|
// TODO : Set package name instead of ewol ...
|
||||||
|
switch(_level) {
|
||||||
|
default:
|
||||||
|
__android_log_print(ANDROID_LOG_VERBOSE, "EWOL", "%s", handle);
|
||||||
|
break;
|
||||||
|
case logLevelPrint:
|
||||||
|
__android_log_print(ANDROID_LOG_INFO, "EWOL", "%s", handle);
|
||||||
|
break;
|
||||||
|
case logLevelCritical:
|
||||||
|
__android_log_print(ANDROID_LOG_FATAL, "EWOL", "%s", handle);
|
||||||
|
break;
|
||||||
|
case logLevelError:
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "EWOL", "%s", handle);
|
||||||
|
break;
|
||||||
|
case logLevelWarning:
|
||||||
|
__android_log_print(ANDROID_LOG_WARN, "EWOL", "%s", handle);
|
||||||
|
break;
|
||||||
|
case logLevelInfo:
|
||||||
|
__android_log_print(ANDROID_LOG_INFO, "EWOL", "%s", handle);
|
||||||
|
break;
|
||||||
|
case logLevelDebug:
|
||||||
|
__android_log_print(ANDROID_LOG_DEBUG, "EWOL", "%s", handle);
|
||||||
|
break;
|
||||||
|
case logLevelVerbose:
|
||||||
|
__android_log_print(ANDROID_LOG_VERBOSE, "EWOL", "%s", handle);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#elif defined(__TARGET_OS__IOs)
|
||||||
|
iosNSLog(handle);
|
||||||
|
#else
|
||||||
|
std::cout << handle << std::endl;
|
||||||
|
#endif
|
||||||
|
g_lock.unlock();
|
||||||
|
if (_level == logLevelCritical) {
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(700));
|
||||||
|
displayBacktrace(true, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
130
elog/log.h
Normal file
130
elog/log.h
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
/**
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
*
|
||||||
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||||
|
*
|
||||||
|
* @license APACHE v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <ostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace elog {
|
||||||
|
/**
|
||||||
|
* @brief Log level is a simple list of all log availlable. This enum is used when setting a log and when user chose the level of log displayed.
|
||||||
|
*/
|
||||||
|
enum level {
|
||||||
|
logLevelPrint = -1, //!< basic print for Help or result (never filtered)
|
||||||
|
logLevelNone = 0, //!< no display requested
|
||||||
|
logLevelCritical = 1, //!< Display only critical logs (note that critical generally assert with a backtrace (when we can))
|
||||||
|
logLevelError = 2, //!< Display Error and critical logs
|
||||||
|
logLevelWarning = 3, //!< Display log critical to warning
|
||||||
|
logLevelInfo = 4, //!< Display log critical to information (removed in release mode)
|
||||||
|
logLevelDebug = 5, //!< Display log critical to debug (removed in release mode)
|
||||||
|
logLevelVerbose = 6 //!< Display all logs (removed in release and debug mode)
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* @brief Register an element in the log system
|
||||||
|
* @param[in] _name Name of the module
|
||||||
|
* @return reference Id of an instance name
|
||||||
|
*/
|
||||||
|
int32_t registerInstance(const std::string& _name);
|
||||||
|
/**
|
||||||
|
* @brief Set the log level of a specific instance
|
||||||
|
* @param[in] _name Name of the intance
|
||||||
|
* @param[in] _id Id of the intance
|
||||||
|
* @param[in] _level New level to set on the instance
|
||||||
|
*/
|
||||||
|
void setLevel(const std::string& _name, enum level _level);
|
||||||
|
//! @previous
|
||||||
|
void setLevel(int32_t _id, enum level _level);
|
||||||
|
/**
|
||||||
|
* @brief Set global debug level
|
||||||
|
* @param[in] _level New level to set on the instance
|
||||||
|
*/
|
||||||
|
void setLevel(enum level _level);
|
||||||
|
/**
|
||||||
|
* @brief Get the current level of debug for a specific intance
|
||||||
|
* @param[in] _id Id Of the intance
|
||||||
|
* @return the enum casted in an integer ==> generise the API (not dependent of etk)
|
||||||
|
*/
|
||||||
|
int32_t getLevel(int32_t _id);
|
||||||
|
/**
|
||||||
|
* @brief Get list of all intance
|
||||||
|
* @return the name list of all intance
|
||||||
|
*/
|
||||||
|
std::vector<std::string> getListInstance();
|
||||||
|
/**
|
||||||
|
* @brief Set Color enable or disable.
|
||||||
|
* @param[in] _status New value of color.
|
||||||
|
*/
|
||||||
|
void setColor(bool _status);
|
||||||
|
/**
|
||||||
|
* @brief Set Time display enable or disable.
|
||||||
|
* @param[in] _status New value.
|
||||||
|
*/
|
||||||
|
void setTime(bool _status);
|
||||||
|
/**
|
||||||
|
* @brief Set Line display enable or disable.
|
||||||
|
* @param[in] _status New value.
|
||||||
|
*/
|
||||||
|
void setLine(bool _status);
|
||||||
|
/**
|
||||||
|
* @brief Set Function display enable or disable.
|
||||||
|
* @param[in] _status New value.
|
||||||
|
*/
|
||||||
|
void setFunction(bool _status);
|
||||||
|
/**
|
||||||
|
* @brief Set thread id enable or disable.
|
||||||
|
* @param[in] _status New value.
|
||||||
|
*/
|
||||||
|
void setThreadId(bool _status);
|
||||||
|
/**
|
||||||
|
* @brief Set thread name enable or disable.
|
||||||
|
* @param[in] _status New value.
|
||||||
|
*/
|
||||||
|
void setThreadNameEnable(bool _status);
|
||||||
|
/**
|
||||||
|
* @brief Set library display enable or disable.
|
||||||
|
* @param[in] _status New value.
|
||||||
|
*/
|
||||||
|
void setLibName(bool _status);
|
||||||
|
/**
|
||||||
|
* @brief Call log to display
|
||||||
|
* @param[in] _id Id of the instance type
|
||||||
|
* @param[in] _level Level debug
|
||||||
|
* @param[in] _ligne Line of the debug
|
||||||
|
* @param[in] _className Class name of the debug
|
||||||
|
* @param[in] _funcName Function name for debug
|
||||||
|
* @param[in] _log Stream to log
|
||||||
|
*/
|
||||||
|
void logChar(int32_t _id, int32_t _level, int32_t _ligne, const char* _className, const char* _funcName, const char* _log);
|
||||||
|
//! @previous
|
||||||
|
void logStream(int32_t _id, int32_t _level, int32_t _ligne, const char* _className, const char* _funcName, const std::ostream& _log);
|
||||||
|
//! @previous
|
||||||
|
void logChar1(int32_t _id, int32_t _level, const char* _log);
|
||||||
|
//! @previous
|
||||||
|
void logStream1(int32_t _id, int32_t _level, const std::ostream& _log);
|
||||||
|
/**
|
||||||
|
* @brief Display the current backtrace
|
||||||
|
* @param[in] _breakAtEnd assert program when backtrace is printed
|
||||||
|
*/
|
||||||
|
void displayBacktrace(bool _breakAtEnd = false, int32_t _removeElement=0);
|
||||||
|
};
|
||||||
|
#ifdef __class__
|
||||||
|
#undef __class__
|
||||||
|
#endif
|
||||||
|
#define __class__ (nullptr)
|
||||||
|
|
||||||
|
// generic define for all logs::
|
||||||
|
#define ELOG_BASE(logId,info,data) \
|
||||||
|
do { \
|
||||||
|
if (info <= elog::getLevel(logId)) { \
|
||||||
|
std::stringbuf sb; \
|
||||||
|
std::ostream tmpStream(&sb); \
|
||||||
|
tmpStream << data; \
|
||||||
|
elog::logStream(logId, info, __LINE__, __class__, __func__, tmpStream); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
20
elog/logIOs.h
Normal file
20
elog/logIOs.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
*
|
||||||
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||||
|
*
|
||||||
|
* @license APACHE v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
#ifdef __TARGET_OS__IOs
|
||||||
|
void iosNSLog(const char * _value);
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
17
elog/logIOs.m
Normal file
17
elog/logIOs.m
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/**
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
*
|
||||||
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||||
|
*
|
||||||
|
* @license APACHE v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#include <elog/logIOs.h>
|
||||||
|
|
||||||
|
void iosNSLog(const char * _value) {
|
||||||
|
NSLog(@"\r%s", _value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
73
lutin_elog.py
Normal file
73
lutin_elog.py
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
import lutin.module as module
|
||||||
|
import lutin.tools as tools
|
||||||
|
|
||||||
|
|
||||||
|
def get_type():
|
||||||
|
return "LIBRARY"
|
||||||
|
|
||||||
|
def get_desc():
|
||||||
|
return "Ewol log basic interface"
|
||||||
|
|
||||||
|
def get_licence():
|
||||||
|
return "APACHE-2"
|
||||||
|
|
||||||
|
def get_compagny_type():
|
||||||
|
return "com"
|
||||||
|
|
||||||
|
def get_compagny_name():
|
||||||
|
return "atria-soft"
|
||||||
|
|
||||||
|
def get_maintainer():
|
||||||
|
return ["Mr DUPIN Edouard <yui.heero@gmail.com>"]
|
||||||
|
|
||||||
|
def get_version():
|
||||||
|
return [0,1,"dev"]
|
||||||
|
|
||||||
|
def create(target, module_name):
|
||||||
|
my_module = module.Module(__file__, module_name, get_type())
|
||||||
|
my_module.add_extra_compile_flags()
|
||||||
|
# add the file to compile:
|
||||||
|
my_module.add_src_file([
|
||||||
|
'elog/debug.cpp',
|
||||||
|
'elog/log.cpp'
|
||||||
|
])
|
||||||
|
|
||||||
|
if target.name=="IOs":
|
||||||
|
my_module.add_src_file('etk/logIOs.m')
|
||||||
|
|
||||||
|
my_module.add_header_file([
|
||||||
|
'elog/log.h',
|
||||||
|
])
|
||||||
|
|
||||||
|
if target.config["mode"] == "debug":
|
||||||
|
# Bor backtrace display :
|
||||||
|
if target.name != "Windows" \
|
||||||
|
and target.name != "MacOs" \
|
||||||
|
and target.name != "IOs":
|
||||||
|
# TODO : check if it is really needed ...
|
||||||
|
my_module.add_export_flag('link', [
|
||||||
|
'-ldl',
|
||||||
|
'-rdynamic'])
|
||||||
|
elif target.name != "Windows":
|
||||||
|
my_module.add_export_flag('link', [
|
||||||
|
'-ldl'])
|
||||||
|
# build in C++ mode
|
||||||
|
my_module.compile_version("c++", 2011)
|
||||||
|
# add dependency of the generic C++ library:
|
||||||
|
my_module.add_module_depend('cxx')
|
||||||
|
my_module.add_optionnal_module_depend('ethread', ["c++", "-DELOG_BUILD_ETHREAD"])
|
||||||
|
|
||||||
|
if target.name=="Windows":
|
||||||
|
pass
|
||||||
|
elif target.name=="Android":
|
||||||
|
my_module.add_module_depend("SDK")
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
#TODO : Set it in a generic include system
|
||||||
|
my_module.add_export_flag('link-lib', "pthread")
|
||||||
|
|
||||||
|
my_module.add_path(tools.get_current_path(__file__))
|
||||||
|
return my_module
|
||||||
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user