• 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 
16 #include "properties.h"
17 #include "hilog_common.h"
18 #include "hilog/log.h"
19 #include "hilog/log_c.h"
20 #include "hilog_napi_base.h"
21 #include "napi/native_api.h"
22 #include "napi/native_node_api.h"
23 #include "n_func_arg.h"
24 #include "n_class.h"
25 #include "securec.h"
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 namespace OHOS {
31 namespace HiviewDFX {
32 using namespace std;
33 const HiLogLabel LABEL = { LOG_CORE, 0xD002D00, "Hilog_JS" };
34 static constexpr int MIN_NUMBER = 3;
35 static constexpr int MAX_NUMBER = 100;
36 static constexpr int PUBLIC_LEN = 6;
37 static constexpr int PRIVATE_LEN = 7;
38 static constexpr int PROPERTY_POS = 2;
39 static const string PRIV_STR = "<private>";
40 
ParseLogContent(string & formatStr,vector<napiParam> & params,string & logContent)41 void ParseLogContent(string& formatStr, vector<napiParam>& params, string& logContent)
42 {
43     if (params.empty()) {
44         logContent += formatStr;
45         return;
46     }
47     auto size = params.size();
48     auto len = formatStr.size();
49     uint32_t pos = 0;
50     uint32_t count = 0;
51     bool isPrivateEnable = true;
52 #if not (defined(__WINDOWS__) || defined(__MAC__) || defined(__LINUX__))
53     isPrivateEnable = IsPrivateModeEnable();
54 #endif
55     for (; pos < len; ++pos) {
56         bool showPriv = true;
57         if (count >= size) {
58             break;
59         }
60         if (formatStr[pos] != '%') {
61             logContent += formatStr[pos];
62             continue;
63         }
64 
65         if (((pos + PUBLIC_LEN + PROPERTY_POS) < len) &&
66             formatStr.substr(pos + PROPERTY_POS, PUBLIC_LEN) == "public") {
67             pos += (PUBLIC_LEN + PROPERTY_POS);
68             showPriv = false;
69         } else if (((pos + PRIVATE_LEN + PROPERTY_POS) < len) &&
70             formatStr.substr(pos + PROPERTY_POS, PRIVATE_LEN) == "private") {
71             pos += (PRIVATE_LEN + PROPERTY_POS);
72         }
73 
74         if (pos + 1 >= len) {
75             break;
76         }
77         switch (formatStr[pos + 1]) {
78             case 'd':
79             case 'i':
80                 if (params[count].type == napi_number || params[count].type == napi_bigint) {
81                     logContent += (isPrivateEnable && showPriv) ? PRIV_STR : params[count].val;
82                 }
83                 ++count;
84                 ++pos;
85                 break;
86             case 's':
87                 if (params[count].type == napi_string || params[count].type == napi_undefined ||
88                     params[count].type == napi_boolean || params[count].type == napi_null) {
89                     logContent += (isPrivateEnable && showPriv) ? PRIV_STR : params[count].val;
90                 }
91                 ++count;
92                 ++pos;
93                 break;
94             case 'O':
95             case 'o':
96                 if (params[count].type == napi_object || params[count].type == napi_function ||
97                     params[count].type == napi_undefined || params[count].type == napi_null) {
98                     logContent += (isPrivateEnable && showPriv) ? PRIV_STR : params[count].val;
99                 }
100                 ++count;
101                 ++pos;
102                 break;
103             case '%':
104                 logContent += formatStr[pos];
105                 ++pos;
106                 break;
107             default:
108                 logContent += formatStr[pos];
109                 break;
110         }
111     }
112     if (pos < len) {
113         logContent += formatStr.substr(pos, len - pos);
114     }
115 }
116 
IsLoggable(napi_env env,napi_callback_info info)117 napi_value HilogNapiBase::IsLoggable(napi_env env, napi_callback_info info)
118 {
119     NFuncArg funcArg(env, info);
120 
121     if (!funcArg.InitArgs(NARG_CNT::THREE)) {
122         return nullptr;
123     }
124     bool succ = false;
125     int32_t domain;
126     tie(succ, domain) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32();
127     if (!succ) {
128         return nullptr;
129     }
130     if ((domain < static_cast<int32_t>(DOMAIN_APP_MIN)) || (domain > static_cast<int32_t>(DOMAIN_APP_MAX))) {
131         return NVal::CreateBool(env, false).val_;
132     }
133     int32_t level;
134     tie(succ, level) = NVal(env, funcArg[NARG_POS::THIRD]).ToInt32();
135     if (!succ) {
136         return nullptr;
137     }
138     unique_ptr<char[]> tag;
139     tie(succ, tag, ignore) = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8String();
140     if (!succ) {
141         return nullptr;
142     }
143     bool res = HiLogIsLoggable(domain, tag.get(), static_cast<LogLevel>(level));
144     return NVal::CreateBool(env, res).val_;
145 }
146 
SetMinLogLevel(napi_env env,napi_callback_info info)147 napi_value HilogNapiBase::SetMinLogLevel(napi_env env, napi_callback_info info)
148 {
149     NFuncArg funcArg(env, info);
150     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
151         return nullptr;
152     }
153     bool succ = false;
154     int32_t level = LOG_LEVEL_MIN;
155     tie(succ, level) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32();
156     if (!succ) {
157         return nullptr;
158     }
159     HiLogSetAppMinLogLevel(static_cast<LogLevel>(level));
160     return nullptr;
161 }
162 
Debug(napi_env env,napi_callback_info info)163 napi_value HilogNapiBase::Debug(napi_env env, napi_callback_info info)
164 {
165     return HilogImpl(env, info, LOG_DEBUG, true);
166 }
167 
Info(napi_env env,napi_callback_info info)168 napi_value HilogNapiBase::Info(napi_env env, napi_callback_info info)
169 {
170     return HilogImpl(env, info, LOG_INFO, true);
171 }
172 
Warn(napi_env env,napi_callback_info info)173 napi_value HilogNapiBase::Warn(napi_env env, napi_callback_info info)
174 {
175     return HilogImpl(env, info, LOG_WARN, true);
176 }
177 
Error(napi_env env,napi_callback_info info)178 napi_value HilogNapiBase::Error(napi_env env, napi_callback_info info)
179 {
180     return HilogImpl(env, info, LOG_ERROR, true);
181 }
182 
Fatal(napi_env env,napi_callback_info info)183 napi_value HilogNapiBase::Fatal(napi_env env, napi_callback_info info)
184 {
185     return HilogImpl(env, info, LOG_FATAL, true);
186 }
187 
SysLogDebug(napi_env env,napi_callback_info info)188 napi_value HilogNapiBase::SysLogDebug(napi_env env, napi_callback_info info)
189 {
190     return HilogImpl(env, info, LOG_DEBUG, false);
191 }
192 
SysLogInfo(napi_env env,napi_callback_info info)193 napi_value HilogNapiBase::SysLogInfo(napi_env env, napi_callback_info info)
194 {
195     return HilogImpl(env, info, LOG_INFO, false);
196 }
197 
SysLogWarn(napi_env env,napi_callback_info info)198 napi_value HilogNapiBase::SysLogWarn(napi_env env, napi_callback_info info)
199 {
200     return HilogImpl(env, info, LOG_WARN, false);
201 }
202 
SysLogError(napi_env env,napi_callback_info info)203 napi_value HilogNapiBase::SysLogError(napi_env env, napi_callback_info info)
204 {
205     return HilogImpl(env, info, LOG_ERROR, false);
206 }
207 
SysLogFatal(napi_env env,napi_callback_info info)208 napi_value HilogNapiBase::SysLogFatal(napi_env env, napi_callback_info info)
209 {
210     return HilogImpl(env, info, LOG_FATAL, false);
211 }
212 
parseNapiValue(napi_env env,napi_callback_info info,napi_value element,vector<napiParam> & params)213 napi_value HilogNapiBase::parseNapiValue(napi_env env, napi_callback_info info,
214     napi_value element, vector<napiParam>& params)
215 {
216     bool succ = false;
217     napi_valuetype type;
218     napiParam res = {napi_null, ""};
219     napi_status typeStatus = napi_typeof(env, element, &type);
220     unique_ptr<char[]> name;
221     if (typeStatus != napi_ok) {
222         return nullptr;
223     }
224     if (type == napi_number || type == napi_bigint || type == napi_undefined ||
225         type == napi_boolean || type == napi_null) {
226         napi_value elmString;
227         napi_status objectStatus = napi_coerce_to_string(env, element, &elmString);
228         if (objectStatus != napi_ok) {
229             return nullptr;
230         }
231         tie(succ, name, ignore) = NVal(env, elmString).ToUTF8String();
232         if (!succ) {
233             return nullptr;
234         }
235     } else if (type == napi_object || type == napi_function) {
236         tie(succ, res.val) = NVal(env, element).GetValObjectAsStr();
237     } else if (type == napi_string) {
238         tie(succ, name, ignore) = NVal(env, element).ToUTF8String();
239         if (!succ) {
240             return nullptr;
241         }
242     } else {
243         HiLog::Info(LABEL, "%{public}s", "type mismatch");
244     }
245     res.type = type;
246     if (name != nullptr) {
247         res.val = name.get();
248     }
249     params.emplace_back(res);
250     return nullptr;
251 }
252 
HilogImpl(napi_env env,napi_callback_info info,int level,bool isAppLog)253 napi_value HilogNapiBase::HilogImpl(napi_env env, napi_callback_info info, int level, bool isAppLog)
254 {
255     NFuncArg funcArg(env, info);
256     funcArg.InitArgs(MIN_NUMBER, MAX_NUMBER);
257     bool succ = false;
258     int32_t domain;
259     tie(succ, domain) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32();
260     if (!succ) {
261         HiLog::Info(LABEL, "%{public}s", "domain mismatch");
262         return nullptr;
263     }
264     unique_ptr<char[]> tag;
265     tie(succ, tag, ignore) = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8String();
266     if (!succ) {
267         HiLog::Info(LABEL, "%{public}s", "tag mismatch");
268         return nullptr;
269     }
270     unique_ptr<char[]> fmt;
271     tie(succ, fmt, ignore) = NVal(env, funcArg[NARG_POS::THIRD]).ToUTF8String();
272     if (!succ) {
273         HiLog::Info(LABEL, "%{public}s", "Format mismatch");
274         return nullptr;
275     }
276     string fmtString = fmt.get();
277     bool res = false;
278     napi_value array = funcArg[NARG_POS::FOURTH];
279     napi_is_array(env, array, &res);
280     string logContent;
281     vector<napiParam> params;
282     if (!res) {
283         for (size_t i = MIN_NUMBER; i < funcArg.GetArgc(); i++) {
284             napi_value argsVal = funcArg[i];
285             (void)parseNapiValue(env, info, argsVal, params);
286         }
287     } else {
288         if (funcArg.GetArgc() != MIN_NUMBER + 1) {
289             NAPI_ASSERT(env, false, "Argc mismatch");
290             HiLog::Info(LABEL, "%{public}s", "Argc mismatch");
291             return nullptr;
292         }
293         uint32_t length;
294         napi_status lengthStatus = napi_get_array_length(env, array, &length);
295         if (lengthStatus != napi_ok) {
296             return nullptr;
297         }
298         uint32_t i;
299         for (i = 0; i < length; i++) {
300             napi_value element;
301             napi_status eleStatus = napi_get_element(env, array, i, &element);
302             if (eleStatus != napi_ok) {
303                 return nullptr;
304             }
305             (void)parseNapiValue(env, info, element, params);
306         }
307     }
308     ParseLogContent(fmtString, params, logContent);
309     HiLogPrint((isAppLog ? LOG_APP : LOG_CORE),
310         static_cast<LogLevel>(level), domain, tag.get(), "%{public}s", logContent.c_str());
311     return nullptr;
312 }
313 }  // namespace HiviewDFX
314 }  // namespace OHOS
315 
316 #ifdef __cplusplus
317 }
318 #endif
319