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#include "log/log.h" 16#include <chrono> 17#include <cstdarg> 18#include <memory> 19#include <unordered_map> 20#include <vector> 21#include <sys/time.h> 22#include <unistd.h> 23#include <mutex> 24#ifndef DIFF_PATCH_SDK 25#include "hilog_base/log_base.h" 26#include "vsnprintf_s_p.h" 27#endif 28#include "securec.h" 29 30namespace Updater { 31static std::ofstream g_updaterLog; 32static std::mutex g_updaterLogLock; 33static std::ofstream g_updaterStage; 34static std::ofstream g_errorCode; 35static std::ofstream g_nullStream; 36static std::string g_logTag; 37static int g_logLevel = INFO; 38#ifndef DIFF_PATCH_SDK 39static constexpr unsigned int UPDATER_DOMAIN = 0XD002E01; 40#endif 41 42void InitUpdaterLogger(const std::string &tag, const std::string &logFile, const std::string &stageFile, 43 const std::string &errorCodeFile) 44{ 45 g_logTag = tag; 46 g_updaterLog.open(logFile.c_str(), std::ios::app | std::ios::out); 47 g_updaterStage.open(stageFile.c_str(), std::ios::app | std::ios::out); 48 g_errorCode.open(errorCodeFile.c_str(), std::ios::app | std::ios::out); 49} 50 51UpdaterLogger::~UpdaterLogger() 52{ 53 std::string str = oss_.str(); 54 if (g_logLevel > level_) { 55 return; 56 } 57 pid_t tid = 0; 58#ifndef DIFF_PATCH_SDK 59 HiLogBasePrint(LOG_CORE, (LogLevel)level_, UPDATER_DOMAIN, g_logTag.c_str(), "%{public}s", str.c_str()); 60 tid = gettid(); 61#endif 62 oss_.str(""); 63 oss_ << std::endl << std::flush; 64 if (g_updaterLog.is_open()) { 65 std::lock_guard<std::mutex> lock(g_updaterLogLock); 66 g_updaterLog << realTime_ << " " << g_logTag << " " << tid << " " 67 << logLevelMap_[level_] << " " << str << std::endl << std::flush; 68 } 69} 70 71StageLogger::~StageLogger() 72{ 73 if (g_updaterStage.is_open()) { 74 g_updaterStage << std::endl << std::flush; 75 } else { 76 std::cout << std::endl << std::flush; 77 } 78} 79 80void SetLogLevel(int level) 81{ 82 g_logLevel = level; 83} 84 85void GetFormatTime(char time[], int size) 86{ 87#ifndef DIFF_PATCH_SDK 88 struct timeval tv {}; 89 struct tm tm {}; 90 91 gettimeofday(&tv, nullptr); 92 localtime_r(&tv.tv_sec, &tm); 93 snprintf_s(time, size, size - 1, "%02d-%02d %02d:%02d:%02d.%03d", 94 tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, 95 static_cast<int>(tv.tv_usec / 1000)); // need div 1000 96#endif 97} 98 99std::ostream& UpdaterLogger::OutputUpdaterLog(const std::string &path, int line) 100{ 101 GetFormatTime(realTime_, sizeof(realTime_)); 102 if (g_logLevel <= level_) { 103 return oss_ << path << " " << line << " : "; 104 } 105 return g_nullStream; 106} 107 108std::ostream& StageLogger::OutputUpdaterStage() 109{ 110 std::unordered_map<int, std::string> updaterStageMap = { 111 { UPDATE_STAGE_BEGIN, "BEGIN" }, 112 { UPDATE_STAGE_SUCCESS, "SUCCESS" }, 113 { UPDATE_STAGE_FAIL, "FAIL" }, 114 { UPDATE_STAGE_OUT, "OUT" } 115 }; 116 char realTime[MAX_TIME_SIZE] = {0}; 117 GetFormatTime(realTime, sizeof(realTime)); 118 119 if (g_updaterLog.is_open()) { 120 if (stage_ == UPDATE_STAGE_OUT) { 121 return g_updaterStage << realTime << " " << g_logTag << " "; 122 } 123 return g_updaterStage << realTime << " " << g_logTag << " status is : " << 124 updaterStageMap[stage_] << ", stage is "; 125 } 126 return std::cout; 127} 128 129void Logger(int level, const char* fileName, int32_t line, const char* format, ...) 130{ 131 std::vector<char> buff(1024); // 1024 : max length of buff 132 va_list list; 133 va_start(list, format); 134 int size = vsnprintf_s(reinterpret_cast<char*>(buff.data()), buff.capacity(), buff.capacity(), format, list); 135 va_end(list); 136 if (size < EOK) { 137 UpdaterLogger(level).OutputUpdaterLog(fileName, line) << "vsnprintf_s failed"; 138 return; 139 } 140 std::string str(buff.data(), size); 141 UpdaterLogger(level).OutputUpdaterLog(fileName, line) << str; 142} 143 144#ifndef DIFF_PATCH_SDK 145// used for external module to adapt %{private|public} format log to updater log 146void UpdaterHiLogger(int level, const char* fileName, int32_t line, const char* format, ...) 147{ 148 char buf[MAX_LOG_LEN] = {0}; 149 va_list list; 150 va_start(list, format); 151 int size = vsnprintfp_s(buf, MAX_LOG_LEN, MAX_LOG_LEN - 1, true, format, list); 152 va_end(list); 153 if (size < EOK) { 154 UpdaterLogger(level).OutputUpdaterLog(fileName, line) << "vsnprintfp_s failed " << size; 155 } else { 156 UpdaterLogger(level).OutputUpdaterLog(fileName, line) << std::string(buf, size); 157 } 158} 159#endif 160 161std::ostream& ErrorCode::OutputErrorCode(const std::string &path, int line, UpdaterErrorCode code) 162{ 163 char realTime[MAX_TIME_SIZE] = {0}; 164 GetFormatTime(realTime, sizeof(realTime)); 165 if (g_errorCode.is_open()) { 166 return g_errorCode << realTime << " " << path << " " << line << " , error code is : " << code << std::endl; 167 } 168 return std::cout; 169} 170} // Updater 171