[DEV] update of external of elog and ethread

This commit is contained in:
Edouard DUPIN 2016-03-08 21:29:34 +01:00
parent da6659cc25
commit 66da9106bf
15 changed files with 44 additions and 1027 deletions

View File

@ -9,7 +9,7 @@
#include <etk/debug.h> #include <etk/debug.h>
int32_t etk::getLogId() { int32_t etk::getLogId() {
static int32_t g_val = etk::log::registerInstance("etk"); static int32_t g_val = elog::registerInstance("etk");
return g_val; return g_val;
} }

View File

@ -10,13 +10,13 @@
#pragma once #pragma once
#include <etk/log.h> #include <elog/log.h>
namespace etk { namespace etk {
int32_t getLogId(); int32_t getLogId();
}; };
#define ETK_BASE(info,data) TK_LOG_BASE(etk::getLogId(),info,data) #define ETK_BASE(info,data) ELOG_BASE(etk::getLogId(),info,data)
#define TK_PRINT(data) ETK_BASE(-1, data) #define TK_PRINT(data) ETK_BASE(-1, data)
#define TK_CRITICAL(data) ETK_BASE(1, data) #define TK_CRITICAL(data) ETK_BASE(1, data)

View File

@ -7,29 +7,29 @@
*/ */
#include <etk/etk.h> #include <etk/etk.h>
#include <etk/log.h> #include <elog/log.h>
#include <etk/types.h> #include <etk/types.h>
#include <etk/debug.h> #include <etk/debug.h>
#include <etk/os/FSNode.h> #include <etk/os/FSNode.h>
static etk::log::level getLogLevel(const std::string& _value) { static elog::level getLogLevel(const std::string& _value) {
if (_value == "0") { if (_value == "0") {
return etk::log::logLevelNone; return elog::logLevelNone;
} else if (_value == "1") { } else if (_value == "1") {
return etk::log::logLevelCritical; return elog::logLevelCritical;
} else if (_value == "2") { } else if (_value == "2") {
return etk::log::logLevelError; return elog::logLevelError;
} else if (_value == "3") { } else if (_value == "3") {
return etk::log::logLevelWarning; return elog::logLevelWarning;
} else if (_value == "4") { } else if (_value == "4") {
return etk::log::logLevelInfo; return elog::logLevelInfo;
} else if (_value == "5") { } else if (_value == "5") {
return etk::log::logLevelDebug; return elog::logLevelDebug;
} else if (_value == "6") { } else if (_value == "6") {
return etk::log::logLevelVerbose; return elog::logLevelVerbose;
} }
TK_ERROR("Unknow log level : " << _value); TK_ERROR("Unknow log level : " << _value);
return etk::log::logLevelVerbose; return elog::logLevelVerbose;
} }
void etk::init(int _argc, const char** _argv) { void etk::init(int _argc, const char** _argv) {
@ -38,34 +38,34 @@ void etk::init(int _argc, const char** _argv) {
for (int32_t iii=0; iii<_argc ; ++iii) { for (int32_t iii=0; iii<_argc ; ++iii) {
std::string data = _argv[iii]; std::string data = _argv[iii];
if (etk::start_with(data, "--etk-log-level=")) { if (etk::start_with(data, "--etk-log-level=")) {
etk::log::setLevel(getLogLevel(std::string(data.begin()+16, data.end()))); elog::setLevel(getLogLevel(std::string(data.begin()+16, data.end())));
} else if (etk::start_with(data, "-l=")) { } else if (etk::start_with(data, "-l=")) {
etk::log::setLevel(getLogLevel(std::string(data.begin()+2, data.end()))); elog::setLevel(getLogLevel(std::string(data.begin()+2, data.end())));
} else if (etk::start_with(data, "--etk-log-color")) { } else if (etk::start_with(data, "--etk-log-color")) {
etk::log::setColor(true); elog::setColor(true);
} else if (etk::start_with(data, "--etk-log-no-color")) { } else if (etk::start_with(data, "--etk-log-no-color")) {
etk::log::setColor(false); elog::setColor(false);
} else if (etk::start_with(data, "--etk-log-config=")) { } else if (etk::start_with(data, "--etk-log-config=")) {
std::string value(data.begin()+17, data.end()); std::string value(data.begin()+17, data.end());
etk::log::setTime(false); elog::setTime(false);
etk::log::setLine(false); elog::setLine(false);
etk::log::setFunction(false); elog::setFunction(false);
etk::log::setLibName(false); elog::setLibName(false);
etk::log::setThreadId(false); elog::setThreadId(false);
etk::log::setThreadNameEnable(false); elog::setThreadNameEnable(false);
for (size_t iii=0; iii<value.size(); ++iii) { for (size_t iii=0; iii<value.size(); ++iii) {
if (value[iii] == 't') { if (value[iii] == 't') {
etk::log::setTime(true); elog::setTime(true);
} else if (value[iii] == 'T') { } else if (value[iii] == 'T') {
etk::log::setThreadId(true); elog::setThreadId(true);
} else if (value[iii] == 'N') { } else if (value[iii] == 'N') {
etk::log::setThreadNameEnable(true); elog::setThreadNameEnable(true);
} else if (value[iii] == 'L') { } else if (value[iii] == 'L') {
etk::log::setLine(true); elog::setLine(true);
} else if (value[iii] == 'l') { } else if (value[iii] == 'l') {
etk::log::setLibName(true); elog::setLibName(true);
} else if (value[iii] == 'f') { } else if (value[iii] == 'f') {
etk::log::setFunction(true); elog::setFunction(true);
} else { } else {
TK_ERROR("In program argument: --etk-log-config= , the value '" << value[iii] << "' is not supported"); TK_ERROR("In program argument: --etk-log-config= , the value '" << value[iii] << "' is not supported");
} }
@ -77,10 +77,10 @@ void etk::init(int _argc, const char** _argv) {
TK_ERROR("Can not set the --etk-log-lib= with value='" << value << "' not formated name:X"); TK_ERROR("Can not set the --etk-log-lib= with value='" << value << "' not formated name:X");
continue; continue;
} }
etk::log::setLevel(list[0], getLogLevel(list[1])); elog::setLevel(list[0], getLogLevel(list[1]));
} else if ( data == "-h" } else if ( data == "-h"
|| data == "--help") { || data == "--help") {
etk::log::setLevel(etk::log::logLevelInfo); elog::setLevel(elog::logLevelInfo);
TK_PRINT("etk - help : "); TK_PRINT("etk - help : ");
TK_PRINT(" " << _argv[0] << " [options]"); TK_PRINT(" " << _argv[0] << " [options]");
TK_PRINT(" -l/--etk-log-level= Change the default log level (set all Log lovel):"); TK_PRINT(" -l/--etk-log-level= Change the default log level (set all Log lovel):");

View File

@ -1,551 +0,0 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <etk/log.h>
#include <time.h>
#include <mutex>
#include <thread>
#include <map>
#include <inttypes.h>
#include <etk/thread/tools.h>
#include <etk/debug.h>
#if defined(__TARGET_OS__Android)
# include <android/log.h>
#endif
#if defined(ETK_EXTERN_FRAMEWORK_ROS)
#include <ros/ros.h>
#endif
#include <etk/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 etk::log::displayBacktrace(bool _breakAtEnd, int32_t _removeElement) {
// retrieve call-stack
void * trace[MAX_DEPTH];
int stack_depth = backtrace(trace, MAX_DEPTH);
TK_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) {
TK_WARNING(" " << dlinfo.dli_fname << ": ");
TK_ERROR(" " << symname);
}
_removeElement--;
if(demangled != nullptr) {
free(demangled);
}
}
if (_breakAtEnd == true) {
assert(false);
}
}
#else
void etk::log::displayBacktrace(bool _breakAtEnd, int32_t _removeElement) {
#ifdef DEBUG
assert(false);
#endif
}
#endif
#ifdef DEBUG
#define DEFAULT_LOG_LEVEL etk::log::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 etk::log::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 etk::log::level& getDefaultLevel() {
static enum etk::log::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 etk::log::level> >& getList() {
static std::vector<std::pair<std::string, enum etk::log::level> > g_val;
return g_val;
}
int32_t etk::log::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 etk::log::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 etk::log::setLevel(enum level _level) {
getDefaultLevel() = _level;
for (size_t iii = 0; iii < getList().size(); ++iii) {
getList()[iii].second = _level;
}
}
void etk::log::setLevel(int32_t _id, enum level _level) {
if (_id < 0 || _id > (int32_t)getList().size()) {
// ERROR...
return;
}
getList()[_id].second = _level;
}
int32_t etk::log::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> etk::log::getListInstance() {
std::vector<std::string> out;
for (size_t iii = 0; iii < getList().size(); ++iii) {
out.push_back(getList()[iii].first);
}
return out;
}
void etk::log::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();
etk::log::logChar(_id, _level, _ligne, _className, _funcName, sss.c_str());
}
void etk::log::logChar1(int32_t _id, int32_t _level, const char* _log) {
etk::log::logChar(_id, _level, -1, nullptr, nullptr, _log);
}
void etk::log::logStream1(int32_t _id, int32_t _level, const std::ostream& _log) {
std::ostringstream oss;
oss << _log.rdbuf();
std::string sss =oss.str();
etk::log::logChar(_id, _level, -1, nullptr, nullptr, sss.c_str());
}
static bool& getColor() {
static bool g_val = DEFAULT_LOG_COLOR;
return g_val;
}
void etk::log::setColor(bool _status) {
getColor() = _status;
}
static bool& getTime() {
static bool g_val = DEFAULT_LOG_TIME;
return g_val;
}
void etk::log::setTime(bool _status) {
getTime() = _status;
}
static bool& getLine() {
static bool g_val = DEFAULT_LOG_LINE;
return g_val;
}
void etk::log::setLine(bool _status) {
getLine() = _status;
}
static bool& getThreadId() {
static bool g_val = DEFAULT_LOG_THREAD_ID;
return g_val;
}
void etk::log::setThreadId(bool _status) {
getThreadId() = _status;
}
static bool& getThreadNameEnable() {
static bool g_val = DEFAULT_LOG_THREAD_NAME;
return g_val;
}
void etk::log::setThreadNameEnable(bool _status) {
getThreadNameEnable() = _status;
}
static bool& getFunction() {
static bool g_val = DEFAULT_LOG_CLASS;
return g_val;
}
void etk::log::setFunction(bool _status) {
getFunction() = _status;
}
static bool& getLibName() {
static bool g_val = DEFAULT_LOG_LIB_NAME;
return g_val;
}
void etk::log::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 etk::log::logChar(int32_t _id, int32_t _level, int32_t _ligne, const char* _className, const char* _funcName, const char* _log) {
static std11::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 !defined(ETK_EXTERN_FRAMEWORK_ROS)
if(getTime() == true) {
getDisplayTime(pointer);
pointer = handle+strlen(handle);
}
#endif
#if !defined(__TARGET_OS__Android) && !defined(ETK_EXTERN_FRAMEWORK_ROS)
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';
}
}
if(getThreadId() == true) {
// display thread ID
uint32_t iddd = etk::thread::getId();
sprintf(pointer, "%3d", iddd);
pointer = handle+strlen(handle);
*pointer++ = ' ';
*pointer++ = '|';
*pointer++ = ' ';
*pointer = '\0';
}
if(getThreadNameEnable() == true) {
// display thread ID
std::string name = etk::thread::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';
}
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(ETK_EXTERN_FRAMEWORK_ROS)
switch(_level) {
default:
//ROS_VERBOSE_STREAM(handle);
break;
case logLevelPrint:
ROS_INFO_STREAM(handle);
break;
case logLevelCritical:
ROS_FATAL_STREAM(handle);
break;
case logLevelError:
ROS_ERROR_STREAM(handle);
break;
case logLevelWarning:
ROS_WARN_STREAM(handle);
break;
case logLevelInfo:
ROS_INFO_STREAM(handle);
break;
case logLevelDebug:
ROS_DEBUG_STREAM(handle);
break;
case logLevelVerbose:
//ROS_VERBOSE_STREAM(handle);
break;
}
#else
#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
#endif
g_lock.unlock();
if (_level == logLevelCritical) {
std::this_thread::sleep_for(std::chrono::milliseconds(700));
displayBacktrace(true, 2);
}
}

133
etk/log.h
View File

@ -1,133 +0,0 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#pragma once
#include <etk/types.h>
#include <sstream>
#include <ostream>
#include <vector>
namespace etk {
namespace log {
/**
* @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 TK_LOG_BASE(logId,info,data) \
do { \
if (info <= etk::log::getLevel(logId)) { \
std::stringbuf sb; \
std::ostream tmpStream(&sb); \
tmpStream << data; \
etk::log::logStream(logId, info, __LINE__, __class__, __func__, tmpStream); \
} \
} while(0)

View File

@ -1,20 +0,0 @@
/**
* @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

View File

@ -1,17 +0,0 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#import <UIKit/UIKit.h>
#include <etk/logIOs.h>
void iosNSLog(const char * _value) {
NSLog(@"\r%s", _value);
}

View File

@ -1380,8 +1380,8 @@ std::ostream& std::operator <<(std::ostream& _os, const std::vector<uint8_t>& _o
namespace std { namespace std {
std::ostream& operator <<(std::ostream& _os, const std11::chrono::system_clock::time_point& _obj) { std::ostream& operator <<(std::ostream& _os, const std::chrono::system_clock::time_point& _obj) {
std11::chrono::nanoseconds ns = std11::chrono::duration_cast<std11::chrono::nanoseconds>(_obj.time_since_epoch()); std::chrono::nanoseconds ns = std::chrono::duration_cast<std::chrono::nanoseconds>(_obj.time_since_epoch());
int64_t totalSecond = ns.count()/1000000000; int64_t totalSecond = ns.count()/1000000000;
int64_t millisecond = (ns.count()%1000000000)/1000000; int64_t millisecond = (ns.count()%1000000000)/1000000;
int64_t microsecond = (ns.count()%1000000)/1000; int64_t microsecond = (ns.count()%1000000)/1000;
@ -1395,8 +1395,8 @@ namespace std {
_os << year << "y " << day << "d " << hour << "h" << minute << ":"<< second << "s " << millisecond << "ms " << microsecond << "µs " << nanosecond << "ns"; _os << year << "y " << day << "d " << hour << "h" << minute << ":"<< second << "s " << millisecond << "ms " << microsecond << "µs " << nanosecond << "ns";
return _os; return _os;
} }
std::ostream& operator <<(std::ostream& _os, const std11::chrono::steady_clock::time_point& _obj) { std::ostream& operator <<(std::ostream& _os, const std::chrono::steady_clock::time_point& _obj) {
std11::chrono::nanoseconds ns = std11::chrono::duration_cast<std11::chrono::nanoseconds>(_obj.time_since_epoch()); std::chrono::nanoseconds ns = std::chrono::duration_cast<std::chrono::nanoseconds>(_obj.time_since_epoch());
int64_t totalSecond = ns.count()/1000000000; int64_t totalSecond = ns.count()/1000000000;
int64_t millisecond = (ns.count()%1000000000)/1000000; int64_t millisecond = (ns.count()%1000000000)/1000000;
int64_t microsecond = (ns.count()%1000000)/1000; int64_t microsecond = (ns.count()%1000000)/1000;

View File

@ -556,8 +556,8 @@ namespace std {
std::ostream& operator <<(std::ostream& _os, const std::vector<int8_t>& _obj); std::ostream& operator <<(std::ostream& _os, const std::vector<int8_t>& _obj);
std::ostream& operator <<(std::ostream& _os, const std::vector<uint8_t>& _obj); std::ostream& operator <<(std::ostream& _os, const std::vector<uint8_t>& _obj);
std::ostream& operator <<(std::ostream& _os, const std11::chrono::system_clock::time_point& _obj); std::ostream& operator <<(std::ostream& _os, const std::chrono::system_clock::time_point& _obj);
std::ostream& operator <<(std::ostream& _os, const std11::chrono::steady_clock::time_point& _obj); std::ostream& operator <<(std::ostream& _os, const std::chrono::steady_clock::time_point& _obj);
}; };

View File

@ -1,180 +0,0 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <etk/debug.h>
#include <etk/thread/tools.h>
#include <mutex>
#include <map>
static std11::mutex g_lock;
static std::map<uint32_t, std::string>& getThreadList() {
static std::map<uint32_t, std::string> g_val;
return g_val;
}
static uint32_t getThreadHumanId(std11::thread::id _id) {
uint32_t out = 0;
uint64_t iddd = std11::hash<std11::thread::id>()(_id);
g_lock.lock();
static std::map<uint64_t, uint32_t> g_list;
std::map<uint64_t, uint32_t>::iterator it = g_list.find(iddd);
if (it == g_list.end()) {
// attribute new ID :
static uint32_t tmpId = 0;
g_list.insert(std::pair<uint64_t, uint32_t>(iddd,tmpId));
out = tmpId;
tmpId++;
} else {
out = it->second;
}
g_lock.unlock();
return out;
}
static std::string getThreadName(std11::thread::id _id) {
std::map<uint32_t,std::string>& list = getThreadList();
uint32_t threadID = getThreadHumanId(_id);
std::string out;
g_lock.lock();
std::map<uint32_t,std::string>::iterator it = list.find(threadID);
if (it != list.end()) {
out = it->second;
}
g_lock.unlock();
return out;
}
static void setThreadName(std11::thread* _thread, const std::string& _name) {
std::map<uint32_t,std::string>& list = getThreadList();
uint32_t threadID = etk::thread::getId();
g_lock.lock();
std::map<uint32_t,std::string>::iterator it = list.find(threadID);
if (it == list.end()) {
list.insert(std::pair<uint32_t, std::string>(threadID, _name));
} else {
it->second = _name;
}
g_lock.unlock();
// try now to set the thread name with Pthread
#if defined(__TARGET_OS__Linux)
pthread_t pthreadID;
if (_thread == nullptr) {
pthreadID = pthread_self();
} else {
pthreadID = (pthread_t) _thread->native_handle();
}
std::string name = _name;
if (name.size() > 15) {
name.resize(15);
}
if (pthread_setname_np(pthreadID, name.c_str()) < 0) {
TK_ERROR("Error when setting the Name in the OS thread naming");
}
#else
TK_DEBUG("Can not set the thread name in this OS (local set)");
#endif
}
uint32_t etk::thread::getId() {
return getThreadHumanId(std11::this_thread::get_id());
}
uint32_t etk::thread::getId(std11::thread& _thread) {
return getThreadHumanId(_thread.get_id());
}
void etk::thread::setName(const std::string& _name) {
setThreadName(nullptr, _name);
}
void etk::thread::setName(std11::thread& _thread, const std::string& _name) {
setThreadName(&_thread, _name);
}
std::string etk::thread::getName() {
return getThreadName(std11::this_thread::get_id());
}
std::string etk::thread::getName(std11::thread& _thread) {
return getThreadName(_thread.get_id());
}
#if defined(__TARGET_OS__Linux)
static void setThreadPriority(pthread_t _threadID, int32_t _priority) {
int retcode;
int policy;
struct sched_param param;
retcode = pthread_getschedparam(_threadID, &policy, &param);
if (retcode != 0) {
TK_ERROR("Can not get prioriry " << ((retcode == ESRCH) ? "WRONG THREAD ID (ESRCH)" :"???") );
return;
}
TK_INFO("Try to set the thread proiority at :" << _priority);
policy = SCHED_OTHER;
if (_priority < 0) {
_priority *= -1;
policy = SCHED_FIFO;
}
param.sched_priority = _priority;
retcode = pthread_setschedparam(_threadID, policy, &param);
if (retcode != 0) {
TK_ERROR("Can not set prioriry " << ((retcode == ESRCH) ? "WRONG THREAD ID (ESRCH)" :
(retcode == EINVAL) ? "WRONG POLICY (EINVAL)" :
(retcode == EPERM) ? "NO PRIVILEGE (EPERM)" :
"???") );
}
}
static int32_t getThreadPriority(pthread_t _threadID) {
int retcode;
int policy;
struct sched_param param;
retcode = pthread_getschedparam(_threadID, &policy, &param);
if (retcode != 0) {
TK_ERROR("Can not get prioriry " << ((retcode == ESRCH) ? "WRONG THREAD ID (ESRCH)" : "???") );
return 20;
}
if (policy != SCHED_OTHER) {
return -param.sched_priority;
}
return param.sched_priority;
}
#endif
void etk::thread::setPriority(int32_t _priority) {
#if defined(__TARGET_OS__Linux)
pthread_t threadID = pthread_self();
setThreadPriority(threadID, _priority);
#endif
}
void etk::thread::setPriority(std11::thread& _thread, int32_t _priority) {
#if defined(__TARGET_OS__Linux)
pthread_t threadID = (pthread_t) _thread.native_handle();
setThreadPriority(threadID, _priority);
#endif
}
int32_t etk::thread::getPriority() {
#if defined(__TARGET_OS__Linux)
pthread_t threadID = pthread_self();
return getThreadPriority(threadID);
#else
return 20;
#endif
}
int32_t etk::thread::getPriority(std11::thread& _thread) {
#if defined(__TARGET_OS__Linux)
pthread_t threadID = static_cast<pthread_t>(_thread.native_handle());
return getThreadPriority(threadID);
#else
return 20;
#endif
}

View File

@ -1,75 +0,0 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <etk/types.h>
#pragma once
#include <thread>
namespace etk {
namespace thread {
/**
* @brief get human readable thread ID. (not the std::thread::get_id())
* @return the ID of the thread.
*/
uint32_t getId();
/**
* @brief get human readable thread ID. (not the std::thread::get_id())
* @param[in] _thread Thread handle
* @return the ID of the thread.
*/
uint32_t getId(std11::thread& _thread);
/**
* @brief Set the Current thread name
* @param[in] _name New name of the thread
*/
void setName(const std::string& _name);
/**
* @brief Set an other thread name
* @param[in] _thread Thread handle
* @param[in] _name New name of the thread
*/
void setName(std11::thread& _thread, const std::string& _name);
/**
* @brief Set the Current thread name
* @return The current name of the thread
*/
std::string getName();
/**
* @brief Get an other thread name
* @praram[in] _thread Thread handle
* @return The external thread name of the thread
*/
std::string getName(std11::thread& _thread);
/**
* @brief Set the Current thread priority [-20..0] for RT and ]0..50] for normal priority
* @param[in] _priority New priority of the thread
* @note If your process have not the right to change thread name, it does not work
*/
void setPriority(int32_t _priority);
/**
* @brief Set an other thread priority [-20..0] for RT and ]0..50] for normal priority
* @param[in] _thread Thread handle
* @param[in] _priority New priority of the thread
* @note If your process have not the right to change thread name, it does not work
*/
void setPriority(std11::thread& _thread, int32_t _priority);
/**
* @brief get the Current thread priority [-20..0] for RT and ]0..50] for normal priority
* @return current priority of the thread
*/
int32_t getPriority();
/**
* @brief Get an other thread priority [-20..0] for RT and ]0..50] for normal priority
* @param[in] _thread Thread handle
* @return current priority of the thread
*/
int32_t getPriority(std11::thread& _thread);
}
}

View File

@ -32,11 +32,9 @@ def create(target, module_name):
'etk/debug.cpp', 'etk/debug.cpp',
'etk/etk.cpp', 'etk/etk.cpp',
'etk/stdTools.cpp', 'etk/stdTools.cpp',
'etk/log.cpp',
'etk/tool.cpp', 'etk/tool.cpp',
'etk/Noise.cpp', 'etk/Noise.cpp',
'etk/Color.cpp', 'etk/Color.cpp',
'etk/thread/tools.cpp',
'etk/math/Matrix2.cpp', 'etk/math/Matrix2.cpp',
'etk/math/Matrix4.cpp', 'etk/math/Matrix4.cpp',
'etk/math/Vector2D.cpp', 'etk/math/Vector2D.cpp',
@ -47,19 +45,14 @@ def create(target, module_name):
'etk/archive/Archive.cpp', 'etk/archive/Archive.cpp',
'etk/archive/Zip.cpp']) 'etk/archive/Zip.cpp'])
if target.name=="IOs":
my_module.add_src_file('etk/logIOs.m')
my_module.add_header_file([ my_module.add_header_file([
'etk/etk.h', 'etk/etk.h',
'etk/types.h', 'etk/types.h',
'etk/stdTools.h', 'etk/stdTools.h',
'etk/log.h',
'etk/tool.h', 'etk/tool.h',
'etk/Noise.h', 'etk/Noise.h',
'etk/Color.h', 'etk/Color.h',
'etk/Hash.h', 'etk/Hash.h',
'etk/thread/tools.h',
'etk/math/Matrix2.h', 'etk/math/Matrix2.h',
'etk/math/Matrix4.h', 'etk/math/Matrix4.h',
'etk/math/Vector2D.h', 'etk/math/Vector2D.h',
@ -76,7 +69,6 @@ def create(target, module_name):
# TODO : Fore release mode : the etk folder are absolutly not at the same position in the tree ... # TODO : Fore release mode : the etk folder are absolutly not at the same position in the tree ...
my_module.compile_flags('c', "-DMODE_RELEASE") my_module.compile_flags('c', "-DMODE_RELEASE")
else: else:
my_module.add_export_flag('c', "-DDEBUG_LEVEL=3")
my_module.add_export_flag('c', "-DDEBUG=1") my_module.add_export_flag('c', "-DDEBUG=1")
# Bor backtrace display : # Bor backtrace display :
if target.name != "Windows" \ if target.name != "Windows" \
@ -95,6 +87,7 @@ def create(target, module_name):
my_module.add_module_depend('cxx') my_module.add_module_depend('cxx')
# add dependency of the generic math library: # add dependency of the generic math library:
my_module.add_module_depend('m') my_module.add_module_depend('m')
my_module.add_module_depend('elog')
# add some optionnal libraries # add some optionnal libraries
my_module.add_optionnal_module_depend('minizip', ["c++", "-DETK_BUILD_MINIZIP"]) my_module.add_optionnal_module_depend('minizip', ["c++", "-DETK_BUILD_MINIZIP"])
my_module.add_optionnal_module_depend('linearmath', ["c", "-DETK_BUILD_LINEARMATH"], export=True) my_module.add_optionnal_module_depend('linearmath', ["c", "-DETK_BUILD_LINEARMATH"], export=True)

View File

@ -13,7 +13,7 @@
#include <etk/Hash.h> #include <etk/Hash.h>
#include <etk/os/FSNode.h> #include <etk/os/FSNode.h>
#include <etk/archive/Archive.h> #include <etk/archive/Archive.h>
#include <etk/log.h> #include <elog/log.h>
#include <etk/Color.h> #include <etk/Color.h>
#include <etk/stdTools.h> #include <etk/stdTools.h>
#include <string> #include <string>
@ -34,8 +34,8 @@ int main(int argc, const char *argv[]) {
// init Google test : // init Google test :
::testing::InitGoogleTest(&argc, const_cast<char **>(argv)); ::testing::InitGoogleTest(&argc, const_cast<char **>(argv));
// the only one init for etk: // the only one init for etk:
//etk::log::setLevel(etk::log::logLevelVerbose); //elog::setLevel(elog::logLevelVerbose);
etk::log::setLevel(etk::log::logLevelInfo); elog::setLevel(elog::logLevelInfo);
etk::setArgZero(argv[0]); etk::setArgZero(argv[0]);
etk::initDefaultFolder("ewolApplNoName"); etk::initDefaultFolder("ewolApplNoName");
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();

View File

@ -9,7 +9,7 @@
#include <test-debug/debug.h> #include <test-debug/debug.h>
int32_t test::getLogId() { int32_t test::getLogId() {
static int32_t g_val = etk::log::registerInstance("test"); static int32_t g_val = elog::registerInstance("test");
return g_val; return g_val;
} }

View File

@ -10,13 +10,13 @@
#pragma once #pragma once
#include <etk/log.h> #include <elog/log.h>
namespace test { namespace test {
int32_t getLogId(); int32_t getLogId();
}; };
#define TEST_BASE(info,data) TK_LOG_BASE(test::getLogId(),info,data) #define TEST_BASE(info,data) ELOG_BASE(test::getLogId(),info,data)
#define TEST_PRINT(data) TEST_BASE(-1, data) #define TEST_PRINT(data) TEST_BASE(-1, data)
#define TEST_CRITICAL(data) TEST_BASE(1, data) #define TEST_CRITICAL(data) TEST_BASE(1, data)