ab859433aa67dc7cf2054ea7c70220cff0e4391c
[folly.git] / folly / experimental / logging / LogMessage.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 <sys/types.h>
19 #include <chrono>
20 #include <string>
21
22 #include <folly/Range.h>
23 #include <folly/experimental/logging/LogLevel.h>
24
25 namespace folly {
26
27 class LogCategory;
28
29 /**
30  * LogMessage represents a single message to be logged.
31  *
32  * LogMessage objects are relatively temporary objects, that only exist for the
33  * time it takes to invoke all of the appropriate LogHandlers.  These generally
34  * only live in the thread that logged the message, and are not modified once
35  * created.  (That said, LogHandler implementations may copy and store
36  * LogMessage objects for later use if desired.)
37  */
38 class LogMessage {
39  public:
40   LogMessage(
41       const LogCategory* category,
42       LogLevel level,
43       folly::StringPiece filename,
44       unsigned int lineNumber,
45       std::string&& msg);
46   LogMessage(
47       const LogCategory* category,
48       LogLevel level,
49       folly::StringPiece filename,
50       unsigned int lineNumber,
51       folly::StringPiece msg)
52       : LogMessage(category, level, filename, lineNumber, msg.str()) {}
53
54   /**
55    * Construct a LogMessage with an explicit timestamp.
56    * This is primarily intended for use in unit tests, so the tests can get
57    * deterministic behavior with regards to timestamps.
58    */
59   LogMessage(
60       const LogCategory* category,
61       LogLevel level,
62       std::chrono::system_clock::time_point timestamp,
63       folly::StringPiece filename,
64       unsigned int lineNumber,
65       std::string&& msg);
66
67   const LogCategory* getCategory() const {
68     return category_;
69   }
70
71   LogLevel getLevel() const {
72     return level_;
73   }
74
75   folly::StringPiece getFileName() const {
76     return filename_;
77   }
78   folly::StringPiece getFileBaseName() const;
79
80   unsigned int getLineNumber() const {
81     return lineNumber_;
82   }
83
84   std::chrono::system_clock::time_point getTimestamp() const {
85     return timestamp_;
86   }
87
88   uint64_t getThreadID() const {
89     return threadID_;
90   }
91
92   const std::string& getMessage() const {
93     // If no characters needed to be sanitized, message_ will be empty.
94     if (message_.empty()) {
95       return rawMessage_;
96     }
97     return message_;
98   }
99
100   const std::string& getRawMessage() const {
101     return rawMessage_;
102   }
103
104   bool containsNewlines() const {
105     return containsNewlines_;
106   }
107
108  private:
109   void sanitizeMessage();
110
111   const LogCategory* const category_{nullptr};
112   LogLevel const level_{static_cast<LogLevel>(0)};
113   uint64_t const threadID_{0};
114   std::chrono::system_clock::time_point const timestamp_;
115
116   /**
117    * The name of the source file that generated this log message.
118    */
119   folly::StringPiece const filename_;
120
121   /**
122    * The line number in the source file that generated this log message.
123    */
124   unsigned int const lineNumber_{0};
125
126   /**
127    * containsNewlines_ will be true if the message contains internal newlines.
128    *
129    * This allows log handlers that perform special handling of multi-line
130    * messages to easily detect if a message contains multiple lines or not.
131    */
132   bool containsNewlines_{false};
133
134   /**
135    * rawMessage_ contains the original message.
136    *
137    * This may contain arbitrary binary data, including unprintable characters
138    * and nul bytes.
139    */
140   std::string const rawMessage_;
141
142   /**
143    * message_ contains a sanitized version of the log message.
144    *
145    * nul bytes and unprintable characters have been escaped.
146    * This message may still contain newlines, however.  LogHandler classes
147    * are responsible for deciding how they want to handle log messages with
148    * internal newlines.
149    */
150   std::string message_;
151 };
152 }