• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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