106f6ba60Sopenharmony_ci/* 206f6ba60Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2022. 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 _HHLOG_H 1706f6ba60Sopenharmony_ci#define _HHLOG_H 1806f6ba60Sopenharmony_ci 1906f6ba60Sopenharmony_ci#include <atomic> 2006f6ba60Sopenharmony_ci#include <cstdio> 2106f6ba60Sopenharmony_ci#include <cstring> 2206f6ba60Sopenharmony_ci#include <ctime> 2306f6ba60Sopenharmony_ci#include <iostream> 2406f6ba60Sopenharmony_ci#include <memory> 2506f6ba60Sopenharmony_ci#include <sstream> 2606f6ba60Sopenharmony_ci#include <string> 2706f6ba60Sopenharmony_ci#include <strstream> 2806f6ba60Sopenharmony_ci#include <thread> 2906f6ba60Sopenharmony_ci 3006f6ba60Sopenharmony_ci#include <fcntl.h> 3106f6ba60Sopenharmony_ci#include <securec.h> 3206f6ba60Sopenharmony_ci#include <stdarg.h> 3306f6ba60Sopenharmony_ci#include <unistd.h> 3406f6ba60Sopenharmony_ci#include <sys/time.h> 3506f6ba60Sopenharmony_ci 3606f6ba60Sopenharmony_ci#include "ringbuffer.h" 3706f6ba60Sopenharmony_ci 3806f6ba60Sopenharmony_cienum HHLOG_LEVEL:int { 3906f6ba60Sopenharmony_ci HHLOG_DEBUG = 0, 4006f6ba60Sopenharmony_ci HHLOG_INFO = 1, 4106f6ba60Sopenharmony_ci HHLOG_WARN = 2, 4206f6ba60Sopenharmony_ci HHLOG_ERROR = 3, 4306f6ba60Sopenharmony_ci HHLOG_FATAL = 4, 4406f6ba60Sopenharmony_ci HHLOG_NONE = 5, 4506f6ba60Sopenharmony_ci}; 4606f6ba60Sopenharmony_ci 4706f6ba60Sopenharmony_ciclass HHLogger { 4806f6ba60Sopenharmony_cipublic: 4906f6ba60Sopenharmony_ci ~HHLogger(); 5006f6ba60Sopenharmony_ci static inline HHLogger& GetInstance() 5106f6ba60Sopenharmony_ci { 5206f6ba60Sopenharmony_ci static HHLogger logger {}; 5306f6ba60Sopenharmony_ci return logger; 5406f6ba60Sopenharmony_ci } 5506f6ba60Sopenharmony_ci 5606f6ba60Sopenharmony_ci int Start(const int logLevel = HHLOG_DEBUG, const std::string& logFile = "./hhlog.txt"); 5706f6ba60Sopenharmony_ci 5806f6ba60Sopenharmony_ci inline int PutLog(const char* format, ...) 5906f6ba60Sopenharmony_ci { 6006f6ba60Sopenharmony_ci va_list args; 6106f6ba60Sopenharmony_ci va_start(args, format); 6206f6ba60Sopenharmony_ci auto ftime = GetFormatTime(); 6306f6ba60Sopenharmony_ci std::size_t nbytes = ftime.length(); 6406f6ba60Sopenharmony_ci if (nbytes == 0 or nbytes >= MAX_HHLOG_SIZE) { 6506f6ba60Sopenharmony_ci return -1; 6606f6ba60Sopenharmony_ci } 6706f6ba60Sopenharmony_ci char buffer[MAX_HHLOG_SIZE]; 6806f6ba60Sopenharmony_ci if (memcpy_s(buffer, sizeof(buffer), ftime.c_str(), nbytes) != EOK) { 6906f6ba60Sopenharmony_ci return -1; 7006f6ba60Sopenharmony_ci } 7106f6ba60Sopenharmony_ci int ret = vsnprintf_s(buffer + nbytes, sizeof(buffer) - nbytes, 7206f6ba60Sopenharmony_ci sizeof(buffer) - nbytes - 1, format, args); 7306f6ba60Sopenharmony_ci va_end(args); 7406f6ba60Sopenharmony_ci if (ret < 0) { 7506f6ba60Sopenharmony_ci return -1; 7606f6ba60Sopenharmony_ci } 7706f6ba60Sopenharmony_ci nbytes += static_cast<std::size_t>(ret); 7806f6ba60Sopenharmony_ci if (nbytes >= MAX_HHLOG_SIZE) { 7906f6ba60Sopenharmony_ci return -1; 8006f6ba60Sopenharmony_ci } 8106f6ba60Sopenharmony_ci buffer[nbytes++] = '\n'; 8206f6ba60Sopenharmony_ci return buf_->Put(buffer, nbytes); 8306f6ba60Sopenharmony_ci } 8406f6ba60Sopenharmony_ci 8506f6ba60Sopenharmony_ci inline int GetLogLevel() const 8606f6ba60Sopenharmony_ci { 8706f6ba60Sopenharmony_ci return logLevel_; 8806f6ba60Sopenharmony_ci } 8906f6ba60Sopenharmony_ci 9006f6ba60Sopenharmony_ci inline bool IsStopped() 9106f6ba60Sopenharmony_ci { 9206f6ba60Sopenharmony_ci return stop_.load(); 9306f6ba60Sopenharmony_ci } 9406f6ba60Sopenharmony_ci 9506f6ba60Sopenharmony_ci inline void LogSaver() 9606f6ba60Sopenharmony_ci { 9706f6ba60Sopenharmony_ci if (logLevel_ == HHLOG_NONE) { 9806f6ba60Sopenharmony_ci return; 9906f6ba60Sopenharmony_ci } 10006f6ba60Sopenharmony_ci logSaver_ = std::thread([this] { this->SaveLog(); }); 10106f6ba60Sopenharmony_ci } 10206f6ba60Sopenharmony_ci 10306f6ba60Sopenharmony_ci enum SizeConsts:std::size_t { 10406f6ba60Sopenharmony_ci RING_BUF_SIZE = 4096, 10506f6ba60Sopenharmony_ci MAX_FORMAT_SIZE = 512, 10606f6ba60Sopenharmony_ci MAX_HHLOG_SIZE = 1024, 10706f6ba60Sopenharmony_ci }; 10806f6ba60Sopenharmony_ci 10906f6ba60Sopenharmony_ciprivate: 11006f6ba60Sopenharmony_ci HHLogger() = default; 11106f6ba60Sopenharmony_ci std::string GetLogFileName() const; 11206f6ba60Sopenharmony_ci std::string GetFormatTime() const; 11306f6ba60Sopenharmony_ci int SaveLog(); 11406f6ba60Sopenharmony_ci int InitLogger(const int logLevel, const std::string& logFile); 11506f6ba60Sopenharmony_ci int UpdateTimer(); 11606f6ba60Sopenharmony_ci 11706f6ba60Sopenharmony_ci int fd_ {-1}; 11806f6ba60Sopenharmony_ci int logLevel_ {HHLOG_NONE}; 11906f6ba60Sopenharmony_ci std::atomic<bool> stop_ {false}; 12006f6ba60Sopenharmony_ci std::atomic<struct timeval> timer_; 12106f6ba60Sopenharmony_ci std::unique_ptr<RingBuffer> buf_ {nullptr}; 12206f6ba60Sopenharmony_ci std::thread logSaver_; 12306f6ba60Sopenharmony_ci}; 12406f6ba60Sopenharmony_ci 12506f6ba60Sopenharmony_ci#define HHLOG(level, expression, format, ...) { \ 12606f6ba60Sopenharmony_ci if ((expression) and \ 12706f6ba60Sopenharmony_ci (!HHLogger::GetInstance().IsStopped()) and \ 12806f6ba60Sopenharmony_ci (HHLogger::GetInstance().GetLogLevel() <= HHLOG_##level)) { \ 12906f6ba60Sopenharmony_ci const char prefix[] {" [" #level "] %s %d %s: %s"}; \ 13006f6ba60Sopenharmony_ci char buffer[HHLogger::MAX_FORMAT_SIZE]; \ 13106f6ba60Sopenharmony_ci if (snprintf_s(buffer, sizeof(buffer), sizeof(buffer) -1, \ 13206f6ba60Sopenharmony_ci prefix, __FILE__, __LINE__, __FUNCTION__, format) < 0) { \ 13306f6ba60Sopenharmony_ci HHLogger::GetInstance().PutLog("snprintf_s error!"); \ 13406f6ba60Sopenharmony_ci } \ 13506f6ba60Sopenharmony_ci HHLogger::GetInstance().PutLog(buffer, ##__VA_ARGS__); \ 13606f6ba60Sopenharmony_ci } \ 13706f6ba60Sopenharmony_ci} 13806f6ba60Sopenharmony_ci 13906f6ba60Sopenharmony_ci#if defined(HH_LOGGER_DEBUG) 14006f6ba60Sopenharmony_ci 14106f6ba60Sopenharmony_ci#define HHLOGD(expression, format, ...) HHLOG(DEBUG, expression, format, ##__VA_ARGS__) 14206f6ba60Sopenharmony_ci#define HHLOGI(expression, format, ...) HHLOG(INFO, expression, format, ##__VA_ARGS__) 14306f6ba60Sopenharmony_ci#define HHLOGW(expression, format, ...) HHLOG(WARN, expression, format, ##__VA_ARGS__) 14406f6ba60Sopenharmony_ci#define HHLOGE(expression, format, ...) HHLOG(ERROR, expression, format, ##__VA_ARGS__) 14506f6ba60Sopenharmony_ci#define HHLOGF(expression, format, ...) HHLOG(FATAL, expression, format, ##__VA_ARGS__) 14606f6ba60Sopenharmony_ci 14706f6ba60Sopenharmony_ci#elif defined(HH_LOGGER_INFO) 14806f6ba60Sopenharmony_ci 14906f6ba60Sopenharmony_ci#define HHLOGD(expression, format, ...) {} 15006f6ba60Sopenharmony_ci#define HHLOGI(expression, format, ...) HHLOG(INFO, expression, format, ##__VA_ARGS__) 15106f6ba60Sopenharmony_ci#define HHLOGW(expression, format, ...) HHLOG(WARN, expression, format, ##__VA_ARGS__) 15206f6ba60Sopenharmony_ci#define HHLOGE(expression, format, ...) HHLOG(ERROR, expression, format, ##__VA_ARGS__) 15306f6ba60Sopenharmony_ci#define HHLOGF(expression, format, ...) HHLOG(FATAL, expression, format, ##__VA_ARGS__) 15406f6ba60Sopenharmony_ci 15506f6ba60Sopenharmony_ci#elif defined(HH_LOGGER_WARN) 15606f6ba60Sopenharmony_ci 15706f6ba60Sopenharmony_ci#define HHLOGD(expression, format, ...) {} 15806f6ba60Sopenharmony_ci#define HHLOGI(expression, format, ...) {} 15906f6ba60Sopenharmony_ci#define HHLOGW(expression, format, ...) HHLOG(WARN, expression, format, ##__VA_ARGS__) 16006f6ba60Sopenharmony_ci#define HHLOGE(expression, format, ...) HHLOG(ERROR, expression, format, ##__VA_ARGS__) 16106f6ba60Sopenharmony_ci#define HHLOGF(expression, format, ...) HHLOG(FATAL, expression, format, ##__VA_ARGS__) 16206f6ba60Sopenharmony_ci 16306f6ba60Sopenharmony_ci#elif defined(HH_LOGGER_ERROR) 16406f6ba60Sopenharmony_ci 16506f6ba60Sopenharmony_ci#define HHLOGD(expression, format, ...) {} 16606f6ba60Sopenharmony_ci#define HHLOGI(expression, format, ...) {} 16706f6ba60Sopenharmony_ci#define HHLOGW(expression, format, ...) {} 16806f6ba60Sopenharmony_ci#define HHLOGE(expression, format, ...) HHLOG(ERROR, expression, format, ##__VA_ARGS__) 16906f6ba60Sopenharmony_ci#define HHLOGF(expression, format, ...) HHLOG(FATAL, expression, format, ##__VA_ARGS__) 17006f6ba60Sopenharmony_ci 17106f6ba60Sopenharmony_ci#elif defined(HH_LOGGER_FATAL) 17206f6ba60Sopenharmony_ci 17306f6ba60Sopenharmony_ci#define HHLOGD(expression, format, ...) {} 17406f6ba60Sopenharmony_ci#define HHLOGI(expression, format, ...) {} 17506f6ba60Sopenharmony_ci#define HHLOGW(expression, format, ...) {} 17606f6ba60Sopenharmony_ci#define HHLOGE(expression, format, ...) {} 17706f6ba60Sopenharmony_ci#define HHLOGF(expression, format, ...) HHLOG(FATAL, expression, format, ##__VA_ARGS__) 17806f6ba60Sopenharmony_ci 17906f6ba60Sopenharmony_ci#else 18006f6ba60Sopenharmony_ci 18106f6ba60Sopenharmony_ci#define HHLOGD(expression, format, ...) {} 18206f6ba60Sopenharmony_ci#define HHLOGI(expression, format, ...) {} 18306f6ba60Sopenharmony_ci#define HHLOGW(expression, format, ...) {} 18406f6ba60Sopenharmony_ci#define HHLOGE(expression, format, ...) {} 18506f6ba60Sopenharmony_ci#define HHLOGF(expression, format, ...) {} 18606f6ba60Sopenharmony_ci 18706f6ba60Sopenharmony_ci#endif 18806f6ba60Sopenharmony_ci 18906f6ba60Sopenharmony_ci#define CHECK_NOTNULL(ptr, retval, fmt, ...) \ 19006f6ba60Sopenharmony_ci do { \ 19106f6ba60Sopenharmony_ci if (ptr == nullptr) { \ 19206f6ba60Sopenharmony_ci HHLOGE(true, "CHECK_NOTNULL(%s) in %s:%d FAILED, " fmt, #ptr, __func__, \ 19306f6ba60Sopenharmony_ci __LINE__, ##__VA_ARGS__); \ 19406f6ba60Sopenharmony_ci return retval; \ 19506f6ba60Sopenharmony_ci } \ 19606f6ba60Sopenharmony_ci } while (0) 19706f6ba60Sopenharmony_ci 19806f6ba60Sopenharmony_ci#define CHECK_TRUE(expr, retval, fmt, ...) \ 19906f6ba60Sopenharmony_ci do { \ 20006f6ba60Sopenharmony_ci if (!(expr)) { \ 20106f6ba60Sopenharmony_ci HHLOGE(true, "CHECK_TRUE(%s) in %s:%d FAILED, " fmt, #expr, __func__, __LINE__, ##__VA_ARGS__); \ 20206f6ba60Sopenharmony_ci return retval; \ 20306f6ba60Sopenharmony_ci } \ 20406f6ba60Sopenharmony_ci } while (0) 20506f6ba60Sopenharmony_ci 20606f6ba60Sopenharmony_ci#endif // HHLOG_H