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