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(7, 8)
EmitLogForDevelop(enum LogTags tag,enum LogLevel ll,const std::string & file,const std::string & func,int line,const char * fmt,...)42 void LogInfo::EmitLogForDevelop(enum LogTags tag, enum LogLevel ll, const std::string &file, const std::string &func,
43 int line, const char *fmt, ...)
44 {
45 char buf[kMaxLogLen];
46 DEBUG_ASSERT(tag < kLtAll, "illegal log tag");
47
48 #ifndef _WIN32
49 pid_t tid = syscall(SYS_gettid);
50 #endif
51
52 time_t timeSeconds = time(nullptr);
53 struct tm *nowTime = localtime(&timeSeconds);
54 CHECK_FATAL(nowTime != nullptr, "(nowTime) null ptr check");
55 int month = nowTime->tm_mon + 1;
56 int day = nowTime->tm_mday;
57 int hour = nowTime->tm_hour;
58 int min = nowTime->tm_min;
59 int sec = nowTime->tm_sec;
60
61 #ifdef _WIN32
62 int lenFront = snprintf_s(buf, kMaxLogLen, kMaxLogLen - 1, "%02d-%02d %02d:%02d:%02d %s %s ", month, day, hour, min,
63 sec, tags[tag], kLongLogLevels[ll]);
64 #else
65 int lenFront = snprintf_s(buf, kMaxLogLen, kMaxLogLen - 1, "%02d-%02d %02d:%02d:%02d %s %d %s ", month, day, hour,
66 min, sec, tags[tag], tid, kLongLogLevels[ll]);
67 #endif
68
69 if (lenFront == -1) {
70 WARN(kLncWarn, "snprintf_s failed in mpl_logging.cpp");
71 return;
72 }
73 va_list l;
74 va_start(l, fmt);
75
76 int lenBack =
77 vsnprintf_s(buf + lenFront, kMaxLogLen - lenFront, static_cast<size_t>(kMaxLogLen - lenFront - 1), fmt, l);
78 if (lenBack == -1) {
79 WARN(kLncWarn, "vsnprintf_s failed ");
80 va_end(l);
81 return;
82 }
83 if (outMode != 0) {
84 int eNum = snprintf_s(buf + lenFront + lenBack, kMaxLogLen - lenFront - lenBack,
85 kMaxLogLen - lenFront - lenBack - 1, " [%s] [%s:%d]", func.c_str(), file.c_str(), line);
86 if (eNum == -1) {
87 WARN(kLncWarn, "snprintf_s failed");
88 va_end(l);
89 return;
90 }
91 } else {
92 int eNum = snprintf_s(buf + lenFront + lenBack, kMaxLogLen - lenFront - lenBack,
93 kMaxLogLen - lenFront - lenBack - 1, " [%s]", func.c_str());
94 if (eNum == -1) {
95 WARN(kLncWarn, "snprintf_s failed");
96 va_end(l);
97 return;
98 }
99 }
100 va_end(l);
101 fprintf(outStream, "%s\n", buf);
102 return;
103 }
104
105 SECUREC_ATTRIBUTE(4, 5)
EmitLogForUser(enum LogNumberCode num,enum LogLevel ll,const char * fmt,...) const106 void LogInfo::EmitLogForUser(enum LogNumberCode num, enum LogLevel ll, const char *fmt, ...) const
107 {
108 char buf[kMaxLogLen];
109 int len = snprintf_s(buf, kMaxLogLen, kMaxLogLen - 1, "%s %02d: ", kLongLogLevels[ll], num);
110 if (len == -1) {
111 WARN(kLncWarn, "snprintf_s failed");
112 return;
113 }
114 if (outMode) {
115 va_list l;
116 va_start(l, fmt);
117 int eNum = vsnprintf_s(buf + len, kMaxLogLen - len, static_cast<size_t>(kMaxLogLen - len - 1), fmt, l);
118 if (eNum == -1) {
119 WARN(kLncWarn, "vsnprintf_s failed");
120 va_end(l);
121 return;
122 }
123 va_end(l);
124 }
125 std::cerr << buf << '\n';
126 return;
127 }
128
EmitLogForUser(enum LogNumberCode num,enum LogLevel ll,const std::string & message) const129 void LogInfo::EmitLogForUser(enum LogNumberCode num, enum LogLevel ll, const std::string &message) const
130 {
131 EmitLogForUser(num, ll, "%s", message.c_str());
132 }
133
134 SECUREC_ATTRIBUTE(5, 6)
EmitErrorMessage(const std::string & cond,const std::string & file,unsigned int line,const char * fmt,...) const135 void LogInfo::EmitErrorMessage(const std::string &cond, const std::string &file, unsigned int line, const char *fmt,
136 ...) const
137 {
138 char buf[kMaxLogLen];
139 #ifdef _WIN32
140 int len = snprintf_s(buf, kMaxLogLen, kMaxLogLen - 1, "CHECK/CHECK_FATAL failure: %s at [%s:%d] ", cond.c_str(),
141 file.c_str(), line);
142 #else
143 pid_t tid = syscall(SYS_gettid);
144 int len = snprintf_s(buf, kMaxLogLen, kMaxLogLen - 1, "Tid(%d): CHECK/CHECK_FATAL failure: %s at [%s:%d] ", tid,
145 cond.c_str(), file.c_str(), line);
146 #endif
147 if (len == -1) {
148 WARN(kLncWarn, "snprintf_s failed");
149 return;
150 }
151 va_list l;
152 va_start(l, fmt);
153 int eNum = vsnprintf_s(buf + len, kMaxLogLen - len, static_cast<size_t>(kMaxLogLen - len - 1), fmt, l);
154 if (eNum == -1) {
155 WARN(kLncWarn, "vsnprintf_s failed");
156 va_end(l);
157 return;
158 }
159 va_end(l);
160 std::cerr << buf;
161 }
162
Flags()163 std::ios::fmtflags LogInfo::Flags()
164 {
165 std::ios::fmtflags flag(std::cout.flags());
166 return std::cout.flags(flag);
167 }
168
MapleLogger(LogLevel level)169 std::ostream &LogInfo::MapleLogger(LogLevel level)
170 {
171 if (level == kLlLog) {
172 return std::cout;
173 } else {
174 return std::cerr;
175 }
176 }
Info()177 std::ostream &LogInfo::Info()
178 {
179 return std::cout;
180 }
Err()181 std::ostream &LogInfo::Err()
182 {
183 return std::cerr;
184 }
185 } // namespace maple
186