/* * Copyright (c) 2020.Huawei Technologies Co., Ltd. All rights reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #ifdef _WIN32 #include #include #else #include #endif #include #include "Log.h" namespace MatrixAiLog { const int TIME_SIZE = 32; const int TIME_DIFF = 28800; // 8 hour const int BYTES6 = 6; const int FILE_SIZE = 52428800; // 50M uint32_t Log::logLevel = LOG_LEVEL_INFO; std::vector Log::levelString{"[Debug]", "[Info ]", "[Warn ]", "[Error]", "[Fatal]"}; std::mutex Log::mutex; std::string Log::logPath = "./logs"; std::string Log::logFile = "log.log"; // default log file std::string Log::logFileBak = "log.log.bak"; Log::Log(std::string file, std::string function, int line, uint32_t level) : myLevel_(level), file_(file), function_(function), line_(line) { } Log::~Log() { if (myLevel_ >= logLevel) { std::lock_guard locker(mutex); // cout to screen std::cout << ss_.str() << std::endl; std::string outPath = logPath + std::string("/") + logFile; // log to the file CreateDirRecursivelyByFile(outPath); std::ofstream fs(outPath, std::ios::app); if (!fs) { std::cout << "open file " << outPath << " fail" << std::endl; return; } fs.seekp(0, fs.end); size_t dstFileSize = fs.tellp(); fs << ss_.str() << std::endl; fs.close(); if (dstFileSize < FILE_SIZE) { return; } std::string bakPath = logPath + std::string("/") + logFileBak; // dstFileSize >= FILE_SIZE if (access(bakPath.c_str(), 0) == APP_ERR_OK) { APP_ERROR ret = remove(bakPath.c_str()); if (ret != APP_ERR_OK) { std::cout << "remove " << bakPath << " failed." << std::endl; return; } } APP_ERROR ret = rename(outPath.c_str(), bakPath.c_str()); if (ret != APP_ERR_OK) { std::cout << "rename " << outPath << " failed." << std::endl; return; } } }; std::ostringstream &Log::Stream() { if (myLevel_ >= logLevel) { long int usValue = 0; #ifndef _WIN32 struct timeval time = {0, 0}; gettimeofday(&time, nullptr); time_t timep = time.tv_sec + TIME_DIFF; struct tm *ptm = gmtime(&timep); char timeString[TIME_SIZE] = {0}; strftime(timeString, TIME_SIZE, "[%F %X:", ptm); usValue = time.tv_usec; #else SYSTEMTIME sysTimes; GetLocalTime(&sysTimes); std::string timeString; timeString = '[' + std::to_string(sysTimes.wYear) + '-' + std::to_string(sysTimes.wMonth) + '-' + std::to_string(sysTimes.wDay) + " " + std::to_string(sysTimes.wHour) + ':' + std::to_string(sysTimes.wMinute) + ':' + std::to_string(sysTimes.wSecond) + ':'; uint32_t msToUs = 1000; usValue = sysTimes.wMilliseconds * msToUs; #endif date_ = timeString; ss_.fill('0'); ss_ << levelString[myLevel_] << timeString << std::setw(BYTES6) << usValue << "]"; std::string fileName = file_.substr(file_.rfind('/') + 1); ss_ << "[" << fileName << " " << function_ << ":" << line_ << "] "; } return ss_; } void Log::LogDebugOn() { logLevel = LOG_LEVEL_DEBUG; return; } void Log::LogInfoOn() { logLevel = LOG_LEVEL_INFO; return; } void Log::LogWarnOn() { logLevel = LOG_LEVEL_WARN; return; } void Log::LogErrorOn() { logLevel = LOG_LEVEL_ERROR; return; } void Log::LogFatalOn() { logLevel = LOG_LEVEL_FATAL; return; } void Log::LogAllOn() { logLevel = LOG_LEVEL_DEBUG; return; } void Log::LogAllOff() { logLevel = LOG_LEVEL_NONE; return; } void Log::SetLogLevel(const std::string &log_level) { if(log_level == "DEBUG") { logLevel = LOG_LEVEL_DEBUG; } else if(log_level == "INFO") { logLevel = LOG_LEVEL_INFO; } else if(log_level == "WARN") { logLevel = LOG_LEVEL_WARN; } else if(log_level == "ERROR") { logLevel = LOG_LEVEL_ERROR; } else if(log_level == "FATAL") { logLevel = LOG_LEVEL_FATAL; } else if(log_level == "NONE") { logLevel = LOG_LEVEL_NONE; } } void Log::SetLogFile(const std::string &log_file) { if (!log_file.empty()) { logPath = log_file; } } #define LOG_DEBUG Log(__FILE__, __FUNCTION__, __LINE__, MatrixAiLog::LOG_LEVEL_DEBUG) #define LOG_INFO Log(__FILE__, __FUNCTION__, __LINE__, MatrixAiLog::LOG_LEVEL_INFO) #define LOG_WARN Log(__FILE__, __FUNCTION__, __LINE__, MatrixAiLog::LOG_LEVEL_WARN) #define LOG_ERROR Log(__FILE__, __FUNCTION__, __LINE__, MatrixAiLog::LOG_LEVEL_ERROR) #define LOG_FATAL Log(__FILE__, __FUNCTION__, __LINE__, MatrixAiLog::LOG_LEVEL_FATAL) } // namespace AtlasAscendLog