Apache Arrow (C++)
A columnar in-memory analytics layer designed to accelerate big data.
logging.h
Go to the documentation of this file.
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 #ifndef ARROW_UTIL_LOGGING_H
19 #define ARROW_UTIL_LOGGING_H
20 
21 #include <cstdlib>
22 #include <iostream>
23 
24 #include "arrow/util/macros.h"
25 
26 namespace arrow {
27 
28 // Stubbed versions of macros defined in glog/logging.h, intended for
29 // environments where glog headers aren't available.
30 //
31 // Add more as needed.
32 
33 // Log levels. LOG ignores them, so their values are arbitrary.
34 
35 #define ARROW_DEBUG (-1)
36 #define ARROW_INFO 0
37 #define ARROW_WARNING 1
38 #define ARROW_ERROR 2
39 #define ARROW_FATAL 3
40 
41 #define ARROW_LOG_INTERNAL(level) ::arrow::internal::CerrLog(level)
42 #define ARROW_LOG(level) ARROW_LOG_INTERNAL(ARROW_##level)
43 #define ARROW_IGNORE_EXPR(expr) ((void)(expr));
44 
45 #define ARROW_CHECK(condition) \
46  (condition) ? 0 \
47  : ::arrow::internal::FatalLog(ARROW_FATAL) \
48  << __FILE__ << ":" << __LINE__ << " Check failed: " #condition " "
49 
50 // If 'to_call' returns a bad status, CHECK immediately with a logged message
51 // of 'msg' followed by the status.
52 #define ARROW_CHECK_OK_PREPEND(to_call, msg) \
53  do { \
54  ::arrow::Status _s = (to_call); \
55  ARROW_CHECK(_s.ok()) << (msg) << ": " << _s.ToString(); \
56  } while (false)
57 
58 // If the status is bad, CHECK immediately, appending the status to the
59 // logged message.
60 #define ARROW_CHECK_OK(s) ARROW_CHECK_OK_PREPEND(s, "Bad status")
61 
62 #ifdef NDEBUG
63 #define ARROW_DFATAL ARROW_WARNING
64 
65 #define DCHECK(condition) \
66  ARROW_IGNORE_EXPR(condition) \
67  while (false) ::arrow::internal::NullLog()
68 #define DCHECK_OK(status) \
69  ARROW_IGNORE_EXPR(status) \
70  while (false) ::arrow::internal::NullLog()
71 #define DCHECK_EQ(val1, val2) \
72  ARROW_IGNORE_EXPR(val1) \
73  while (false) ::arrow::internal::NullLog()
74 #define DCHECK_NE(val1, val2) \
75  ARROW_IGNORE_EXPR(val1) \
76  while (false) ::arrow::internal::NullLog()
77 #define DCHECK_LE(val1, val2) \
78  ARROW_IGNORE_EXPR(val1) \
79  while (false) ::arrow::internal::NullLog()
80 #define DCHECK_LT(val1, val2) \
81  ARROW_IGNORE_EXPR(val1) \
82  while (false) ::arrow::internal::NullLog()
83 #define DCHECK_GE(val1, val2) \
84  ARROW_IGNORE_EXPR(val1) \
85  while (false) ::arrow::internal::NullLog()
86 #define DCHECK_GT(val1, val2) \
87  ARROW_IGNORE_EXPR(val1) \
88  while (false) ::arrow::internal::NullLog()
89 
90 #else
91 #define ARROW_DFATAL ARROW_FATAL
92 
93 #define DCHECK(condition) ARROW_CHECK(condition)
94 #define DCHECK_OK(status) (ARROW_CHECK((status).ok()) << (status).message())
95 #define DCHECK_EQ(val1, val2) ARROW_CHECK((val1) == (val2))
96 #define DCHECK_NE(val1, val2) ARROW_CHECK((val1) != (val2))
97 #define DCHECK_LE(val1, val2) ARROW_CHECK((val1) <= (val2))
98 #define DCHECK_LT(val1, val2) ARROW_CHECK((val1) < (val2))
99 #define DCHECK_GE(val1, val2) ARROW_CHECK((val1) >= (val2))
100 #define DCHECK_GT(val1, val2) ARROW_CHECK((val1) > (val2))
101 
102 #endif // NDEBUG
103 
104 namespace internal {
105 
106 class NullLog {
107  public:
108  template <class T>
109  NullLog& operator<<(const T& ARROW_ARG_UNUSED(t)) {
110  return *this;
111  }
112 };
113 
114 class CerrLog {
115  public:
116  CerrLog(int severity) // NOLINT(runtime/explicit)
117  : severity_(severity), has_logged_(false) {}
118 
119  virtual ~CerrLog() {
120  if (has_logged_) {
121  std::cerr << std::endl;
122  }
123  if (severity_ == ARROW_FATAL) {
124  std::abort();
125  }
126  }
127 
128  template <class T>
129  CerrLog& operator<<(const T& t) {
130  if (severity_ != ARROW_DEBUG) {
131  has_logged_ = true;
132  std::cerr << t;
133  }
134  return *this;
135  }
136 
137  protected:
138  const int severity_;
139  bool has_logged_;
140 };
141 
142 // Clang-tidy isn't smart enough to determine that DCHECK using CerrLog doesn't
143 // return so we create a new class to give it a hint.
144 class FatalLog : public CerrLog {
145  public:
146  explicit FatalLog(int /* severity */) // NOLINT
147  : CerrLog(ARROW_FATAL) {} // NOLINT
148 
149  ARROW_NORETURN ~FatalLog() {
150  if (has_logged_) {
151  std::cerr << std::endl;
152  }
153  std::abort();
154  }
155 };
156 
157 } // namespace internal
158 
159 } // namespace arrow
160 
161 #endif // ARROW_UTIL_LOGGING_H
#define ARROW_NORETURN
Definition: macros.h:47
#define ARROW_FATAL
Definition: logging.h:39
#define ARROW_DEBUG
Definition: logging.h:35
#define ARROW_ARG_UNUSED(x)
Definition: macros.h:29
Top-level namespace for Apache Arrow C++ API.
Definition: adapter.h:32