1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "mpl_logging.h"
17 #include <unistd.h>
18 #include <cstring>
19 #include <ctime>
20 #ifndef _WIN32
21 #include <sys/syscall.h>
22 #endif
23 #include "securec.h"
24 
25 namespace {
26 constexpr uint32_t kMaxLogLen = 10000;
27 }
28 
29 namespace maple {
30 LogInfo logInfo;
31 LogInfo &log = logInfo;
32 
33 const char *kLongLogLevels[] = {
34     [kLlDbg] = "D", [kLlLog] = "L", [kLlInfo] = "Info ", [kLlWarn] = "Warn ", [kLlErr] = "Error", [kLlFatal] = "Fatal"};
35 
36 const char *tags[] = {
37     [kLtThread] = "TR",
38     [kLtLooper] = "LP",
39 };
40 
41 SECUREC_ATTRIBUTE(4, 5)
EmitLogForUser(enum LogNumberCode num, enum LogLevel ll, const char *fmt, ...) const42 void LogInfo::EmitLogForUser(enum LogNumberCode num, enum LogLevel ll, const char *fmt, ...) const
43 {
44     char buf[kMaxLogLen];
45     int len = snprintf_s(buf, kMaxLogLen, kMaxLogLen - 1, "%s %02d: ", kLongLogLevels[ll], num);
46     if (len == -1) {
47         WARN(kLncWarn, "snprintf_s failed");
48         return;
49     }
50     if (outMode) {
51         va_list l;
52         va_start(l, fmt);
53         int eNum = vsnprintf_s(buf + len, kMaxLogLen - len, static_cast<size_t>(kMaxLogLen - len - 1), fmt, l);
54         if (eNum == -1) {
55             WARN(kLncWarn, "vsnprintf_s failed");
56             va_end(l);
57             return;
58         }
59         va_end(l);
60     }
61     std::cerr << buf << '\n';
62     return;
63 }
64 
EmitLogForUser(enum LogNumberCode num, enum LogLevel ll, const std::string &message) const65 void LogInfo::EmitLogForUser(enum LogNumberCode num, enum LogLevel ll, const std::string &message) const
66 {
67     EmitLogForUser(num, ll, "%s", message.c_str());
68 }
69 
70 SECUREC_ATTRIBUTE(5, 6)
EmitErrorMessage(const std::string &cond, const std::string &file, unsigned int line, const char *fmt, ...) const71 void LogInfo::EmitErrorMessage(const std::string &cond, const std::string &file, unsigned int line, const char *fmt,
72                                ...) const
73 {
74     char buf[kMaxLogLen];
75 #ifdef _WIN32
76     int len = snprintf_s(buf, kMaxLogLen, kMaxLogLen - 1, "CHECK/CHECK_FATAL failure: %s at [%s:%d] ", cond.c_str(),
77                          file.c_str(), line);
78 #else
79     pid_t tid = syscall(SYS_gettid);
80     int len = snprintf_s(buf, kMaxLogLen, kMaxLogLen - 1, "Tid(%d): CHECK/CHECK_FATAL failure: %s at [%s:%d] ", tid,
81                          cond.c_str(), file.c_str(), line);
82 #endif
83     if (len == -1) {
84         WARN(kLncWarn, "snprintf_s failed");
85         return;
86     }
87     va_list l;
88     va_start(l, fmt);
89     int eNum = vsnprintf_s(buf + len, kMaxLogLen - len, static_cast<size_t>(kMaxLogLen - len - 1), fmt, l);
90     if (eNum == -1) {
91         WARN(kLncWarn, "vsnprintf_s failed");
92         va_end(l);
93         return;
94     }
95     va_end(l);
96     std::cerr << buf;
97 }
98 
MapleLogger(LogLevel level)99 std::ostream &LogInfo::MapleLogger(LogLevel level)
100 {
101     if (level == kLlLog) {
102         return std::cout;
103     }
104     return std::cerr;
105 }
106 }  // namespace maple
107