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
16 #include "gslogger.h"
17
18 #include <fstream>
19 #include <iostream>
20 #include <unistd.h>
21
22 #include <hilog/log.h>
23
24 namespace {
GetLevelStr(enum Gslogger::LOG_LEVEL level)25 const char *GetLevelStr(enum Gslogger::LOG_LEVEL level)
26 {
27 switch (level) {
28 case Gslogger::LOG_LEVEL::DEBUG: return "D";
29 case Gslogger::LOG_LEVEL::INFO: return "I";
30 case Gslogger::LOG_LEVEL::WARN: return "W";
31 case Gslogger::LOG_LEVEL::ERROR: return "E";
32 case Gslogger::LOG_LEVEL::FATAL: return "F";
33 }
34 return "?";
35 }
36 } // namespace
37
Stdout(Gslogger & logger,enum LOG_PHASE phase)38 void Gslogger::Stdout(Gslogger& logger, enum LOG_PHASE phase)
39 {
40 if (phase == LOG_PHASE::BEGIN) {
41 return;
42 }
43
44 // LOG_PHASE::END
45 std::cout << "[" << GetLevelStr(logger.GetLevel()) << "] " << logger.str() << std::endl;
46 }
47
Stderr(Gslogger & logger,enum LOG_PHASE phase)48 void Gslogger::Stderr(Gslogger& logger, enum LOG_PHASE phase)
49 {
50 if (phase == LOG_PHASE::BEGIN) {
51 return;
52 }
53
54 // LOG_PHASE::END
55 std::cerr << "[" << GetLevelStr(logger.GetLevel()) << "] " << logger.str() << std::endl;
56 }
57
Hilog(Gslogger & logger,enum LOG_PHASE phase)58 void Gslogger::Hilog(Gslogger& logger, enum LOG_PHASE phase)
59 {
60 struct HilogData {
61 OHOS::HiviewDFX::HiLogLabel hiLogLabel;
62 };
63 auto data = logger.GetData<struct HilogData>();
64 if (phase == LOG_PHASE::BEGIN) {
65 auto label = va_arg(logger.GetVariousArgument(), const char *);
66 data->hiLogLabel = { LOG_CORE, 0, label };
67 return;
68 }
69
70 // LOG_PHASE::END
71 auto fn = OHOS::HiviewDFX::HiLog::Debug;
72 switch (logger.GetLevel()) {
73 case LOG_LEVEL::DEBUG:
74 fn = OHOS::HiviewDFX::HiLog::Debug;
75 break;
76 case LOG_LEVEL::INFO:
77 fn = OHOS::HiviewDFX::HiLog::Info;
78 break;
79 case LOG_LEVEL::WARN:
80 fn = OHOS::HiviewDFX::HiLog::Warn;
81 break;
82 case LOG_LEVEL::ERROR:
83 fn = OHOS::HiviewDFX::HiLog::Error;
84 break;
85 case LOG_LEVEL::FATAL:
86 fn = OHOS::HiviewDFX::HiLog::Fatal;
87 break;
88 }
89 fn(data->hiLogLabel, "%{public}s", logger.str().c_str());
90 }
91
FileLog(Gslogger & logger,enum LOG_PHASE phase)92 void Gslogger::FileLog(Gslogger& logger, enum LOG_PHASE phase)
93 {
94 struct FileLogData {
95 const char *filename;
96 };
97 auto data = logger.GetData<struct FileLogData>();
98 if (phase == LOG_PHASE::BEGIN) {
99 auto filename = va_arg(logger.GetVariousArgument(), const char *);
100 data->filename = filename;
101 return;
102 }
103
104 char path[PATH_MAX + 1] = { 0x00 };
105 if (strlen(data->filename) > PATH_MAX || realpath(data->filename, path) == NULL) {
106 std::cerr << "File path error!" << std::endl;
107 return;
108 }
109
110 // LOG_PHASE::END
111 std::ofstream ofs(path, std::ofstream::out | std::ofstream::app);
112 if (!ofs) {
113 // open failed, errno
114 return;
115 }
116
117 if (ofs) {
118 ofs << "[" << GetLevelStr(logger.GetLevel()) << "] " << logger.str() << std::endl;
119 }
120 }
121
Func(Gslogger & logger,enum LOG_PHASE phase)122 void Gslogger::Func(Gslogger& logger, enum LOG_PHASE phase)
123 {
124 if (phase == LOG_PHASE::BEGIN) {
125 logger << "[" << logger.GetFunc() << "] ";
126 }
127 }
128
FuncLine(Gslogger & logger,enum LOG_PHASE phase)129 void Gslogger::FuncLine(Gslogger& logger, enum LOG_PHASE phase)
130 {
131 if (phase == LOG_PHASE::BEGIN) {
132 logger << "[" << logger.GetFunc() << ":" << logger.GetLine() << "] ";
133 }
134 }
135
FileLine(Gslogger & logger,enum LOG_PHASE phase)136 void Gslogger::FileLine(Gslogger& logger, enum LOG_PHASE phase)
137 {
138 if (phase == LOG_PHASE::BEGIN) {
139 logger << "[" << logger.GetFile() << " +" << logger.GetLine() << "] ";
140 }
141 }
142
FileFuncLine(Gslogger & logger,enum LOG_PHASE phase)143 void Gslogger::FileFuncLine(Gslogger& logger, enum LOG_PHASE phase)
144 {
145 if (phase == LOG_PHASE::BEGIN) {
146 logger << "[" << logger.GetFile() << " +" << logger.GetLine() << ":" << logger.GetFunc() << "] ";
147 }
148 }
149
PidTid(Gslogger & logger,enum LOG_PHASE phase)150 void Gslogger::PidTid(Gslogger &logger, enum LOG_PHASE phase)
151 {
152 if (phase == LOG_PHASE::BEGIN) {
153 logger << "[" << getpid() << "][" << gettid() << "]";
154 }
155 }
156
Gslogger(const std::string & file,const std::string & func,int line,enum LOG_LEVEL level,...)157 Gslogger::Gslogger(const std::string &file, const std::string &func, int line, enum LOG_LEVEL level, ...)
158 {
159 file_ = file;
160 func_ = func;
161 line_ = line;
162 level_ = level;
163 va_start(vl_, level);
164
165 while (true) {
166 GsloggerWrapperFunc f = va_arg(vl_, GsloggerWrapperFunc);
167 if (f == nullptr) {
168 break;
169 }
170
171 f(*this, LOG_PHASE::BEGIN);
172 wrappers_.push_back(f);
173 }
174 }
175
~Gslogger()176 Gslogger::~Gslogger()
177 {
178 for (const auto &wrapper : wrappers_) {
179 wrapper(*this, LOG_PHASE::END);
180 }
181 }
182
GetFile() const183 const std::string &Gslogger::GetFile() const
184 {
185 return file_;
186 }
187
GetFunc() const188 const std::string &Gslogger::GetFunc() const
189 {
190 return func_;
191 }
192
GetLine() const193 int Gslogger::GetLine() const
194 {
195 return line_;
196 }
197
GetLevel() const198 enum Gslogger::LOG_LEVEL Gslogger::GetLevel() const
199 {
200 return level_;
201 }
202
GetVariousArgument()203 va_list &Gslogger::GetVariousArgument()
204 {
205 return vl_;
206 }
207