1 // Copyright 2022 The Abseil Authors. 2 // 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 // https://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 // File: log/internal/nullstream.h 17 // ----------------------------------------------------------------------------- 18 // 19 // Classes `NullStream`, `NullStreamMaybeFatal ` and `NullStreamFatal` 20 // implement a subset of the `LogMessage` API and are used instead when logging 21 // of messages has been disabled. 22 23 #ifndef ABSL_LOG_INTERNAL_NULLSTREAM_H_ 24 #define ABSL_LOG_INTERNAL_NULLSTREAM_H_ 25 26 #ifdef _WIN32 27 #include <cstdlib> 28 #else 29 #include <unistd.h> 30 #endif 31 #include <ios> 32 #include <ostream> 33 34 #include "absl/base/attributes.h" 35 #include "absl/base/config.h" 36 #include "absl/base/log_severity.h" 37 #include "absl/strings/string_view.h" 38 39 namespace absl { 40 ABSL_NAMESPACE_BEGIN 41 namespace log_internal { 42 43 // A `NullStream` implements the API of `LogMessage` (a few methods and 44 // `operator<<`) but does nothing. All methods are defined inline so the 45 // compiler can eliminate the whole instance and discard anything that's 46 // streamed in. 47 class NullStream { 48 public: AtLocation(absl::string_view,int)49 NullStream& AtLocation(absl::string_view, int) { return *this; } 50 template <typename SourceLocationType> AtLocation(SourceLocationType)51 NullStream& AtLocation(SourceLocationType) { 52 return *this; 53 } NoPrefix()54 NullStream& NoPrefix() { return *this; } WithVerbosity(int)55 NullStream& WithVerbosity(int) { return *this; } 56 template <typename TimeType> WithTimestamp(TimeType)57 NullStream& WithTimestamp(TimeType) { 58 return *this; 59 } 60 template <typename Tid> WithThreadID(Tid)61 NullStream& WithThreadID(Tid) { 62 return *this; 63 } 64 template <typename LogEntryType> WithMetadataFrom(const LogEntryType &)65 NullStream& WithMetadataFrom(const LogEntryType&) { 66 return *this; 67 } WithPerror()68 NullStream& WithPerror() { return *this; } 69 template <typename LogSinkType> ToSinkAlso(LogSinkType *)70 NullStream& ToSinkAlso(LogSinkType*) { 71 return *this; 72 } 73 template <typename LogSinkType> ToSinkOnly(LogSinkType *)74 NullStream& ToSinkOnly(LogSinkType*) { 75 return *this; 76 } 77 template <typename LogSinkType> OutputToSink(LogSinkType *,bool)78 NullStream& OutputToSink(LogSinkType*, bool) { 79 return *this; 80 } InternalStream()81 NullStream& InternalStream() { return *this; } Flush()82 void Flush() {} 83 }; 84 template <typename T> 85 inline NullStream& operator<<(NullStream& str, const T&) { 86 return str; 87 } 88 inline NullStream& operator<<(NullStream& str, 89 std::ostream& (*)(std::ostream& os)) { 90 return str; 91 } 92 inline NullStream& operator<<(NullStream& str, 93 std::ios_base& (*)(std::ios_base& os)) { 94 return str; 95 } 96 97 // `NullStreamMaybeFatal` implements the process termination semantics of 98 // `LogMessage`, which is used for `DFATAL` severity and expression-defined 99 // severity e.g. `LOG(LEVEL(HowBadIsIt()))`. Like `LogMessage`, it terminates 100 // the process when destroyed if the passed-in severity equals `FATAL`. 101 class NullStreamMaybeFatal final : public NullStream { 102 public: NullStreamMaybeFatal(absl::LogSeverity severity)103 explicit NullStreamMaybeFatal(absl::LogSeverity severity) 104 : fatal_(severity == absl::LogSeverity::kFatal) {} ~NullStreamMaybeFatal()105 ~NullStreamMaybeFatal() { 106 if (fatal_) { 107 _exit(1); 108 } 109 } 110 111 private: 112 bool fatal_; 113 }; 114 115 // `NullStreamFatal` implements the process termination semantics of 116 // `LogMessageFatal`, which means it always terminates the process. `DFATAL` 117 // and expression-defined severity use `NullStreamMaybeFatal` above. 118 class NullStreamFatal final : public NullStream { 119 public: 120 NullStreamFatal() = default; ~NullStreamFatal()121 [[noreturn]] ~NullStreamFatal() { _exit(1); } 122 }; 123 124 } // namespace log_internal 125 ABSL_NAMESPACE_END 126 } // namespace absl 127 128 #endif // ABSL_LOG_INTERNAL_GLOBALS_H_ 129