• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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