1 /* 2 * Copyright (c) 2021 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 #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 #define PROFILER_SUBSYSTEM 0xD002D0C 28 #ifndef LOG_DOMAIN 29 #define LOG_DOMAIN PROFILER_SUBSYSTEM 30 #endif 31 32 #ifndef UNUSED_PARAMETER 33 #define UNUSED_PARAMETER(x) ((void)(x)) 34 #endif 35 36 #ifdef HAVE_HILOG 37 #include "hilog/log.h" 38 #include <string> 39 #else // HAVE_HILOG 40 #include <mutex> 41 #include <string> 42 #include <securec.h> 43 #include <stdarg.h> 44 #if !is_mingw 45 #include <sys/syscall.h> 46 #undef getsystid 47 #define getsystid() syscall(SYS_gettid) 48 #else 49 #include "windows.h" getsystid()50 inline long getsystid() 51 { 52 return GetCurrentThreadId(); 53 } 54 #endif 55 #include <time.h> 56 #include <unistd.h> 57 #include <vector> 58 GetTid(void)59 static inline long GetTid(void) 60 { 61 return getsystid(); 62 } 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 } 79 80 static inline std::string GetTimeStr(); 81 82 typedef const char* ConstCharPtr; 83 HiLogPrintArgs(int prio,int domain,ConstCharPtr tag,ConstCharPtr fmt,va_list vargs)84 static inline int HiLogPrintArgs(int prio, int domain, ConstCharPtr tag, ConstCharPtr fmt, va_list vargs) 85 { 86 static std::mutex mtx; 87 static std::vector<std::string> prioNames = {"U", " ", "V", "D", "I", "W", "E", "F", "S"}; 88 std::unique_lock<std::mutex> lock(mtx); 89 int count = fprintf(stderr, "%04x %s %7d %7ld %5s %s ", domain, GetTimeStr().c_str(), getpid(), GetTid(), 90 prioNames[prio].c_str(), tag); 91 if (count < 0) { 92 return 0; 93 } 94 count = count + vfprintf(stderr, fmt, vargs) + fprintf(stderr, "\n"); 95 fflush(stderr); 96 return count; 97 } 98 HiLogPrint(int type,int prio,int domain,ConstCharPtr tag,ConstCharPtr fmt,...)99 static inline int HiLogPrint(int type, int prio, int domain, ConstCharPtr tag, ConstCharPtr fmt, ...) 100 { 101 va_list vargs; 102 UNUSED_PARAMETER(type); 103 va_start(vargs, fmt); 104 int count = HiLogPrintArgs(prio, domain, tag, fmt, vargs); 105 va_end(vargs); 106 return count; 107 } 108 109 #ifndef LOG_CORE 110 #define LOG_CORE 0 111 #endif 112 113 #define HILOG_DEBUG(LOG_CORE, fmt, ...) HiLogPrint(LOG_CORE, LOG_DEBUG, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__) 114 #define HILOG_INFO(LOG_CORE, fmt, ...) HiLogPrint(LOG_CORE, LOG_INFO, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__) 115 #define HILOG_WARN(LOG_CORE, fmt, ...) HiLogPrint(LOG_CORE, LOG_WARN, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__) 116 #define HILOG_ERROR(LOG_CORE, fmt, ...) HiLogPrint(LOG_CORE, LOG_ERROR, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__) 117 118 #endif // HAVE_HILOG 119 120 #ifndef NDEBUG 121 #include <securec.h> 122 namespace logging { StringReplace(std::string & str,const std::string & oldStr,const std::string & newStr)123 inline void StringReplace(std::string& str, const std::string& oldStr, const std::string& newStr) 124 { 125 std::string::size_type pos = 0u; 126 while ((pos = str.find(oldStr, pos)) != std::string::npos) { 127 str.replace(pos, oldStr.length(), newStr); 128 pos += newStr.length(); 129 } 130 } 131 132 // let compiler check format string and variable arguments 133 static inline std::string StringFormat(const char* fmt, ...) __attribute__((format(printf, 1, 2))); 134 StringFormat(const char * fmt,...)135 static inline std::string StringFormat(const char* fmt, ...) 136 { 137 va_list vargs; 138 char buf[1024] = {0}; 139 140 if (fmt == nullptr) { 141 return ""; 142 } 143 std::string format(fmt); 144 StringReplace(format, "%{public}", "%"); 145 146 va_start(vargs, fmt); 147 if (vsnprintf_s(buf, sizeof(buf), sizeof(buf) - 1, format.c_str(), vargs) < 0) { 148 va_end(vargs); 149 return ""; 150 } 151 152 va_end(vargs); 153 return buf; 154 } 155 } // logging 156 157 #ifdef HILOG_DEBUG 158 #undef HILOG_DEBUG 159 #endif 160 161 #ifdef HILOG_INFO 162 #undef HILOG_INFO 163 #endif 164 165 #ifdef HILOG_WARN 166 #undef HILOG_WARN 167 #endif 168 169 #ifdef HILOG_ERROR 170 #undef HILOG_ERROR 171 #endif 172 173 #ifdef HILOG_PRINT 174 #undef HILOG_PRINT 175 #endif 176 177 #ifdef HAVE_HILOG 178 #define HILOG_PRINT(type, level, fmt, ...) \ 179 HiLogPrint(type, level, LOG_DOMAIN, LOG_TAG, "%{public}s", logging::StringFormat(fmt, ##__VA_ARGS__).c_str()) 180 #else 181 #define HILOG_PRINT(type, level, fmt, ...) \ 182 HiLogPrint(type, level, LOG_DOMAIN, LOG_TAG, "%s", logging::StringFormat(fmt, ##__VA_ARGS__).c_str()) 183 #endif 184 185 #define HILOG_DEBUG(type, fmt, ...) HILOG_PRINT(type, LOG_DEBUG, fmt, ##__VA_ARGS__) 186 #define HILOG_INFO(type, fmt, ...) HILOG_PRINT(type, LOG_INFO, fmt, ##__VA_ARGS__) 187 #define HILOG_WARN(type, fmt, ...) HILOG_PRINT(type, LOG_WARN, fmt, ##__VA_ARGS__) 188 #define HILOG_ERROR(type, fmt, ...) HILOG_PRINT(type, LOG_ERROR, fmt, ##__VA_ARGS__) 189 #endif // NDEBUG 190 191 #define STD_PTR(K, T) std::K##_ptr<T> 192 193 #define NO_RETVAL /* retval */ 194 195 #define CHECK_NOTNULL(ptr, retval, fmt, ...) \ 196 do { \ 197 if (ptr == nullptr) { \ 198 HILOG_WARN(LOG_CORE, "CHECK_NOTNULL(%s) in %s:%d FAILED, " fmt, #ptr, __func__, \ 199 __LINE__, ##__VA_ARGS__); \ 200 return retval; \ 201 } \ 202 } while (0) 203 204 #ifndef FUZZ_TEST 205 #define CHECK_TRUE(expr, retval, fmt, ...) \ 206 do { \ 207 if (!(expr)) { \ 208 HILOG_WARN(LOG_CORE, "CHECK_TRUE(%s) in %s:%d FAILED, " fmt, #expr, __func__, __LINE__, ##__VA_ARGS__); \ 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_WARN(LOG_CORE, fmt, ##__VA_ARGS__); \ 225 return retval; \ 226 } \ 227 } while (0) 228 229 #ifndef HAVE_HILOG GetTimeStr()230 static std::string GetTimeStr() 231 { 232 char timeStr[64]; 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 snprintf_s(&timeStr[used], sizeof(timeStr) - used, sizeof(timeStr) - used - 1, ".%03ld", 243 ts.tv_nsec / NS_PER_MS_LOG); 244 return timeStr; 245 } 246 #endif // !HAVE_HILOG 247 #endif // OHOS_PROFILER_LOGGING_H 248