You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

misc.cpp 3.9 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /**
  2. * \file inlude/misc.cpp
  3. * MegEngine is Licensed under the Apache License, Version 2.0 (the "License")
  4. *
  5. * Copyright (c) 2014-2021 Megvii Inc. All rights reserved.
  6. *
  7. * Unless required by applicable law or agreed to in writing,
  8. * software distributed under the License is distributed on an
  9. * "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. */
  11. #include "./misc.h"
  12. #include "lite/global.h"
  13. #include <time.h>
  14. #include <chrono>
  15. #include <cstdarg>
  16. #if LITE_BUILD_WITH_MGE
  17. #include "megbrain/common.h"
  18. #endif
  19. #ifdef __ANDROID__
  20. #include <android/log.h>
  21. #endif
  22. using namespace lite;
  23. namespace lite {
  24. namespace log_detail {
  25. LiteLogLevel current_log_level = LiteLogLevel::ERROR;
  26. template <class T, size_t N>
  27. constexpr size_t countof(T (&)[N]) {
  28. return N;
  29. }
  30. } // namespace log_detail
  31. } // namespace lite
  32. namespace {
  33. std::string svsprintf(const char* fmt, va_list ap_orig) {
  34. int size = 100; /* Guess we need no more than 100 bytes */
  35. char* p;
  36. if ((p = (char*)malloc(size)) == nullptr)
  37. return "svsprintf: malloc failed";
  38. for (;;) {
  39. va_list ap;
  40. va_copy(ap, ap_orig);
  41. int n = vsnprintf(p, size, fmt, ap);
  42. va_end(ap);
  43. if (n < 0)
  44. return "svsprintf: vsnprintf failed";
  45. if (n < size) {
  46. std::string rst(p);
  47. free(p);
  48. return rst;
  49. }
  50. size = n + 1;
  51. char* np = (char*)realloc(p, size);
  52. if (!np) {
  53. free(p);
  54. return "svsprintf: realloc failed";
  55. } else
  56. p = np;
  57. }
  58. }
  59. } // namespace
  60. void lite::set_log_level(LiteLogLevel l) {
  61. log_detail::current_log_level = l;
  62. #if LITE_BUILD_WITH_MGE
  63. mgb::LogLevel lite_log_level = mgb::LogLevel::DEBUG;
  64. switch (l) {
  65. case LiteLogLevel::DEBUG:
  66. lite_log_level = mgb::LogLevel::DEBUG;
  67. break;
  68. case LiteLogLevel::INFO:
  69. lite_log_level = mgb::LogLevel::INFO;
  70. break;
  71. case LiteLogLevel::WARN:
  72. lite_log_level = mgb::LogLevel::WARN;
  73. break;
  74. case LiteLogLevel::ERROR:
  75. lite_log_level = mgb::LogLevel::ERROR;
  76. break;
  77. default:
  78. LITE_THROW("unkonw loglevel");
  79. }
  80. mgb::set_log_level(lite_log_level);
  81. #endif
  82. }
  83. LiteLogLevel lite::get_log_level() {
  84. return log_detail::current_log_level;
  85. }
  86. std::string lite::ssprintf(const char* format, ...) {
  87. if (!format)
  88. return "";
  89. va_list ap;
  90. va_start(ap, format);
  91. auto ret = svsprintf(format, ap);
  92. va_end(ap);
  93. return ret;
  94. }
  95. void lite::print_log(LiteLogLevel level, const char* format, ...) {
  96. if (!format)
  97. return;
  98. if (static_cast<uint32_t>(level) < static_cast<uint32_t>(get_log_level())) {
  99. return;
  100. }
  101. using namespace std::chrono;
  102. auto now = system_clock::now();
  103. auto now_time_t = system_clock::to_time_t(now);
  104. tm now_tm;
  105. #if _WIN32
  106. localtime_s(&now_tm, &now_time_t);
  107. #else
  108. localtime_r(&now_time_t, &now_tm);
  109. #endif
  110. auto now_trunc_to_sec = system_clock::from_time_t(mktime(&now_tm));
  111. auto microsec = duration_cast<microseconds>(now - now_trunc_to_sec);
  112. char time_buffer[100];
  113. snprintf(
  114. time_buffer, log_detail::countof(time_buffer), "%02d:%02d:%02d.%06ld ",
  115. now_tm.tm_hour, now_tm.tm_min, now_tm.tm_sec, long(microsec.count()));
  116. const char* prefix[] = {"LITE[DBG] ", "LITE[INF] ", "LITE[WRN] ", "LITE[ERR] "};
  117. std::string out;
  118. out += prefix[int(level)];
  119. out += time_buffer;
  120. va_list ap;
  121. va_start(ap, format);
  122. auto ret = svsprintf(format, ap);
  123. va_end(ap);
  124. out += ret;
  125. #ifdef __ANDROID__
  126. __android_log_print(ANDROID_LOG_INFO, "lite", "%s", out.c_str());
  127. #else
  128. fprintf(stderr, "%s\n", out.c_str());
  129. #endif
  130. }
  131. // vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}}