1 | /** |
2 | * Copyright 2021 Alibaba, Inc. and its affiliates. All Rights Reserved. |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | |
16 | * \author Hechong.xyf |
17 | * \date May 2018 |
18 | * \brief Interface of AiTheta Index Logger |
19 | */ |
20 | |
21 | #ifndef __AITHETA2_INDEX_LOGGER_H__ |
22 | #define __AITHETA2_INDEX_LOGGER_H__ |
23 | |
24 | #include <cstdarg> |
25 | #include <cstring> |
26 | #include <memory> |
27 | #include "index_module.h" |
28 | #include "index_params.h" |
29 | |
30 | //! Log Debug Message |
31 | #ifndef LOG_DEBUG |
32 | #define LOG_DEBUG(format, ...) \ |
33 | aitheta2::IndexLoggerBroker::Log(aitheta2::IndexLogger::LEVEL_DEBUG, \ |
34 | __FILE__, __LINE__, format, ##__VA_ARGS__) |
35 | #endif |
36 | |
37 | //! Log Information Message |
38 | #ifndef LOG_INFO |
39 | #define LOG_INFO(format, ...) \ |
40 | aitheta2::IndexLoggerBroker::Log(aitheta2::IndexLogger::LEVEL_INFO, \ |
41 | __FILE__, __LINE__, format, ##__VA_ARGS__) |
42 | #endif |
43 | |
44 | //! Log Warn Message |
45 | #ifndef LOG_WARN |
46 | #define LOG_WARN(format, ...) \ |
47 | aitheta2::IndexLoggerBroker::Log(aitheta2::IndexLogger::LEVEL_WARN, \ |
48 | __FILE__, __LINE__, format, ##__VA_ARGS__) |
49 | #endif |
50 | |
51 | //! Log Error Message |
52 | #ifndef LOG_ERROR |
53 | #define LOG_ERROR(format, ...) \ |
54 | aitheta2::IndexLoggerBroker::Log(aitheta2::IndexLogger::LEVEL_ERROR, \ |
55 | __FILE__, __LINE__, format, ##__VA_ARGS__) |
56 | #endif |
57 | |
58 | //! Log Fatal Message |
59 | #ifndef LOG_FATAL |
60 | #define LOG_FATAL(format, ...) \ |
61 | aitheta2::IndexLoggerBroker::Log(aitheta2::IndexLogger::LEVEL_FATAL, \ |
62 | __FILE__, __LINE__, format, ##__VA_ARGS__) |
63 | #endif |
64 | |
65 | namespace aitheta2 { |
66 | |
67 | /*! Index Logger |
68 | */ |
69 | struct IndexLogger : public IndexModule { |
70 | //! Index Logger Pointer |
71 | typedef std::shared_ptr<IndexLogger> Pointer; |
72 | |
73 | static const int LEVEL_DEBUG; |
74 | static const int LEVEL_INFO; |
75 | static const int LEVEL_WARN; |
76 | static const int LEVEL_ERROR; |
77 | static const int LEVEL_FATAL; |
78 | |
79 | //! Retrieve string of level |
80 | static const char *LevelString(int level) { |
81 | static const char *info[] = {"DEBUG" , " INFO" , " WARN" , "ERROR" , "FATAL" }; |
82 | if (level < (int)(sizeof(info) / sizeof(info[0]))) { |
83 | return info[level]; |
84 | } |
85 | return "" ; |
86 | } |
87 | |
88 | //! Retrieve symbol of level |
89 | static char LevelSymbol(int level) { |
90 | static const char info[5] = {'D', 'I', 'W', 'E', 'F'}; |
91 | if (level < (int)(sizeof(info) / sizeof(info[0]))) { |
92 | return info[level]; |
93 | } |
94 | return ' '; |
95 | } |
96 | |
97 | //! Destructor |
98 | virtual ~IndexLogger(void) {} |
99 | |
100 | //! Initialize Logger |
101 | virtual int init(const IndexParams ¶ms) = 0; |
102 | |
103 | //! Cleanup Logger |
104 | virtual int cleanup(void) = 0; |
105 | |
106 | //! Log Message |
107 | virtual void log(int level, const char *file, int line, const char *format, |
108 | va_list args) = 0; |
109 | }; |
110 | |
111 | /*! Index Logger Broker |
112 | */ |
113 | class IndexLoggerBroker { |
114 | public: |
115 | //! Register Logger |
116 | static IndexLogger::Pointer Register(IndexLogger::Pointer logger) { |
117 | IndexLogger::Pointer ret = std::move(logger_); |
118 | logger_ = std::move(logger); |
119 | return ret; |
120 | } |
121 | |
122 | //! Register Logger with init params |
123 | static int Register(IndexLogger::Pointer logger, |
124 | const aitheta2::IndexParams ¶ms) { |
125 | //! Cleanup the previous, before initizlizing the new one |
126 | if (logger_) { |
127 | logger_->cleanup(); |
128 | } |
129 | logger_ = std::move(logger); |
130 | return logger_->init(params); |
131 | } |
132 | |
133 | //! Unregister Logger |
134 | static void Unregister(void) { |
135 | logger_ = nullptr; |
136 | } |
137 | |
138 | //! Set Level of Logger |
139 | static void SetLevel(int level) { |
140 | logger_level_ = level; |
141 | } |
142 | |
143 | //! Log Message |
144 | __attribute__((format(printf, 4, 5))) static void Log( |
145 | int level, const char *file, int line, const char *format, ...) { |
146 | if (logger_level_ <= level && logger_) { |
147 | va_list args; |
148 | va_start(args, format); |
149 | logger_->log(level, file, line, format, args); |
150 | va_end(args); |
151 | } |
152 | } |
153 | |
154 | private: |
155 | //! Disable them |
156 | IndexLoggerBroker(void) = delete; |
157 | IndexLoggerBroker(const IndexLoggerBroker &) = delete; |
158 | IndexLoggerBroker(IndexLoggerBroker &&) = delete; |
159 | |
160 | //! Members |
161 | static int logger_level_; |
162 | static IndexLogger::Pointer logger_; |
163 | }; |
164 | |
165 | } // namespace aitheta2 |
166 | |
167 | #endif // __AITHETA2_INDEX_LOGGER_H__ |
168 | |