28 #include <ArmarXCore/interface/core/Log.h>
33 #include <sys/syscall.h>
38 #include <boost/logic/tribool.hpp>
40 #include <SimoxUtility/algorithm/string/string_tools.h>
42 #include <IceUtil/Time.h>
97 impl->cancelNextMessage =
false;
99 impl->printBackTrace = boost::logic::indeterminate;
111 impl->cancelNextMessage =
false;
113 impl->printBackTrace =
true;
122 if (!currentMessage.str().empty())
164 return *this << std::chrono::duration_cast<std::chrono::microseconds>(
timestamp);
167 currentMessage <<
timestamp.count() <<
" ns";
175 return *this << std::chrono::duration_cast<std::chrono::milliseconds>(
timestamp);
180 return *this << std::chrono::duration_cast<std::chrono::nanoseconds>(
timestamp);
183 currentMessage <<
timestamp.count() <<
" µs";
191 return *this << std::chrono::duration_cast<std::chrono::seconds>(
timestamp);
196 return *this << std::chrono::duration_cast<std::chrono::microseconds>(
timestamp);
199 currentMessage <<
timestamp.count() <<
" ms";
207 return *this << std::chrono::duration_cast<std::chrono::minutes>(
timestamp);
212 return *this << std::chrono::duration_cast<std::chrono::milliseconds>(
timestamp);
215 currentMessage <<
timestamp.count() <<
" s";
223 return *this << std::chrono::duration_cast<std::chrono::seconds>(
timestamp);
226 currentMessage <<
timestamp.count() <<
" min";
232 double time_count =
timestamp.toMicroSecondsDouble();
233 std::string unit =
"µs";
235 if (time_count >= 1000)
240 if (time_count >= 1000)
245 if (time_count >= 60)
250 if (time_count >= 60)
255 if (time_count >= 24)
302 std::stringstream stream;
306 stream <<
"\033[0" <<
"m";
310 stream <<
"\033[3" << colorCode <<
"m";
316 void LogSender::resetLocation()
318 impl->currentFile =
"";
319 impl->currentLine = -1;
320 impl->currentFunction =
"";
326 if (impl->cancelNextMessage)
328 impl->cancelNextMessage =
false;
337 if (severity < impl->minimumLoggingLevel)
353 if (!impl->currentTag.tagName.empty())
355 catStr =
"[" + impl->currentTag.tagName +
"]: ";
362 std::string outputStr;
370 outputStr +=
"\033[1m";
374 outputStr +=
"[" + time.toDateTime().substr(time.toDateTime().find(
' ') + 1) +
"]" +
"[" +
LogSender_componentName +
"]" + catStr;
391 msg.time = time.toMicroSeconds();
392 msg.tag = impl->currentTag.tagName;
393 msg.type = (MessageType)severity;
395 msg.file = impl->currentFile;
396 msg.line = impl->currentLine;
397 msg.function = impl->currentFunction;
398 msg.threadId = impl->threadId ? *impl->threadId :
getThreadId();
400 if ((severity >=
MessageTypeT::WARN && boost::logic::indeterminate(impl->printBackTrace))
401 || impl->printBackTrace)
435 std::cout << outputStr << std::endl;
442 return syscall(SYS_gettid);
458 log(impl->currentSeverity, currentMessage.str());
459 currentMessage.str(
"");
464 unsigned int maxLength = 40;
467 if (originalFunctionName.length() <= maxLength)
469 return originalFunctionName;
472 std::string beforeFunctionName = originalFunctionName.substr(0, originalFunctionName.rfind(
"::"));
473 std::string::size_type namespaceDotsPos = beforeFunctionName.find(
"::", beforeFunctionName.find(
' '));
475 if (namespaceDotsPos != std::string::npos)
477 std::string afterClassName = originalFunctionName.substr(originalFunctionName.rfind(
"::"));
478 result = beforeFunctionName.substr(namespaceDotsPos + 2) + afterClassName;
482 result = originalFunctionName;
485 if (result.length() <= maxLength)
491 result = result.substr(0, result.find(
"("));
503 void* callstack[128];
504 const int nMaxFrames =
sizeof(callstack) /
sizeof(callstack[0]);
507 int nFrames = ::backtrace(callstack, nMaxFrames);
508 char** symbols = backtrace_symbols(callstack, nFrames);
510 std::ostringstream trace_buf;
512 for (
int i = linesToSkip; i < nFrames; i++)
516 if (dladdr(callstack[i], &info) && info.dli_sname)
518 char* demangled =
nullptr;
521 if (info.dli_sname[0] ==
'_')
523 demangled = abi::__cxa_demangle(info.dli_sname,
nullptr,
nullptr, &
status);
526 snprintf(buf,
sizeof(buf),
"%-3d %*p %s + %zd\n",
527 i - linesToSkip + 1,
int(2 +
sizeof(
void*) * 2), callstack[i],
529 info.dli_sname ==
nullptr ? symbols[i] : info.dli_sname,
530 (
char*)callstack[i] - (
char*)info.dli_saddr);
535 snprintf(buf,
sizeof(buf),
"%-3d %*p %s\n",
536 i - linesToSkip + 1,
int(2 +
sizeof(
void*) * 2), callstack[i], symbols[i]);
544 if (nFrames == nMaxFrames)
546 trace_buf <<
"[truncated]\n";
549 return trace_buf.str();
554 return impl->currentSeverity;
559 impl->currentFile = file;
560 return shared_from_this();
565 impl->currentLine = line;
566 return shared_from_this();
571 impl->currentFunction =
function;
572 return shared_from_this();
577 impl->minimumLoggingLevel = level;
578 return shared_from_this();
583 impl->printBackTrace = printBackTrace;
584 return shared_from_this();
588 impl->threadId = tid;
589 return shared_from_this();
594 impl->currentTag = tag;
595 return shared_from_this();
636 if (simox::alg::to_lower(typeStr) ==
"debug")
641 if (simox::alg::to_lower(typeStr) ==
"verbose")
646 if (simox::alg::to_lower(typeStr) ==
"important")
651 if (simox::alg::to_lower(typeStr) ==
"warning")
656 if (simox::alg::to_lower(typeStr) ==
"error")
661 if (simox::alg::to_lower(typeStr) ==
"fatal")
691 std::cout <<
"logging is now DEACTIVATED" << std::endl;
696 std::cout <<
"logging is now ACTIVATED" << std::endl;
711 void LogSender::initConsole()
713 static bool initialized =
false;
718 char* termType = getenv(
"TERM");
720 if (termType !=
nullptr)
722 std::string termTypeStr(termType);
724 if (termTypeStr !=
"xterm"
725 && termTypeStr !=
"emacs"
726 && termTypeStr !=
"xterm-256color")
751 LogSender& LogSender::operator<< <MessageTypeT>(
const MessageTypeT& severity)
753 impl->currentSeverity = severity;
759 LogSender& LogSender::operator<< <LogTag>(
const LogTag& tag)
761 impl->currentTag =
tag;
767 LogSender& LogSender::operator<< <LogSender::manipulator>(
const manipulator& manipulator)
769 (this->*manipulator)();
782 LogSender& LogSender::operator<< <bool>(
const bool& duality)
786 currentMessage <<
"true";
790 currentMessage <<
"false";
797 LogSender& LogSender::operator<< <SpamFilterDataPtr>(
const SpamFilterDataPtr& spamFilterData)
804 std::unique_lock lock(*spamFilterData->mutex);
805 float deactivationDurationSec = spamFilterData->durationSec;
807 std::string
id = impl->currentFile +
":" +
to_string(impl->currentLine);
808 auto it = spamFilter->find(spamFilterData->identifier);
810 if (it != spamFilter->end())
812 auto itSub = it->second.find(
id);
813 IceUtil::Time durationEnd = IceUtil::Time::now() + IceUtil::Time::milliSecondsDouble(deactivationDurationSec * 1000);
815 if (itSub == it->second.end())
817 itSub = it->second.insert(
821 impl->cancelNextMessage =
false;
823 else if (IceUtil::Time::now() < itSub->second)
825 impl->cancelNextMessage =
true;
829 impl->cancelNextMessage =
false;
830 itSub->second = durationEnd;