]>
Commit | Line | Data |
---|---|---|
1d09f67e TL |
1 | // Licensed to the Apache Software Foundation (ASF) under one |
2 | // or more contributor license agreements. See the NOTICE file | |
3 | // distributed with this work for additional information | |
4 | // regarding copyright ownership. The ASF licenses this file | |
5 | // to you under the Apache License, Version 2.0 (the | |
6 | // "License"); you may not use this file except in compliance | |
7 | // with the License. You may obtain a copy of the License at | |
8 | // | |
9 | // http://www.apache.org/licenses/LICENSE-2.0 | |
10 | // | |
11 | // Unless required by applicable law or agreed to in writing, | |
12 | // software distributed under the License is distributed on an | |
13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
14 | // KIND, either express or implied. See the License for the | |
15 | // specific language governing permissions and limitations | |
16 | // under the License. | |
17 | ||
18 | #pragma once | |
19 | ||
20 | #ifdef GANDIVA_IR | |
21 | ||
22 | // The LLVM IR code doesn't have an NDEBUG mode. And, it shouldn't include references to | |
23 | // streams or stdc++. So, making the DCHECK calls void in that case. | |
24 | ||
25 | #define ARROW_IGNORE_EXPR(expr) ((void)(expr)) | |
26 | ||
27 | #define DCHECK(condition) ARROW_IGNORE_EXPR(condition) | |
28 | #define DCHECK_OK(status) ARROW_IGNORE_EXPR(status) | |
29 | #define DCHECK_EQ(val1, val2) ARROW_IGNORE_EXPR(val1) | |
30 | #define DCHECK_NE(val1, val2) ARROW_IGNORE_EXPR(val1) | |
31 | #define DCHECK_LE(val1, val2) ARROW_IGNORE_EXPR(val1) | |
32 | #define DCHECK_LT(val1, val2) ARROW_IGNORE_EXPR(val1) | |
33 | #define DCHECK_GE(val1, val2) ARROW_IGNORE_EXPR(val1) | |
34 | #define DCHECK_GT(val1, val2) ARROW_IGNORE_EXPR(val1) | |
35 | ||
36 | #else // !GANDIVA_IR | |
37 | ||
38 | #include <memory> | |
39 | #include <ostream> | |
40 | #include <string> | |
41 | ||
42 | #include "arrow/util/macros.h" | |
43 | #include "arrow/util/visibility.h" | |
44 | ||
45 | namespace arrow { | |
46 | namespace util { | |
47 | ||
48 | enum class ArrowLogLevel : int { | |
49 | ARROW_DEBUG = -1, | |
50 | ARROW_INFO = 0, | |
51 | ARROW_WARNING = 1, | |
52 | ARROW_ERROR = 2, | |
53 | ARROW_FATAL = 3 | |
54 | }; | |
55 | ||
56 | #define ARROW_LOG_INTERNAL(level) ::arrow::util::ArrowLog(__FILE__, __LINE__, level) | |
57 | #define ARROW_LOG(level) ARROW_LOG_INTERNAL(::arrow::util::ArrowLogLevel::ARROW_##level) | |
58 | ||
59 | #define ARROW_IGNORE_EXPR(expr) ((void)(expr)) | |
60 | ||
61 | #define ARROW_CHECK(condition) \ | |
62 | ARROW_PREDICT_TRUE(condition) \ | |
63 | ? ARROW_IGNORE_EXPR(0) \ | |
64 | : ::arrow::util::Voidify() & \ | |
65 | ::arrow::util::ArrowLog(__FILE__, __LINE__, \ | |
66 | ::arrow::util::ArrowLogLevel::ARROW_FATAL) \ | |
67 | << " Check failed: " #condition " " | |
68 | ||
69 | // If 'to_call' returns a bad status, CHECK immediately with a logged message | |
70 | // of 'msg' followed by the status. | |
71 | #define ARROW_CHECK_OK_PREPEND(to_call, msg) \ | |
72 | do { \ | |
73 | ::arrow::Status _s = (to_call); \ | |
74 | ARROW_CHECK(_s.ok()) << "Operation failed: " << ARROW_STRINGIFY(to_call) << "\n" \ | |
75 | << (msg) << ": " << _s.ToString(); \ | |
76 | } while (false) | |
77 | ||
78 | // If the status is bad, CHECK immediately, appending the status to the | |
79 | // logged message. | |
80 | #define ARROW_CHECK_OK(s) ARROW_CHECK_OK_PREPEND(s, "Bad status") | |
81 | ||
82 | #define ARROW_CHECK_EQ(val1, val2) ARROW_CHECK((val1) == (val2)) | |
83 | #define ARROW_CHECK_NE(val1, val2) ARROW_CHECK((val1) != (val2)) | |
84 | #define ARROW_CHECK_LE(val1, val2) ARROW_CHECK((val1) <= (val2)) | |
85 | #define ARROW_CHECK_LT(val1, val2) ARROW_CHECK((val1) < (val2)) | |
86 | #define ARROW_CHECK_GE(val1, val2) ARROW_CHECK((val1) >= (val2)) | |
87 | #define ARROW_CHECK_GT(val1, val2) ARROW_CHECK((val1) > (val2)) | |
88 | ||
89 | #ifdef NDEBUG | |
90 | #define ARROW_DFATAL ::arrow::util::ArrowLogLevel::ARROW_WARNING | |
91 | ||
92 | // CAUTION: DCHECK_OK() always evaluates its argument, but other DCHECK*() macros | |
93 | // only do so in debug mode. | |
94 | ||
95 | #define ARROW_DCHECK(condition) \ | |
96 | while (false) ARROW_IGNORE_EXPR(condition); \ | |
97 | while (false) ::arrow::util::detail::NullLog() | |
98 | #define ARROW_DCHECK_OK(s) \ | |
99 | ARROW_IGNORE_EXPR(s); \ | |
100 | while (false) ::arrow::util::detail::NullLog() | |
101 | #define ARROW_DCHECK_EQ(val1, val2) \ | |
102 | while (false) ARROW_IGNORE_EXPR(val1); \ | |
103 | while (false) ARROW_IGNORE_EXPR(val2); \ | |
104 | while (false) ::arrow::util::detail::NullLog() | |
105 | #define ARROW_DCHECK_NE(val1, val2) \ | |
106 | while (false) ARROW_IGNORE_EXPR(val1); \ | |
107 | while (false) ARROW_IGNORE_EXPR(val2); \ | |
108 | while (false) ::arrow::util::detail::NullLog() | |
109 | #define ARROW_DCHECK_LE(val1, val2) \ | |
110 | while (false) ARROW_IGNORE_EXPR(val1); \ | |
111 | while (false) ARROW_IGNORE_EXPR(val2); \ | |
112 | while (false) ::arrow::util::detail::NullLog() | |
113 | #define ARROW_DCHECK_LT(val1, val2) \ | |
114 | while (false) ARROW_IGNORE_EXPR(val1); \ | |
115 | while (false) ARROW_IGNORE_EXPR(val2); \ | |
116 | while (false) ::arrow::util::detail::NullLog() | |
117 | #define ARROW_DCHECK_GE(val1, val2) \ | |
118 | while (false) ARROW_IGNORE_EXPR(val1); \ | |
119 | while (false) ARROW_IGNORE_EXPR(val2); \ | |
120 | while (false) ::arrow::util::detail::NullLog() | |
121 | #define ARROW_DCHECK_GT(val1, val2) \ | |
122 | while (false) ARROW_IGNORE_EXPR(val1); \ | |
123 | while (false) ARROW_IGNORE_EXPR(val2); \ | |
124 | while (false) ::arrow::util::detail::NullLog() | |
125 | ||
126 | #else | |
127 | #define ARROW_DFATAL ::arrow::util::ArrowLogLevel::ARROW_FATAL | |
128 | ||
129 | #define ARROW_DCHECK ARROW_CHECK | |
130 | #define ARROW_DCHECK_OK ARROW_CHECK_OK | |
131 | #define ARROW_DCHECK_EQ ARROW_CHECK_EQ | |
132 | #define ARROW_DCHECK_NE ARROW_CHECK_NE | |
133 | #define ARROW_DCHECK_LE ARROW_CHECK_LE | |
134 | #define ARROW_DCHECK_LT ARROW_CHECK_LT | |
135 | #define ARROW_DCHECK_GE ARROW_CHECK_GE | |
136 | #define ARROW_DCHECK_GT ARROW_CHECK_GT | |
137 | ||
138 | #endif // NDEBUG | |
139 | ||
140 | #define DCHECK ARROW_DCHECK | |
141 | #define DCHECK_OK ARROW_DCHECK_OK | |
142 | #define DCHECK_EQ ARROW_DCHECK_EQ | |
143 | #define DCHECK_NE ARROW_DCHECK_NE | |
144 | #define DCHECK_LE ARROW_DCHECK_LE | |
145 | #define DCHECK_LT ARROW_DCHECK_LT | |
146 | #define DCHECK_GE ARROW_DCHECK_GE | |
147 | #define DCHECK_GT ARROW_DCHECK_GT | |
148 | ||
149 | // This code is adapted from | |
150 | // https://github.com/ray-project/ray/blob/master/src/ray/util/logging.h. | |
151 | ||
152 | // To make the logging lib pluggable with other logging libs and make | |
153 | // the implementation unawared by the user, ArrowLog is only a declaration | |
154 | // which hide the implementation into logging.cc file. | |
155 | // In logging.cc, we can choose different log libs using different macros. | |
156 | ||
157 | // This is also a null log which does not output anything. | |
158 | class ARROW_EXPORT ArrowLogBase { | |
159 | public: | |
160 | virtual ~ArrowLogBase() {} | |
161 | ||
162 | virtual bool IsEnabled() const { return false; } | |
163 | ||
164 | template <typename T> | |
165 | ArrowLogBase& operator<<(const T& t) { | |
166 | if (IsEnabled()) { | |
167 | Stream() << t; | |
168 | } | |
169 | return *this; | |
170 | } | |
171 | ||
172 | protected: | |
173 | virtual std::ostream& Stream() = 0; | |
174 | }; | |
175 | ||
176 | class ARROW_EXPORT ArrowLog : public ArrowLogBase { | |
177 | public: | |
178 | ArrowLog(const char* file_name, int line_number, ArrowLogLevel severity); | |
179 | ~ArrowLog() override; | |
180 | ||
181 | /// Return whether or not current logging instance is enabled. | |
182 | /// | |
183 | /// \return True if logging is enabled and false otherwise. | |
184 | bool IsEnabled() const override; | |
185 | ||
186 | /// The init function of arrow log for a program which should be called only once. | |
187 | /// | |
188 | /// \param appName The app name which starts the log. | |
189 | /// \param severity_threshold Logging threshold for the program. | |
190 | /// \param logDir Logging output file name. If empty, the log won't output to file. | |
191 | static void StartArrowLog(const std::string& appName, | |
192 | ArrowLogLevel severity_threshold = ArrowLogLevel::ARROW_INFO, | |
193 | const std::string& logDir = ""); | |
194 | ||
195 | /// The shutdown function of arrow log, it should be used with StartArrowLog as a pair. | |
196 | static void ShutDownArrowLog(); | |
197 | ||
198 | /// Install the failure signal handler to output call stack when crash. | |
199 | /// If glog is not installed, this function won't do anything. | |
200 | static void InstallFailureSignalHandler(); | |
201 | ||
202 | /// Uninstall the signal actions installed by InstallFailureSignalHandler. | |
203 | static void UninstallSignalAction(); | |
204 | ||
205 | /// Return whether or not the log level is enabled in current setting. | |
206 | /// | |
207 | /// \param log_level The input log level to test. | |
208 | /// \return True if input log level is not lower than the threshold. | |
209 | static bool IsLevelEnabled(ArrowLogLevel log_level); | |
210 | ||
211 | private: | |
212 | ARROW_DISALLOW_COPY_AND_ASSIGN(ArrowLog); | |
213 | ||
214 | // Hide the implementation of log provider by void *. | |
215 | // Otherwise, lib user may define the same macro to use the correct header file. | |
216 | void* logging_provider_; | |
217 | /// True if log messages should be logged and false if they should be ignored. | |
218 | bool is_enabled_; | |
219 | ||
220 | static ArrowLogLevel severity_threshold_; | |
221 | ||
222 | protected: | |
223 | std::ostream& Stream() override; | |
224 | }; | |
225 | ||
226 | // This class make ARROW_CHECK compilation pass to change the << operator to void. | |
227 | // This class is copied from glog. | |
228 | class ARROW_EXPORT Voidify { | |
229 | public: | |
230 | Voidify() {} | |
231 | // This has to be an operator with a precedence lower than << but | |
232 | // higher than ?: | |
233 | void operator&(ArrowLogBase&) {} | |
234 | }; | |
235 | ||
236 | namespace detail { | |
237 | ||
238 | /// @brief A helper for the nil log sink. | |
239 | /// | |
240 | /// Using this helper is analogous to sending log messages to /dev/null: | |
241 | /// nothing gets logged. | |
242 | class NullLog { | |
243 | public: | |
244 | /// The no-op output operator. | |
245 | /// | |
246 | /// @param [in] t | |
247 | /// The object to send into the nil sink. | |
248 | /// @return Reference to the updated object. | |
249 | template <class T> | |
250 | NullLog& operator<<(const T& t) { | |
251 | return *this; | |
252 | } | |
253 | }; | |
254 | ||
255 | } // namespace detail | |
256 | } // namespace util | |
257 | } // namespace arrow | |
258 | ||
259 | #endif // GANDIVA_IR |