203 lines
6.0 KiB
C++
203 lines
6.0 KiB
C++
|
|
/*
|
||
|
|
* 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 <fstream>
|
||
|
|
#include <iomanip>
|
||
|
|
#include <iostream>
|
||
|
|
#ifdef _WIN32
|
||
|
|
#include <windows.h>
|
||
|
|
#include <stdio.h>
|
||
|
|
#else
|
||
|
|
#include <sys/time.h>
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#include <FileManager.h>
|
||
|
|
|
||
|
|
#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<std::string> 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<std::mutex> 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
|