James Kuszmaul | ba0ac1a | 2022-08-12 16:29:30 -0700 | [diff] [blame] | 1 | Google Logging Library |
| 2 | ====================== |
| 3 | |
| 4 | |Linux Github actions| |Windows Github actions| |macOS Github actions| |Total alerts| |Language grade: C++| |Codecov| |
| 5 | |
| 6 | Google Logging (glog) is a C++98 library that implements application-level |
| 7 | logging. The library provides logging APIs based on C++-style streams and |
| 8 | various helper macros. |
| 9 | |
| 10 | .. role:: cmake(code) |
| 11 | :language: cmake |
| 12 | |
| 13 | .. role:: cmd(code) |
| 14 | :language: bash |
| 15 | |
| 16 | .. role:: cpp(code) |
| 17 | :language: cpp |
| 18 | |
| 19 | .. role:: bazel(code) |
| 20 | :language: starlark |
| 21 | |
| 22 | |
| 23 | Getting Started |
| 24 | --------------- |
| 25 | |
| 26 | You can log a message by simply streaming things to ``LOG``\ (<a |
| 27 | particular `severity level <#severity-levels>`__>), e.g., |
| 28 | |
| 29 | .. code:: cpp |
| 30 | |
| 31 | #include <glog/logging.h> |
| 32 | |
| 33 | int main(int argc, char* argv[]) { |
| 34 | // Initialize Google’s logging library. |
| 35 | google::InitGoogleLogging(argv[0]); |
| 36 | |
| 37 | // ... |
| 38 | LOG(INFO) << "Found " << num_cookies << " cookies"; |
| 39 | } |
| 40 | |
| 41 | |
| 42 | For a detailed overview of glog features and their usage, please refer |
| 43 | to the `user guide <#user-guide>`__. |
| 44 | |
| 45 | .. contents:: Table of Contents |
| 46 | |
| 47 | |
| 48 | Building from Source |
| 49 | -------------------- |
| 50 | |
| 51 | glog supports multiple build systems for compiling the project from |
| 52 | source: `Bazel <#bazel>`__, `CMake <#cmake>`__, and `vcpkg <#vcpkg>`__. |
| 53 | |
| 54 | Bazel |
| 55 | ~~~~~ |
| 56 | |
| 57 | To use glog within a project which uses the |
| 58 | `Bazel <https://bazel.build/>`__ build tool, add the following lines to |
| 59 | your ``WORKSPACE`` file: |
| 60 | |
| 61 | .. code:: bazel |
| 62 | |
| 63 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") |
| 64 | |
| 65 | http_archive( |
| 66 | name = "com_github_gflags_gflags", |
| 67 | sha256 = "34af2f15cf7367513b352bdcd2493ab14ce43692d2dcd9dfc499492966c64dcf", |
| 68 | strip_prefix = "gflags-2.2.2", |
| 69 | urls = ["https://github.com/gflags/gflags/archive/v2.2.2.tar.gz"], |
| 70 | ) |
| 71 | |
| 72 | http_archive( |
| 73 | name = "com_github_google_glog", |
| 74 | sha256 = "122fb6b712808ef43fbf80f75c52a21c9760683dae470154f02bddfc61135022", |
| 75 | strip_prefix = "glog-0.6.0", |
| 76 | urls = ["https://github.com/google/glog/archive/v0.6.0.zip"], |
| 77 | ) |
| 78 | |
| 79 | You can then add :bazel:`@com_github_google_glog//:glog` to the deps section |
| 80 | of a :bazel:`cc_binary` or :bazel:`cc_library` rule, and :code:`#include |
| 81 | <glog/logging.h>` to include it in your source code. Here’s a simple example: |
| 82 | |
| 83 | .. code:: bazel |
| 84 | |
| 85 | cc_binary( |
| 86 | name = "main", |
| 87 | srcs = ["main.cc"], |
| 88 | deps = ["@com_github_google_glog//:glog"], |
| 89 | ) |
| 90 | |
| 91 | CMake |
| 92 | ~~~~~ |
| 93 | |
| 94 | glog also supports CMake that can be used to build the project on a wide |
| 95 | range of platforms. If you don’t have CMake installed already, you can |
| 96 | download it for from CMake’s `official |
| 97 | website <http://www.cmake.org>`__. |
| 98 | |
| 99 | CMake works by generating native makefiles or build projects that can be |
| 100 | used in the compiler environment of your choice. You can either build |
| 101 | glog with CMake as a standalone project or it can be incorporated into |
| 102 | an existing CMake build for another project. |
| 103 | |
| 104 | Building glog with CMake |
| 105 | ^^^^^^^^^^^^^^^^^^^^^^^^ |
| 106 | |
| 107 | When building glog as a standalone project, on Unix-like systems with |
| 108 | GNU Make as build tool, the typical workflow is: |
| 109 | |
| 110 | 1. Get the source code and change to it. e.g., cloning with git: |
| 111 | |
| 112 | .. code:: bash |
| 113 | |
| 114 | git clone https://github.com/google/glog.git |
| 115 | cd glog |
| 116 | |
| 117 | 2. Run CMake to configure the build tree. |
| 118 | |
| 119 | .. code:: bash |
| 120 | |
| 121 | cmake -S . -B build -G "Unix Makefiles" |
| 122 | |
| 123 | CMake provides different generators, and by default will pick the most |
| 124 | relevant one to your environment. If you need a specific version of Visual |
| 125 | Studio, use :cmd:`cmake . -G <generator-name>`, and see :cmd:`cmake --help` |
| 126 | for the available generators. Also see :cmd:`-T <toolset-name>`, which can |
| 127 | be used to request the native x64 toolchain with :cmd:`-T host=x64`. |
| 128 | |
| 129 | 3. Afterwards, generated files can be used to compile the project. |
| 130 | |
| 131 | .. code:: bash |
| 132 | |
| 133 | cmake --build build |
| 134 | |
| 135 | 4. Test the build software (optional). |
| 136 | |
| 137 | .. code:: bash |
| 138 | |
| 139 | cmake --build build --target test |
| 140 | |
| 141 | 5. Install the built files (optional). |
| 142 | |
| 143 | .. code:: bash |
| 144 | |
| 145 | cmake --build build --target install |
| 146 | |
| 147 | Consuming glog in a CMake Project |
| 148 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 149 | |
| 150 | If you have glog installed in your system, you can use the CMake command |
| 151 | :cmake:`find_package` to build against glog in your CMake Project as follows: |
| 152 | |
| 153 | .. code:: cmake |
| 154 | |
| 155 | cmake_minimum_required (VERSION 3.16) |
| 156 | project (myproj VERSION 1.0) |
| 157 | |
| 158 | find_package (glog 0.6.0 REQUIRED) |
| 159 | |
| 160 | add_executable (myapp main.cpp) |
| 161 | target_link_libraries (myapp glog::glog) |
| 162 | |
| 163 | Compile definitions and options will be added automatically to your |
| 164 | target as needed. |
| 165 | |
| 166 | Incorporating glog into a CMake Project |
| 167 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 168 | |
| 169 | You can also use the CMake command :cmake:`add_subdirectory` to include glog |
| 170 | directly from a subdirectory of your project by replacing the |
| 171 | :cmake:`find_package` call from the previous example by |
| 172 | :cmake:`add_subdirectory`. The :cmake:`glog::glog` target is in this case an |
| 173 | :cmake:`ALIAS` library target for the ``glog`` library target. |
| 174 | |
| 175 | Again, compile definitions and options will be added automatically to |
| 176 | your target as needed. |
| 177 | |
| 178 | vcpkg |
| 179 | ~~~~~ |
| 180 | |
| 181 | You can download and install glog using the `vcpkg |
| 182 | <https://github.com/Microsoft/vcpkg>`__ dependency manager: |
| 183 | |
| 184 | .. code:: bash |
| 185 | |
| 186 | git clone https://github.com/Microsoft/vcpkg.git |
| 187 | cd vcpkg |
| 188 | ./bootstrap-vcpkg.sh |
| 189 | ./vcpkg integrate install |
| 190 | ./vcpkg install glog |
| 191 | |
| 192 | The glog port in vcpkg is kept up to date by Microsoft team members and |
| 193 | community contributors. If the version is out of date, please create an |
| 194 | issue or pull request on the vcpkg repository. |
| 195 | |
| 196 | User Guide |
| 197 | ---------- |
| 198 | |
| 199 | glog defines a series of macros that simplify many common logging tasks. |
| 200 | You can log messages by severity level, control logging behavior from |
| 201 | the command line, log based on conditionals, abort the program when |
| 202 | expected conditions are not met, introduce your own verbose logging |
| 203 | levels, customize the prefix attached to log messages, and more. |
| 204 | |
| 205 | Following sections describe the functionality supported by glog. Please note |
| 206 | this description may not be complete but limited to the most useful ones. If you |
| 207 | want to find less common features, please check header files under `src/glog |
| 208 | <src/glog>`__ directory. |
| 209 | |
| 210 | Severity Levels |
| 211 | ~~~~~~~~~~~~~~~ |
| 212 | |
| 213 | You can specify one of the following severity levels (in increasing |
| 214 | order of severity): ``INFO``, ``WARNING``, ``ERROR``, and ``FATAL``. |
| 215 | Logging a ``FATAL`` message terminates the program (after the message is |
| 216 | logged). Note that messages of a given severity are logged not only in |
| 217 | the logfile for that severity, but also in all logfiles of lower |
| 218 | severity. E.g., a message of severity ``FATAL`` will be logged to the |
| 219 | logfiles of severity ``FATAL``, ``ERROR``, ``WARNING``, and ``INFO``. |
| 220 | |
| 221 | The ``DFATAL`` severity logs a ``FATAL`` error in debug mode (i.e., |
| 222 | there is no ``NDEBUG`` macro defined), but avoids halting the program in |
| 223 | production by automatically reducing the severity to ``ERROR``. |
| 224 | |
| 225 | Unless otherwise specified, glog writes to the filename |
| 226 | ``/tmp/\<program name\>.\<hostname\>.\<user name\>.log.\<severity level\>.\<date\>-\<time\>.\<pid\>`` |
| 227 | (e.g., |
| 228 | ``/tmp/hello_world.example.com.hamaji.log.INFO.20080709-222411.10474``). |
| 229 | By default, glog copies the log messages of severity level ``ERROR`` or |
| 230 | ``FATAL`` to standard error (``stderr``) in addition to log files. |
| 231 | |
| 232 | Setting Flags |
| 233 | ~~~~~~~~~~~~~ |
| 234 | |
| 235 | Several flags influence glog’s output behavior. If the `Google gflags library |
| 236 | <https://github.com/gflags/gflags>`__ is installed on your machine, the build |
| 237 | system will automatically detect and use it, allowing you to pass flags on the |
| 238 | command line. For example, if you want to turn the flag :cmd:`--logtostderr` on, |
| 239 | you can start your application with the following command line: |
| 240 | |
| 241 | .. code:: bash |
| 242 | |
| 243 | ./your_application --logtostderr=1 |
| 244 | |
| 245 | If the Google gflags library isn’t installed, you set flags via |
| 246 | environment variables, prefixing the flag name with ``GLOG_``, e.g., |
| 247 | |
| 248 | .. code:: bash |
| 249 | |
| 250 | GLOG_logtostderr=1 ./your_application |
| 251 | |
| 252 | The following flags are most commonly used: |
| 253 | |
| 254 | ``logtostderr`` (``bool``, default=\ ``false``) |
| 255 | Log messages to ``stderr`` instead of logfiles. Note: you can set |
| 256 | binary flags to ``true`` by specifying ``1``, ``true``, or ``yes`` |
| 257 | (case insensitive). Also, you can set binary flags to ``false`` by |
| 258 | specifying ``0``, ``false``, or ``no`` (again, case insensitive). |
| 259 | |
| 260 | ``stderrthreshold`` (``int``, default=2, which is ``ERROR``) |
| 261 | Copy log messages at or above this level to stderr in addition to |
| 262 | logfiles. The numbers of severity levels ``INFO``, ``WARNING``, |
| 263 | ``ERROR``, and ``FATAL`` are 0, 1, 2, and 3, respectively. |
| 264 | |
| 265 | ``minloglevel`` (``int``, default=0, which is ``INFO``) |
| 266 | Log messages at or above this level. Again, the numbers of severity |
| 267 | levels ``INFO``, ``WARNING``, ``ERROR``, and ``FATAL`` are 0, 1, 2, |
| 268 | and 3, respectively. |
| 269 | |
| 270 | ``log_dir`` (``string``, default="") |
| 271 | If specified, logfiles are written into this directory instead of the |
| 272 | default logging directory. |
| 273 | |
| 274 | ``v`` (``int``, default=0) |
| 275 | Show all ``VLOG(m)`` messages for ``m`` less or equal the value of |
| 276 | this flag. Overridable by :cmd:`--vmodule`. See `the section about |
| 277 | verbose logging <#verbose-logging>`__ for more detail. |
| 278 | |
| 279 | ``vmodule`` (``string``, default="") |
| 280 | Per-module verbose level. The argument has to contain a |
| 281 | comma-separated list of <module name>=<log level>. <module name> is a |
| 282 | glob pattern (e.g., ``gfs*`` for all modules whose name starts with |
| 283 | "gfs"), matched against the filename base (that is, name ignoring |
| 284 | .cc/.h./-inl.h). <log level> overrides any value given by :cmd:`--v`. |
| 285 | See also `the section about verbose logging <#verbose-logging>`__. |
| 286 | |
| 287 | There are some other flags defined in logging.cc. Please grep the source |
| 288 | code for ``DEFINE_`` to see a complete list of all flags. |
| 289 | |
| 290 | You can also modify flag values in your program by modifying global |
| 291 | variables ``FLAGS_*`` . Most settings start working immediately after |
| 292 | you update ``FLAGS_*`` . The exceptions are the flags related to |
| 293 | destination files. For example, you might want to set ``FLAGS_log_dir`` |
| 294 | before calling :cpp:`google::InitGoogleLogging` . Here is an example: |
| 295 | |
| 296 | .. code:: cpp |
| 297 | |
| 298 | LOG(INFO) << "file"; |
| 299 | // Most flags work immediately after updating values. |
| 300 | FLAGS_logtostderr = 1; |
| 301 | LOG(INFO) << "stderr"; |
| 302 | FLAGS_logtostderr = 0; |
| 303 | // This won’t change the log destination. If you want to set this |
| 304 | // value, you should do this before google::InitGoogleLogging . |
| 305 | FLAGS_log_dir = "/some/log/directory"; |
| 306 | LOG(INFO) << "the same file"; |
| 307 | |
| 308 | Conditional / Occasional Logging |
| 309 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 310 | |
| 311 | Sometimes, you may only want to log a message under certain conditions. |
| 312 | You can use the following macros to perform conditional logging: |
| 313 | |
| 314 | .. code:: cpp |
| 315 | |
| 316 | LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; |
| 317 | |
| 318 | The "Got lots of cookies" message is logged only when the variable |
| 319 | ``num_cookies`` exceeds 10. If a line of code is executed many times, it |
| 320 | may be useful to only log a message at certain intervals. This kind of |
| 321 | logging is most useful for informational messages. |
| 322 | |
| 323 | .. code:: cpp |
| 324 | |
| 325 | LOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie"; |
| 326 | |
| 327 | The above line outputs a log messages on the 1st, 11th, 21st, ... times |
| 328 | it is executed. Note that the special ``google::COUNTER`` value is used |
| 329 | to identify which repetition is happening. |
| 330 | |
| 331 | You can combine conditional and occasional logging with the following |
| 332 | macro. |
| 333 | |
| 334 | .. code:: cpp |
| 335 | |
| 336 | LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << google::COUNTER |
| 337 | << "th big cookie"; |
| 338 | |
| 339 | Instead of outputting a message every nth time, you can also limit the |
| 340 | output to the first n occurrences: |
| 341 | |
| 342 | .. code:: cpp |
| 343 | |
| 344 | LOG_FIRST_N(INFO, 20) << "Got the " << google::COUNTER << "th cookie"; |
| 345 | |
| 346 | Outputs log messages for the first 20 times it is executed. Again, the |
| 347 | ``google::COUNTER`` identifier indicates which repetition is happening. |
| 348 | |
| 349 | Other times, it is desired to only log a message periodically based on a time. |
| 350 | So for example, to log a message every 10ms: |
| 351 | |
| 352 | .. code:: cpp |
| 353 | |
| 354 | LOG_EVERY_T(INFO, 0.01) << "Got a cookie"; |
| 355 | |
| 356 | Or every 2.35s: |
| 357 | |
| 358 | .. code:: cpp |
| 359 | |
| 360 | LOG_EVERY_T(INFO, 2.35) << "Got a cookie"; |
| 361 | |
| 362 | Debug Mode Support |
| 363 | ~~~~~~~~~~~~~~~~~~ |
| 364 | |
| 365 | Special "debug mode" logging macros only have an effect in debug mode |
| 366 | and are compiled away to nothing for non-debug mode compiles. Use these |
| 367 | macros to avoid slowing down your production application due to |
| 368 | excessive logging. |
| 369 | |
| 370 | .. code:: cpp |
| 371 | |
| 372 | DLOG(INFO) << "Found cookies"; |
| 373 | DLOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; |
| 374 | DLOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie"; |
| 375 | |
| 376 | |
| 377 | ``CHECK`` Macros |
| 378 | ~~~~~~~~~~~~~~~~ |
| 379 | |
| 380 | It is a good practice to check expected conditions in your program |
| 381 | frequently to detect errors as early as possible. The ``CHECK`` macro |
| 382 | provides the ability to abort the application when a condition is not |
| 383 | met, similar to the ``assert`` macro defined in the standard C library. |
| 384 | |
| 385 | ``CHECK`` aborts the application if a condition is not true. Unlike |
| 386 | ``assert``, it is \*not\* controlled by ``NDEBUG``, so the check will be |
| 387 | executed regardless of compilation mode. Therefore, ``fp->Write(x)`` in |
| 388 | the following example is always executed: |
| 389 | |
| 390 | .. code:: cpp |
| 391 | |
| 392 | CHECK(fp->Write(x) == 4) << "Write failed!"; |
| 393 | |
| 394 | There are various helper macros for equality/inequality checks - |
| 395 | ``CHECK_EQ``, ``CHECK_NE``, ``CHECK_LE``, ``CHECK_LT``, ``CHECK_GE``, |
| 396 | and ``CHECK_GT``. They compare two values, and log a ``FATAL`` message |
| 397 | including the two values when the result is not as expected. The values |
| 398 | must have :cpp:`operator<<(ostream, ...)` defined. |
| 399 | |
| 400 | You may append to the error message like so: |
| 401 | |
| 402 | .. code:: cpp |
| 403 | |
| 404 | CHECK_NE(1, 2) << ": The world must be ending!"; |
| 405 | |
| 406 | We are very careful to ensure that each argument is evaluated exactly |
| 407 | once, and that anything which is legal to pass as a function argument is |
| 408 | legal here. In particular, the arguments may be temporary expressions |
| 409 | which will end up being destroyed at the end of the apparent statement, |
| 410 | for example: |
| 411 | |
| 412 | .. code:: cpp |
| 413 | |
| 414 | CHECK_EQ(string("abc")[1], ’b’); |
| 415 | |
| 416 | The compiler reports an error if one of the arguments is a pointer and the other |
| 417 | is :cpp:`NULL`. To work around this, simply :cpp:`static_cast` :cpp:`NULL` to |
| 418 | the type of the desired pointer. |
| 419 | |
| 420 | .. code:: cpp |
| 421 | |
| 422 | CHECK_EQ(some_ptr, static_cast<SomeType*>(NULL)); |
| 423 | |
| 424 | Better yet, use the ``CHECK_NOTNULL`` macro: |
| 425 | |
| 426 | .. code:: cpp |
| 427 | |
| 428 | CHECK_NOTNULL(some_ptr); |
| 429 | some_ptr->DoSomething(); |
| 430 | |
| 431 | Since this macro returns the given pointer, this is very useful in |
| 432 | constructor initializer lists. |
| 433 | |
| 434 | .. code:: cpp |
| 435 | |
| 436 | struct S { |
| 437 | S(Something* ptr) : ptr_(CHECK_NOTNULL(ptr)) {} |
| 438 | Something* ptr_; |
| 439 | }; |
| 440 | |
| 441 | Note that you cannot use this macro as a C++ stream due to this feature. |
| 442 | Please use ``CHECK_EQ`` described above to log a custom message before |
| 443 | aborting the application. |
| 444 | |
| 445 | If you are comparing C strings (:cpp:`char *`), a handy set of macros performs |
| 446 | case sensitive as well as case insensitive comparisons - ``CHECK_STREQ``, |
| 447 | ``CHECK_STRNE``, ``CHECK_STRCASEEQ``, and ``CHECK_STRCASENE``. The CASE versions |
| 448 | are case-insensitive. You can safely pass :cpp:`NULL` pointers for this macro. They |
| 449 | treat :cpp:`NULL` and any non-:cpp:`NULL` string as not equal. Two :cpp:`NULL`\ |
| 450 | s are equal. |
| 451 | |
| 452 | Note that both arguments may be temporary strings which are destructed |
| 453 | at the end of the current "full expression" (e.g., |
| 454 | :cpp:`CHECK_STREQ(Foo().c_str(), Bar().c_str())` where ``Foo`` and ``Bar`` |
| 455 | return C++’s :cpp:`std::string`). |
| 456 | |
| 457 | The ``CHECK_DOUBLE_EQ`` macro checks the equality of two floating point |
| 458 | values, accepting a small error margin. ``CHECK_NEAR`` accepts a third |
| 459 | floating point argument, which specifies the acceptable error margin. |
| 460 | |
| 461 | Verbose Logging |
| 462 | ~~~~~~~~~~~~~~~ |
| 463 | |
| 464 | When you are chasing difficult bugs, thorough log messages are very useful. |
| 465 | However, you may want to ignore too verbose messages in usual development. For |
| 466 | such verbose logging, glog provides the ``VLOG`` macro, which allows you to |
| 467 | define your own numeric logging levels. The :cmd:`--v` command line option |
| 468 | controls which verbose messages are logged: |
| 469 | |
| 470 | .. code:: cpp |
| 471 | |
| 472 | VLOG(1) << "I’m printed when you run the program with --v=1 or higher"; |
| 473 | VLOG(2) << "I’m printed when you run the program with --v=2 or higher"; |
| 474 | |
| 475 | With ``VLOG``, the lower the verbose level, the more likely messages are to be |
| 476 | logged. For example, if :cmd:`--v==1`, ``VLOG(1)`` will log, but ``VLOG(2)`` |
| 477 | will not log. This is opposite of the severity level, where ``INFO`` is 0, and |
| 478 | ``ERROR`` is 2. :cmd:`--minloglevel` of 1 will log ``WARNING`` and above. Though |
| 479 | you can specify any integers for both ``VLOG`` macro and :cmd:`--v` flag, the |
| 480 | common values for them are small positive integers. For example, if you write |
| 481 | ``VLOG(0)``, you should specify :cmd:`--v=-1` or lower to silence it. This is |
| 482 | less useful since we may not want verbose logs by default in most cases. The |
| 483 | ``VLOG`` macros always log at the ``INFO`` log level (when they log at all). |
| 484 | |
| 485 | Verbose logging can be controlled from the command line on a per-module |
| 486 | basis: |
| 487 | |
| 488 | .. code:: bash |
| 489 | |
| 490 | --vmodule=mapreduce=2,file=1,gfs*=3 --v=0 |
| 491 | |
| 492 | will: |
| 493 | |
| 494 | (a) Print ``VLOG(2)`` and lower messages from mapreduce.{h,cc} |
| 495 | (b) Print ``VLOG(1)`` and lower messages from file.{h,cc} |
| 496 | (c) Print ``VLOG(3)`` and lower messages from files prefixed with "gfs" |
| 497 | (d) Print ``VLOG(0)`` and lower messages from elsewhere |
| 498 | |
| 499 | The wildcarding functionality shown by (c) supports both ’*’ (matches 0 |
| 500 | or more characters) and ’?’ (matches any single character) wildcards. |
| 501 | Please also check the section about `command line flags <#setting-flags>`__. |
| 502 | |
| 503 | There’s also ``VLOG_IS_ON(n)`` "verbose level" condition macro. This |
| 504 | macro returns true when the :cmd:`--v` is equal or greater than ``n``. To |
| 505 | be used as |
| 506 | |
| 507 | .. code:: cpp |
| 508 | |
| 509 | if (VLOG_IS_ON(2)) { |
| 510 | // do some logging preparation and logging |
| 511 | // that can’t be accomplished with just VLOG(2) << ...; |
| 512 | } |
| 513 | |
| 514 | Verbose level condition macros ``VLOG_IF``, ``VLOG_EVERY_N`` and |
| 515 | ``VLOG_IF_EVERY_N`` behave analogous to ``LOG_IF``, ``LOG_EVERY_N``, |
| 516 | ``LOF_IF_EVERY``, but accept a numeric verbosity level as opposed to a |
| 517 | severity level. |
| 518 | |
| 519 | .. code:: cpp |
| 520 | |
| 521 | VLOG_IF(1, (size > 1024)) |
| 522 | << "I’m printed when size is more than 1024 and when you run the " |
| 523 | "program with --v=1 or more"; |
| 524 | VLOG_EVERY_N(1, 10) |
| 525 | << "I’m printed every 10th occurrence, and when you run the program " |
| 526 | "with --v=1 or more. Present occurence is " << google::COUNTER; |
| 527 | VLOG_IF_EVERY_N(1, (size > 1024), 10) |
| 528 | << "I’m printed on every 10th occurence of case when size is more " |
| 529 | " than 1024, when you run the program with --v=1 or more. "; |
| 530 | "Present occurence is " << google::COUNTER; |
| 531 | |
| 532 | |
| 533 | Custom Log Prefix Format |
| 534 | ~~~~~~~~~~~~~~~~~~~~~~~~ |
| 535 | |
| 536 | glog supports changing the format of the prefix attached to log messages by |
| 537 | receiving a user-provided callback to be used to generate such strings. That |
| 538 | feature must be enabled at compile time by the ``WITH_CUSTOM_PREFIX`` flag. |
| 539 | |
| 540 | For each log entry, the callback will be invoked with a ``LogMessageInfo`` |
| 541 | struct containing the severity, filename, line number, thread ID, and time of |
| 542 | the event. It will also be given a reference to the output stream, whose |
| 543 | contents will be prepended to the actual message in the final log line. |
| 544 | |
| 545 | For example: |
| 546 | |
| 547 | .. code:: cpp |
| 548 | |
| 549 | /* This function writes a prefix that matches glog's default format. |
| 550 | * (The third parameter can be used to receive user-supplied data, and is |
| 551 | * NULL by default.) |
| 552 | */ |
| 553 | void CustomPrefix(std::ostream &s, const LogMessageInfo &l, void*) { |
| 554 | s << l.severity[0] |
| 555 | << setw(4) << 1900 + l.time.year() |
| 556 | << setw(2) << 1 + l.time.month() |
| 557 | << setw(2) << l.time.day() |
| 558 | << ' ' |
| 559 | << setw(2) << l.time.hour() << ':' |
| 560 | << setw(2) << l.time.min() << ':' |
| 561 | << setw(2) << l.time.sec() << "." |
| 562 | << setw(6) << l.time.usec() |
| 563 | << ' ' |
| 564 | << setfill(' ') << setw(5) |
| 565 | << l.thread_id << setfill('0') |
| 566 | << ' ' |
| 567 | << l.filename << ':' << l.line_number << "]"; |
| 568 | } |
| 569 | |
| 570 | |
| 571 | To enable the use of ``CustomPrefix()``, simply give glog a pointer to it |
| 572 | during initialization: ``InitGoogleLogging(argv[0], &CustomPrefix);``. |
| 573 | |
| 574 | Optionally, ``InitGoogleLogging()`` takes a third argument of type ``void*`` |
| 575 | to pass on to the callback function. |
| 576 | |
| 577 | Failure Signal Handler |
| 578 | ~~~~~~~~~~~~~~~~~~~~~~ |
| 579 | |
| 580 | The library provides a convenient signal handler that will dump useful |
| 581 | information when the program crashes on certain signals such as ``SIGSEGV``. The |
| 582 | signal handler can be installed by :cpp:`google::InstallFailureSignalHandler()`. |
| 583 | The following is an example of output from the signal handler. |
| 584 | |
| 585 | :: |
| 586 | |
| 587 | *** Aborted at 1225095260 (unix time) try "date -d @1225095260" if you are using GNU date *** |
| 588 | *** SIGSEGV (@0x0) received by PID 17711 (TID 0x7f893090a6f0) from PID 0; stack trace: *** |
| 589 | PC: @ 0x412eb1 TestWaitingLogSink::send() |
| 590 | @ 0x7f892fb417d0 (unknown) |
| 591 | @ 0x412eb1 TestWaitingLogSink::send() |
| 592 | @ 0x7f89304f7f06 google::LogMessage::SendToLog() |
| 593 | @ 0x7f89304f35af google::LogMessage::Flush() |
| 594 | @ 0x7f89304f3739 google::LogMessage::~LogMessage() |
| 595 | @ 0x408cf4 TestLogSinkWaitTillSent() |
| 596 | @ 0x4115de main |
| 597 | @ 0x7f892f7ef1c4 (unknown) |
| 598 | @ 0x4046f9 (unknown) |
| 599 | |
| 600 | By default, the signal handler writes the failure dump to the standard |
| 601 | error. You can customize the destination by :cpp:`InstallFailureWriter()`. |
| 602 | |
| 603 | Performance of Messages |
| 604 | ~~~~~~~~~~~~~~~~~~~~~~~ |
| 605 | |
| 606 | The conditional logging macros provided by glog (e.g., ``CHECK``, |
| 607 | ``LOG_IF``, ``VLOG``, etc.) are carefully implemented and don’t execute |
| 608 | the right hand side expressions when the conditions are false. So, the |
| 609 | following check may not sacrifice the performance of your application. |
| 610 | |
| 611 | .. code:: cpp |
| 612 | |
| 613 | CHECK(obj.ok) << obj.CreatePrettyFormattedStringButVerySlow(); |
| 614 | |
| 615 | User-defined Failure Function |
| 616 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 617 | |
| 618 | ``FATAL`` severity level messages or unsatisfied ``CHECK`` condition |
| 619 | terminate your program. You can change the behavior of the termination |
| 620 | by :cpp:`InstallFailureFunction`. |
| 621 | |
| 622 | .. code:: cpp |
| 623 | |
| 624 | void YourFailureFunction() { |
| 625 | // Reports something... |
| 626 | exit(EXIT_FAILURE); |
| 627 | } |
| 628 | |
| 629 | int main(int argc, char* argv[]) { |
| 630 | google::InstallFailureFunction(&YourFailureFunction); |
| 631 | } |
| 632 | |
| 633 | By default, glog tries to dump stacktrace and makes the program exit |
| 634 | with status 1. The stacktrace is produced only when you run the program |
| 635 | on an architecture for which glog supports stack tracing (as of |
| 636 | September 2008, glog supports stack tracing for x86 and x86_64). |
| 637 | |
| 638 | Raw Logging |
| 639 | ~~~~~~~~~~~ |
| 640 | |
| 641 | The header file ``<glog/raw_logging.h>`` can be used for thread-safe logging, |
| 642 | which does not allocate any memory or acquire any locks. Therefore, the macros |
| 643 | defined in this header file can be used by low-level memory allocation and |
| 644 | synchronization code. Please check `src/glog/raw_logging.h.in |
| 645 | <src/glog/raw_logging.h.in>`__ for detail. |
| 646 | |
| 647 | Google Style ``perror()`` |
| 648 | ~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 649 | |
| 650 | ``PLOG()`` and ``PLOG_IF()`` and ``PCHECK()`` behave exactly like their |
| 651 | ``LOG*`` and ``CHECK`` equivalents with the addition that they append a |
| 652 | description of the current state of errno to their output lines. E.g. |
| 653 | |
| 654 | .. code:: cpp |
| 655 | |
| 656 | PCHECK(write(1, NULL, 2) >= 0) << "Write NULL failed"; |
| 657 | |
| 658 | This check fails with the following error message. |
| 659 | |
| 660 | :: |
| 661 | |
| 662 | F0825 185142 test.cc:22] Check failed: write(1, NULL, 2) >= 0 Write NULL failed: Bad address [14] |
| 663 | |
| 664 | Syslog |
| 665 | ~~~~~~ |
| 666 | |
| 667 | ``SYSLOG``, ``SYSLOG_IF``, and ``SYSLOG_EVERY_N`` macros are available. |
| 668 | These log to syslog in addition to the normal logs. Be aware that |
| 669 | logging to syslog can drastically impact performance, especially if |
| 670 | syslog is configured for remote logging! Make sure you understand the |
| 671 | implications of outputting to syslog before you use these macros. In |
| 672 | general, it’s wise to use these macros sparingly. |
| 673 | |
| 674 | Strip Logging Messages |
| 675 | ~~~~~~~~~~~~~~~~~~~~~~ |
| 676 | |
| 677 | Strings used in log messages can increase the size of your binary and |
| 678 | present a privacy concern. You can therefore instruct glog to remove all |
| 679 | strings which fall below a certain severity level by using the |
| 680 | ``GOOGLE_STRIP_LOG`` macro: |
| 681 | |
| 682 | If your application has code like this: |
| 683 | |
| 684 | .. code:: cpp |
| 685 | |
| 686 | #define GOOGLE_STRIP_LOG 1 // this must go before the #include! |
| 687 | #include <glog/logging.h> |
| 688 | |
| 689 | The compiler will remove the log messages whose severities are less than |
| 690 | the specified integer value. Since ``VLOG`` logs at the severity level |
| 691 | ``INFO`` (numeric value ``0``), setting ``GOOGLE_STRIP_LOG`` to 1 or |
| 692 | greater removes all log messages associated with ``VLOG``\ s as well as |
| 693 | ``INFO`` log statements. |
| 694 | |
| 695 | Automatically Remove Old Logs |
| 696 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 697 | |
| 698 | To enable the log cleaner: |
| 699 | |
| 700 | .. code:: cpp |
| 701 | |
| 702 | google::EnableLogCleaner(3); // keep your logs for 3 days |
| 703 | |
| 704 | And then glog will check if there are overdue logs whenever a flush is |
| 705 | performed. In this example, any log file from your project whose last |
| 706 | modified time is greater than 3 days will be unlink()ed. |
| 707 | |
| 708 | This feature can be disabled at any time (if it has been enabled) |
| 709 | |
| 710 | .. code:: cpp |
| 711 | |
| 712 | google::DisableLogCleaner(); |
| 713 | |
| 714 | Notes for Windows Users |
| 715 | ~~~~~~~~~~~~~~~~~~~~~~~ |
| 716 | |
| 717 | glog defines a severity level ``ERROR``, which is also defined in |
| 718 | ``windows.h`` . You can make glog not define ``INFO``, ``WARNING``, |
| 719 | ``ERROR``, and ``FATAL`` by defining ``GLOG_NO_ABBREVIATED_SEVERITIES`` |
| 720 | before including ``glog/logging.h`` . Even with this macro, you can |
| 721 | still use the iostream like logging facilities: |
| 722 | |
| 723 | .. code:: cpp |
| 724 | |
| 725 | #define GLOG_NO_ABBREVIATED_SEVERITIES |
| 726 | #include <windows.h> |
| 727 | #include <glog/logging.h> |
| 728 | |
| 729 | // ... |
| 730 | |
| 731 | LOG(ERROR) << "This should work"; |
| 732 | LOG_IF(ERROR, x > y) << "This should be also OK"; |
| 733 | |
| 734 | However, you cannot use ``INFO``, ``WARNING``, ``ERROR``, and ``FATAL`` |
| 735 | anymore for functions defined in ``glog/logging.h`` . |
| 736 | |
| 737 | .. code:: cpp |
| 738 | |
| 739 | #define GLOG_NO_ABBREVIATED_SEVERITIES |
| 740 | #include <windows.h> |
| 741 | #include <glog/logging.h> |
| 742 | |
| 743 | // ... |
| 744 | |
| 745 | // This won’t work. |
| 746 | // google::FlushLogFiles(google::ERROR); |
| 747 | |
| 748 | // Use this instead. |
| 749 | google::FlushLogFiles(google::GLOG_ERROR); |
| 750 | |
| 751 | If you don’t need ``ERROR`` defined by ``windows.h``, there are a couple |
| 752 | of more workarounds which sometimes don’t work: |
| 753 | |
| 754 | - ``#define WIN32_LEAN_AND_MEAN`` or ``NOGDI`` **before** you |
| 755 | ``#include windows.h``. |
| 756 | - ``#undef ERROR`` **after** you ``#include windows.h`` . |
| 757 | |
| 758 | See `this |
| 759 | issue <http://code.google.com/p/google-glog/issues/detail?id=33>`__ for |
| 760 | more detail. |
| 761 | |
| 762 | |
| 763 | Installation Notes for 64-bit Linux Systems |
| 764 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 765 | |
| 766 | The glibc built-in stack-unwinder on 64-bit systems has some problems with glog. |
| 767 | (In particular, if you are using :cpp:`InstallFailureSignalHandler()`, the |
| 768 | signal may be raised in the middle of malloc, holding some malloc-related locks |
| 769 | when they invoke the stack unwinder. The built-in stack unwinder may call malloc |
| 770 | recursively, which may require the thread to acquire a lock it already holds: |
| 771 | deadlock.) |
| 772 | |
| 773 | For that reason, if you use a 64-bit system and you need |
| 774 | :cpp:`InstallFailureSignalHandler()`, we strongly recommend you install |
| 775 | ``libunwind`` before trying to configure or install google glog. |
| 776 | libunwind can be found |
| 777 | `here <http://download.savannah.nongnu.org/releases/libunwind/libunwind-snap-070410.tar.gz>`__. |
| 778 | |
| 779 | Even if you already have ``libunwind`` installed, you will probably |
| 780 | still need to install from the snapshot to get the latest version. |
| 781 | |
| 782 | Caution: if you install libunwind from the URL above, be aware that you |
| 783 | may have trouble if you try to statically link your binary with glog: |
| 784 | that is, if you link with ``gcc -static -lgcc_eh ...``. This is because |
| 785 | both ``libunwind`` and ``libgcc`` implement the same C++ exception |
| 786 | handling APIs, but they implement them differently on some platforms. |
| 787 | This is not likely to be a problem on ia64, but may be on x86-64. |
| 788 | |
| 789 | Also, if you link binaries statically, make sure that you add |
| 790 | :cmd:`-Wl,--eh-frame-hdr` to your linker options. This is required so that |
| 791 | ``libunwind`` can find the information generated by the compiler required for |
| 792 | stack unwinding. |
| 793 | |
| 794 | Using :cmd:`-static` is rare, though, so unless you know this will affect you it |
| 795 | probably won’t. |
| 796 | |
| 797 | If you cannot or do not wish to install libunwind, you can still try to |
| 798 | use two kinds of stack-unwinder: 1. glibc built-in stack-unwinder and 2. |
| 799 | frame pointer based stack-unwinder. |
| 800 | |
| 801 | 1. As we already mentioned, glibc’s unwinder has a deadlock issue. |
| 802 | However, if you don’t use :cpp:`InstallFailureSignalHandler()` or you |
| 803 | don’t worry about the rare possibilities of deadlocks, you can use |
| 804 | this stack-unwinder. If you specify no options and ``libunwind`` |
| 805 | isn’t detected on your system, the configure script chooses this |
| 806 | unwinder by default. |
| 807 | |
| 808 | 2. The frame pointer based stack unwinder requires that your |
| 809 | application, the glog library, and system libraries like libc, all be |
| 810 | compiled with a frame pointer. This is *not* the default for x86-64. |
| 811 | |
| 812 | |
| 813 | How to Contribute |
| 814 | ----------------- |
| 815 | |
| 816 | We’d love to accept your patches and contributions to this project. |
| 817 | There are a just a few small guidelines you need to follow. |
| 818 | |
| 819 | Contributor License Agreement (CLA) |
| 820 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 821 | |
| 822 | Contributions to any Google project must be accompanied by a Contributor |
| 823 | License Agreement. This is not a copyright **assignment**, it simply |
| 824 | gives Google permission to use and redistribute your contributions as |
| 825 | part of the project. |
| 826 | |
| 827 | * If you are an individual writing original source code and you’re sure |
| 828 | you own the intellectual property, then you’ll need to sign an |
| 829 | `individual |
| 830 | CLA <https://developers.google.com/open-source/cla/individual>`__. |
| 831 | * If you work for a company that wants to allow you to contribute your |
| 832 | work, then you’ll need to sign a `corporate |
| 833 | CLA <https://developers.google.com/open-source/cla/corporate>`__. |
| 834 | |
| 835 | You generally only need to submit a CLA once, so if you’ve already |
| 836 | submitted one (even if it was for a different project), you probably |
| 837 | don’t need to do it again. |
| 838 | |
| 839 | Once your CLA is submitted (or if you already submitted one for another |
| 840 | Google project), make a commit adding yourself to the |
| 841 | `AUTHORS <./AUTHORS>`__ and `CONTRIBUTORS <./CONTRIBUTORS>`__ files. This |
| 842 | commit can be part of your first `pull |
| 843 | request <https://help.github.com/articles/creating-a-pull-request>`__. |
| 844 | |
| 845 | Submitting a Patch |
| 846 | ~~~~~~~~~~~~~~~~~~ |
| 847 | |
| 848 | 1. It’s generally best to start by opening a new issue describing the |
| 849 | bug or feature you’re intending to fix. Even if you think it’s |
| 850 | relatively minor, it’s helpful to know what people are working on. |
| 851 | Mention in the initial issue that you are planning to work on that |
| 852 | bug or feature so that it can be assigned to you. |
| 853 | 2. Follow the normal process of |
| 854 | `forking <https://help.github.com/articles/fork-a-repo>`__ the |
| 855 | project, and setup a new branch to work in. It’s important that each |
| 856 | group of changes be done in separate branches in order to ensure that |
| 857 | a pull request only includes the commits related to that bug or |
| 858 | feature. |
| 859 | 3. Do your best to have `well-formed commit |
| 860 | messages <http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html>`__ |
| 861 | for each change. This provides consistency throughout the project, |
| 862 | and ensures that commit messages are able to be formatted properly by |
| 863 | various git tools. |
| 864 | 4. Finally, push the commits to your fork and submit a `pull |
| 865 | request <https://help.github.com/articles/creating-a-pull-request>`__. |
| 866 | |
| 867 | |
| 868 | .. |Linux Github actions| image:: https://github.com/google/glog/actions/workflows/linux.yml/badge.svg |
| 869 | :target: https://github.com/google/glog/actions |
| 870 | .. |Windows Github actions| image:: https://github.com/google/glog/actions/workflows/windows.yml/badge.svg |
| 871 | :target: https://github.com/google/glog/actions |
| 872 | .. |macOS Github actions| image:: https://github.com/google/glog/actions/workflows/macos.yml/badge.svg |
| 873 | :target: https://github.com/google/glog/actions |
| 874 | .. |Total alerts| image:: https://img.shields.io/lgtm/alerts/g/google/glog.svg?logo=lgtm&logoWidth=18 |
| 875 | :target: https://lgtm.com/projects/g/google/glog/alerts/ |
| 876 | .. |Language grade: C++| image:: https://img.shields.io/lgtm/grade/cpp/g/google/glog.svg?logo=lgtm&logoWidth=18) |
| 877 | :target: https://lgtm.com/projects/g/google/glog/context:cpp |
| 878 | .. |Codecov| image:: https://codecov.io/gh/google/glog/branch/master/graph/badge.svg?token=8an420vNju |
| 879 | :target: https://codecov.io/gh/google/glog |