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 #ifndef ROSEN_MODULES_TEXGINE_EXPORT_TEXGINE_UTILS_LOGGER_H 17 #define ROSEN_MODULES_TEXGINE_EXPORT_TEXGINE_UTILS_LOGGER_H 18 19 #include <any> 20 #include <cerrno> 21 #include <cstdarg> 22 #include <cstring> 23 #include <memory> 24 #include <mutex> 25 #include <sstream> 26 #include <vector> 27 28 namespace OHOS { 29 namespace Rosen { 30 namespace TextEngine { 31 class Logger : public std::stringstream { 32 public: 33 enum class LOG_LEVEL { DEBUG, INFO, WARN, ERROR, FATAL }; 34 enum class LOG_PHASE { BEGIN, END }; 35 36 using LoggerWrapperFunc = void(*)(Logger &, enum LOG_PHASE phase); 37 38 /* 39 * @brief output LoggerWrapperFunc 40 */ 41 static void SetToNoReturn(Logger &logger, enum LOG_PHASE phase); 42 static void SetToContinue(Logger &logger, enum LOG_PHASE phase); 43 static void OutputByStdout(Logger &logger, enum LOG_PHASE phase); 44 static void OutputByStderr(Logger &logger, enum LOG_PHASE phase); 45 static void OutputByHilog(Logger &logger, enum LOG_PHASE phase); 46 static void OutputByFileLog(Logger &logger, enum LOG_PHASE phase); 47 48 /* 49 * @brief wrapper LoggerWrapperFunc 50 */ 51 static void AppendFunc(Logger &logger, enum LOG_PHASE phase); 52 static void AppendFuncLine(Logger &logger, enum LOG_PHASE phase); 53 static void AppendFileLine(Logger &logger, enum LOG_PHASE phase); 54 static void AppendFileFuncLine(Logger &logger, enum LOG_PHASE phase); 55 static void AppendPidTid(Logger &logger, enum LOG_PHASE phase); 56 57 static void SetScopeParam(int func, int line); 58 static void EnterScope(); 59 static void ExitScope(); 60 61 Logger(const std::string &file, const std::string &func, int line, enum LOG_LEVEL level, ...); 62 Logger(const Logger &logger); 63 Logger(Logger &&logger); 64 virtual ~Logger() override; 65 66 const std::string &GetFile() const; 67 const std::string &GetFunc() const; 68 int GetLine() const; 69 enum LOG_LEVEL GetLevel() const; 70 va_list &GetVariousArgument(); 71 72 void Align(int num); 73 void AlignLine(); 74 void AlignFunc(); 75 76 template<class T> GetData()77 std::shared_ptr<T> GetData() 78 { 79 using sptrT = std::shared_ptr<T>; 80 sptrT ret = nullptr; 81 auto pRet = std::any_cast<sptrT>(&data_); 82 if (pRet != nullptr) { 83 ret = *pRet; 84 } else { 85 ret = std::make_shared<T>(); 86 data_ = ret; 87 } 88 return ret; 89 } 90 91 private: 92 std::string file_ = ""; 93 std::string func_ = ""; 94 int line_ = 0; 95 enum LOG_LEVEL level_ = LOG_LEVEL::DEBUG; 96 bool return_ = true; 97 bool continue_ = false; 98 va_list vl_; 99 std::any data_; 100 std::vector<LoggerWrapperFunc> wrappers_; 101 102 static inline int scope_ = 0; 103 static inline std::mutex scopeMutex_; 104 105 #ifdef LOGGER_ENABLE_SCOPE 106 static inline int alignFunc = 20; 107 static inline int alignLine = 4; 108 #else 109 static inline int alignFunc = 0; 110 static inline int alignLine = 0; 111 #endif 112 }; 113 114 class NoLogger { 115 public: 116 template<class T> 117 NoLogger &operator <<(const T &) 118 { 119 return *this; 120 } 121 }; 122 123 class ScopedLogger { 124 public: 125 ScopedLogger(const ScopedLogger &) = default; 126 ScopedLogger(NoLogger &&logger); 127 ScopedLogger(NoLogger &&logger, const std::string &name); 128 ScopedLogger(Logger &&logger); 129 ScopedLogger(Logger &&logger, const std::string &name); 130 ScopedLogger &operator=(const ScopedLogger &) = default; 131 ~ScopedLogger(); 132 133 void Finish(); 134 135 private: 136 Logger *logger_ = nullptr; 137 }; 138 139 #define LOGGER_ARG(level) __FILE__, __func__, __LINE__, (Logger::LOG_LEVEL::level) 140 #define LOGSYSERR " failed, because " << strerror(errno) 141 142 #define LOGSCOPED(name, logger, ...) ScopedLogger name(logger, ##__VA_ARGS__) 143 #define LOGSCOPED_FINISH(name) name.Finish() 144 #define LOGENTER() Logger::EnterScope() 145 #define LOGEXIT() Logger::ExitScope() 146 147 /* 148 * @brief stdout 149 */ 150 #define LOGNSO(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 151 Logger::SetToNoReturn, Logger::SetToContinue, Logger::OutputByStdout, NULL) 152 #define LOGCSO(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 153 Logger::SetToContinue, Logger::OutputByStdout, NULL) 154 #define LOGSO(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 155 Logger::OutputByStdout, NULL) 156 #define LOGSO_FUNC(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 157 Logger::AppendFunc, Logger::OutputByStdout, NULL) 158 #define LOGSO_FUNC_LINE(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 159 Logger::AppendFuncLine, Logger::OutputByStdout, NULL) 160 #define LOGSO_FILE_LINE(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 161 Logger::AppendFileLine, Logger::OutputByStdout, NULL) 162 #define LOGSO_FFL(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 163 Logger::AppendFileFuncLine, Logger::OutputByStdout, NULL) 164 #define LOGSO_PT(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 165 Logger::AppendPidTid, Logger::OutputByStdout, NULL) 166 #define LOGSO_PT_FUNC(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 167 Logger::AppendPidTid, Logger::AppendFunc, Logger::OutputByStdout, NULL) 168 #define LOGSO_PT_FUNC_LINE(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 169 Logger::AppendPidTid, Logger::AppendFuncLine, Logger::OutputByStdout, NULL) 170 #define LOGSO_PT_FILE_LINE(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 171 Logger::AppendPidTid, Logger::AppendFileLine, Logger::OutputByStdout, NULL) 172 #define LOGSO_PT_FFL(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 173 Logger::AppendPidTid, Logger::AppendFileFuncLine, Logger::OutputByStdout, NULL) 174 175 /* 176 * @brief stderr 177 */ 178 #define LOGNSE(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 179 Logger::SetToNoReturn, Logger::SetToContinue, Logger::OutputByStderr, NULL) 180 #define LOGCSE(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 181 Logger::SetToContinue, Logger::OutputByStderr, NULL) 182 #define LOGSE(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 183 Logger::OutputByStderr, NULL) 184 #define LOGSE_FUNC(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 185 Logger::AppendFunc, Logger::OutputByStderr, NULL) 186 #define LOGSE_FUNC_LINE(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 187 Logger::AppendFuncLine, Logger::OutputByStderr, NULL) 188 #define LOGSE_FILE_LINE(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 189 Logger::AppendFileLine, Logger::OutputByStderr, NULL) 190 #define LOGSE_FFL(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 191 Logger::AppendFileFuncLine, Logger::OutputByStderr, NULL) 192 #define LOGSE_PT(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 193 Logger::AppendPidTid, Logger::OutputByStderr, NULL) 194 #define LOGSE_PT_FUNC(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 195 Logger::AppendPidTid, Logger::AppendFunc, Logger::OutputByStderr, NULL) 196 #define LOGSE_PT_FUNC_LINE(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 197 Logger::AppendPidTid, Logger::AppendFuncLine, Logger::OutputByStderr, NULL) 198 #define LOGSE_PT_FILE_LINE(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 199 Logger::AppendPidTid, Logger::AppendFileLine, Logger::OutputByStderr, NULL) 200 #define LOGSE_PT_FFL(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 201 Logger::AppendPidTid, Logger::AppendFileFuncLine, Logger::OutputByStderr, NULL) 202 203 /* 204 * @brief filelog 205 */ 206 #define DEFINE_FILE_LABEL(str) namespace { constexpr const char *FILE_LABEL = str; } 207 #define LOGNF(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 208 Logger::SetToNoReturn, Logger::SetToContinue, Logger::OutputByFileLog, FILE_LABEL, NULL) 209 #define LOGCF(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 210 Logger::SetToContinue, Logger::OutputByFileLog, FILE_LABEL, NULL) 211 #define LOGF(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 212 Logger::OutputByFileLog, FILE_LABEL, NULL) 213 #define LOGF_FUNC(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 214 Logger::AppendFunc, Logger::OutputByFileLog, FILE_LABEL, NULL) 215 #define LOGF_FUNC_LINE(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 216 Logger::AppendFuncLine, Logger::OutputByFileLog, FILE_LABEL, NULL) 217 #define LOGF_FILE_LINE(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 218 Logger::AppendFileLine, Logger::OutputByFileLog, FILE_LABEL, NULL) 219 #define LOGF_FFL(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 220 Logger::AppendFileFuncLine, Logger::OutputByFileLog, FILE_LABEL, NULL) 221 #define LOGF_PT(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 222 Logger::AppendPidTid, Logger::OutputByFileLog, FILE_LABEL, NULL) 223 #define LOGF_PT_FUNC(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 224 Logger::AppendPidTid, Logger::AppendFunc, Logger::OutputByFileLog, FILE_LABEL, NULL) 225 #define LOGF_PT_FUNC_LINE(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 226 Logger::AppendPidTid, Logger::AppendFuncLine, Logger::OutputByFileLog, FILE_LABEL, NULL) 227 #define LOGF_PT_FILE_LINE(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 228 Logger::AppendPidTid, Logger::AppendFileLine, Logger::OutputByFileLog, FILE_LABEL, NULL) 229 #define LOGF_PT_FFL(level, ...) Logger(LOGGER_ARG(level), ##__VA_ARGS__, \ 230 Logger::AppendPidTid, Logger::AppendFileFuncLine, Logger::OutputByFileLog, FILE_LABEL, NULL) 231 } // namespace TextEngine 232 } // namespace Rosen 233 } // namespace OHOS 234 235 #endif // ROSEN_MODULES_TEXGINE_EXPORT_TEXGINE_UTILS_LOGGER_H 236