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/log.h 17 // ----------------------------------------------------------------------------- 18 // 19 // This header declares a family of LOG macros. 20 // 21 // Basic invocation looks like this: 22 // 23 // LOG(INFO) << "Found " << num_cookies << " cookies"; 24 // 25 // Most `LOG` macros take a severity level argument. The severity levels are 26 // `INFO`, `WARNING`, `ERROR`, and `FATAL`. They are defined 27 // in absl/base/log_severity.h. 28 // * The `FATAL` severity level terminates the program with a stack trace after 29 // logging its message. Error handlers registered with `RunOnFailure` 30 // (process_state.h) are run, but exit handlers registered with `atexit(3)` 31 // are not. 32 // * The `QFATAL` pseudo-severity level is equivalent to `FATAL` but triggers 33 // quieter termination messages, e.g. without a full stack trace, and skips 34 // running registered error handlers. 35 // Some preprocessor shenanigans are used to ensure that e.g. `LOG(INFO)` has 36 // the same meaning even if a local symbol or preprocessor macro named `INFO` is 37 // defined. To specify a severity level using an expression instead of a 38 // literal, use `LEVEL(expr)`. 39 // Example: 40 // 41 // LOG(LEVEL(stale ? absl::LogSeverity::kWarning : absl::LogSeverity::kInfo)) 42 // << "Cookies are " << days << " days old"; 43 44 // `LOG` macros evaluate to an unterminated statement. The value at the end of 45 // the statement supports some chainable methods: 46 // 47 // * .AtLocation(absl::string_view file, int line) 48 // .AtLocation(absl::SourceLocation loc) 49 // Overrides the location inferred from the callsite. The string pointed to 50 // by `file` must be valid until the end of the statement. 51 // * .NoPrefix() 52 // Omits the prefix from this line. The prefix includes metadata about the 53 // logged data such as source code location and timestamp. 54 // * .WithTimestamp(absl::Time timestamp) 55 // Uses the specified timestamp instead of one collected at the time of 56 // execution. 57 // * .WithThreadID(absl::LogEntry::tid_t tid) 58 // Uses the specified thread ID instead of one collected at the time of 59 // execution. 60 // * .WithMetadataFrom(const absl::LogEntry &entry) 61 // Copies all metadata (but no data) from the specified `absl::LogEntry`. 62 // This can be used to change the severity of a message, but it has some 63 // limitations: 64 // * `ABSL_MIN_LOG_LEVEL` is evaluated against the severity passed into 65 // `LOG` (or the implicit `FATAL` level of `CHECK`). 66 // * `LOG(FATAL)` and `CHECK` terminate the process unconditionally, even if 67 // the severity is changed later. 68 // `.WithMetadataFrom(entry)` should almost always be used in combination 69 // with `LOG(LEVEL(entry.log_severity()))`. 70 // * .WithPerror() 71 // Appends to the logged message a colon, a space, a textual description of 72 // the current value of `errno` (as by `strerror(3)`), and the numerical 73 // value of `errno`. 74 // * .ToSinkAlso(absl::LogSink* sink) 75 // Sends this message to `*sink` in addition to whatever other sinks it 76 // would otherwise have been sent to. `sink` must not be null. 77 // * .ToSinkOnly(absl::LogSink* sink) 78 // Sends this message to `*sink` and no others. `sink` must not be null. 79 // 80 // No interfaces in this header are async-signal-safe; their use in signal 81 // handlers is unsupported and may deadlock your program or eat your lunch. 82 // 83 // Many logging statements are inherently conditional. For example, 84 // `LOG_IF(INFO, !foo)` does nothing if `foo` is true. Even seemingly 85 // unconditional statements like `LOG(INFO)` might be disabled at 86 // compile-time to minimize binary size or for security reasons. 87 // 88 // * Except for the condition in a `CHECK` or `QCHECK` statement, programs must 89 // not rely on evaluation of expressions anywhere in logging statements for 90 // correctness. For example, this is ok: 91 // 92 // CHECK((fp = fopen("config.ini", "r")) != nullptr); 93 // 94 // But this is probably not ok: 95 // 96 // LOG(INFO) << "Server status: " << StartServerAndReturnStatusString(); 97 // 98 // The example below is bad too; the `i++` in the `LOG_IF` condition might 99 // not be evaluated, resulting in an infinite loop: 100 // 101 // for (int i = 0; i < 1000000;) 102 // LOG_IF(INFO, i++ % 1000 == 0) << "Still working..."; 103 // 104 // * Except where otherwise noted, conditions which cause a statement not to log 105 // also cause expressions not to be evaluated. Programs may rely on this for 106 // performance reasons, e.g. by streaming the result of an expensive function 107 // call into a `DLOG` or `LOG_EVERY_N` statement. 108 // * Care has been taken to ensure that expressions are parsed by the compiler 109 // even if they are never evaluated. This means that syntax errors will be 110 // caught and variables will be considered used for the purposes of 111 // unused-variable diagnostics. For example, this statement won't compile 112 // even if `INFO`-level logging has been compiled out: 113 // 114 // int number_of_cakes = 40; 115 // LOG(INFO) << "Number of cakes: " << number_of_cake; // Note the typo! 116 // 117 // Similarly, this won't produce unused-variable compiler diagnostics even 118 // if `INFO`-level logging is compiled out: 119 // 120 // { 121 // char fox_line1[] = "Hatee-hatee-hatee-ho!"; 122 // LOG_IF(ERROR, false) << "The fox says " << fox_line1; 123 // char fox_line2[] = "A-oo-oo-oo-ooo!"; 124 // LOG(INFO) << "The fox also says " << fox_line2; 125 // } 126 // 127 // This error-checking is not perfect; for example, symbols that have been 128 // declared but not defined may not produce link errors if used in logging 129 // statements that compile away. 130 // 131 // Expressions streamed into these macros are formatted using `operator<<` just 132 // as they would be if streamed into a `std::ostream`, however it should be 133 // noted that their actual type is unspecified. 134 // 135 // To implement a custom formatting operator for a type you own, define 136 // `std::ostream& operator<<(std::ostream&, ...)` in your type's namespace (for 137 // ADL) just as you would to stream it to `std::cout`. 138 // 139 // Those macros that support streaming honor output manipulators and `fmtflag` 140 // changes that output data (e.g. `std::ends`) or control formatting of data 141 // (e.g. `std::hex` and `std::fixed`), however flushing such a stream is 142 // ignored. The message produced by a log statement is sent to registered 143 // `absl::LogSink` instances at the end of the statement; those sinks are 144 // responsible for their own flushing (e.g. to disk) semantics. 145 // 146 // Flag settings are not carried over from one `LOG` statement to the next; this 147 // is a bit different than e.g. `std::cout`: 148 // 149 // LOG(INFO) << std::hex << 0xdeadbeef; // logs "0xdeadbeef" 150 // LOG(INFO) << 0xdeadbeef; // logs "3735928559" 151 152 #ifndef ABSL_LOG_LOG_H_ 153 #define ABSL_LOG_LOG_H_ 154 155 #include "absl/log/internal/conditions.h" 156 #include "absl/log/internal/log_message.h" 157 #include "absl/log/internal/strip.h" 158 159 // LOG() 160 // 161 // `LOG` takes a single argument which is a severity level. Data streamed in 162 // comprise the logged message. 163 // Example: 164 // 165 // LOG(INFO) << "Found " << num_cookies << " cookies"; 166 #define LOG(severity) \ 167 ABSL_LOG_INTERNAL_CONDITION_##severity(STATELESS, true) \ 168 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 169 170 // PLOG() 171 // 172 // `PLOG` behaves like `LOG` except that a description of the current state of 173 // `errno` is appended to the streamed message. 174 #define PLOG(severity) \ 175 ABSL_LOG_INTERNAL_CONDITION_##severity(STATELESS, true) \ 176 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() \ 177 .WithPerror() 178 179 // DLOG() 180 // 181 // `DLOG` behaves like `LOG` in debug mode (i.e. `#ifndef NDEBUG`). Otherwise 182 // it compiles away and does nothing. Note that `DLOG(FATAL)` does not 183 // terminate the program if `NDEBUG` is defined. 184 #ifndef NDEBUG 185 #define DLOG(severity) \ 186 ABSL_LOG_INTERNAL_CONDITION_##severity(STATELESS, true) \ 187 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 188 #else 189 #define DLOG(severity) \ 190 ABSL_LOG_INTERNAL_CONDITION_##severity(STATELESS, false) \ 191 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 192 #endif 193 194 // `LOG_IF` and friends add a second argument which specifies a condition. If 195 // the condition is false, nothing is logged. 196 // Example: 197 // 198 // LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; 199 #define LOG_IF(severity, condition) \ 200 ABSL_LOG_INTERNAL_CONDITION_##severity(STATELESS, condition) \ 201 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 202 #define PLOG_IF(severity, condition) \ 203 ABSL_LOG_INTERNAL_CONDITION_##severity(STATELESS, condition) \ 204 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() \ 205 .WithPerror() 206 207 #ifndef NDEBUG 208 #define DLOG_IF(severity, condition) \ 209 ABSL_LOG_INTERNAL_CONDITION_##severity(STATELESS, condition) \ 210 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 211 #else 212 #define DLOG_IF(severity, condition) \ 213 ABSL_LOG_INTERNAL_CONDITION_##severity(STATELESS, false && (condition)) \ 214 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 215 #endif 216 217 // LOG_EVERY_N 218 // 219 // An instance of `LOG_EVERY_N` increments a hidden zero-initialized counter 220 // every time execution passes through it and logs the specified message when 221 // the counter's value is a multiple of `n`, doing nothing otherwise. Each 222 // instance has its own counter. The counter's value can be logged by streaming 223 // the symbol `COUNTER`. `LOG_EVERY_N` is thread-safe. 224 // Example: 225 // 226 // LOG_EVERY_N(WARNING, 1000) << "Got a packet with a bad CRC (" << COUNTER 227 // << " total)"; 228 #define LOG_EVERY_N(severity, n) \ 229 ABSL_LOG_INTERNAL_CONDITION_##severity(STATEFUL, true)(EveryN, n) \ 230 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 231 232 // LOG_FIRST_N 233 // 234 // `LOG_FIRST_N` behaves like `LOG_EVERY_N` except that the specified message is 235 // logged when the counter's value is less than `n`. `LOG_FIRST_N` is 236 // thread-safe. 237 #define LOG_FIRST_N(severity, n) \ 238 ABSL_LOG_INTERNAL_CONDITION_##severity(STATEFUL, true)(FirstN, n) \ 239 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 240 241 // LOG_EVERY_POW_2 242 // 243 // `LOG_EVERY_POW_2` behaves like `LOG_EVERY_N` except that the specified 244 // message is logged when the counter's value is a power of 2. 245 // `LOG_EVERY_POW_2` is thread-safe. 246 #define LOG_EVERY_POW_2(severity) \ 247 ABSL_LOG_INTERNAL_CONDITION_##severity(STATEFUL, true)(EveryPow2) \ 248 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 249 250 // LOG_EVERY_N_SEC 251 // 252 // An instance of `LOG_EVERY_N_SEC` uses a hidden state variable to log the 253 // specified message at most once every `n_seconds`. A hidden counter of 254 // executions (whether a message is logged or not) is also maintained and can be 255 // logged by streaming the symbol `COUNTER`. `LOG_EVERY_N_SEC` is thread-safe. 256 // Example: 257 // 258 // LOG_EVERY_N_SEC(INFO, 2.5) << "Got " << COUNTER << " cookies so far"; 259 #define LOG_EVERY_N_SEC(severity, n_seconds) \ 260 ABSL_LOG_INTERNAL_CONDITION_##severity(STATEFUL, true)(EveryNSec, n_seconds) \ 261 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 262 263 #define PLOG_EVERY_N(severity, n) \ 264 ABSL_LOG_INTERNAL_CONDITION_##severity(STATEFUL, true)(EveryN, n) \ 265 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() \ 266 .WithPerror() 267 268 #define PLOG_FIRST_N(severity, n) \ 269 ABSL_LOG_INTERNAL_CONDITION_##severity(STATEFUL, true)(FirstN, n) \ 270 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() \ 271 .WithPerror() 272 273 #define PLOG_EVERY_POW_2(severity) \ 274 ABSL_LOG_INTERNAL_CONDITION_##severity(STATEFUL, true)(EveryPow2) \ 275 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() \ 276 .WithPerror() 277 278 #define PLOG_EVERY_N_SEC(severity, n_seconds) \ 279 ABSL_LOG_INTERNAL_CONDITION_##severity(STATEFUL, true)(EveryNSec, n_seconds) \ 280 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() \ 281 .WithPerror() 282 283 #ifndef NDEBUG 284 #define DLOG_EVERY_N(severity, n) \ 285 ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true) \ 286 (EveryN, n) ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 287 288 #define DLOG_FIRST_N(severity, n) \ 289 ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true) \ 290 (FirstN, n) ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 291 292 #define DLOG_EVERY_POW_2(severity) \ 293 ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true) \ 294 (EveryPow2) ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 295 296 #define DLOG_EVERY_N_SEC(severity, n_seconds) \ 297 ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true) \ 298 (EveryNSec, n_seconds) ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 299 300 #else // def NDEBUG 301 #define DLOG_EVERY_N(severity, n) \ 302 ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false) \ 303 (EveryN, n) ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 304 305 #define DLOG_FIRST_N(severity, n) \ 306 ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false) \ 307 (FirstN, n) ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 308 309 #define DLOG_EVERY_POW_2(severity) \ 310 ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false) \ 311 (EveryPow2) ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 312 313 #define DLOG_EVERY_N_SEC(severity, n_seconds) \ 314 ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false) \ 315 (EveryNSec, n_seconds) ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 316 #endif // def NDEBUG 317 318 // `LOG_IF_EVERY_N` and friends behave as the corresponding `LOG_EVERY_N` 319 // but neither increment a counter nor log a message if condition is false (as 320 // `LOG_IF`). 321 // Example: 322 // 323 // LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << COUNTER 324 // << "th big cookie"; 325 #define LOG_IF_EVERY_N(severity, condition, n) \ 326 ABSL_LOG_INTERNAL_CONDITION_##severity(STATEFUL, condition)(EveryN, n) \ 327 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 328 329 #define LOG_IF_FIRST_N(severity, condition, n) \ 330 ABSL_LOG_INTERNAL_CONDITION_##severity(STATEFUL, condition)(FirstN, n) \ 331 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 332 333 #define LOG_IF_EVERY_POW_2(severity, condition) \ 334 ABSL_LOG_INTERNAL_CONDITION_##severity(STATEFUL, condition)(EveryPow2) \ 335 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 336 337 #define LOG_IF_EVERY_N_SEC(severity, condition, n_seconds) \ 338 ABSL_LOG_INTERNAL_CONDITION_##severity(STATEFUL, condition)(EveryNSec, \ 339 n_seconds) \ 340 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 341 342 #define PLOG_IF_EVERY_N(severity, condition, n) \ 343 ABSL_LOG_INTERNAL_CONDITION_##severity(STATEFUL, condition)(EveryN, n) \ 344 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() \ 345 .WithPerror() 346 347 #define PLOG_IF_FIRST_N(severity, condition, n) \ 348 ABSL_LOG_INTERNAL_CONDITION_##severity(STATEFUL, condition)(FirstN, n) \ 349 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() \ 350 .WithPerror() 351 352 #define PLOG_IF_EVERY_POW_2(severity, condition) \ 353 ABSL_LOG_INTERNAL_CONDITION_##severity(STATEFUL, condition)(EveryPow2) \ 354 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() \ 355 .WithPerror() 356 357 #define PLOG_IF_EVERY_N_SEC(severity, condition, n_seconds) \ 358 ABSL_LOG_INTERNAL_CONDITION_##severity(STATEFUL, condition)(EveryNSec, \ 359 n_seconds) \ 360 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() \ 361 .WithPerror() 362 363 #ifndef NDEBUG 364 #define DLOG_IF_EVERY_N(severity, condition, n) \ 365 ABSL_LOG_INTERNAL_CONDITION_##severity(STATEFUL, condition)(EveryN, n) \ 366 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 367 368 #define DLOG_IF_FIRST_N(severity, condition, n) \ 369 ABSL_LOG_INTERNAL_CONDITION_##severity(STATEFUL, condition)(FirstN, n) \ 370 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 371 372 #define DLOG_IF_EVERY_POW_2(severity, condition) \ 373 ABSL_LOG_INTERNAL_CONDITION_##severity(STATEFUL, condition)(EveryPow2) \ 374 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 375 376 #define DLOG_IF_EVERY_N_SEC(severity, condition, n_seconds) \ 377 ABSL_LOG_INTERNAL_CONDITION_##severity(STATEFUL, condition)(EveryNSec, \ 378 n_seconds) \ 379 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 380 381 #else // def NDEBUG 382 #define DLOG_IF_EVERY_N(severity, condition, n) \ 383 ABSL_LOG_INTERNAL_CONDITION_##severity(STATEFUL, false && (condition))( \ 384 EveryN, n) ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 385 386 #define DLOG_IF_FIRST_N(severity, condition, n) \ 387 ABSL_LOG_INTERNAL_CONDITION_##severity(STATEFUL, false && (condition))( \ 388 FirstN, n) ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 389 390 #define DLOG_IF_EVERY_POW_2(severity, condition) \ 391 ABSL_LOG_INTERNAL_CONDITION_##severity(STATEFUL, false && (condition))( \ 392 EveryPow2) ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 393 394 #define DLOG_IF_EVERY_N_SEC(severity, condition, n_seconds) \ 395 ABSL_LOG_INTERNAL_CONDITION_##severity(STATEFUL, false && (condition))( \ 396 EveryNSec, n_seconds) \ 397 ABSL_LOGGING_INTERNAL_LOG_##severity.InternalStream() 398 #endif // def NDEBUG 399 400 #endif // ABSL_LOG_LOG_H_ 401