xref: /base/update/updater/services/log/log.cpp (revision fb299fa2)
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