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.

log_adapter.cc 7.4 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /**
  2. * Copyright 2019 Huawei Technologies Co., Ltd
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "utils/log_adapter.h"
  17. #include <unistd.h>
  18. #include "pybind11/pybind11.h"
  19. #include "debug/trace.h"
  20. // namespace to support utils module definition
  21. namespace mindspore {
  22. #ifdef USE_GLOG
  23. static std::string GetTime() {
  24. #define BUFLEN 80
  25. static char buf[BUFLEN];
  26. #if defined(_WIN32) || defined(_WIN64)
  27. time_t time_seconds = time(0);
  28. struct tm now_time;
  29. localtime_s(&now_time, &time_seconds);
  30. sprintf_s(buf, BUFLEN, "%d-%d-%d %d:%d:%d", now_time.tm_year + 1900, now_time.tm_mon + 1, now_time.tm_mday,
  31. now_time.tm_hour, now_time.tm_min, now_time.tm_sec);
  32. #else
  33. struct timeval cur_time;
  34. (void)gettimeofday(&cur_time, nullptr);
  35. struct tm now;
  36. (void)localtime_r(&cur_time.tv_sec, &now);
  37. (void)strftime(buf, BUFLEN, "%Y-%m-%d-%H:%M:%S", &now); // format date and time
  38. // set micro-second
  39. buf[27] = '\0';
  40. int idx = 26;
  41. auto num = cur_time.tv_usec;
  42. for (int i = 5; i >= 0; i--) {
  43. buf[idx--] = static_cast<char>(num % 10 + '0');
  44. num /= 10;
  45. if (i % 3 == 0) {
  46. buf[idx--] = '.';
  47. }
  48. }
  49. #endif
  50. return std::string(buf);
  51. }
  52. static std::string GetProcName() {
  53. #if defined(__APPLE__) || defined(__FreeBSD__)
  54. const char *appname = getprogname();
  55. #elif defined(_GNU_SOURCE)
  56. const char *appname = program_invocation_name;
  57. #else
  58. const char *appname = "?";
  59. #endif
  60. // some times, the appname is an absolute path, its too long
  61. std::string app_name(appname);
  62. std::size_t pos = app_name.rfind("/");
  63. if (pos == std::string::npos) {
  64. return app_name;
  65. }
  66. if (pos + 1 >= app_name.size()) {
  67. return app_name;
  68. }
  69. return app_name.substr(pos + 1);
  70. }
  71. static std::string GetLogLevel(MsLogLevel level) {
  72. #define _TO_STRING(x) #x
  73. static const char *const level_names[] = {
  74. _TO_STRING(DEBUG),
  75. _TO_STRING(INFO),
  76. _TO_STRING(WARNING),
  77. _TO_STRING(ERROR),
  78. };
  79. #undef _TO_STRING
  80. if (level > ERROR) {
  81. level = ERROR;
  82. }
  83. return std::string(level_names[level]);
  84. }
  85. // convert MsLogLevel to corresponding glog level
  86. static int GetGlogLevel(MsLogLevel level) {
  87. switch (level) {
  88. case DEBUG:
  89. case INFO:
  90. return google::GLOG_INFO;
  91. case WARNING:
  92. return google::GLOG_WARNING;
  93. case ERROR:
  94. default:
  95. return google::GLOG_ERROR;
  96. }
  97. }
  98. #else
  99. #undef Dlog
  100. #define Dlog(module_id, level, format, ...) \
  101. do { \
  102. DlogInner((module_id), (level), (format), ##__VA_ARGS__); \
  103. } while (0)
  104. // convert MsLogLevel to corresponding slog level
  105. static int GetSlogLevel(MsLogLevel level) {
  106. switch (level) {
  107. case DEBUG:
  108. return DLOG_DEBUG;
  109. case INFO:
  110. return DLOG_INFO;
  111. case WARNING:
  112. return DLOG_WARN;
  113. case ERROR:
  114. default:
  115. return DLOG_ERROR;
  116. }
  117. }
  118. #endif
  119. static std::string ExceptionTypeToString(ExceptionType type) {
  120. #define _TO_STRING(x) #x
  121. // clang-format off
  122. static const char *const type_names[] = {
  123. _TO_STRING(NoExceptionType),
  124. _TO_STRING(UnknownError),
  125. _TO_STRING(ArgumentError),
  126. _TO_STRING(NotSupportError),
  127. _TO_STRING(NotExistsError),
  128. _TO_STRING(AlreadyExistsError),
  129. _TO_STRING(UnavailableError),
  130. _TO_STRING(DeviceProcessError),
  131. _TO_STRING(AbortedError),
  132. _TO_STRING(TimeOutError),
  133. _TO_STRING(ResourceUnavailable),
  134. _TO_STRING(NoPermissionError),
  135. _TO_STRING(ValueError),
  136. _TO_STRING(TypeError),
  137. };
  138. // clang-format on
  139. #undef _TO_STRING
  140. if (type < UnknownError || type > TypeError) {
  141. type = UnknownError;
  142. }
  143. return std::string(type_names[type]);
  144. }
  145. void LogWriter::OutputLog(const std::ostringstream &msg) const {
  146. #ifdef USE_GLOG
  147. google::LogMessage("", 0, GetGlogLevel(log_level_)).stream()
  148. << "[" << GetLogLevel(log_level_) << "] ME(" << getpid() << "," << GetProcName() << "):" << GetTime() << " "
  149. << "[" << location_.file_ << ":" << location_.line_ << "] " << location_.func_ << "] " << msg.str() << std::endl;
  150. #else
  151. auto str_msg = msg.str();
  152. Dlog(static_cast<int>(ME), GetSlogLevel(log_level_), "[%s:%d] %s] %s", location_.file_, location_.line_,
  153. location_.func_, str_msg.c_str());
  154. #endif
  155. }
  156. void LogWriter::operator<(const LogStream &stream) const noexcept {
  157. std::ostringstream msg;
  158. msg << stream.sstream_->rdbuf();
  159. OutputLog(msg);
  160. }
  161. void LogWriter::operator^(const LogStream &stream) const {
  162. std::ostringstream msg;
  163. msg << stream.sstream_->rdbuf();
  164. OutputLog(msg);
  165. std::ostringstream oss;
  166. oss << location_.file_ << ":" << location_.line_ << " " << location_.func_ << "] ";
  167. if (exception_type_ != NoExceptionType && exception_type_ != TypeError && exception_type_ != ValueError) {
  168. oss << ExceptionTypeToString(exception_type_) << " ";
  169. }
  170. oss << msg.str();
  171. trace::TraceGraphInfer();
  172. trace::GetInferStackInfo(oss);
  173. if (exception_type_ == ValueError) {
  174. throw pybind11::value_error(oss.str());
  175. }
  176. if (exception_type_ == TypeError) {
  177. throw pybind11::type_error(oss.str());
  178. }
  179. pybind11::pybind11_fail(oss.str());
  180. }
  181. static std::string GetEnv(const std::string &envvar) {
  182. const char *value = ::getenv(envvar.c_str());
  183. if (value == nullptr) {
  184. return std::string();
  185. }
  186. return std::string(value);
  187. }
  188. #ifndef USE_GLOG
  189. // set default log warning to WARNING
  190. int g_mslog_level = WARNING;
  191. static void InitMsLogLevel() {
  192. int log_level = WARNING; // set default log level to WARNING
  193. auto str_level = GetEnv("GLOG_v");
  194. if (str_level.size() == 1) {
  195. int ch = str_level.c_str()[0];
  196. ch = ch - '0'; // substract ASCII code of '0', which is 48
  197. if (ch >= DEBUG && ch <= ERROR) {
  198. log_level = ch;
  199. }
  200. }
  201. g_mslog_level = log_level;
  202. }
  203. #endif
  204. } // namespace mindspore
  205. extern "C" {
  206. // shared lib init hook
  207. #if defined(_WIN32) || defined(_WIN64)
  208. __attribute__((constructor)) void mindspore_log_init(void) {
  209. #else
  210. void mindspore_log_init(void) {
  211. #endif
  212. #ifdef USE_GLOG
  213. // do not use glog predefined log prefix
  214. FLAGS_log_prefix = false;
  215. static bool is_glog_initialzed = false;
  216. if (!is_glog_initialzed) {
  217. #if !defined(_WIN32) && !defined(_WIN64)
  218. google::InitGoogleLogging("mindspore");
  219. #endif
  220. is_glog_initialzed = true;
  221. }
  222. // set default log level to WARNING
  223. if (mindspore::GetEnv("GLOG_v").empty()) {
  224. FLAGS_v = mindspore::WARNING;
  225. }
  226. // set default log file mode to 0640
  227. if (mindspore::GetEnv("GLOG_logfile_mode").empty()) {
  228. FLAGS_logfile_mode = 0640;
  229. }
  230. std::string logtostderr = mindspore::GetEnv("GLOG_logtostderr");
  231. // default print log to screen
  232. if (logtostderr.empty()) {
  233. FLAGS_logtostderr = true;
  234. } else if (logtostderr == "0" && mindspore::GetEnv("GLOG_log_dir").empty()) {
  235. FLAGS_logtostderr = true;
  236. MS_LOG(WARNING) << "`GLOG_log_dir` is not set, output log to screen.";
  237. }
  238. #else
  239. mindspore::InitMsLogLevel();
  240. #endif
  241. }
  242. }