logging: reduce the amount of code emitted for log statements
[folly.git] / folly / experimental / logging / LogStream.h
1 /*
2  * Copyright 2004-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17
18 #include <ostream>
19
20 #include <folly/experimental/logging/LogCategory.h>
21 #include <folly/experimental/logging/LogMessage.h>
22
23 namespace folly {
24
25 /**
26  * A std::streambuf implementation for use by LogStream
27  */
28 class LogStreamBuffer : public std::streambuf {
29  public:
30   LogStreamBuffer() {
31     // We intentionally do not reserve any string buffer space initially,
32     // since this will not be needed for XLOG() and XLOGF() statements
33     // that do not use the streaming API.  (e.g., XLOG(INFO, "test ", 1234) )
34   }
35
36   bool empty() const {
37     return str_.empty();
38   }
39
40   std::string extractString() {
41     str_.resize(pptr() - (&str_.front()));
42     return std::move(str_);
43   }
44
45   int_type overflow(int_type ch) override;
46
47  private:
48   enum : size_t { kInitialCapacity = 256 };
49   std::string str_;
50 };
51
52 class LogStreamProcessor;
53
54 /**
55  * A std::ostream implementation for use by the logging macros.
56  *
57  * All-in-all this is pretty similar to std::stringstream, but lets us
58  * destructively extract an rvalue-reference to the underlying string.
59  */
60 class LogStream : public std::ostream {
61  public:
62   // Explicitly declare the default constructor and destructor, but only
63   // define them in the .cpp file.  This prevents them from being inlined at
64   // each FB_LOG() or XLOG() statement.  Inlining them just causes extra code
65   // bloat, with minimal benefit--for debug log statements these never even get
66   // called in the common case where the log statement is disabled.
67   explicit LogStream(LogStreamProcessor* processor);
68   ~LogStream();
69
70   bool empty() const {
71     return buffer_.empty();
72   }
73
74   std::string extractString() {
75     return buffer_.extractString();
76   }
77
78   LogStreamProcessor* getProcessor() const {
79     return processor_;
80   }
81
82  private:
83   LogStreamBuffer buffer_;
84   LogStreamProcessor* const processor_;
85 };
86 }