[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