1020a203aSopenharmony_ci/*
2020a203aSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
3020a203aSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4020a203aSopenharmony_ci * you may not use this file except in compliance with the License.
5020a203aSopenharmony_ci * You may obtain a copy of the License at
6020a203aSopenharmony_ci *
7020a203aSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8020a203aSopenharmony_ci *
9020a203aSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10020a203aSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11020a203aSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12020a203aSopenharmony_ci * See the License for the specific language governing permissions and
13020a203aSopenharmony_ci * limitations under the License.
14020a203aSopenharmony_ci */
15020a203aSopenharmony_ci#include "log_util.h"
16020a203aSopenharmony_ci
17020a203aSopenharmony_ci#include <cstring>
18020a203aSopenharmony_ci#include <fcntl.h>
19020a203aSopenharmony_ci#include <fstream>
20020a203aSopenharmony_ci#include <sstream>
21020a203aSopenharmony_ci#include <unistd.h>
22020a203aSopenharmony_ci
23020a203aSopenharmony_ci#include "file_util.h"
24020a203aSopenharmony_ci#include "hiview_logger.h"
25020a203aSopenharmony_ci#include "string_util.h"
26020a203aSopenharmony_ci
27020a203aSopenharmony_ciusing namespace std;
28020a203aSopenharmony_cinamespace OHOS {
29020a203aSopenharmony_cinamespace HiviewDFX {
30020a203aSopenharmony_ciDEFINE_LOG_TAG("LogUtil");
31020a203aSopenharmony_ci
32020a203aSopenharmony_cinamespace {
33020a203aSopenharmony_ci    const string ARROW = "->";
34020a203aSopenharmony_ci    const string CODE = "code";
35020a203aSopenharmony_ci    const string WAIT = "wait";
36020a203aSopenharmony_ci    const int BUF_LEN_2048 = 2048;
37020a203aSopenharmony_ci    const int TOTAL_SKIP_NUM = 4;
38020a203aSopenharmony_ci}
39020a203aSopenharmony_ci
40020a203aSopenharmony_ciconst std::string LogUtil::SPLIT_PATTERN = "\n";
41020a203aSopenharmony_ciconst std::string LogUtil::SMART_PARSER_TEST_DIR = "/data/test/test_data/SmartParser";
42020a203aSopenharmony_ciconst int LogUtil::TOTAL_LINE_NUM = 200;
43020a203aSopenharmony_ci
44020a203aSopenharmony_ci/* GetTrace function:
45020a203aSopenharmony_ci * buffer : log buffer
46020a203aSopenharmony_ci * cursor : buffer seekg
47020a203aSopenharmony_ci * reg : regex which is used to get trace line
48020a203aSopenharmony_ci * result : all trace line will be spliced by "\n"
49020a203aSopenharmony_ci * startReg : start place when regex is match, default empty string
50020a203aSopenharmony_ci */
51020a203aSopenharmony_civoid LogUtil::GetTrace(stringstream& buffer, int cursor, const string& reg, string& result, string startReg)
52020a203aSopenharmony_ci{
53020a203aSopenharmony_ci    buffer.seekg(cursor, ios::beg);
54020a203aSopenharmony_ci    string line;
55020a203aSopenharmony_ci    bool start = false;
56020a203aSopenharmony_ci    int num = 0;
57020a203aSopenharmony_ci    int skipNum = 0;
58020a203aSopenharmony_ci    startReg = startReg.empty() ? reg : startReg;
59020a203aSopenharmony_ci
60020a203aSopenharmony_ci    while (getline(buffer, line) && num++ < TOTAL_LINE_NUM) {
61020a203aSopenharmony_ci        if (line.length() > BUF_LEN_2048) {
62020a203aSopenharmony_ci            continue;
63020a203aSopenharmony_ci        }
64020a203aSopenharmony_ci        if (line.size() == 0 || skipNum >= TOTAL_SKIP_NUM) {
65020a203aSopenharmony_ci            break; // blank line
66020a203aSopenharmony_ci        }
67020a203aSopenharmony_ci        if (!start) {
68020a203aSopenharmony_ci            start = regex_search(line, regex(startReg));
69020a203aSopenharmony_ci            if (!start) {
70020a203aSopenharmony_ci                continue;
71020a203aSopenharmony_ci            }
72020a203aSopenharmony_ci        }
73020a203aSopenharmony_ci
74020a203aSopenharmony_ci        smatch matches;
75020a203aSopenharmony_ci        if (regex_search(line, matches, regex(reg))) {
76020a203aSopenharmony_ci            skipNum = 0;
77020a203aSopenharmony_ci        } else {
78020a203aSopenharmony_ci            skipNum++;
79020a203aSopenharmony_ci            continue;
80020a203aSopenharmony_ci        }
81020a203aSopenharmony_ci        result += matches.str(0) + LogUtil::SPLIT_PATTERN;
82020a203aSopenharmony_ci    }
83020a203aSopenharmony_ci}
84020a203aSopenharmony_ci
85020a203aSopenharmony_cibool LogUtil::ReadFileBuff(const string& file, stringstream& buffer)
86020a203aSopenharmony_ci{
87020a203aSopenharmony_ci    int fd = LogUtil::GetFileFd(file);
88020a203aSopenharmony_ci    if (fd < 0) {
89020a203aSopenharmony_ci        HIVIEW_LOGE("%{public}s get fd fail, fd is %{public}d.", file.c_str(), fd);
90020a203aSopenharmony_ci        return false;
91020a203aSopenharmony_ci    }
92020a203aSopenharmony_ci
93020a203aSopenharmony_ci    std::string content;
94020a203aSopenharmony_ci    if (!FileUtil::LoadStringFromFd(fd, content)) {
95020a203aSopenharmony_ci        HIVIEW_LOGE("read file: %s failed, fd is %d\n", file.c_str(), fd);
96020a203aSopenharmony_ci        close(fd);
97020a203aSopenharmony_ci        return false;
98020a203aSopenharmony_ci    }
99020a203aSopenharmony_ci    buffer.str(content);
100020a203aSopenharmony_ci    close(fd);
101020a203aSopenharmony_ci    return true;
102020a203aSopenharmony_ci}
103020a203aSopenharmony_ci
104020a203aSopenharmony_ciint LogUtil::GetFileFd(const string& file)
105020a203aSopenharmony_ci{
106020a203aSopenharmony_ci    if (file.empty() || !FileUtil::IsLegalPath(file)) {
107020a203aSopenharmony_ci        HIVIEW_LOGE("the system file (%{public}s) is illegal.", file.c_str());
108020a203aSopenharmony_ci        return -1;
109020a203aSopenharmony_ci    }
110020a203aSopenharmony_ci    std::string realFileName;
111020a203aSopenharmony_ci    if (!FileUtil::PathToRealPath(file, realFileName) || realFileName.empty() ||
112020a203aSopenharmony_ci        !FileUtil::FileExists(realFileName)) {
113020a203aSopenharmony_ci        HIVIEW_LOGE("the system file (%{public}s) is not found.", realFileName.c_str());
114020a203aSopenharmony_ci        return -1;
115020a203aSopenharmony_ci    }
116020a203aSopenharmony_ci    return open(realFileName.c_str(), O_RDONLY);
117020a203aSopenharmony_ci}
118020a203aSopenharmony_ci
119020a203aSopenharmony_cibool LogUtil::FileExist(const string& file)
120020a203aSopenharmony_ci{
121020a203aSopenharmony_ci    return FileUtil::FileExists(file);
122020a203aSopenharmony_ci}
123020a203aSopenharmony_ci
124020a203aSopenharmony_cibool LogUtil::IsTestModel(const string& sourceFile, const string& name,
125020a203aSopenharmony_ci    const string& pattern, string& desPath)
126020a203aSopenharmony_ci{
127020a203aSopenharmony_ci    if (FileUtil::IsDirectory(LogUtil::SMART_PARSER_TEST_DIR)) {
128020a203aSopenharmony_ci        HIVIEW_LOGI("test dir exist.");
129020a203aSopenharmony_ci        std::string sourceFileName = StringUtil::GetRrightSubstr(sourceFile, "/");
130020a203aSopenharmony_ci        std::string dirOrFileName = StringUtil::GetRrightSubstr(name, "/");
131020a203aSopenharmony_ci        std::string fileName = pattern.find("/") != std::string::npos ?
132020a203aSopenharmony_ci            StringUtil::GetRrightSubstr(pattern, "/") : pattern;
133020a203aSopenharmony_ci        smatch result;
134020a203aSopenharmony_ci        if (regex_match(sourceFileName, result, regex(dirOrFileName)) ||
135020a203aSopenharmony_ci            regex_match(sourceFileName, result, regex(fileName))) {
136020a203aSopenharmony_ci            return LogUtil::FileExist(desPath);
137020a203aSopenharmony_ci        }
138020a203aSopenharmony_ci        return false;
139020a203aSopenharmony_ci    }
140020a203aSopenharmony_ci    return false;
141020a203aSopenharmony_ci}
142020a203aSopenharmony_ci} // namespace HiviewDFX
143020a203aSopenharmony_ci} // namespace OHOS