1*9356374aSAndroid Build Coastguard Worker // Copyright 2022 The Abseil Authors. 2*9356374aSAndroid Build Coastguard Worker // 3*9356374aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); 4*9356374aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License. 5*9356374aSAndroid Build Coastguard Worker // You may obtain a copy of the License at 6*9356374aSAndroid Build Coastguard Worker // 7*9356374aSAndroid Build Coastguard Worker // https://www.apache.org/licenses/LICENSE-2.0 8*9356374aSAndroid Build Coastguard Worker // 9*9356374aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software 10*9356374aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, 11*9356374aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*9356374aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and 13*9356374aSAndroid Build Coastguard Worker // limitations under the License. 14*9356374aSAndroid Build Coastguard Worker // 15*9356374aSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------- 16*9356374aSAndroid Build Coastguard Worker // File: log/internal/nullstream.h 17*9356374aSAndroid Build Coastguard Worker // ----------------------------------------------------------------------------- 18*9356374aSAndroid Build Coastguard Worker // 19*9356374aSAndroid Build Coastguard Worker // Classes `NullStream`, `NullStreamMaybeFatal ` and `NullStreamFatal` 20*9356374aSAndroid Build Coastguard Worker // implement a subset of the `LogMessage` API and are used instead when logging 21*9356374aSAndroid Build Coastguard Worker // of messages has been disabled. 22*9356374aSAndroid Build Coastguard Worker 23*9356374aSAndroid Build Coastguard Worker #ifndef ABSL_LOG_INTERNAL_NULLSTREAM_H_ 24*9356374aSAndroid Build Coastguard Worker #define ABSL_LOG_INTERNAL_NULLSTREAM_H_ 25*9356374aSAndroid Build Coastguard Worker 26*9356374aSAndroid Build Coastguard Worker #ifdef _WIN32 27*9356374aSAndroid Build Coastguard Worker #include <cstdlib> 28*9356374aSAndroid Build Coastguard Worker #else 29*9356374aSAndroid Build Coastguard Worker #include <unistd.h> 30*9356374aSAndroid Build Coastguard Worker #endif 31*9356374aSAndroid Build Coastguard Worker #include <ios> 32*9356374aSAndroid Build Coastguard Worker #include <ostream> 33*9356374aSAndroid Build Coastguard Worker 34*9356374aSAndroid Build Coastguard Worker #include "absl/base/attributes.h" 35*9356374aSAndroid Build Coastguard Worker #include "absl/base/config.h" 36*9356374aSAndroid Build Coastguard Worker #include "absl/base/log_severity.h" 37*9356374aSAndroid Build Coastguard Worker #include "absl/strings/string_view.h" 38*9356374aSAndroid Build Coastguard Worker 39*9356374aSAndroid Build Coastguard Worker namespace absl { 40*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_BEGIN 41*9356374aSAndroid Build Coastguard Worker namespace log_internal { 42*9356374aSAndroid Build Coastguard Worker 43*9356374aSAndroid Build Coastguard Worker // A `NullStream` implements the API of `LogMessage` (a few methods and 44*9356374aSAndroid Build Coastguard Worker // `operator<<`) but does nothing. All methods are defined inline so the 45*9356374aSAndroid Build Coastguard Worker // compiler can eliminate the whole instance and discard anything that's 46*9356374aSAndroid Build Coastguard Worker // streamed in. 47*9356374aSAndroid Build Coastguard Worker class NullStream { 48*9356374aSAndroid Build Coastguard Worker public: AtLocation(absl::string_view,int)49*9356374aSAndroid Build Coastguard Worker NullStream& AtLocation(absl::string_view, int) { return *this; } 50*9356374aSAndroid Build Coastguard Worker template <typename SourceLocationType> AtLocation(SourceLocationType)51*9356374aSAndroid Build Coastguard Worker NullStream& AtLocation(SourceLocationType) { 52*9356374aSAndroid Build Coastguard Worker return *this; 53*9356374aSAndroid Build Coastguard Worker } NoPrefix()54*9356374aSAndroid Build Coastguard Worker NullStream& NoPrefix() { return *this; } WithVerbosity(int)55*9356374aSAndroid Build Coastguard Worker NullStream& WithVerbosity(int) { return *this; } 56*9356374aSAndroid Build Coastguard Worker template <typename TimeType> WithTimestamp(TimeType)57*9356374aSAndroid Build Coastguard Worker NullStream& WithTimestamp(TimeType) { 58*9356374aSAndroid Build Coastguard Worker return *this; 59*9356374aSAndroid Build Coastguard Worker } 60*9356374aSAndroid Build Coastguard Worker template <typename Tid> WithThreadID(Tid)61*9356374aSAndroid Build Coastguard Worker NullStream& WithThreadID(Tid) { 62*9356374aSAndroid Build Coastguard Worker return *this; 63*9356374aSAndroid Build Coastguard Worker } 64*9356374aSAndroid Build Coastguard Worker template <typename LogEntryType> WithMetadataFrom(const LogEntryType &)65*9356374aSAndroid Build Coastguard Worker NullStream& WithMetadataFrom(const LogEntryType&) { 66*9356374aSAndroid Build Coastguard Worker return *this; 67*9356374aSAndroid Build Coastguard Worker } WithPerror()68*9356374aSAndroid Build Coastguard Worker NullStream& WithPerror() { return *this; } 69*9356374aSAndroid Build Coastguard Worker template <typename LogSinkType> ToSinkAlso(LogSinkType *)70*9356374aSAndroid Build Coastguard Worker NullStream& ToSinkAlso(LogSinkType*) { 71*9356374aSAndroid Build Coastguard Worker return *this; 72*9356374aSAndroid Build Coastguard Worker } 73*9356374aSAndroid Build Coastguard Worker template <typename LogSinkType> ToSinkOnly(LogSinkType *)74*9356374aSAndroid Build Coastguard Worker NullStream& ToSinkOnly(LogSinkType*) { 75*9356374aSAndroid Build Coastguard Worker return *this; 76*9356374aSAndroid Build Coastguard Worker } 77*9356374aSAndroid Build Coastguard Worker template <typename LogSinkType> OutputToSink(LogSinkType *,bool)78*9356374aSAndroid Build Coastguard Worker NullStream& OutputToSink(LogSinkType*, bool) { 79*9356374aSAndroid Build Coastguard Worker return *this; 80*9356374aSAndroid Build Coastguard Worker } InternalStream()81*9356374aSAndroid Build Coastguard Worker NullStream& InternalStream() { return *this; } 82*9356374aSAndroid Build Coastguard Worker }; 83*9356374aSAndroid Build Coastguard Worker template <typename T> 84*9356374aSAndroid Build Coastguard Worker inline NullStream& operator<<(NullStream& str, const T&) { 85*9356374aSAndroid Build Coastguard Worker return str; 86*9356374aSAndroid Build Coastguard Worker } 87*9356374aSAndroid Build Coastguard Worker inline NullStream& operator<<(NullStream& str, 88*9356374aSAndroid Build Coastguard Worker std::ostream& (*)(std::ostream& os)) { 89*9356374aSAndroid Build Coastguard Worker return str; 90*9356374aSAndroid Build Coastguard Worker } 91*9356374aSAndroid Build Coastguard Worker inline NullStream& operator<<(NullStream& str, 92*9356374aSAndroid Build Coastguard Worker std::ios_base& (*)(std::ios_base& os)) { 93*9356374aSAndroid Build Coastguard Worker return str; 94*9356374aSAndroid Build Coastguard Worker } 95*9356374aSAndroid Build Coastguard Worker 96*9356374aSAndroid Build Coastguard Worker // `NullStreamMaybeFatal` implements the process termination semantics of 97*9356374aSAndroid Build Coastguard Worker // `LogMessage`, which is used for `DFATAL` severity and expression-defined 98*9356374aSAndroid Build Coastguard Worker // severity e.g. `LOG(LEVEL(HowBadIsIt()))`. Like `LogMessage`, it terminates 99*9356374aSAndroid Build Coastguard Worker // the process when destroyed if the passed-in severity equals `FATAL`. 100*9356374aSAndroid Build Coastguard Worker class NullStreamMaybeFatal final : public NullStream { 101*9356374aSAndroid Build Coastguard Worker public: NullStreamMaybeFatal(absl::LogSeverity severity)102*9356374aSAndroid Build Coastguard Worker explicit NullStreamMaybeFatal(absl::LogSeverity severity) 103*9356374aSAndroid Build Coastguard Worker : fatal_(severity == absl::LogSeverity::kFatal) {} ~NullStreamMaybeFatal()104*9356374aSAndroid Build Coastguard Worker ~NullStreamMaybeFatal() { 105*9356374aSAndroid Build Coastguard Worker if (fatal_) { 106*9356374aSAndroid Build Coastguard Worker _exit(1); 107*9356374aSAndroid Build Coastguard Worker } 108*9356374aSAndroid Build Coastguard Worker } 109*9356374aSAndroid Build Coastguard Worker 110*9356374aSAndroid Build Coastguard Worker private: 111*9356374aSAndroid Build Coastguard Worker bool fatal_; 112*9356374aSAndroid Build Coastguard Worker }; 113*9356374aSAndroid Build Coastguard Worker 114*9356374aSAndroid Build Coastguard Worker // `NullStreamFatal` implements the process termination semantics of 115*9356374aSAndroid Build Coastguard Worker // `LogMessageFatal`, which means it always terminates the process. `DFATAL` 116*9356374aSAndroid Build Coastguard Worker // and expression-defined severity use `NullStreamMaybeFatal` above. 117*9356374aSAndroid Build Coastguard Worker class NullStreamFatal final : public NullStream { 118*9356374aSAndroid Build Coastguard Worker public: 119*9356374aSAndroid Build Coastguard Worker NullStreamFatal() = default; ~NullStreamFatal()120*9356374aSAndroid Build Coastguard Worker [[noreturn]] ~NullStreamFatal() { _exit(1); } 121*9356374aSAndroid Build Coastguard Worker }; 122*9356374aSAndroid Build Coastguard Worker 123*9356374aSAndroid Build Coastguard Worker } // namespace log_internal 124*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_END 125*9356374aSAndroid Build Coastguard Worker } // namespace absl 126*9356374aSAndroid Build Coastguard Worker 127*9356374aSAndroid Build Coastguard Worker #endif // ABSL_LOG_INTERNAL_GLOBALS_H_ 128