106f6ba60Sopenharmony_ci/* 206f6ba60Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. 306f6ba60Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 406f6ba60Sopenharmony_ci * you may not use this file except in compliance with the License. 506f6ba60Sopenharmony_ci * You may obtain a copy of the License at 606f6ba60Sopenharmony_ci * 706f6ba60Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 806f6ba60Sopenharmony_ci * 906f6ba60Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1006f6ba60Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1106f6ba60Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1206f6ba60Sopenharmony_ci * See the License for the specific language governing permissions and 1306f6ba60Sopenharmony_ci * limitations under the License. 1406f6ba60Sopenharmony_ci */ 1506f6ba60Sopenharmony_ci 1606f6ba60Sopenharmony_ci#ifndef OHOS_PROFILER_LOGGING_H 1706f6ba60Sopenharmony_ci#define OHOS_PROFILER_LOGGING_H 1806f6ba60Sopenharmony_ci 1906f6ba60Sopenharmony_ci#define EXPORT_API __attribute__((visibility("default"))) 2006f6ba60Sopenharmony_ci 2106f6ba60Sopenharmony_ci#undef NDEBUG 2206f6ba60Sopenharmony_ci 2306f6ba60Sopenharmony_ci#ifndef LOG_TAG 2406f6ba60Sopenharmony_ci#define LOG_TAG "Hiprofiler" 2506f6ba60Sopenharmony_ci#endif 2606f6ba60Sopenharmony_ci 2706f6ba60Sopenharmony_ci#define PROFILER_SUBSYSTEM 0xD002D0C 2806f6ba60Sopenharmony_ci#ifndef LOG_DOMAIN 2906f6ba60Sopenharmony_ci#define LOG_DOMAIN PROFILER_SUBSYSTEM 3006f6ba60Sopenharmony_ci#endif 3106f6ba60Sopenharmony_ci 3206f6ba60Sopenharmony_ci#ifndef UNUSED_PARAMETER 3306f6ba60Sopenharmony_ci#define UNUSED_PARAMETER(x) ((void)(x)) 3406f6ba60Sopenharmony_ci#endif 3506f6ba60Sopenharmony_ci 3606f6ba60Sopenharmony_ci#ifdef HAVE_HILOG 3706f6ba60Sopenharmony_ci#include "hilog_base/log_base.h" 3806f6ba60Sopenharmony_ci#include <string> 3906f6ba60Sopenharmony_ci#else // HAVE_HILOG 4006f6ba60Sopenharmony_ci#include <mutex> 4106f6ba60Sopenharmony_ci#include <string> 4206f6ba60Sopenharmony_ci#include <securec.h> 4306f6ba60Sopenharmony_ci#include <stdarg.h> 4406f6ba60Sopenharmony_ci#if !is_mingw 4506f6ba60Sopenharmony_ci#include <sys/syscall.h> 4606f6ba60Sopenharmony_ci#undef getsystid 4706f6ba60Sopenharmony_ci#define getsystid() syscall(SYS_gettid) 4806f6ba60Sopenharmony_ci#else 4906f6ba60Sopenharmony_ci#include "windows.h" 5006f6ba60Sopenharmony_ciinline long getsystid() 5106f6ba60Sopenharmony_ci{ 5206f6ba60Sopenharmony_ci return GetCurrentThreadId(); 5306f6ba60Sopenharmony_ci} 5406f6ba60Sopenharmony_ci#endif 5506f6ba60Sopenharmony_ci 5606f6ba60Sopenharmony_ci#include <ctime> 5706f6ba60Sopenharmony_ci#include <vector> 5806f6ba60Sopenharmony_ci#include <unistd.h> 5906f6ba60Sopenharmony_ci 6006f6ba60Sopenharmony_cienum { 6106f6ba60Sopenharmony_ci LOG_UNKNOWN = 0, 6206f6ba60Sopenharmony_ci LOG_DEFAULT, 6306f6ba60Sopenharmony_ci LOG_VERBOSE, 6406f6ba60Sopenharmony_ci LOG_DEBUG, 6506f6ba60Sopenharmony_ci LOG_INFO, 6606f6ba60Sopenharmony_ci LOG_WARN, 6706f6ba60Sopenharmony_ci LOG_ERROR, 6806f6ba60Sopenharmony_ci LOG_FATAL, 6906f6ba60Sopenharmony_ci LOG_SILENT, 7006f6ba60Sopenharmony_ci}; 7106f6ba60Sopenharmony_ci 7206f6ba60Sopenharmony_cinamespace { 7306f6ba60Sopenharmony_ciconstexpr int NS_PER_MS_LOG = 1000 * 1000; 7406f6ba60Sopenharmony_ciconstexpr int TIME_STRING_MAX_LENGTH = 64; 7506f6ba60Sopenharmony_ci} 7606f6ba60Sopenharmony_ci 7706f6ba60Sopenharmony_cistatic inline std::string GetTimeString(); 7806f6ba60Sopenharmony_ci 7906f6ba60Sopenharmony_citypedef const char* ConstCharPtr; 8006f6ba60Sopenharmony_ci 8106f6ba60Sopenharmony_cistatic inline int HiLogPrintArgs(int prio, int domain, ConstCharPtr tag, ConstCharPtr fmt, va_list vargs) 8206f6ba60Sopenharmony_ci{ 8306f6ba60Sopenharmony_ci static std::mutex mtx; 8406f6ba60Sopenharmony_ci static std::vector<std::string> prioNames = {"U", " ", "V", "D", "I", "W", "E", "F", "S"}; 8506f6ba60Sopenharmony_ci std::unique_lock<std::mutex> lock(mtx); 8606f6ba60Sopenharmony_ci int count = fprintf(stderr, "%04x %s %7d %7ld %5s %s ", domain, GetTimeString().c_str(), getpid(), getsystid(), 8706f6ba60Sopenharmony_ci prioNames[prio].c_str(), tag); 8806f6ba60Sopenharmony_ci if (count < 0) { 8906f6ba60Sopenharmony_ci return 0; 9006f6ba60Sopenharmony_ci } 9106f6ba60Sopenharmony_ci count = count + vfprintf(stderr, fmt, vargs) + fprintf(stderr, "\n"); 9206f6ba60Sopenharmony_ci fflush(stderr); 9306f6ba60Sopenharmony_ci return count; 9406f6ba60Sopenharmony_ci} 9506f6ba60Sopenharmony_ci 9606f6ba60Sopenharmony_cistatic inline int HiLogPrint(int type, int prio, int domain, ConstCharPtr tag, ConstCharPtr fmt, ...) 9706f6ba60Sopenharmony_ci{ 9806f6ba60Sopenharmony_ci va_list vargs; 9906f6ba60Sopenharmony_ci UNUSED_PARAMETER(type); 10006f6ba60Sopenharmony_ci va_start(vargs, fmt); 10106f6ba60Sopenharmony_ci int count = HiLogPrintArgs(prio, domain, tag, fmt, vargs); 10206f6ba60Sopenharmony_ci va_end(vargs); 10306f6ba60Sopenharmony_ci return count; 10406f6ba60Sopenharmony_ci} 10506f6ba60Sopenharmony_ci 10606f6ba60Sopenharmony_ci#ifndef LOG_CORE 10706f6ba60Sopenharmony_ci#define LOG_CORE 0 10806f6ba60Sopenharmony_ci#endif 10906f6ba60Sopenharmony_ci 11006f6ba60Sopenharmony_ci#define HILOG_BASE_DEBUG(LOG_CORE, fmt, ...) HiLogPrint(LOG_CORE, LOG_DEBUG, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__) 11106f6ba60Sopenharmony_ci#define HILOG_BASE_INFO(LOG_CORE, fmt, ...) HiLogPrint(LOG_CORE, LOG_INFO, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__) 11206f6ba60Sopenharmony_ci#define HILOG_BASE_WARN(LOG_CORE, fmt, ...) HiLogPrint(LOG_CORE, LOG_WARN, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__) 11306f6ba60Sopenharmony_ci#define HILOG_BASE_ERROR(LOG_CORE, fmt, ...) HiLogPrint(LOG_CORE, LOG_ERROR, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__) 11406f6ba60Sopenharmony_ci 11506f6ba60Sopenharmony_ci#endif // HAVE_HILOG 11606f6ba60Sopenharmony_ci 11706f6ba60Sopenharmony_ci#ifndef NDEBUG 11806f6ba60Sopenharmony_ci#include <securec.h> 11906f6ba60Sopenharmony_cinamespace logging { 12006f6ba60Sopenharmony_ciinline void StringReplace(std::string& str, const std::string& oldStr, const std::string& newStr) 12106f6ba60Sopenharmony_ci{ 12206f6ba60Sopenharmony_ci std::string::size_type pos = 0u; 12306f6ba60Sopenharmony_ci while ((pos = str.find(oldStr, pos)) != std::string::npos) { 12406f6ba60Sopenharmony_ci str.replace(pos, oldStr.length(), newStr); 12506f6ba60Sopenharmony_ci pos += newStr.length(); 12606f6ba60Sopenharmony_ci } 12706f6ba60Sopenharmony_ci} 12806f6ba60Sopenharmony_ci 12906f6ba60Sopenharmony_ci// let compiler check format string and variable arguments 13006f6ba60Sopenharmony_cistatic inline std::string StringFormat(const char* fmt, ...) __attribute__((format(printf, 1, 2))); 13106f6ba60Sopenharmony_ci 13206f6ba60Sopenharmony_cistatic inline std::string StringFormat(const char* fmt, ...) 13306f6ba60Sopenharmony_ci{ 13406f6ba60Sopenharmony_ci va_list vargs; 13506f6ba60Sopenharmony_ci char buf[1024] = {0}; 13606f6ba60Sopenharmony_ci 13706f6ba60Sopenharmony_ci if (fmt == nullptr) { 13806f6ba60Sopenharmony_ci return ""; 13906f6ba60Sopenharmony_ci } 14006f6ba60Sopenharmony_ci std::string format(fmt); 14106f6ba60Sopenharmony_ci StringReplace(format, "%{public}", "%"); 14206f6ba60Sopenharmony_ci 14306f6ba60Sopenharmony_ci va_start(vargs, fmt); 14406f6ba60Sopenharmony_ci if (vsnprintf_s(buf, sizeof(buf), sizeof(buf) - 1, format.c_str(), vargs) < 0) { 14506f6ba60Sopenharmony_ci va_end(vargs); 14606f6ba60Sopenharmony_ci return ""; 14706f6ba60Sopenharmony_ci } 14806f6ba60Sopenharmony_ci 14906f6ba60Sopenharmony_ci va_end(vargs); 15006f6ba60Sopenharmony_ci return buf; 15106f6ba60Sopenharmony_ci} 15206f6ba60Sopenharmony_ci} // logging 15306f6ba60Sopenharmony_ci 15406f6ba60Sopenharmony_ci#ifdef HAVE_HILOG 15506f6ba60Sopenharmony_ci#define HILOG_PRINT_DEBUG(type, fmt, ...) \ 15606f6ba60Sopenharmony_ci HILOG_BASE_DEBUG(type, "%{public}s", logging::StringFormat(fmt, ##__VA_ARGS__).c_str()) 15706f6ba60Sopenharmony_ci#define HILOG_PRINT_INFO(type, fmt, ...) \ 15806f6ba60Sopenharmony_ci HILOG_BASE_INFO(type, "%{public}s", logging::StringFormat(fmt, ##__VA_ARGS__).c_str()) 15906f6ba60Sopenharmony_ci#define HILOG_PRINT_WARN(type, fmt, ...) \ 16006f6ba60Sopenharmony_ci HILOG_BASE_WARN(type, "%{public}s", logging::StringFormat(fmt, ##__VA_ARGS__).c_str()) 16106f6ba60Sopenharmony_ci#define HILOG_PRINT_ERROR(type, fmt, ...) \ 16206f6ba60Sopenharmony_ci HILOG_BASE_ERROR(type, "%{public}s", logging::StringFormat(fmt, ##__VA_ARGS__).c_str()) 16306f6ba60Sopenharmony_ci#else 16406f6ba60Sopenharmony_ci#define HILOG_PRINT_DEBUG(type, fmt, ...) \ 16506f6ba60Sopenharmony_ci HiLogPrint(type, LOG_DEBUG, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__) 16606f6ba60Sopenharmony_ci#define HILOG_PRINT_INFO(type, fmt, ...) \ 16706f6ba60Sopenharmony_ci HiLogPrint(type, LOG_INFO, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__) 16806f6ba60Sopenharmony_ci#define HILOG_PRINT_WARN(type, fmt, ...) \ 16906f6ba60Sopenharmony_ci HiLogPrint(type, LOG_WARN, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__) 17006f6ba60Sopenharmony_ci#define HILOG_PRINT_ERROR(type, fmt, ...) \ 17106f6ba60Sopenharmony_ci HiLogPrint(type, LOG_ERROR, LOG_DOMAIN, LOG_TAG, fmt, ##__VA_ARGS__) 17206f6ba60Sopenharmony_ci#endif 17306f6ba60Sopenharmony_ci 17406f6ba60Sopenharmony_ci#define PROFILER_LOG_DEBUG(type, fmt, ...) HILOG_PRINT_DEBUG(type, fmt, ##__VA_ARGS__) 17506f6ba60Sopenharmony_ci#define PROFILER_LOG_INFO(type, fmt, ...) HILOG_PRINT_INFO(type, fmt, ##__VA_ARGS__) 17606f6ba60Sopenharmony_ci#define PROFILER_LOG_WARN(type, fmt, ...) HILOG_PRINT_WARN(type, fmt, ##__VA_ARGS__) 17706f6ba60Sopenharmony_ci#define PROFILER_LOG_ERROR(type, fmt, ...) HILOG_PRINT_ERROR(type, fmt, ##__VA_ARGS__) 17806f6ba60Sopenharmony_ci#endif // NDEBUG 17906f6ba60Sopenharmony_ci 18006f6ba60Sopenharmony_ci#define STD_PTR(K, T) std::K##_ptr<T> 18106f6ba60Sopenharmony_ci 18206f6ba60Sopenharmony_ci#define NO_RETVAL /* retval */ 18306f6ba60Sopenharmony_ci 18406f6ba60Sopenharmony_ci#define CHECK_NOTNULL(ptr, retval, fmt, ...) \ 18506f6ba60Sopenharmony_ci do { \ 18606f6ba60Sopenharmony_ci if (ptr == nullptr) { \ 18706f6ba60Sopenharmony_ci std::string str = std::string("CHECK_NOTNULL(") + logging::StringFormat(fmt, ##__VA_ARGS__) + \ 18806f6ba60Sopenharmony_ci ") in " + __func__ + ":" + std::to_string(__LINE__) + "FAILED"; \ 18906f6ba60Sopenharmony_ci HILOG_BASE_WARN(LOG_CORE, "%{public}s", str.c_str()); \ 19006f6ba60Sopenharmony_ci return retval; \ 19106f6ba60Sopenharmony_ci } \ 19206f6ba60Sopenharmony_ci } while (0) 19306f6ba60Sopenharmony_ci 19406f6ba60Sopenharmony_ci#ifndef FUZZ_TEST 19506f6ba60Sopenharmony_ci#define CHECK_TRUE(expr, retval, fmt, ...) \ 19606f6ba60Sopenharmony_ci do { \ 19706f6ba60Sopenharmony_ci if (!(expr)) { \ 19806f6ba60Sopenharmony_ci std::string str = std::string("CHECK_TRUE(") + logging::StringFormat(fmt, ##__VA_ARGS__) + \ 19906f6ba60Sopenharmony_ci ") in " + __func__ + ":" + std::to_string(__LINE__) + "FAILED"; \ 20006f6ba60Sopenharmony_ci HILOG_BASE_WARN(LOG_CORE, "%{public}s", str.c_str()); \ 20106f6ba60Sopenharmony_ci return retval; \ 20206f6ba60Sopenharmony_ci } \ 20306f6ba60Sopenharmony_ci } while (0) 20406f6ba60Sopenharmony_ci#else 20506f6ba60Sopenharmony_ci#define CHECK_TRUE(expr, retval, fmt, ...) \ 20606f6ba60Sopenharmony_ci do { \ 20706f6ba60Sopenharmony_ci if (!(expr)) { \ 20806f6ba60Sopenharmony_ci return retval; \ 20906f6ba60Sopenharmony_ci } \ 21006f6ba60Sopenharmony_ci } while (0) 21106f6ba60Sopenharmony_ci#endif // FUZZ_TEST 21206f6ba60Sopenharmony_ci 21306f6ba60Sopenharmony_ci#define RETURN_IF(expr, retval, fmt, ...) \ 21406f6ba60Sopenharmony_ci do { \ 21506f6ba60Sopenharmony_ci if ((expr)) { \ 21606f6ba60Sopenharmony_ci HILOG_BASE_WARN(LOG_CORE, "%{public}s", logging::StringFormat(fmt, ##__VA_ARGS__).c_str()); \ 21706f6ba60Sopenharmony_ci return retval; \ 21806f6ba60Sopenharmony_ci } \ 21906f6ba60Sopenharmony_ci } while (0) 22006f6ba60Sopenharmony_ci 22106f6ba60Sopenharmony_ci#ifndef HAVE_HILOG 22206f6ba60Sopenharmony_cistatic std::string GetTimeString() 22306f6ba60Sopenharmony_ci{ 22406f6ba60Sopenharmony_ci char timeStr[TIME_STRING_MAX_LENGTH]; 22506f6ba60Sopenharmony_ci struct timespec ts; 22606f6ba60Sopenharmony_ci struct tm tmStruct; 22706f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &ts); 22806f6ba60Sopenharmony_ci#if !is_mingw 22906f6ba60Sopenharmony_ci localtime_r(&ts.tv_sec, &tmStruct); 23006f6ba60Sopenharmony_ci#else 23106f6ba60Sopenharmony_ci CHECK_TRUE(localtime_s(&tmStruct, &ts.tv_sec) == 0, "", "localtime_s FAILED!"); 23206f6ba60Sopenharmony_ci#endif 23306f6ba60Sopenharmony_ci size_t used = strftime(timeStr, sizeof(timeStr), "%m-%d %H:%M:%S", &tmStruct); 23406f6ba60Sopenharmony_ci if (used >= TIME_STRING_MAX_LENGTH) { 23506f6ba60Sopenharmony_ci return ""; 23606f6ba60Sopenharmony_ci } 23706f6ba60Sopenharmony_ci (void)snprintf_s(&timeStr[used], sizeof(timeStr) - used, sizeof(timeStr) - used - 1, ".%03ld", 23806f6ba60Sopenharmony_ci ts.tv_nsec / NS_PER_MS_LOG); 23906f6ba60Sopenharmony_ci return timeStr; 24006f6ba60Sopenharmony_ci} 24106f6ba60Sopenharmony_ci#endif // !HAVE_HILOG 24206f6ba60Sopenharmony_ci#endif // OHOS_PROFILER_LOGGING_H 243