35 # include <ace/Stack_Trace.h>
40 #elif defined(YARP_HAS_EXECINFO_H)
41 # include <execinfo.h>
51 #ifdef YARP_HAS_WIN_VT_SUPPORT
60 const unsigned int line,
73 const unsigned int line,
78 const char* comp_name);
83 const unsigned int line,
88 const char* comp_name);
94 const unsigned int line,
106 const unsigned int line,
111 const char* comp_name)
123 const unsigned int line,
128 const char* comp_name)
137 #ifdef YARP_HAS_WIN_VT_SUPPORT
138 bool enable_vt_colors();
162 #ifdef YARP_HAS_WIN_VT_SUPPORT
163 static std::atomic<bool> vt_colors_enabled;
177 #define BOLD_RED (yarp::os::impl::LogPrivate::colored_output.load() ? "\033[01;31m" : "")
178 #define BOLD_GREEN (yarp::os::impl::LogPrivate::colored_output.load() ? "\033[01;32m" : "")
179 #define BOLD_YELLOW (yarp::os::impl::LogPrivate::colored_output.load() ? "\033[01;33m" : "")
180 #define BOLD_BLUE (yarp::os::impl::LogPrivate::colored_output.load() ? "\033[01;34m" : "")
181 #define BOLD_MAGENTA (yarp::os::impl::LogPrivate::colored_output.load() ? "\033[01;35m" : "")
182 #define BOLD_CYAN (yarp::os::impl::LogPrivate::colored_output.load() ? "\033[01;36m" : "")
183 #define BOLD_WHITE (yarp::os::impl::LogPrivate::colored_output.load() ? "\033[01;37m" : "")
184 #define RED (yarp::os::impl::LogPrivate::colored_output.load() ? "\033[31m" : "")
185 #define GREEN (yarp::os::impl::LogPrivate::colored_output.load() ? "\033[32m" : "")
186 #define YELLOW (yarp::os::impl::LogPrivate::colored_output.load() ? "\033[33m" : "")
187 #define BLUE (yarp::os::impl::LogPrivate::colored_output.load() ? "\033[34m" : "")
188 #define MAGENTA (yarp::os::impl::LogPrivate::colored_output.load() ? "\033[35m" : "")
189 #define CYAN (yarp::os::impl::LogPrivate::colored_output.load() ? "\033[36m" : "")
190 #define WHITE (yarp::os::impl::LogPrivate::colored_output.load() ? "\033[37m" : "")
191 #define RED_BG (yarp::os::impl::LogPrivate::colored_output.load() ? "\033[41m" : "")
192 #define GREEN_BG (yarp::os::impl::LogPrivate::colored_output.load() ? "\033[42m" : "")
193 #define YELLOW_BG (yarp::os::impl::LogPrivate::colored_output.load() ? "\033[43m" : "")
194 #define BLUE_BG (yarp::os::impl::LogPrivate::colored_output.load() ? "\033[44m" : "")
195 #define MAGENTA_BG (yarp::os::impl::LogPrivate::colored_output.load() ? "\033[45m" : "")
196 #define CYAN_BG (yarp::os::impl::LogPrivate::colored_output.load() ? "\033[46m" : "")
197 #define WHITE_BG (yarp::os::impl::LogPrivate::colored_output.load() ? "\033[47m" : "")
198 #define CLEAR (yarp::os::impl::LogPrivate::colored_output.load() ? "\033[00m" : "")
202 inline bool from_env(
const char* name,
bool defaultvalue)
206 if(!strvalue) {
return defaultvalue; }
208 if(strcmp(strvalue,
"1") == 0) {
return true; }
209 if(strcmp(strvalue,
"true") == 0) {
return true; }
210 if(strcmp(strvalue,
"True") == 0) {
return true; }
211 if(strcmp(strvalue,
"TRUE") == 0) {
return true; }
212 if(strcmp(strvalue,
"on") == 0) {
return true; }
213 if(strcmp(strvalue,
"On") == 0) {
return true; }
214 if(strcmp(strvalue,
"ON") == 0) {
return true; }
216 if(strcmp(strvalue,
"0") == 0) {
return false; }
217 if(strcmp(strvalue,
"false") == 0) {
return false; }
218 if(strcmp(strvalue,
"False") == 0) {
return false; }
219 if(strcmp(strvalue,
"FALSE") == 0) {
return false; }
220 if(strcmp(strvalue,
"off") == 0) {
return false; }
221 if(strcmp(strvalue,
"Off") == 0) {
return false; }
222 if(strcmp(strvalue,
"OFF") == 0) {
return false; }
284 inline const char* compNameToColor(
const char* comp_name)
297 static std::hash<std::string> hsh;
298 std::size_t comp_hash = hsh(comp_name) % 12;
329 std::string backtrace()
332 ACE_Stack_Trace st(-1);
336 #elif defined(YARP_HAS_EXECINFO_H)
337 const size_t max_depth = 100;
339 void* stack_addrs[max_depth];
340 char** stack_strings;
341 stack_depth = ::backtrace(stack_addrs, max_depth);
342 stack_strings = backtrace_symbols(stack_addrs, stack_depth);
343 std::ostringstream ost;
344 for (
size_t i = 1; i < stack_depth; i++) {
345 ost << stack_strings[i] <<
'\n';
355 inline void forwardable_output(std::ostream* ost,
359 const unsigned int line,
364 const char* comp_name)
366 const char *level = logTypeToString(
t);
390 if (externaltime != 0.0) {
395 *ost <<
" (line " << line <<
")";
404 static std::string cmd(processInfo.
name.substr(processInfo.
name.find_last_of(
"\\/") + 1));
406 *ost <<
" (pid " << processInfo.
pid <<
")";
422 inline void printable_output(std::ostream* ost,
426 const unsigned int line,
431 const char* comp_name)
439 #if !defined (_MSC_VER)
440 static constexpr
const char* level_char = u8
"\u25CF";
442 static constexpr
const char* level_char =
"*";
445 const char* level_string = logTypeToString(
t);
446 const char* level_color = logTypeToColor(
t);
447 const char* level_bgcolor = logTypeToBgColor(
t);
449 const char* comp_color = compNameToColor(comp_name);
453 *ost << level_color << level_bgcolor << level_char <<
CLEAR <<
" ";
455 *ost <<
"[" << level_color << level_bgcolor << level_string <<
CLEAR <<
"] ";
460 *ost << level_color << func <<
CLEAR << ((msg[0] || comp_name) ?
": " :
"");
465 *ost <<
"|" << comp_color << comp_name <<
CLEAR <<
"| ";
470 *ost << reserved_color <<
'^' <<
CLEAR;
474 *ost << reserved_color <<
'$' <<
CLEAR;
478 inline void printable_output_verbose(std::ostream* ost,
482 const unsigned int line,
487 const char* comp_name)
491 const char* level_string = logTypeToString(
t);
492 const char *level_color = logTypeToColor(
t);
493 const char *level_bgcolor = logTypeToBgColor(
t);
495 const char* comp_color = compNameToColor(comp_name);
498 if (externaltime != 0.0) {
499 *ost <<
"[" << std::fixed << externaltime <<
"] ";
503 *ost <<
"[" << std::fixed << networktime <<
"] ";
507 *ost <<
"[" << level_color << level_bgcolor << level_string <<
CLEAR <<
"] ";
510 *ost << file <<
":" << line <<
" " << level_color << level_bgcolor << func <<
CLEAR <<
" ";
517 *ost <<
"|" << comp_color << comp_name <<
CLEAR <<
"| ";
522 *ost << reserved_color <<
'^' <<
CLEAR;
526 *ost << reserved_color <<
'$' <<
CLEAR;
538 from_env(
"YARPRUN_IS_FORWARDING_LOG",
false));
540 #if defined(_WIN32) && !defined(YARP_HAS_WIN_VT_SUPPORT)
569 #ifdef YARP_HAS_WIN_VT_SUPPORT
570 std::atomic<bool> yarp::os::impl::LogPrivate::vt_colors_enabled =
false;
608 const double externaltime,
616 externaltime(externaltime),
620 #ifdef YARP_HAS_WIN_VT_SUPPORT
621 if (
colored_output.load() && !yarp::os::impl::LogPrivate::vt_colors_enabled.load()) {
630 const unsigned int line,
635 const char* comp_name)
646 static std::mutex log_mutex;
647 std::lock_guard<std::mutex> lock(log_mutex);
649 if (yarprun_format.load()) {
651 forwardable_output(ost,
t, msg, file, line, func, systemtime, networktime, externaltime, comp_name);
652 }
else if (verbose_output.load()) {
653 printable_output_verbose(ost,
t, msg, file, line, func, systemtime, networktime, externaltime, comp_name);
655 printable_output(ost,
t, msg, file, line, func, systemtime, networktime, externaltime, comp_name);
663 const unsigned int line,
668 const char* comp_name)
675 std::stringstream stringstream_buffer;
676 forwardable_output(&stringstream_buffer,
t, msg, file, line, func, systemtime, networktime, externaltime, comp_name);
684 constexpr
size_t YARP_MAX_STATIC_LOG_MSG_SIZE = 1024;
686 if (msg !=
nullptr) {
687 if (!pred || pred()) {
688 char buf[YARP_MAX_STATIC_LOG_MSG_SIZE];
689 char* dyn_buf =
nullptr;
692 size_t buf_size = YARP_MAX_STATIC_LOG_MSG_SIZE;
698 va_copy(args_bak, args);
700 auto log_line_size =
static_cast<size_t>(std::vsnprintf(buf, YARP_MAX_STATIC_LOG_MSG_SIZE, msg, args));
702 if (log_line_size > YARP_MAX_STATIC_LOG_MSG_SIZE) {
706 size_t dyn_buf_size = [](
size_t x) {
716 dyn_buf =
new char[dyn_buf_size];
717 std::vsnprintf(dyn_buf, dyn_buf_size, msg, args_bak);
721 buf_size = dyn_buf_size;
724 auto p = std::min(log_line_size - 1, buf_size);
725 if (log_line_size > 0 && p < buf_size && out[p] ==
'\n' && msg[strlen(msg) - 1] ==
'\n') {
726 yarp::os::Log(file, line, func,
nullptr, log_internal_component).
warning(
"Removing extra '\\n' (c-style)");
730 do_log(type, out, file, line, func, systemtime, networktime, externaltime, comp);
733 yarp::os::Log(file, line, func,
nullptr, log_internal_component).
warning(
"Previous message was longer than the static buffer size, dynamic allocation was used");
738 yarp::os::Log(file, line, func,
nullptr, log_internal_component).
warning(
"Unexpected nullptr received");
745 const unsigned int line,
754 print_cb(type, msg, file, line, func, systemtime, networktime, externaltime, comp.
name());
756 if (comp != log_internal_component) {
758 yarp::os::Log(file, line, func,
nullptr, log_internal_component).
debug(
"Not printing [%s][%s]", comp.
name(), msg);
760 yarp::os::Log(file, line, func,
nullptr, log_internal_component).
debug(
"Not printing [%s]", msg);
767 forward_cb(type, msg, file, line, func, systemtime, networktime, externaltime, comp.
name());
769 if (comp != log_internal_component) {
771 yarp::os::Log(file, line, func,
nullptr, log_internal_component).
debug(
"Not forwarding [%s][%s]", comp.
name(), msg);
773 yarp::os::Log(file, line, func,
nullptr, log_internal_component).
debug(
"Not forwarding [%s]", msg);
779 #ifdef YARP_HAS_WIN_VT_SUPPORT
780 bool yarp::os::impl::LogPrivate::enable_vt_colors()
782 DWORD handleMode = 0;
783 HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
784 bool success =
false;
786 if (hStdout != INVALID_HANDLE_VALUE && GetConsoleMode(hStdout, &handleMode)) {
787 handleMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
788 success = SetConsoleMode(hStdout, handleMode);
791 yarp::os::impl::LogPrivate::vt_colors_enabled =
true;
840 #ifndef YARP_NO_DEPRECATED // Since YARP 3.4
892 minimumForwardLevel(),
910 mPriv(new
yarp::os::impl::LogPrivate(file, line, func, 0.0, pred, comp))
918 const double externaltime,
921 mPriv(new
yarp::os::impl::LogPrivate(file, line, func, externaltime, pred, comp))
926 mPriv(new
yarp::os::impl::LogPrivate(nullptr, 0, nullptr, 0.0, nullptr, nullptr))
938 const unsigned int line,
1002 mPriv->externaltime,
1011 va_start(args, msg);
1022 mPriv->externaltime,
1031 va_start(args, msg);
1042 mPriv->externaltime,
1050 va_start(args, msg);
1063 mPriv->externaltime,
1070 fprintf(out,
"Trace requested at %s:%u by code called from:\n", file, line);
1071 fprintf(out,
"%s", backtrace().c_str());