• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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