1 /*
2 * Copyright (c) 2022 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 "log_print.h"
17
18 #include <atomic>
19 #include <cstdarg>
20 #include <cstdio>
21 #include <mutex>
22
23 #include "securec.h"
24
25 Logger *Logger::logHandler = nullptr;
26 const std::string Logger::PRIVATE_TAG = "{private}";
27 const std::string Logger::PUBLIC_TAG = "{public}";
28
Print(Level level,const char * func,int line,const std::string & tag,const std::string & msg)29 void Logger::Print(Level level, const char *func, int line, const std::string &tag, const std::string &msg)
30 {
31 printf("%d %s:%d [%s]:%s \n", level, func, line, tag.c_str(), msg.c_str());
32 }
33
GetInstance()34 Logger *Logger::GetInstance()
35 {
36 static Logger logger;
37 return &logger;
38 }
39
RegisterLogger(Logger * logger)40 void Logger::RegisterLogger(Logger *logger)
41 {
42 static std::mutex logHandlerLock;
43 if (logger == nullptr) {
44 return;
45 }
46 if (logHandler == nullptr) {
47 std::lock_guard<std::mutex> lock(logHandlerLock);
48 if (logHandler == nullptr) {
49 logHandler = logger;
50 }
51 }
52 }
53
Log(Level level,const std::string & tag,const char * func,int line,const char * format,...)54 void Logger::Log(Level level, const std::string &tag, const char *func, int line, const char *format, ...)
55 {
56 if (format == nullptr) {
57 return;
58 }
59 static const int maxLogLength = 1024;
60 va_list argList;
61 va_start(argList, format);
62 char logBuff[maxLogLength];
63 std::string msg;
64 std::string formatTemp;
65 PreparePrivateLog(format, formatTemp);
66 int bytes = vsnprintf_s(logBuff, maxLogLength, maxLogLength - 1, formatTemp.c_str(), argList);
67 if (bytes < 0) {
68 msg = "log buffer overflow!";
69 } else {
70 msg = logBuff;
71 }
72 va_end(argList);
73 if (logHandler != nullptr) {
74 logHandler->Print(level, func, line, tag, msg);
75 return;
76 }
77
78 Logger::RegisterLogger(Logger::GetInstance());
79 if (logHandler != nullptr) {
80 logHandler->Print(level, func, line, tag, msg);
81 }
82 }
83
PreparePrivateLog(const char * format,std::string & outStrFormat)84 void Logger::PreparePrivateLog(const char *format, std::string &outStrFormat)
85 {
86 outStrFormat = format;
87 std::string::size_type pos;
88 while ((pos = outStrFormat.find(PRIVATE_TAG)) != std::string::npos) {
89 outStrFormat.replace(pos, PRIVATE_TAG.size(), "");
90 }
91
92 while ((pos = outStrFormat.find(PUBLIC_TAG)) != std::string::npos) {
93 outStrFormat.replace(pos, PUBLIC_TAG.size(), "");
94 }
95 }
96