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