Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #include <fstream>
12 : #include <iostream>
13 : #include <mutex>
14 : #include <nlohmann/json.hpp>
15 : #include <sstream>
16 : #include <exception>
17 : #include <securec.h>
18 : #include "mmpa/mmpa_api.h"
19 : #include "dlog_pub.h"
20 : #include "base/err_msg.h"
21 : #include "base/err_mgr.h"
22 : #include "error_manager.h"
23 :
24 : #define GE_MODULE_NAME static_cast<int32_t>(GE)
25 :
26 : template <typename TI, typename TO>
27 78 : inline TO* PtrToPtr(TI* const ptr)
28 : {
29 78 : return reinterpret_cast<TO*>(ptr);
30 : }
31 :
32 : template <typename TI, typename TO>
33 75 : inline const TO* PtrToPtr(const TI* const ptr)
34 : {
35 75 : return reinterpret_cast<const TO*>(ptr);
36 : }
37 :
38 : namespace {
39 : const std::string kParamCheckErrorSuffix = "8888";
40 : class GeLog {
41 : public:
42 25 : static uint64_t GetTid()
43 : {
44 : #ifdef __GNUC__
45 25 : thread_local static const uint64_t tid = static_cast<uint64_t>(syscall(__NR_gettid));
46 : #else
47 : thread_local static const uint64_t tid = static_cast<uint64_t>(GetCurrentThreadId());
48 : #endif
49 25 : return tid;
50 : }
51 : };
52 :
53 26273 : inline bool IsLogEnable(const int32_t module_name, const int32_t log_level)
54 : {
55 26273 : const int32_t enable = CheckLogLevel(module_name, log_level);
56 : // 1:enable, 0:disable
57 26273 : return (enable == 1);
58 : }
59 :
60 75 : std::string CurrentTimeFormatStr()
61 : {
62 75 : std::string time_str;
63 75 : auto now = std::chrono::system_clock::now();
64 75 : auto milli_seconds = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
65 75 : auto micro_seconds = std::chrono::time_point_cast<std::chrono::microseconds>(now);
66 75 : const auto now_t = std::chrono::system_clock::to_time_t(now);
67 75 : const std::tm* tm_now = std::localtime(&now_t);
68 75 : if (tm_now == nullptr) {
69 0 : return time_str;
70 : }
71 :
72 75 : constexpr int32_t year_base = 1900;
73 75 : constexpr size_t kMaxTimeLen = 128U;
74 75 : constexpr int64_t kOneThousandMs = 1000L;
75 75 : error_message::char_t format_time[kMaxTimeLen] = {};
76 150 : (void)snprintf_s(
77 : format_time, kMaxTimeLen, kMaxTimeLen - 1U, "%04d-%02d-%02d-%02d:%02d:%02d.%03ld.%03ld",
78 75 : tm_now->tm_year + year_base, tm_now->tm_mon + 1, tm_now->tm_mday, tm_now->tm_hour, tm_now->tm_min,
79 75 : tm_now->tm_sec, milli_seconds.time_since_epoch().count() % kOneThousandMs,
80 75 : micro_seconds.time_since_epoch().count() % kOneThousandMs);
81 75 : time_str = format_time;
82 75 : return time_str;
83 0 : }
84 : } // namespace
85 :
86 : #define GELOGE(fmt, ...) \
87 : do { \
88 : dlog_error( \
89 : GE_MODULE_NAME, "%" PRIu64 " %s: %s" fmt, GeLog::GetTid(), &__FUNCTION__[0], \
90 : ErrorManager::GetInstance().GetLogHeader().c_str(), ##__VA_ARGS__); \
91 : } while (false)
92 :
93 : #define GELOGW(fmt, ...) \
94 : do { \
95 : if (IsLogEnable(GE_MODULE_NAME, DLOG_WARN)) { \
96 : dlog_warn(GE_MODULE_NAME, "%" PRIu64 " %s:" fmt, GeLog::GetTid(), &__FUNCTION__[0], ##__VA_ARGS__); \
97 : } \
98 : } while (false)
99 :
100 : #define GELOGI(fmt, ...) \
101 : do { \
102 : if (IsLogEnable(GE_MODULE_NAME, DLOG_INFO)) { \
103 : dlog_info(GE_MODULE_NAME, "%" PRIu64 " %s:" fmt, GeLog::GetTid(), &__FUNCTION__[0], ##__VA_ARGS__); \
104 : } \
105 : } while (false)
106 :
107 : #define GELOGD(fmt, ...) \
108 : do { \
109 : if (IsLogEnable(GE_MODULE_NAME, DLOG_DEBUG)) { \
110 : dlog_debug(GE_MODULE_NAME, "%" PRIu64 " %s:" fmt, GeLog::GetTid(), &__FUNCTION__[0], ##__VA_ARGS__); \
111 : } \
112 : } while (false)
113 :
114 : namespace {
115 8 : int32_t ReportInnerErrorMessage(
116 : const char* file_name, const char* func, uint32_t line, const char* error_code, const char* format,
117 : va_list arg_list)
118 : {
119 8 : std::vector<char> buf(LIMIT_PER_MESSAGE, '\0');
120 8 : auto ret = vsprintf_s(buf.data(), LIMIT_PER_MESSAGE, format, arg_list);
121 8 : if (ret < 0) {
122 3 : GELOGE("[Check][Param] FormatErrorMessage failed, ret:%d, file:%s, line:%u", ret, file_name, line);
123 3 : return -1;
124 : }
125 5 : ret = sprintf_s(
126 5 : buf.data() + ret, LIMIT_PER_MESSAGE - static_cast<size_t>(ret), "[FUNC:%s][FILE:%s][LINE:%u]", func,
127 10 : error_message::TrimPath(std::string(file_name)).c_str(), line);
128 5 : if (ret < 0) {
129 1 : GELOGE("[Check][Param] FormatErrorMessage failed, ret:%d, file:%s, line:%u", ret, file_name, line);
130 1 : return -1;
131 : }
132 :
133 20 : return ErrorManager::GetInstance().ReportInterErrMessage(error_code, std::string(buf.data()));
134 8 : }
135 :
136 44 : std::unique_ptr<error_message::char_t[]> CreateUniquePtrFromString(const std::string& str)
137 : {
138 44 : const size_t buf_size = str.empty() ? 1U : (str.size() + 1U);
139 44 : auto uni_ptr = std::make_unique<error_message::char_t[]>(buf_size);
140 44 : if (uni_ptr == nullptr) {
141 0 : return nullptr;
142 : }
143 :
144 44 : if (str.empty()) {
145 11 : uni_ptr[0U] = '\0';
146 : } else {
147 : // 当src size < dst size时,strncpy_s会在末尾str.size()位置添加'\0'
148 33 : if (strncpy_s(uni_ptr.get(), str.size() + 1, str.c_str(), str.size()) != EOK) {
149 0 : return nullptr;
150 : }
151 : }
152 44 : return uni_ptr;
153 44 : }
154 :
155 66 : void ClearMessageContainerByWorkId(
156 : std::map<uint64_t, std::vector<ErrorManager::ErrorItem>>& message_container, const uint64_t work_stream_id)
157 : {
158 : const std::map<uint64_t, std::vector<ErrorManager::ErrorItem>>::const_iterator err_iter =
159 66 : message_container.find(work_stream_id);
160 66 : if (err_iter != message_container.cend()) {
161 45 : (void)message_container.erase(err_iter);
162 : }
163 66 : }
164 :
165 139 : std::vector<ErrorManager::ErrorItem>& GetOrCreateMessageContainerByWorkId(
166 : std::map<uint64_t, std::vector<ErrorManager::ErrorItem>>& message_container, uint64_t work_id)
167 : {
168 139 : auto iter = message_container.find(work_id);
169 139 : if (iter == message_container.end()) {
170 60 : (void)message_container.emplace(work_id, std::vector<ErrorManager::ErrorItem>());
171 60 : iter = message_container.find(work_id);
172 : }
173 278 : return iter->second;
174 : }
175 : } // namespace
176 :
177 : namespace error_message {
178 : // first stage
179 : const std::string kInitialize = "INIT";
180 : const std::string kModelCompile = "COMP";
181 : const std::string kModelLoad = "LOAD";
182 : const std::string kModelExecute = "EXEC";
183 : const std::string kFinalize = "FINAL";
184 :
185 : // SecondStage
186 : // INITIALIZE
187 : const std::string kParser = "PARSER";
188 : const std::string kOpsProtoInit = "OPS_PRO";
189 : const std::string kSystemInit = "SYS";
190 : const std::string kEngineInit = "ENGINE";
191 : const std::string kOpsKernelInit = "OPS_KER";
192 : const std::string kOpsKernelBuilderInit = "OPS_KER_BLD";
193 : // MODEL_COMPILE
194 : const std::string kPrepareOptimize = "PRE_OPT";
195 : const std::string kOriginOptimize = "ORI_OPT";
196 : const std::string kSubGraphOptimize = "SUB_OPT";
197 : const std::string kMergeGraphOptimize = "MERGE_OPT";
198 : const std::string kPreBuild = "PRE_BLD";
199 : const std::string kStreamAlloc = "STM_ALLOC";
200 : const std::string kMemoryAlloc = "MEM_ALLOC";
201 : const std::string kTaskGenerate = "TASK_GEN";
202 : // COMMON
203 : const std::string kOther = "DEFAULT";
204 :
205 : #ifdef __GNUC__
206 6 : std::string TrimPath(const std::string& str)
207 : {
208 6 : if (str.find_last_of('/') != std::string::npos) {
209 0 : return str.substr(str.find_last_of('/') + 1U);
210 : }
211 6 : return str;
212 : }
213 : #else
214 : std::string TrimPath(const std::string& str)
215 : {
216 : if (str.find_last_of('\\') != std::string::npos) {
217 : return str.substr(str.find_last_of('\\') + 1U);
218 : }
219 : return str;
220 : }
221 : #endif
222 :
223 1 : int32_t FormatErrorMessage(char_t* str_dst, size_t dst_max, const char_t* format, ...)
224 : {
225 : int32_t ret;
226 : va_list arg_list;
227 :
228 1 : va_start(arg_list, format);
229 1 : ret = vsprintf_s(str_dst, dst_max, format, arg_list);
230 : (void)arg_list;
231 1 : va_end(arg_list);
232 1 : if (ret < 0) {
233 0 : GELOGE("[Check][Param] FormatErrorMessage failed, ret:%d, pattern:%s", ret, format);
234 : }
235 1 : return ret;
236 : }
237 :
238 0 : void ReportInnerError(
239 : const char_t* file_name, const char_t* func, uint32_t line, const std::string error_code, const char_t* format, ...)
240 : {
241 : va_list arg_list;
242 0 : va_start(arg_list, format);
243 0 : (void)ReportInnerErrorMessage(file_name, func, line, error_code.c_str(), format, arg_list);
244 0 : va_end(arg_list);
245 0 : return;
246 : }
247 : } // namespace error_message
248 :
249 : namespace {
250 : #ifdef __GNUC__
251 : constexpr const error_message::char_t* const kErrorCodePath = "../conf/error_manager/error_code.json";
252 : constexpr const error_message::char_t* const kSeparator = "/";
253 : #else
254 : const error_message::char_t* const kErrorCodePath = "..\\conf\\error_manager\\error_code.json";
255 : const error_message::char_t* const kSeparator = "\\";
256 : #endif
257 :
258 : constexpr uint64_t kLength = 2UL;
259 :
260 58325 : void Ltrim(std::string& s)
261 : {
262 58325 : (void)s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](const error_message::char_t c) -> bool {
263 68438 : return static_cast<bool>(std::isspace(static_cast<uint8_t>(c)) == 0);
264 : }));
265 58325 : }
266 :
267 58325 : void Rtrim(std::string& s)
268 : {
269 116650 : (void)s.erase(
270 58325 : std::find_if(
271 58325 : s.rbegin(), s.rend(),
272 58389 : [](const error_message::char_t c) -> bool {
273 58389 : return static_cast<bool>(std::isspace(static_cast<uint8_t>(c)) == 0);
274 : })
275 : .base(),
276 : s.end());
277 58325 : }
278 :
279 : /// @ingroup domi_common
280 : /// @brief trim space
281 58325 : void Trim(std::string& s)
282 : {
283 58325 : Rtrim(s);
284 58325 : Ltrim(s);
285 58325 : }
286 :
287 : /// @brief Obtain error manager self library path
288 : /// @return store liberror_manager.so path
289 4 : std::string GetSelfLibraryDir(void)
290 : {
291 4 : mmDlInfo dl_info{nullptr, nullptr, nullptr, nullptr, 0, 0, 0};
292 4 : if (mmDladdr(reinterpret_cast<void*>(GetSelfLibraryDir), &dl_info) != EN_OK) {
293 0 : const error_message::char_t* error = mmDlerror();
294 0 : error = (error == nullptr) ? "" : error;
295 0 : GELOGW("Failed to read the shared library file path! reason:%s", error);
296 0 : return std::string();
297 : } else {
298 4 : std::string so_path = dl_info.dli_fname;
299 4 : error_message::char_t path[MMPA_MAX_PATH] = {};
300 4 : if (so_path.length() >= static_cast<size_t>(MMPA_MAX_PATH)) {
301 0 : GELOGW("The shared library file path is too long!");
302 0 : return std::string();
303 : }
304 4 : if (mmRealPath(so_path.c_str(), &(path[0]), MMPA_MAX_PATH) != EN_OK) {
305 0 : GELOGW("Failed to get realpath of %s, reason:%s", so_path.c_str(), strerror(errno));
306 0 : return std::string();
307 : }
308 :
309 4 : so_path = &(path[0]);
310 4 : so_path = so_path.substr(0U, so_path.rfind(kSeparator) + 1U);
311 4 : return so_path;
312 4 : }
313 : }
314 :
315 : // split string
316 25930 : std::vector<std::string> SplitByDelim(const std::string& str, const error_message::char_t delim)
317 : {
318 25930 : std::vector<std::string> elems;
319 :
320 25930 : if (str.empty()) {
321 3264 : elems.emplace_back("");
322 3264 : return elems;
323 : }
324 :
325 22666 : std::stringstream ss(str);
326 22666 : std::string item;
327 :
328 80991 : while (getline(ss, item, delim)) {
329 58325 : Trim(item);
330 58325 : elems.push_back(item);
331 : }
332 22666 : const auto str_size = str.size();
333 22666 : if ((str_size > 0U) && (str[str_size - 1U] == delim)) {
334 0 : elems.emplace_back("");
335 : }
336 :
337 22666 : return elems;
338 22666 : }
339 : } // namespace
340 :
341 : thread_local error_message::Context ErrorManager::error_context_ = {0UL, "", "", ""};
342 :
343 : /// @brief Obtain ErrorManager instance
344 : /// @return ErrorManager instance
345 519 : ErrorManager& ErrorManager::GetInstance()
346 : {
347 519 : static ErrorManager instance;
348 519 : return instance;
349 : }
350 :
351 : /// @brief init
352 : /// @param [in] path: current so path
353 : /// @return int 0(success) -1(fail)
354 6 : int32_t ErrorManager::Init(const std::string path)
355 : {
356 6 : const std::unique_lock<std::mutex> lck(mutex_);
357 6 : const std::string file_path = path + kErrorCodePath;
358 6 : GELOGI("Begin to init, path is %s", path.c_str());
359 6 : const int32_t ret = ParseJsonFile(file_path);
360 6 : if (ret != 0) {
361 6 : GELOGW("[Parse][File]Parse config file:%s failed", file_path.c_str());
362 6 : return -1;
363 : }
364 0 : is_init_ = true;
365 0 : return 0;
366 6 : }
367 :
368 : /// @brief init
369 : /// @return int 0(success) -1(fail)
370 3 : int32_t ErrorManager::Init() { return Init(GetSelfLibraryDir()); }
371 :
372 3 : int32_t ErrorManager::Init(error_message::ErrorMsgMode error_mode)
373 : {
374 3 : if (error_mode >= error_message::ErrorMsgMode::ERR_MSG_MODE_MAX) {
375 2 : GELOGE("[Init][Error]error mode is invalid %u", error_mode);
376 2 : return -1;
377 : }
378 1 : error_mode_ = error_mode;
379 1 : return Init(GetSelfLibraryDir());
380 : }
381 :
382 29 : int32_t ErrorManager::ReportInterErrMessage(const std::string error_code, const std::string& error_msg)
383 : {
384 29 : std::string report_time = CurrentTimeFormatStr();
385 29 : constexpr uint64_t kMaxWorkSize = 1000UL;
386 29 : if (!is_init_) {
387 0 : const int32_t kRetInit = Init();
388 0 : if (kRetInit == -1) {
389 0 : GELOGI("ErrorManager has not been initialized, can't report error_message.");
390 0 : return -1;
391 : }
392 : }
393 29 : if (!IsInnerErrorCode(error_code)) {
394 2 : GELOGE("[Report][Error]error_code %s is not internal error code", error_code.c_str());
395 2 : return -1;
396 : }
397 :
398 27 : const std::unique_lock<std::mutex> lck(mutex_);
399 27 : if (error_context_.work_stream_id == 0UL) {
400 2 : if (error_message_per_work_id_.size() > kMaxWorkSize) {
401 1 : GELOGW(
402 : "[Report][Error]error_code %s, error work_stream total size exceed %lu, skip record",
403 : error_code.c_str(), kMaxWorkSize);
404 1 : return -1;
405 : }
406 1 : GenWorkStreamIdDefault();
407 : }
408 :
409 26 : GELOGI(
410 : "report error_message, error_code:%s, work_stream_id:%lu, error_mode:%u", error_code.c_str(),
411 : error_context_.work_stream_id, error_mode_);
412 :
413 26 : auto& error_messages = GetErrorMsgContainer(error_context_.work_stream_id);
414 26 : auto& warning_messages = GetWarningMsgContainer(error_context_.work_stream_id);
415 :
416 26 : if (error_messages.size() > kMaxWorkSize) {
417 1 : GELOGW(
418 : "[Report][Error]error_code %s, error work_stream_id:%lu item size exceed %lu, skip record",
419 : error_code.c_str(), error_context_.work_stream_id, kMaxWorkSize);
420 1 : return -1;
421 : }
422 :
423 25 : std::string tmp = error_msg;
424 25 : if (error_mode_ == error_message::ErrorMsgMode::PROCESS_MODE) {
425 8 : tmp += "[THREAD:" + std::to_string(mmGetTid()) + "]";
426 : }
427 :
428 100 : ErrorManager::ErrorItem item = {error_code, "", tmp, "", "", {}, report_time};
429 25 : if (error_code[0UL] == 'W') {
430 10 : const auto it = find(warning_messages.begin(), warning_messages.end(), item);
431 10 : if (it == warning_messages.end()) {
432 10 : warning_messages.emplace_back(item);
433 : }
434 : } else {
435 15 : const auto it = find(error_messages.begin(), error_messages.end(), item);
436 15 : if (it == error_messages.end()) {
437 15 : error_messages.emplace_back(item);
438 : }
439 : }
440 25 : return 0;
441 29 : }
442 :
443 : /// @brief report error message
444 : /// @param [in] error_code: error code
445 : /// @param [in] args_map: parameter map
446 : /// @return int 0(success) -1(fail)
447 38 : int32_t ErrorManager::ReportErrMessage(const std::string error_code, const std::map<std::string, std::string>& args_map)
448 : {
449 38 : std::string report_time = CurrentTimeFormatStr();
450 38 : if (!is_init_) {
451 0 : const int32_t kRetInit = Init();
452 0 : if (kRetInit == -1) {
453 0 : GELOGI("ErrorManager has not been initialized, can't report error_message.");
454 0 : return 0;
455 : }
456 : }
457 :
458 38 : if (error_context_.work_stream_id == 0UL) {
459 10 : GenWorkStreamIdDefault();
460 : }
461 :
462 38 : GELOGI(
463 : "report error_message, error_code:%s, work_stream_id:%lu, error_mode:%u.", error_code.c_str(),
464 : error_context_.work_stream_id, error_mode_);
465 38 : const std::map<std::string, ErrorManager::ErrorInfoConfig>::const_iterator iter = error_map_.find(error_code);
466 38 : if (iter == error_map_.cend()) {
467 2 : GELOGW("[Report][Warning]error_code %s is not registered", error_code.c_str());
468 2 : return -1;
469 : }
470 36 : const ErrorInfoConfig& error_info = iter->second;
471 36 : std::string error_message = error_info.error_message;
472 74 : for (const std::string& arg : error_info.arg_list) {
473 45 : if (arg.empty()) {
474 4 : GELOGI("arg is null");
475 4 : break;
476 : }
477 41 : const auto arg_it = args_map.find(arg);
478 41 : if (arg_it == args_map.end()) {
479 2 : GELOGE("[Report][Error]error_code: %s, arg %s does not exist in map", error_code.c_str(), arg.c_str());
480 3 : return -1;
481 : }
482 39 : const std::string& arg_value = arg_it->second;
483 39 : const auto index = error_message.find("%s");
484 39 : if (index == std::string::npos) {
485 1 : GELOGE(
486 : "[Report][Error]error_code: %s, %s location in error_message is not found", error_code.c_str(),
487 : arg.c_str());
488 1 : return -1;
489 : }
490 38 : (void)error_message.replace(index, kLength, arg_value);
491 : }
492 :
493 33 : const std::unique_lock<std::mutex> lock(mutex_);
494 33 : auto& error_messages = GetErrorMsgContainer(error_context_.work_stream_id);
495 33 : auto& warning_messages = GetWarningMsgContainer(error_context_.work_stream_id);
496 :
497 33 : if (error_mode_ == error_message::ErrorMsgMode::PROCESS_MODE) {
498 8 : error_message += "[THREAD:" + std::to_string(mmGetTid()) + "]";
499 : }
500 : ErrorManager::ErrorItem error_item = {
501 99 : error_code, error_info.error_title, error_message, error_info.possible_cause, error_info.solution, args_map,
502 33 : report_time};
503 33 : if (error_code[0UL] == 'W') {
504 11 : const auto it = find(warning_messages.begin(), warning_messages.end(), error_item);
505 11 : if (it == warning_messages.end()) {
506 11 : warning_messages.emplace_back(error_item);
507 : }
508 : } else {
509 22 : const auto it = find(error_messages.begin(), error_messages.end(), error_item);
510 22 : if (it == error_messages.end()) {
511 18 : error_messages.emplace_back(error_item);
512 : }
513 : }
514 33 : return 0;
515 38 : }
516 :
517 8 : int32_t ErrorManager::ReportErrMsgWithoutTpl(const std::string& error_code, const std::string& errmsg)
518 : {
519 8 : std::string report_time = CurrentTimeFormatStr();
520 8 : if (!is_init_) {
521 1 : const auto ret = Init();
522 1 : if (ret == -1) {
523 1 : GELOGI("ErrorManager has not been initialized, can't report error_message.");
524 1 : return -1;
525 : }
526 : }
527 :
528 7 : if (error_context_.work_stream_id == 0UL) {
529 1 : GenWorkStreamIdDefault();
530 : }
531 :
532 7 : auto final_error_code = error_code;
533 7 : if (!IsUserDefinedErrorCode(final_error_code)) {
534 5 : GELOGW(
535 : "[Report] Current error code is [%s], suggest using the recommended U segment. "
536 : "The error code EU0000 is reported!",
537 : final_error_code.c_str());
538 5 : final_error_code = "EU0000";
539 : }
540 :
541 7 : GELOGI(
542 : "report error_message, error_code:%s, work_stream_id:%lu, error_mode:%u.", error_code.c_str(),
543 : error_context_.work_stream_id, error_mode_);
544 :
545 7 : const std::unique_lock<std::mutex> lock(mutex_);
546 7 : auto& error_messages = GetErrorMsgContainer(error_context_.work_stream_id);
547 :
548 28 : ErrorItem error_item{final_error_code, "", errmsg, "", "", {}, report_time};
549 7 : const auto it = find(error_messages.begin(), error_messages.end(), error_item);
550 7 : if (it == error_messages.end()) {
551 7 : error_messages.emplace_back(error_item);
552 : }
553 7 : return 0;
554 8 : }
555 :
556 4 : void ErrorManager::AssembleInnerErrorMessage(
557 : const std::vector<ErrorItem>& error_messages, const std::string& first_code, std::stringstream& err_stream) const
558 : {
559 4 : std::string current_code_print = first_code;
560 4 : const bool IsErrorId = IsParamCheckErrorId(first_code);
561 8 : for (auto& item : error_messages) {
562 6 : if (!IsParamCheckErrorId(item.error_id)) {
563 2 : current_code_print = item.error_id;
564 2 : break;
565 : }
566 : }
567 4 : err_stream << current_code_print << ": Internal error!" << std::endl;
568 4 : bool print_traceback_once = false;
569 10 : for (auto& item : error_messages) { // Display the first non 8888 error code
570 6 : if (IsParamCheckErrorId(item.error_id) && IsErrorId) {
571 4 : err_stream << " " << item.error_message << std::endl;
572 4 : continue;
573 : }
574 2 : current_code_print == " " ?
575 0 : (err_stream << current_code_print << " " << item.error_message << std::endl) :
576 4 : (err_stream << current_code_print << "[PID: " << std::to_string(mmGetPid()) << "] " << item.report_time
577 4 : << " " << item.error_title << "(" << item.error_id << "): "
578 4 : << " " << item.error_message << std::endl);
579 :
580 2 : current_code_print = " ";
581 2 : if (!print_traceback_once) {
582 2 : err_stream << "TraceBack (most recent call last):" << std::endl;
583 2 : print_traceback_once = true;
584 : }
585 : }
586 4 : }
587 :
588 36 : std::string ErrorManager::GetErrorMessage()
589 : {
590 36 : const auto& error_messages = GetRawErrorMessages();
591 36 : if (error_messages.empty()) {
592 30 : return "";
593 : }
594 :
595 21 : std::stringstream err_stream;
596 21 : std::string first_code = error_messages[0UL].error_id;
597 27 : for (const auto& item : error_messages) {
598 23 : if (!IsInnerErrorCode(item.error_id)) {
599 17 : first_code = item.error_id;
600 34 : err_stream << "[PID: " << std::to_string(mmGetPid()) << "] " << item.report_time << " " << item.error_title
601 34 : << "(" << first_code << "): " << item.error_message << std::endl;
602 17 : if (!item.possible_cause.empty() && item.possible_cause != "N/A") {
603 1 : err_stream << " Possible Cause: " << item.possible_cause << std::endl;
604 : }
605 17 : if (!item.solution.empty() && item.solution != "N/A") {
606 5 : err_stream << " Solution: " << item.solution << std::endl;
607 : }
608 17 : break;
609 : }
610 : }
611 21 : if (IsInnerErrorCode(first_code)) {
612 4 : AssembleInnerErrorMessage(error_messages, first_code, err_stream);
613 : } else {
614 17 : bool print_traceback_once = false;
615 49 : for (const auto& item : error_messages) {
616 32 : if (first_code == item.error_id && error_messages[0].error_message == item.error_message) {
617 18 : continue;
618 : }
619 14 : if (!print_traceback_once) {
620 6 : err_stream << "TraceBack (most recent call last):" << std::endl;
621 6 : print_traceback_once = true;
622 : }
623 14 : err_stream << " " << item.error_message << std::endl;
624 : }
625 : }
626 21 : const std::unique_lock<std::mutex> lck(mutex_);
627 21 : ClearErrorMsgContainer(error_context_.work_stream_id);
628 21 : return err_stream.str();
629 36 : }
630 :
631 15 : std::string ErrorManager::GetWarningMessage()
632 : {
633 15 : GELOGI("current work_stream_id:%lu, error_mode:%u", error_context_.work_stream_id, error_mode_);
634 15 : const std::unique_lock<std::mutex> lck(mutex_);
635 15 : auto& warning_messages = GetWarningMsgContainer(error_context_.work_stream_id);
636 :
637 15 : std::stringstream warning_stream;
638 30 : for (auto& item : warning_messages) {
639 30 : warning_stream << "[PID: " << std::to_string(mmGetPid()) << "] " << item.report_time << " " << item.error_title
640 30 : << "(" << item.error_id << "): " << item.error_message << std::endl;
641 : }
642 15 : ClearWarningMsgContainer(error_context_.work_stream_id);
643 30 : return warning_stream.str();
644 15 : }
645 :
646 : /// @brief output error message
647 : /// @param [in] handle: print handle
648 : /// @return int 0(success) -1(fail)
649 2 : int32_t ErrorManager::OutputErrMessage(int32_t handle)
650 : {
651 2 : std::string err_msg = GetErrorMessage();
652 2 : if (err_msg.empty()) {
653 2 : std::stringstream err_stream;
654 2 : err_stream << "E19999: Internal error!" << std::endl;
655 : err_stream << " "
656 2 : << "Unknown error occurred. Please check the log." << std::endl;
657 2 : err_msg = err_stream.str();
658 2 : }
659 :
660 2 : if (handle <= fileno(stderr)) {
661 1 : std::cout << err_msg << std::endl;
662 : } else {
663 1 : const mmSsize_t ret = mmWrite(
664 1 : handle, const_cast<error_message::char_t*>(err_msg.c_str()), static_cast<uint32_t>(err_msg.length()));
665 1 : if (ret == -1) {
666 1 : GELOGE("[Write][File]fail, reason:%s", strerror(errno));
667 1 : return -1;
668 : }
669 : }
670 1 : return 0;
671 2 : }
672 :
673 : /// @brief output message
674 : /// @param [in] handle: print handle
675 : /// @return int 0(success) -1(fail)
676 1 : int32_t ErrorManager::OutputMessage(int32_t handle)
677 : {
678 1 : const std::string warning_msg = GetWarningMessage();
679 1 : std::cout << warning_msg << std::endl;
680 1 : handle = 0;
681 1 : return handle;
682 1 : }
683 :
684 7 : int32_t ErrorManager::ParseJsonFile(const std::string path)
685 : {
686 7 : GELOGD("Begin to parse json file, path is %s", path.c_str());
687 7 : nlohmann::json json_file;
688 7 : const int32_t status = ReadJsonFile(path, &json_file);
689 7 : if (status != 0) {
690 6 : GELOGW("[Read][JsonFile]file path is %s", path.c_str());
691 6 : return -1;
692 : }
693 1 : return ParseJsonFormatString(PtrToPtr<nlohmann::json, void>(&json_file));
694 7 : }
695 : /// @brief parse json file
696 : /// @param [in] handle: json handle
697 : /// @return int 0(success) -1(fail)
698 75 : int32_t ErrorManager::ParseJsonFormatString(const void* const handle, uint32_t priority)
699 : {
700 75 : GELOGD("Begin to parse json string");
701 : try {
702 75 : const nlohmann::json* const json_file = PtrToPtr<void, nlohmann::json>(handle);
703 75 : if (json_file->find("error_info_list") == json_file->end()) {
704 2 : GELOGW("[Check][Config]The message of error_info_list is not found");
705 2 : return -1;
706 : }
707 73 : const nlohmann::json& error_list_json = json_file->at("error_info_list");
708 73 : if (error_list_json.is_null() || !error_list_json.is_array()) {
709 1 : GELOGW("[Check][Config]The message of error_info_list is not found or "
710 : "the message of error_info_list is not array");
711 1 : return -1;
712 : }
713 26002 : for (const auto& error_json : error_list_json) {
714 25931 : ErrorInfoConfig error_info;
715 25931 : error_info.error_id = error_json["ErrCode"];
716 25930 : error_info.error_message = error_json["ErrMessage"];
717 25930 : if (error_json.contains("errTitle")) {
718 23240 : error_info.error_title = error_json["errTitle"];
719 : }
720 25930 : if (error_json.contains("suggestion")) {
721 10760 : error_info.possible_cause = error_json["suggestion"]["Possible Cause"];
722 10760 : error_info.solution = error_json["suggestion"]["Solution"];
723 : }
724 25930 : error_info.arg_list = SplitByDelim(error_json["Arglist"], ',');
725 25930 : error_info.priority = priority;
726 25930 : auto it = error_map_.find(error_info.error_id);
727 25930 : if (it == error_map_.cend()) {
728 414 : (void)error_map_.emplace(error_info.error_id, error_info);
729 414 : GELOGD("add error_code %s success", error_info.error_id.c_str());
730 : } else {
731 25516 : if (it->second.priority < error_info.priority) {
732 0 : it->second = error_info;
733 0 : GELOGD(
734 : "Update error_code %s success, current priority[%u] is greater than saved priority[%u]",
735 : error_info.error_id.c_str(), priority, it->second.priority);
736 : } else {
737 25516 : GELOGD(
738 : "No need update error_code %s, due to current priority[%u] is less than "
739 : "or equal to saved priority[%u]",
740 : error_info.error_id.c_str(), priority, it->second.priority);
741 : }
742 : }
743 25931 : }
744 1 : } catch (const nlohmann::json::exception& e) {
745 1 : GELOGW("[Parse][JsonFile]exception message: %s", e.what());
746 1 : return -1;
747 1 : }
748 71 : return 0;
749 : }
750 :
751 : /// @brief read json file
752 : /// @param [in] file_path: json path
753 : /// @param [in] handle: print handle
754 : /// @return int 0(success) -1(fail)
755 79 : int32_t ErrorManager::ReadJsonFile(const std::string& file_path, void* const handle)
756 : {
757 79 : if (file_path.empty()) {
758 1 : GELOGW("[Read][JsonFile]path %s is not valid", file_path.c_str());
759 1 : return -1;
760 : }
761 78 : nlohmann::json* const json_file = PtrToPtr<void, nlohmann::json>(handle);
762 78 : if (json_file == nullptr) {
763 1 : GELOGW("[Check][Param]JsonFile is nullptr");
764 1 : return -1;
765 : }
766 77 : const error_message::char_t* const file = file_path.data();
767 77 : if ((mmAccess2(file, M_F_OK)) != EN_OK) {
768 6 : GELOGW("[Read][JsonFile] %s does not exist, error %s", file_path.c_str(), strerror(errno));
769 6 : return -1;
770 : }
771 :
772 71 : std::ifstream ifs(file_path);
773 71 : if (!ifs.is_open()) {
774 0 : GELOGW("[Read][JsonFile]Open %s failed", file_path.c_str());
775 0 : return -1;
776 : }
777 :
778 71 : const std::string content((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
779 : try {
780 72 : *json_file = nlohmann::json::parse(content.c_str(), content.c_str() + content.size());
781 1 : } catch (const nlohmann::json::exception& e) {
782 1 : GELOGW("[Read][JsonFile]Parse json fail. path: %s, exception message: %s.", file_path.c_str(), e.what());
783 1 : ifs.close();
784 1 : return -1;
785 1 : }
786 :
787 70 : ifs.close();
788 70 : GELOGD("Read json file success");
789 70 : return 0;
790 71 : }
791 :
792 : /// @brief report error message
793 : /// @param [in] error_code: error code
794 : /// @param [in] vector parameter key, vector parameter value
795 : /// @return int 0(success) -1(fail)
796 4 : void ErrorManager::ATCReportErrMessage(
797 : const std::string error_code, const std::vector<std::string>& key, const std::vector<std::string>& value)
798 : {
799 4 : if (!is_init_) {
800 0 : const int32_t kRetInit = Init();
801 0 : if (kRetInit == -1) {
802 0 : GELOGI("ErrorManager has not been initialized, can't report error_message.");
803 0 : return;
804 : }
805 : }
806 4 : std::map<std::string, std::string> args_map;
807 4 : if (key.empty()) {
808 2 : (void)ErrorManager::GetInstance().ReportErrMessage(error_code, args_map);
809 2 : } else if (key.size() == value.size()) {
810 2 : for (size_t i = 0UL; i < key.size(); ++i) {
811 1 : (void)args_map.insert(std::make_pair(key[i], value[i]));
812 : }
813 1 : (void)ErrorManager::GetInstance().ReportErrMessage(error_code, args_map);
814 : } else {
815 1 : GELOGW("ATCReportErrMessage wrong, vector key and value size is not equal");
816 : }
817 4 : }
818 :
819 : /// @brief report graph compile failed message such as error code and op_name in mustune case
820 : /// @param [in] msg: failed message map, key is error code, value is op_name
821 : /// @param [out] classified_msg: classified_msg message map, key is error code, value is op_name vector
822 4 : void ErrorManager::ClassifyCompileFailedMsg(
823 : const std::map<std::string, std::string>& msg, std::map<std::string, std::vector<std::string>>& classified_msg)
824 : {
825 8 : for (const auto& itr : msg) {
826 4 : GELOGD("msg is error_code:%s, op_name:%s", itr.first.c_str(), itr.second.c_str());
827 4 : const auto err_code_itr = classified_msg.find(itr.first);
828 4 : if (err_code_itr == classified_msg.end()) {
829 9 : (void)classified_msg.emplace(itr.first, std::vector<std::string>{itr.second});
830 : } else {
831 1 : std::vector<std::string>& op_name_list = err_code_itr->second;
832 1 : op_name_list.emplace_back(itr.second);
833 : }
834 : }
835 7 : }
836 :
837 : /// @brief report graph compile failed message such as error code and op_name in mustune case
838 : /// @param [in] root_graph_name: root graph name
839 : /// @param [in] msg: failed message map, key is error code, value is op_name
840 : /// @return int 0(success) -1(fail)
841 4 : int32_t ErrorManager::ReportMstuneCompileFailedMsg(
842 : const std::string& root_graph_name, const std::map<std::string, std::string>& msg)
843 : {
844 4 : if (!is_init_) {
845 0 : const int32_t kRetInit = Init();
846 0 : if (kRetInit == -1) {
847 0 : GELOGI("ErrorManager has not been initialized, can't report error_message.");
848 0 : return 0;
849 : }
850 : }
851 4 : if (msg.empty() || root_graph_name.empty()) {
852 2 : GELOGW(
853 : "Msg or root graph name is empty, msg size is %zu, root graph name is %s", msg.size(),
854 : root_graph_name.c_str());
855 2 : return -1;
856 : }
857 2 : GELOGD("Report graph:%s compile failed msg", root_graph_name.c_str());
858 2 : const std::unique_lock<std::mutex> lock(mutex_);
859 2 : const auto itr = compile_failed_msg_map_.find(root_graph_name);
860 2 : if (itr != compile_failed_msg_map_.end()) {
861 1 : std::map<std::string, std::vector<std::string>>& classified_msg = itr->second;
862 1 : ClassifyCompileFailedMsg(msg, classified_msg);
863 : } else {
864 1 : std::map<std::string, std::vector<std::string>> classified_msg;
865 1 : ClassifyCompileFailedMsg(msg, classified_msg);
866 1 : (void)compile_failed_msg_map_.emplace(root_graph_name, classified_msg);
867 1 : }
868 2 : return 0;
869 2 : }
870 :
871 : /// @brief get graph compile failed message in mustune case
872 : /// @param [in] graph_name: graph name
873 : /// @param [out] msg_map: failed message map, key is error code, value is op_name list
874 : /// @return int 0(success) -1(fail)
875 4 : int32_t ErrorManager::GetMstuneCompileFailedMsg(
876 : const std::string& graph_name, std::map<std::string, std::vector<std::string>>& msg_map)
877 : {
878 4 : if (!is_init_) {
879 0 : const int32_t kRetInit = Init();
880 0 : if (kRetInit == -1) {
881 0 : GELOGI("ErrorManager has not been initialized, can't report error_message.");
882 0 : return 0;
883 : }
884 : }
885 4 : if (!msg_map.empty()) {
886 2 : GELOGW("msg_map is not empty, exist msg");
887 2 : return -1;
888 : }
889 2 : const std::unique_lock<std::mutex> lock(mutex_);
890 2 : const auto iter = compile_failed_msg_map_.find(graph_name);
891 2 : if (iter == compile_failed_msg_map_.end()) {
892 1 : GELOGW("can not find graph, name is:%s", graph_name.c_str());
893 1 : return -1;
894 : } else {
895 1 : auto& compile_failed_msg = iter->second;
896 1 : msg_map.swap(compile_failed_msg);
897 1 : (void)compile_failed_msg_map_.erase(graph_name);
898 : }
899 1 : GELOGI("get graph:%s compile result msg success", graph_name.c_str());
900 :
901 1 : return 0;
902 2 : }
903 :
904 85 : std::vector<ErrorManager::ErrorItem>& ErrorManager::GetErrorMsgContainerByWorkId(uint64_t work_id)
905 : {
906 85 : return GetOrCreateMessageContainerByWorkId(error_message_per_work_id_, work_id);
907 : }
908 :
909 54 : std::vector<ErrorManager::ErrorItem>& ErrorManager::GetWarningMsgContainerByWorkId(uint64_t work_id)
910 : {
911 54 : return GetOrCreateMessageContainerByWorkId(warning_messages_per_work_id_, work_id);
912 : }
913 :
914 104 : std::vector<ErrorManager::ErrorItem>& ErrorManager::GetErrorMsgContainer(uint64_t work_stream_id)
915 : {
916 104 : return (error_mode_ == error_message::ErrorMsgMode::INTERNAL_MODE) ? GetErrorMsgContainerByWorkId(work_stream_id) :
917 104 : error_message_process_;
918 : }
919 :
920 74 : std::vector<ErrorManager::ErrorItem>& ErrorManager::GetWarningMsgContainer(uint64_t work_stream_id)
921 : {
922 74 : return (error_mode_ == error_message::ErrorMsgMode::INTERNAL_MODE) ?
923 54 : GetWarningMsgContainerByWorkId(work_stream_id) :
924 74 : warning_messages_process_;
925 : }
926 :
927 14 : void ErrorManager::GenWorkStreamIdDefault()
928 : {
929 : // system getpid and gettid is always successful
930 14 : const int32_t pid = mmGetPid();
931 14 : const int32_t tid = mmGetTid();
932 :
933 14 : constexpr uint64_t kPidOffset = 100000UL;
934 14 : const uint64_t work_stream_id =
935 14 : static_cast<uint64_t>(static_cast<uint32_t>(pid) * kPidOffset) + static_cast<uint64_t>(tid);
936 14 : error_context_.work_stream_id = work_stream_id;
937 14 : }
938 :
939 1 : void ErrorManager::GenWorkStreamIdBySessionGraph(const uint64_t session_id, const uint64_t graph_id)
940 : {
941 1 : constexpr uint64_t kSessionIdOffset = 100000UL;
942 1 : const uint64_t work_stream_id = (session_id * kSessionIdOffset) + graph_id;
943 1 : error_context_.work_stream_id = work_stream_id;
944 :
945 1 : const std::unique_lock<std::mutex> lck(mutex_);
946 1 : ClearErrorMsgContainerByWorkId(work_stream_id);
947 1 : ClearWarningMsgContainerByWorkId(work_stream_id);
948 1 : }
949 :
950 1 : void ErrorManager::GenWorkStreamIdWithSessionIdGraphId(const uint64_t session_id, const uint64_t graph_id)
951 : {
952 1 : constexpr uint64_t kSessionIdOffset = 100000UL;
953 1 : const uint64_t work_stream_id = (session_id * kSessionIdOffset) + graph_id;
954 1 : error_context_.work_stream_id = work_stream_id;
955 1 : }
956 :
957 54 : void ErrorManager::ClearErrorMsgContainerByWorkId(const uint64_t work_stream_id)
958 : {
959 54 : return ClearMessageContainerByWorkId(error_message_per_work_id_, work_stream_id);
960 : }
961 :
962 12 : void ErrorManager::ClearWarningMsgContainerByWorkId(const uint64_t work_stream_id)
963 : {
964 12 : return ClearMessageContainerByWorkId(warning_messages_per_work_id_, work_stream_id);
965 : }
966 :
967 58 : void ErrorManager::ClearErrorMsgContainer(const uint64_t work_stream_id)
968 : {
969 58 : if (error_mode_ == error_message::ErrorMsgMode::PROCESS_MODE) {
970 6 : error_message_process_.clear();
971 : } else {
972 52 : ClearErrorMsgContainerByWorkId(work_stream_id);
973 : }
974 58 : }
975 :
976 15 : void ErrorManager::ClearWarningMsgContainer(const uint64_t work_stream_id)
977 : {
978 15 : if (error_mode_ == error_message::ErrorMsgMode::PROCESS_MODE) {
979 4 : warning_messages_process_.clear();
980 : } else {
981 11 : ClearWarningMsgContainerByWorkId(work_stream_id);
982 : }
983 15 : }
984 :
985 25 : const std::string& ErrorManager::GetLogHeader()
986 : {
987 25 : if ((error_context_.first_stage == "") && (error_context_.second_stage == "")) {
988 25 : error_context_.log_header = "";
989 : } else {
990 0 : error_context_.log_header = "[" + error_context_.first_stage + "][" + error_context_.second_stage + "]";
991 : }
992 25 : return error_context_.log_header;
993 : }
994 :
995 3 : error_message::Context& ErrorManager::GetErrorManagerContext()
996 : {
997 : // son thread need set father thread work_stream_id, but work_stream_id cannot be zero
998 : // so GenWorkStreamIdDefault here directly
999 3 : if (error_context_.work_stream_id == 0UL) {
1000 1 : GenWorkStreamIdDefault();
1001 : }
1002 3 : return error_context_;
1003 : }
1004 :
1005 4 : void ErrorManager::SetErrorContext(error_message::Context error_context)
1006 : {
1007 4 : error_context_.work_stream_id = error_context.work_stream_id;
1008 4 : error_context_.first_stage = std::move(error_context.first_stage);
1009 4 : error_context_.second_stage = std::move(error_context.second_stage);
1010 4 : error_context_.log_header = std::move(error_context.log_header);
1011 4 : }
1012 :
1013 0 : void ErrorManager::SetStage(const std::string& first_stage, const std::string& second_stage)
1014 : {
1015 0 : error_context_.first_stage = first_stage;
1016 0 : error_context_.second_stage = second_stage;
1017 0 : }
1018 :
1019 83 : bool ErrorManager::IsInnerErrorCode(const std::string& error_code) const
1020 : {
1021 83 : const std::string kInterErrorCodePrefix = "9999";
1022 83 : if (!IsValidErrorCode(error_code)) {
1023 7 : return false;
1024 : } else {
1025 76 : return (error_code.substr(2U, 4U) == kInterErrorCodePrefix) || IsParamCheckErrorId(error_code);
1026 : }
1027 83 : }
1028 :
1029 : // 这里只做简单校验, 校验是非内部错误码、非预定义错误码的6位字符串即可
1030 13 : bool ErrorManager::IsUserDefinedErrorCode(const std::string& error_code)
1031 : {
1032 13 : if (!IsValidErrorCode(error_code) || IsInnerErrorCode(error_code)) {
1033 7 : return false;
1034 : }
1035 :
1036 6 : if (!is_init_) {
1037 1 : const auto ret = Init();
1038 1 : if (ret == -1) {
1039 1 : GELOGI("ErrorManager has not been initialized, can't verify error code.");
1040 1 : return false;
1041 : }
1042 : }
1043 :
1044 5 : if (error_map_.find(error_code) != error_map_.end()) {
1045 2 : GELOGW("Report error_code:[%s] is predefined error code, suggested use U error code", error_code.c_str());
1046 2 : return false;
1047 : }
1048 3 : return true;
1049 : }
1050 :
1051 83 : bool ErrorManager::IsParamCheckErrorId(const std::string& error_code) const
1052 : {
1053 83 : return (error_code.substr(2U, 4U) == kParamCheckErrorSuffix);
1054 : }
1055 :
1056 1 : int32_t ErrorManager::SetRawErrorMessages(const std::vector<ErrorItem>& items)
1057 : {
1058 1 : const std::unique_lock<std::mutex> lck(mutex_);
1059 1 : if (error_context_.work_stream_id == 0UL) {
1060 1 : GenWorkStreamIdDefault();
1061 : }
1062 :
1063 1 : GELOGI("Set error_message, work_stream_id:%lu.", error_context_.work_stream_id);
1064 1 : auto& error_messages = GetErrorMsgContainer(error_context_.work_stream_id);
1065 1 : (void)error_messages.insert(error_messages.end(), items.begin(), items.end());
1066 1 : return 0;
1067 1 : }
1068 :
1069 37 : std::vector<error_message::ErrorItem> ErrorManager::GetRawErrorMessages()
1070 : {
1071 37 : GELOGI("current work_stream_id:%lu", error_context_.work_stream_id);
1072 37 : const std::unique_lock<std::mutex> lck(mutex_);
1073 37 : auto error_items = GetErrorMsgContainer(error_context_.work_stream_id);
1074 37 : ClearErrorMsgContainer(error_context_.work_stream_id);
1075 37 : return error_items;
1076 37 : }
1077 :
1078 : namespace error_message {
1079 8 : int32_t RegisterFormatErrorMessage(const char_t* error_msg, size_t error_msg_len)
1080 : {
1081 8 : nlohmann::json j;
1082 : try {
1083 10 : j = nlohmann::json::parse(error_msg, error_msg + error_msg_len);
1084 2 : } catch (const nlohmann::json::parse_error& e) {
1085 2 : return -1;
1086 2 : }
1087 6 : GELOGI("RegisterFormatErrorMessage, try to register error message");
1088 : // User registration error codes have high priority than those defined in the json file,
1089 : // set priority to 1 here.
1090 6 : return ErrorManager::GetInstance().ParseJsonFormatString(PtrToPtr<nlohmann::json, void>(&j), 1);
1091 8 : }
1092 :
1093 6 : int32_t ReportInnerErrMsg(
1094 : const char* file_name, const char* func, uint32_t line, const char* error_code, const char* format, ...)
1095 : {
1096 : va_list arg_list;
1097 6 : va_start(arg_list, format);
1098 6 : const auto ret = ReportInnerErrorMessage(file_name, func, line, error_code, format, arg_list);
1099 6 : va_end(arg_list);
1100 6 : return ret;
1101 : }
1102 :
1103 9 : int32_t ReportUserDefinedErrMsg(const char* error_code, const char* format, ...)
1104 : {
1105 : va_list arg_list;
1106 9 : std::vector<char> buf(LIMIT_PER_MESSAGE, '\0');
1107 9 : va_start(arg_list, format);
1108 9 : const auto ret = vsprintf_s(buf.data(), LIMIT_PER_MESSAGE, format, arg_list);
1109 9 : if (ret < 0) {
1110 1 : GELOGE("[Check][Param] Format error message failed, ret:%d", ret);
1111 1 : return -1;
1112 : }
1113 :
1114 40 : return ErrorManager::GetInstance().ReportErrMsgWithoutTpl(error_code, std::string(buf.data()));
1115 9 : }
1116 :
1117 11 : int32_t ReportPredefinedErrMsg(
1118 : const char* error_code, const std::vector<const char*>& key, const std::vector<const char*>& value)
1119 : {
1120 11 : if (key.size() != value.size()) {
1121 1 : GELOGE(
1122 : "[Check][Param] ReportPredefinedErrMsg failed, vector key size:[%zu] and value size:[%zu] is not equal",
1123 : key.size(), value.size());
1124 1 : return -1;
1125 : }
1126 10 : std::map<std::string, std::string> args_map;
1127 28 : for (size_t i = 0UL; i < key.size(); ++i) {
1128 18 : (void)args_map.insert(std::make_pair(key[i], value[i]));
1129 : }
1130 20 : return ErrorManager::GetInstance().ReportErrMessage(error_code, args_map);
1131 10 : }
1132 :
1133 1 : int32_t ReportPredefinedErrMsg(const char* error_code) { return ReportPredefinedErrMsg(error_code, {}, {}); }
1134 :
1135 1 : int32_t ErrMgrInit(ErrorMessageMode error_mode)
1136 : {
1137 1 : return ErrorManager::GetInstance().Init(static_cast<error_message::ErrorMsgMode>(error_mode));
1138 : }
1139 :
1140 1 : ErrorManagerContext GetErrMgrContext()
1141 : {
1142 1 : auto ctx = ErrorManager::GetInstance().GetErrorManagerContext();
1143 1 : ErrorManagerContext error_context{};
1144 1 : error_context.work_stream_id = ctx.work_stream_id;
1145 2 : return error_context;
1146 1 : }
1147 :
1148 3 : void SetErrMgrContext(ErrorManagerContext error_context)
1149 : {
1150 3 : Context ctx;
1151 3 : ctx.work_stream_id = error_context.work_stream_id;
1152 6 : return ErrorManager::GetInstance().SetErrorContext(ctx);
1153 3 : }
1154 :
1155 23 : unique_const_char_array GetErrMgrErrorMessage()
1156 : {
1157 23 : return CreateUniquePtrFromString(ErrorManager::GetInstance().GetErrorMessage());
1158 : }
1159 :
1160 9 : unique_const_char_array GetErrMgrWarningMessage()
1161 : {
1162 9 : return CreateUniquePtrFromString(ErrorManager::GetInstance().GetWarningMessage());
1163 : }
1164 :
1165 1 : std::vector<ErrMsgRawItem> GetErrMgrRawErrorMessages()
1166 : {
1167 1 : std::vector<ErrMsgRawItem> raw_items;
1168 1 : auto error_items = ErrorManager::GetInstance().GetRawErrorMessages();
1169 2 : for (const auto& item : error_items) {
1170 1 : ErrMsgRawItem raw_item;
1171 1 : raw_item.error_id = CreateUniquePtrFromString(item.error_id);
1172 1 : raw_item.error_title = CreateUniquePtrFromString(item.error_title);
1173 1 : raw_item.error_message = CreateUniquePtrFromString(item.error_message);
1174 1 : raw_item.possible_cause = CreateUniquePtrFromString(item.possible_cause);
1175 1 : raw_item.solution = CreateUniquePtrFromString(item.solution);
1176 4 : for (const auto& arg : item.args_map) {
1177 3 : raw_item.args_key.emplace_back(CreateUniquePtrFromString(arg.first));
1178 3 : raw_item.args_value.emplace_back(CreateUniquePtrFromString(arg.second));
1179 : }
1180 1 : raw_item.report_time = CreateUniquePtrFromString(item.report_time);
1181 1 : raw_items.emplace_back(std::move(raw_item));
1182 1 : }
1183 1 : return raw_items;
1184 1 : }
1185 : } // namespace error_message
1186 :
1187 : extern "C" {
1188 3 : int32_t RegisterFormatErrorMessageForC(const char* error_msg, unsigned long error_msg_len)
1189 : {
1190 3 : if (error_msg == nullptr) {
1191 1 : GELOGE("[Check][Param] error_msg is null");
1192 1 : return -1;
1193 : }
1194 : try {
1195 2 : return error_message::RegisterFormatErrorMessage(error_msg, error_msg_len);
1196 0 : } catch (const std::exception& e) {
1197 0 : GELOGE("[Check][Exception] RegisterFormatErrorMessageForC caught exception: %s", e.what());
1198 0 : return -1;
1199 0 : } catch (...) {
1200 0 : GELOGE("[Check][Exception] RegisterFormatErrorMessageForC caught unknown exception");
1201 0 : return -1;
1202 0 : }
1203 : }
1204 :
1205 8 : int32_t ReportPredefinedErrMsgForC(const char* error_code, const char** key, const char** value, unsigned long arg_num)
1206 : {
1207 8 : if (error_code == nullptr) {
1208 1 : GELOGE("[Check][Param] error_code is null");
1209 1 : return -1;
1210 : }
1211 7 : if ((arg_num != 0U) && ((key == nullptr) || (value == nullptr))) {
1212 3 : GELOGE("[Check][Param] Argument arrays are null when arg_num:[%lu]", arg_num);
1213 3 : return -1;
1214 : }
1215 :
1216 9 : for (size_t i = 0U; i < arg_num; ++i) {
1217 7 : if ((key[i] == nullptr) || (value[i] == nullptr)) {
1218 2 : GELOGE("[Check][Param] Argument array contains null entry at index:[%zu]", i);
1219 2 : return -1;
1220 : }
1221 : }
1222 :
1223 : try {
1224 2 : std::vector<const char*> key_vec;
1225 2 : std::vector<const char*> value_vec;
1226 2 : key_vec.reserve(arg_num);
1227 2 : value_vec.reserve(arg_num);
1228 5 : for (size_t i = 0U; i < arg_num; ++i) {
1229 3 : key_vec.push_back(key[i]);
1230 3 : value_vec.push_back(value[i]);
1231 : }
1232 2 : return error_message::ReportPredefinedErrMsg(error_code, key_vec, value_vec);
1233 2 : } catch (const std::exception& e) {
1234 0 : GELOGE("[Check][Exception] ReportPredefinedErrMsgForC caught exception: %s", e.what());
1235 0 : return -1;
1236 0 : } catch (...) {
1237 0 : GELOGE("[Check][Exception] ReportPredefinedErrMsgForC caught unknown exception");
1238 0 : return -1;
1239 0 : }
1240 : }
1241 :
1242 6 : int32_t ReportInnerErrMsgForC(
1243 : const char* file_name, const char* func, uint32_t line, const char* error_code, const char* format, ...)
1244 : {
1245 6 : if ((file_name == nullptr) || (func == nullptr) || (error_code == nullptr) || (format == nullptr)) {
1246 4 : GELOGE("[Check][Param] file_name or func or error_code or format is null");
1247 4 : return -1;
1248 : }
1249 :
1250 : va_list arg_list;
1251 2 : va_start(arg_list, format);
1252 2 : int32_t ret = -1;
1253 : try {
1254 2 : ret = ReportInnerErrorMessage(file_name, func, line, error_code, format, arg_list);
1255 0 : } catch (const std::exception& e) {
1256 0 : GELOGE("[Check][Exception] ReportInnerErrMsgForC caught exception: %s", e.what());
1257 0 : } catch (...) {
1258 0 : GELOGE("[Check][Exception] ReportInnerErrMsgForC caught unknown exception");
1259 0 : }
1260 2 : va_end(arg_list);
1261 2 : return ret;
1262 : }
1263 : } // extern "C"
|