!35633 Error message structure optimization, hierarchical printing
Merge pull request !35633 from wangjunbao/master
This commit is contained in:
commit
aa7e67d1d6
|
@ -16,6 +16,7 @@
|
||||||
"mindspore/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/" "readability/casting"
|
"mindspore/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/" "readability/casting"
|
||||||
"mindspore/mindspore/ccsrc/plugin/device/gpu/hal/device/gpu_kernel_runtime.cc" "build/include_what_you_use"
|
"mindspore/mindspore/ccsrc/plugin/device/gpu/hal/device/gpu_kernel_runtime.cc" "build/include_what_you_use"
|
||||||
"mindspore/mindspore/ccsrc/utils/convert_utils_py.cc" "whitespace/indent"
|
"mindspore/mindspore/ccsrc/utils/convert_utils_py.cc" "whitespace/indent"
|
||||||
|
"mindspore/mindspore/core/utils/log_adapter.cc" "runtime/references"
|
||||||
|
|
||||||
# Modelzoo
|
# Modelzoo
|
||||||
"mindspore/model_zoo/official/cv/yolov4_tiny/infer/mxbase/src/Yolov4TinyDetection.h" "runtime/references"
|
"mindspore/model_zoo/official/cv/yolov4_tiny/infer/mxbase/src/Yolov4TinyDetection.h" "runtime/references"
|
||||||
|
|
|
@ -475,7 +475,22 @@ void ClearTraceStack() {
|
||||||
cnode_debug_stack.clear();
|
cnode_debug_stack.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetTraceStackInfo(std::ostringstream &oss) {
|
void PrintMessage(std::ostringstream &oss, const std::string &content, bool add_title) {
|
||||||
|
if (add_title) {
|
||||||
|
const std::string &message = oss.str();
|
||||||
|
size_t length = message.length();
|
||||||
|
if ((length != 0) && (message[length - 1] != '\n')) {
|
||||||
|
oss << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
oss << "\n----------------------------------------------------\n"
|
||||||
|
<< "- The Traceback of Net Construct Code:"
|
||||||
|
<< "\n----------------------------------------------------";
|
||||||
|
}
|
||||||
|
oss << content;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetTraceStackInfo(std::ostringstream &oss, bool add_title) {
|
||||||
TraceGraphEval();
|
TraceGraphEval();
|
||||||
std::ostringstream trace_info;
|
std::ostringstream trace_info;
|
||||||
GetEvalStackInfo(trace_info);
|
GetEvalStackInfo(trace_info);
|
||||||
|
@ -484,11 +499,13 @@ void GetTraceStackInfo(std::ostringstream &oss) {
|
||||||
if (debug_info != nullptr && TraceManager::record_debug_info_flag() == true) {
|
if (debug_info != nullptr && TraceManager::record_debug_info_flag() == true) {
|
||||||
auto debug_str = trace::GetDebugInfo(debug_info);
|
auto debug_str = trace::GetDebugInfo(debug_info);
|
||||||
if (!debug_str.empty()) {
|
if (!debug_str.empty()) {
|
||||||
oss << "\n\n# " << debug_str;
|
std::ostringstream content;
|
||||||
|
content << "\n\n# " << debug_str;
|
||||||
|
PrintMessage(oss, content.str(), add_title);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
oss << trace_info.str();
|
PrintMessage(oss, trace_info.str(), add_title);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ void TraceEvalCNodeEnter(const abstract::AnfNodeConfigPtr &node_cfg);
|
||||||
void TraceEvalCNodeLeave();
|
void TraceEvalCNodeLeave();
|
||||||
TraceCNodeEvalStack &GetCNodeDebugStack();
|
TraceCNodeEvalStack &GetCNodeDebugStack();
|
||||||
TraceGraphEvalStack &GetCurrentGraphEvalStack();
|
TraceGraphEvalStack &GetCurrentGraphEvalStack();
|
||||||
void GetTraceStackInfo(std::ostringstream &oss);
|
void GetTraceStackInfo(std::ostringstream &oss, bool add_title = false);
|
||||||
std::string GetAbstractStr(const abstract::AbstractBasePtr &abs);
|
std::string GetAbstractStr(const abstract::AbstractBasePtr &abs);
|
||||||
void ClearTraceStack();
|
void ClearTraceStack();
|
||||||
} // namespace trace
|
} // namespace trace
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
// namespace to support utils module definition
|
// namespace to support utils module definition
|
||||||
namespace mindspore {
|
namespace mindspore {
|
||||||
constexpr int kNameMaxLength = 18;
|
constexpr int kNameMaxLength = 18;
|
||||||
|
constexpr size_t kStep = 2;
|
||||||
#if defined(__ANDROID__) || defined(ANDROID)
|
#if defined(__ANDROID__) || defined(ANDROID)
|
||||||
constexpr const char *ANDROID_LOG_TAG = "MS_LITE";
|
constexpr const char *ANDROID_LOG_TAG = "MS_LITE";
|
||||||
#endif
|
#endif
|
||||||
|
@ -179,6 +180,137 @@ void LogWriter::set_trace_provider(const TraceProvider &trace_provider) {
|
||||||
|
|
||||||
LogWriter::TraceProvider LogWriter::trace_provider() { return trace_provider_; }
|
LogWriter::TraceProvider LogWriter::trace_provider() { return trace_provider_; }
|
||||||
|
|
||||||
|
static inline std::string GetEnv(const std::string &envvar) {
|
||||||
|
const char *value = std::getenv(envvar.c_str());
|
||||||
|
|
||||||
|
if (value == nullptr) {
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::string(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// When GLOG_logtostderr is set to 0, logs are output to a file, then will print duplicate message
|
||||||
|
// in exception log and stack. Otherwise when GLOG_logtostderr is set to 1, logs are output to the screen,
|
||||||
|
// then will only print message in exception stack.
|
||||||
|
void LogWriter::RemoveLabelBeforeOutputLog(const std::ostringstream &msg) const {
|
||||||
|
if (GetEnv("GLOG_logtostderr") == "0") {
|
||||||
|
std::string str = msg.str();
|
||||||
|
auto replace = [&](const std::string &orgStr, const std::string &newStr) {
|
||||||
|
std::string::size_type pos;
|
||||||
|
while ((pos = str.find(orgStr)) != std::string::npos) {
|
||||||
|
str.replace(pos, orgStr.length(), newStr);
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
};
|
||||||
|
// remove label "#dmsg#" and "#umsg#"
|
||||||
|
str = replace("#dmsg#", "");
|
||||||
|
str = replace("#umsg#", "");
|
||||||
|
std::ostringstream replaced_msg;
|
||||||
|
replaced_msg << str;
|
||||||
|
OutputLog(replaced_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to split string based on character delimiter
|
||||||
|
void SplitString(const std::string &message, const std::string &delimiter, std::vector<std::string> *output) {
|
||||||
|
size_t pos1, pos2;
|
||||||
|
pos1 = 0;
|
||||||
|
pos2 = message.find(delimiter);
|
||||||
|
MS_EXCEPTION_IF_NULL(output);
|
||||||
|
|
||||||
|
while (pos2 != std::string::npos) {
|
||||||
|
(void)output->emplace_back(message.substr(pos1, pos2 - pos1));
|
||||||
|
pos1 = pos2 + delimiter.size();
|
||||||
|
pos2 = message.find(delimiter, pos1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pos1 != message.length()) {
|
||||||
|
(void)output->emplace_back(message.substr(pos1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse exception message format like: Error Description#dmsg#Developer Message Title#dmsg#Developer Message Content
|
||||||
|
// #umsg#User Message Title#umsg#User Message Content
|
||||||
|
void ParseExceptionMessage(const std::string &message, std::ostringstream &oss, std::vector<std::string> *dmsg,
|
||||||
|
std::vector<std::string> *umsg) {
|
||||||
|
std::vector<std::string> vec;
|
||||||
|
SplitString(message, "#dmsg#", &vec); // first:split message by label #dmsg#
|
||||||
|
|
||||||
|
if (!vec.empty() && (vec[0].find("#umsg#") == std::string::npos)) {
|
||||||
|
oss << vec[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
MS_EXCEPTION_IF_NULL(dmsg);
|
||||||
|
MS_EXCEPTION_IF_NULL(umsg);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < vec.size(); i++) {
|
||||||
|
if (vec[i].find("#umsg#") != std::string::npos) {
|
||||||
|
std::vector<std::string> temp;
|
||||||
|
SplitString(vec[i], "#umsg#", &temp); // second:split message by label #umsg#
|
||||||
|
if (!temp.empty()) {
|
||||||
|
if (i == 0) {
|
||||||
|
oss << temp[0];
|
||||||
|
} else {
|
||||||
|
(void)dmsg->emplace_back(temp[0]);
|
||||||
|
}
|
||||||
|
(void)umsg->insert(umsg->end(), temp.begin() + 1, temp.end());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (i != 0) {
|
||||||
|
(void)dmsg->emplace_back(vec[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintMessage(std::ostringstream &oss, const std::string &title, const std::string &content) {
|
||||||
|
const std::string &message = oss.str();
|
||||||
|
size_t length = message.length();
|
||||||
|
if ((length != 0) && (message[length - 1] != '\n')) {
|
||||||
|
oss << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
oss << "\n----------------------------------------------------\n"
|
||||||
|
<< title << "\n----------------------------------------------------\n"
|
||||||
|
<< content;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayDevExceptionMessage(std::ostringstream &oss, const std::vector<std::string> &dmsg,
|
||||||
|
const LocationInfo &location) {
|
||||||
|
bool display = true;
|
||||||
|
if (GetEnv("MS_EXCEPTION_DISPLAY_LEVEL") == "1") {
|
||||||
|
display = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (display) {
|
||||||
|
const std::string CPP_CALL_STACK_TITLE = "- C++ Call Stack: (For framework developers)";
|
||||||
|
std::ostringstream cpp_call_stack_content;
|
||||||
|
cpp_call_stack_content << location.file_ << ":" << location.line_ << " " << location.func_ << "\n";
|
||||||
|
PrintMessage(oss, CPP_CALL_STACK_TITLE, cpp_call_stack_content.str());
|
||||||
|
|
||||||
|
size_t size = dmsg.size();
|
||||||
|
if ((size != 0) && (size % kStep == 0)) {
|
||||||
|
for (size_t i = 0; i < size; i += kStep) {
|
||||||
|
std::ostringstream dmsg_title;
|
||||||
|
dmsg_title << "- " << dmsg[i] << " (For framework developers)";
|
||||||
|
PrintMessage(oss, dmsg_title.str(), dmsg[i + 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayUserExceptionMessage(std::ostringstream &oss, const std::vector<std::string> &umsg) {
|
||||||
|
size_t size = umsg.size();
|
||||||
|
if ((size != 0) && (size % kStep == 0)) {
|
||||||
|
for (size_t i = 0; i < size; i += kStep) {
|
||||||
|
std::ostringstream umsg_title;
|
||||||
|
umsg_title << "- " << umsg[i];
|
||||||
|
PrintMessage(oss, umsg_title.str(), umsg[i + 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LogWriter::OutputLog(const std::ostringstream &msg) const {
|
void LogWriter::OutputLog(const std::ostringstream &msg) const {
|
||||||
#ifdef USE_GLOG
|
#ifdef USE_GLOG
|
||||||
#define google mindspore_private
|
#define google mindspore_private
|
||||||
|
@ -219,21 +351,26 @@ void LogWriter::operator^(const LogStream &stream) const {
|
||||||
std::ostringstream msg;
|
std::ostringstream msg;
|
||||||
msg << stream.sstream_->rdbuf();
|
msg << stream.sstream_->rdbuf();
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << location_.file_ << ":" << location_.line_ << " " << location_.func_ << "] ";
|
std::vector<std::string> dmsg;
|
||||||
oss << msg.str();
|
std::vector<std::string> umsg;
|
||||||
|
|
||||||
|
ParseExceptionMessage(msg.str(), oss, &dmsg, &umsg);
|
||||||
|
DisplayUserExceptionMessage(oss, umsg);
|
||||||
|
|
||||||
thread_local bool running = false;
|
thread_local bool running = false;
|
||||||
if (!running) {
|
if (!running) {
|
||||||
running = true;
|
running = true;
|
||||||
if (this_thread_max_log_level >= EXCEPTION) {
|
if (this_thread_max_log_level >= EXCEPTION) {
|
||||||
OutputLog(msg);
|
RemoveLabelBeforeOutputLog(msg);
|
||||||
}
|
}
|
||||||
if (trace_provider_ != nullptr) {
|
if (trace_provider_ != nullptr) {
|
||||||
trace_provider_(oss);
|
trace_provider_(oss, true);
|
||||||
}
|
}
|
||||||
running = false;
|
running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DisplayDevExceptionMessage(oss, dmsg, location_);
|
||||||
|
|
||||||
if (exception_handler_ != nullptr) {
|
if (exception_handler_ != nullptr) {
|
||||||
exception_handler_(exception_type_, oss.str());
|
exception_handler_(exception_type_, oss.str());
|
||||||
}
|
}
|
||||||
|
@ -241,16 +378,6 @@ void LogWriter::operator^(const LogStream &stream) const {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline std::string GetEnv(const std::string &envvar) {
|
|
||||||
const char *value = std::getenv(envvar.c_str());
|
|
||||||
|
|
||||||
if (value == nullptr) {
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::string(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class LogConfigToken : size_t {
|
enum class LogConfigToken : size_t {
|
||||||
INVALID, // indicate invalid token
|
INVALID, // indicate invalid token
|
||||||
LEFT_BRACE, // '{'
|
LEFT_BRACE, // '{'
|
||||||
|
|
|
@ -247,7 +247,7 @@ class TryCatchGuard {
|
||||||
class MS_CORE_API LogWriter {
|
class MS_CORE_API LogWriter {
|
||||||
public:
|
public:
|
||||||
using ExceptionHandler = void (*)(ExceptionType, const std::string &);
|
using ExceptionHandler = void (*)(ExceptionType, const std::string &);
|
||||||
using TraceProvider = std::function<void(std::ostringstream &oss)>;
|
using TraceProvider = std::function<void(std::ostringstream &oss, bool add_title)>;
|
||||||
|
|
||||||
LogWriter(const LocationInfo &location, MsLogLevel log_level, SubModuleId submodule,
|
LogWriter(const LocationInfo &location, MsLogLevel log_level, SubModuleId submodule,
|
||||||
ExceptionType excp_type = NoExceptionType)
|
ExceptionType excp_type = NoExceptionType)
|
||||||
|
@ -272,6 +272,7 @@ class MS_CORE_API LogWriter {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void OutputLog(const std::ostringstream &msg) const;
|
void OutputLog(const std::ostringstream &msg) const;
|
||||||
|
void RemoveLabelBeforeOutputLog(const std::ostringstream &msg) const;
|
||||||
|
|
||||||
LocationInfo location_;
|
LocationInfo location_;
|
||||||
MsLogLevel log_level_;
|
MsLogLevel log_level_;
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2022 Huawei Technologies Co., Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common/common_test.h"
|
||||||
|
#include "utils/log_adapter.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr char kMsExceptionDisplayLevel[] = "MS_EXCEPTION_DISPLAY_LEVEL";
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace mindspore {
|
||||||
|
class TestLogAdapter : public UT::Common {
|
||||||
|
public:
|
||||||
|
TestLogAdapter() {}
|
||||||
|
|
||||||
|
void TearDown() override { (void)unsetenv(kMsExceptionDisplayLevel); }
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Feature: Error message structure optimization, hierarchical printing
|
||||||
|
/// Description: set MS_EXCEPTION_DISPLAY_LEVEL to 0 and run pass
|
||||||
|
/// Expectation: dmsg and umsg both display
|
||||||
|
TEST_F(TestLogAdapter, TestParseExceptionMessage1) {
|
||||||
|
(void)setenv(kMsExceptionDisplayLevel, "0", 1);
|
||||||
|
try {
|
||||||
|
MS_LOG(EXCEPTION) << "Exception Description#dmsg#The Dev Title1:#dmsg#The Dev Content1"
|
||||||
|
<< "#umsg#The User Title1:#umsg#The User Content1";
|
||||||
|
} catch (const std::exception &ex) {
|
||||||
|
const std::string &exception_str = ex.what();
|
||||||
|
MS_LOG(INFO) << exception_str;
|
||||||
|
ASSERT_TRUE(exception_str.find("- C++ Call Stack: (For framework developers)") != std::string::npos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Feature: Error message structure optimization, hierarchical printing
|
||||||
|
/// Description: set MS_EXCEPTION_DISPLAY_LEVEL to 1 and run pass
|
||||||
|
/// Expectation: only umsg displays
|
||||||
|
TEST_F(TestLogAdapter, TestParseExceptionMessage2) {
|
||||||
|
(void)setenv(kMsExceptionDisplayLevel, "1", 1);
|
||||||
|
try {
|
||||||
|
MS_EXCEPTION(TypeError) << "Exception Description#dmsg#The Dev Title1:#dmsg#The Dev Content1"
|
||||||
|
<< "#umsg#The User Title1:#umsg#The User Content1";
|
||||||
|
} catch (const std::exception &ex) {
|
||||||
|
const std::string &exception_str = ex.what();
|
||||||
|
MS_LOG(INFO) << exception_str;
|
||||||
|
ASSERT_TRUE(exception_str.find("The Dev Content1") == std::string::npos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace mindspore
|
Loading…
Reference in New Issue