• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
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 #ifndef OHOS_PROFILER_LOGGING_H
17 #define OHOS_PROFILER_LOGGING_H
18 
19 #define EXPORT_API __attribute__((visibility("default")))
20 
21 #undef NDEBUG
22 
23 #ifndef LOG_TAG
24 #define LOG_TAG "Hiprofiler"
25 #endif
26 
27 #ifndef HIPROFILER_LOG_TAG
28 #define HIPROFILER_LOG_TAG "Hiprofiler"
29 #endif
30 
31 #define PROFILER_SUBSYSTEM 0xD002D0C
32 #ifndef LOG_DOMAIN
33 #define LOG_DOMAIN PROFILER_SUBSYSTEM
34 #endif
35 
36 #ifndef UNUSED_PARAMETER
37 #define UNUSED_PARAMETER(x) ((void)(x))
38 #endif
39 
40 #ifdef HAVE_HILOG
41 #include "hilog_base/log_base.h"
42 #include <string>
43 #else // HAVE_HILOG
44 #include <mutex>
45 #include <string>
46 #include <securec.h>
47 #include <stdarg.h>
48 #if !is_mingw
49 #include <sys/syscall.h>
50 #undef getsystid
51 #define getsystid() syscall(SYS_gettid)
52 #else
53 #include "windows.h"
getsystid()54 inline long getsystid()
55 {
56     return GetCurrentThreadId();
57 }
58 #endif
59 
60 #include <ctime>
61 #include <vector>
62 #include <unistd.h>
63 
64 enum {
65     LOG_UNKNOWN = 0,
66     LOG_DEFAULT,
67     LOG_VERBOSE,
68     LOG_DEBUG,
69     LOG_INFO,
70     LOG_WARN,
71     LOG_ERROR,
72     LOG_FATAL,
73     LOG_SILENT,
74 };
75 
76 namespace {
77 constexpr int NS_PER_MS_LOG = 1000 * 1000;
78 constexpr int TIME_STRING_MAX_LENGTH = 64;
79 }
80 
81 static inline std::string GetTimeString();
82 
83 typedef const char* ConstCharPtr;
84 
HiLogPrintArgs(int prio,int domain,ConstCharPtr tag,ConstCharPtr fmt,va_list vargs)85 static inline int HiLogPrintArgs(int prio, int domain, ConstCharPtr tag, ConstCharPtr fmt, va_list vargs)
86 {
87     static std::mutex mtx;
88     static std::vector<std::string> prioNames = {"U", " ", "V", "D", "I", "W", "E", "F", "S"};
89     std::unique_lock<std::mutex> lock(mtx);
90     int count = fprintf(stderr, "%04x %s %7d %7ld %5s %s ", domain, GetTimeString().c_str(), getpid(), getsystid(),
91                         prioNames[prio].c_str(), tag);
92     if (count < 0) {
93         return 0;
94     }
95     count = count + vfprintf(stderr, fmt, vargs) + fprintf(stderr, "\n");
96     fflush(stderr);
97     return count;
98 }
99 
HiLogPrint(int type,int prio,int domain,ConstCharPtr tag,ConstCharPtr fmt,...)100 static inline int HiLogPrint(int type, int prio, int domain, ConstCharPtr tag, ConstCharPtr fmt, ...)
101 {
102     va_list vargs;
103     UNUSED_PARAMETER(type);
104     va_start(vargs, fmt);
105     int count = HiLogPrintArgs(prio, domain, tag, fmt, vargs);
106     va_end(vargs);
107     return count;
108 }
109 
110 #ifndef LOG_CORE
111 #define LOG_CORE 0
112 #endif
113 
114 #define HILOG_BASE_DEBUG(LOG_CORE, fmt, ...) HiLogPrint(LOG_CORE, LOG_DEBUG, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__)
115 #define HILOG_BASE_INFO(LOG_CORE, fmt, ...) HiLogPrint(LOG_CORE, LOG_INFO, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__)
116 #define HILOG_BASE_WARN(LOG_CORE, fmt, ...) HiLogPrint(LOG_CORE, LOG_WARN, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__)
117 #define HILOG_BASE_ERROR(LOG_CORE, fmt, ...) HiLogPrint(LOG_CORE, LOG_ERROR, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__)
118 
119 #endif // HAVE_HILOG
120 
121 #ifndef NDEBUG
122 #include <securec.h>
123 namespace logging {
StringReplace(std::string & str,const std::string & oldStr,const std::string & newStr)124 inline void StringReplace(std::string& str, const std::string& oldStr, const std::string& newStr)
125 {
126     std::string::size_type pos = 0u;
127     while ((pos = str.find(oldStr, pos)) != std::string::npos) {
128         str.replace(pos, oldStr.length(), newStr);
129         pos += newStr.length();
130     }
131 }
132 
133 // let compiler check format string and variable arguments
134 static inline std::string StringFormat(const char* fmt, ...)  __attribute__((format(printf, 1, 2)));
135 
StringFormat(const char * fmt,...)136 static inline std::string StringFormat(const char* fmt, ...)
137 {
138     va_list vargs;
139     char buf[1024] = {0};
140 
141     if (fmt == nullptr) {
142         return "";
143     }
144     std::string format(fmt);
145     StringReplace(format, "%{public}", "%");
146 
147     va_start(vargs, fmt);
148     if (vsnprintf_s(buf, sizeof(buf), sizeof(buf) - 1, format.c_str(), vargs) < 0) {
149         va_end(vargs);
150         return "";
151     }
152 
153     va_end(vargs);
154     return buf;
155 }
156 }  // logging
157 
158 #ifdef HAVE_HILOG
159 #define HILOG_PRINT_DEBUG(type, fmt, ...) \
160     (void)HiLogBasePrint(type, LOG_DEBUG, PROFILER_SUBSYSTEM, HIPROFILER_LOG_TAG, \
161                          "%{public}s", logging::StringFormat(fmt, ##__VA_ARGS__).c_str())
162 #define HILOG_PRINT_INFO(type, fmt, ...) \
163     (void)HiLogBasePrint(type, LOG_INFO, PROFILER_SUBSYSTEM, HIPROFILER_LOG_TAG, \
164                          "%{public}s", logging::StringFormat(fmt, ##__VA_ARGS__).c_str())
165 #define HILOG_PRINT_WARN(type, fmt, ...) \
166     (void)HiLogBasePrint(type, LOG_WARN, PROFILER_SUBSYSTEM, HIPROFILER_LOG_TAG, \
167                          "%{public}s", logging::StringFormat(fmt, ##__VA_ARGS__).c_str())
168 #define HILOG_PRINT_ERROR(type, fmt, ...) \
169     (void)HiLogBasePrint(type, LOG_ERROR, PROFILER_SUBSYSTEM, HIPROFILER_LOG_TAG, \
170                          "%{public}s", logging::StringFormat(fmt, ##__VA_ARGS__).c_str())
171 #else
172 #define HILOG_PRINT_DEBUG(type, fmt, ...) \
173     HiLogPrint(type, LOG_DEBUG, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__)
174 #define HILOG_PRINT_INFO(type, fmt, ...) \
175     HiLogPrint(type, LOG_INFO, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__)
176 #define HILOG_PRINT_WARN(type, fmt, ...) \
177     HiLogPrint(type, LOG_WARN, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__)
178 #define HILOG_PRINT_ERROR(type, fmt, ...) \
179     HiLogPrint(type, LOG_ERROR, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__)
180 #endif
181 
182 #define PROFILER_LOG_DEBUG(type, fmt, ...) HILOG_PRINT_DEBUG(type, fmt, ##__VA_ARGS__)
183 #define PROFILER_LOG_INFO(type, fmt, ...) HILOG_PRINT_INFO(type, fmt, ##__VA_ARGS__)
184 #define PROFILER_LOG_WARN(type, fmt, ...) HILOG_PRINT_WARN(type, fmt, ##__VA_ARGS__)
185 #define PROFILER_LOG_ERROR(type, fmt, ...) HILOG_PRINT_ERROR(type, fmt, ##__VA_ARGS__)
186 #endif  // NDEBUG
187 
188 #define STD_PTR(K, T) std::K##_ptr<T>
189 
190 #define NO_RETVAL /* retval */
191 
192 #define CHECK_NOTNULL(ptr, retval, fmt, ...)                                                                        \
193     do {                                                                                                            \
194         if (ptr == nullptr) {                                                                                       \
195             std::string str = std::string("CHECK_NOTNULL(") + logging::StringFormat(fmt, ##__VA_ARGS__) +           \
196                               ") in " + __func__ + ":" + std::to_string(__LINE__) + "FAILED";                       \
197             HILOG_BASE_WARN(LOG_CORE, "%{public}s", str.c_str());                                                   \
198             return retval;                                                                                          \
199         }                                                                                                           \
200     } while (0)
201 
202 #ifndef FUZZ_TEST
203 #define CHECK_TRUE(expr, retval, fmt, ...)                                                                          \
204     do {                                                                                                            \
205         if (!(expr)) {                                                                                              \
206             std::string str = std::string("CHECK_TRUE(") + logging::StringFormat(fmt, ##__VA_ARGS__) +              \
207                               ") in " + __func__ + ":" + std::to_string(__LINE__) + "FAILED";                       \
208             HILOG_BASE_WARN(LOG_CORE, "%{public}s", str.c_str());                                                   \
209             return retval;                                                                                          \
210         }                                                                                                           \
211     } while (0)
212 #else
213 #define CHECK_TRUE(expr, retval, fmt, ...) \
214     do {                                   \
215         if (!(expr)) {                     \
216             return retval;                 \
217         }                                  \
218     } while (0)
219 #endif  // FUZZ_TEST
220 
221 #define RETURN_IF(expr, retval, fmt, ...)             \
222     do {                                              \
223         if ((expr)) {                                 \
224             HILOG_BASE_WARN(LOG_CORE, "%{public}s", logging::StringFormat(fmt, ##__VA_ARGS__).c_str()); \
225             return retval;                            \
226         }                                             \
227     } while (0)
228 
229 #ifndef HAVE_HILOG
GetTimeString()230 static std::string GetTimeString()
231 {
232     char timeStr[TIME_STRING_MAX_LENGTH];
233     struct timespec ts;
234     struct tm tmStruct;
235     clock_gettime(CLOCK_REALTIME, &ts);
236 #if !is_mingw
237     localtime_r(&ts.tv_sec, &tmStruct);
238 #else
239     CHECK_TRUE(localtime_s(&tmStruct, &ts.tv_sec) == 0, "", "localtime_s FAILED!");
240 #endif
241     size_t used = strftime(timeStr, sizeof(timeStr), "%m-%d %H:%M:%S", &tmStruct);
242     if (used >= TIME_STRING_MAX_LENGTH) {
243         return "";
244     }
245     (void)snprintf_s(&timeStr[used], sizeof(timeStr) - used, sizeof(timeStr) - used - 1, ".%03ld",
246         ts.tv_nsec / NS_PER_MS_LOG);
247     return timeStr;
248 }
249 #endif // !HAVE_HILOG
250 #endif // OHOS_PROFILER_LOGGING_H
251