| Google Logging Library |
| ====================== |
| |
| |Linux Github actions| |Windows Github actions| |macOS Github actions| |Codecov| |
| |
| Google Logging (glog) is a C++14 library that implements application-level |
| logging. The library provides logging APIs based on C++-style streams and |
| various helper macros. |
| |
| .. role:: cmake(code) |
| :language: cmake |
| |
| .. role:: cmd(code) |
| :language: bash |
| |
| .. role:: cpp(code) |
| :language: cpp |
| |
| .. role:: bazel(code) |
| :language: starlark |
| |
| |
| Getting Started |
| --------------- |
| |
| You can log a message by simply streaming things to ``LOG``\ (<a |
| particular `severity level <#severity-levels>`__>), e.g., |
| |
| .. code:: cpp |
| |
| #include <glog/logging.h> |
| |
| int main(int argc, char* argv[]) { |
| // Initialize Google’s logging library. |
| google::InitGoogleLogging(argv[0]); |
| |
| // ... |
| LOG(INFO) << "Found " << num_cookies << " cookies"; |
| } |
| |
| |
| The library can be installed using various package managers or compiled from |
| `source <#building-from-source>`__. For a detailed overview of glog features and |
| their usage, please refer to the `user guide <#user-guide>`__. |
| |
| .. pull-quote:: |
| [!IMPORTANT] |
| |
| The above example requires further `Bazel <#bazel>`__ or |
| `CMake <#usage-in-projects>`__ setup for use in own projects. |
| |
| |
| .. contents:: Table of Contents |
| |
| |
| Usage in Projects |
| ~~~~~~~~~~~~~~~~~ |
| |
| Assuming that glog was previously `built glog using CMake <#cmake>`__ or |
| installed using a package manager, you can use the CMake command |
| :cmake:`find_package` to build against glog in your CMake project as follows: |
| |
| .. code:: cmake |
| |
| cmake_minimum_required (VERSION 3.16) |
| project (myproj VERSION 1.0) |
| |
| find_package (glog 0.6.0 REQUIRED) |
| |
| add_executable (myapp main.cpp) |
| target_link_libraries (myapp glog::glog) |
| |
| |
| Compile definitions and options will be added automatically to your |
| target as needed. |
| |
| Alternatively, glog can be incorporated into using the CMake command |
| :cmake:`add_subdirectory` to include glog directly from a subdirectory of your |
| project by replacing the :cmake:`find_package` call from the previous snippet by |
| :cmake:`add_subdirectory`. The :cmake:`glog::glog` target is in this case an |
| :cmake:`ALIAS` library target for the ``glog`` library target. |
| |
| Building from Source |
| ~~~~~~~~~~~~~~~~~~~~ |
| |
| Bazel |
| ^^^^^ |
| |
| To use glog within a project which uses the |
| `Bazel <https://bazel.build/>`__ build tool, add the following lines to |
| your ``WORKSPACE`` file: |
| |
| .. code:: bazel |
| |
| load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") |
| |
| http_archive( |
| name = "com_github_gflags_gflags", |
| sha256 = "34af2f15cf7367513b352bdcd2493ab14ce43692d2dcd9dfc499492966c64dcf", |
| strip_prefix = "gflags-2.2.2", |
| urls = ["https://github.com/gflags/gflags/archive/v2.2.2.tar.gz"], |
| ) |
| |
| http_archive( |
| name = "com_github_google_glog", |
| sha256 = "122fb6b712808ef43fbf80f75c52a21c9760683dae470154f02bddfc61135022", |
| strip_prefix = "glog-0.6.0", |
| urls = ["https://github.com/google/glog/archive/v0.6.0.zip"], |
| ) |
| |
| You can then add :bazel:`@com_github_google_glog//:glog` to the deps section |
| of a :bazel:`cc_binary` or :bazel:`cc_library` rule, and :code:`#include <glog/logging.h>` |
| to include it in your source code. Here’s a simple example: |
| |
| .. code:: bazel |
| |
| cc_binary( |
| name = "main", |
| srcs = ["main.cc"], |
| deps = ["@com_github_google_glog//:glog"], |
| ) |
| |
| CMake |
| ^^^^^ |
| |
| glog can be compiled using `CMake <http://www.cmake.org>`__ on a wide range of |
| platforms. The typical workflow for building glog on a Unix-like system with |
| GNU Make as build tool is as follows: |
| |
| 1. Clone the repository and change into source directory. |
| |
| .. code:: bash |
| |
| git clone https://github.com/google/glog.git |
| cd glog |
| |
| 2. Run CMake to configure the build tree. |
| |
| .. code:: bash |
| |
| cmake -S . -B build -G "Unix Makefiles" |
| |
| CMake provides different generators, and by default will pick the most |
| relevant one to your environment. If you need a specific version of Visual |
| Studio, use :cmd:`cmake . -G <generator-name>`, and see :cmd:`cmake --help` |
| for the available generators. Also see :cmd:`-T <toolset-name>`, which can |
| be used to request the native x64 toolchain with :cmd:`-T host=x64`. |
| |
| 3. Afterwards, generated files can be used to compile the project. |
| |
| .. code:: bash |
| |
| cmake --build build |
| |
| 4. Test the build software (optional). |
| |
| .. code:: bash |
| |
| cmake --build build --target test |
| |
| 5. Install the built files (optional). |
| |
| .. code:: bash |
| |
| cmake --build build --target install |
| |
| |
| Once successfully built, glog can be |
| `integrated into own projects <#usage-in-projects>`__. |
| |
| |
| conan |
| ~~~~~ |
| |
| You can download and install glog using the `conan |
| <https://conan.io>`__ package manager: |
| |
| .. code:: bash |
| |
| pip install conan |
| conan install -r conancenter glog/<glog-version>@ |
| |
| The glog recipe in conan center is kept up to date by conan center index community |
| contributors. If the version is out of date, please create an |
| issue or pull request on the `conan-center-index |
| <https://github.com/conan-io/conan-center-index>`__ repository. |
| |
| vcpkg |
| ~~~~~ |
| |
| You can download and install glog using the `vcpkg |
| <https://github.com/Microsoft/vcpkg>`__ dependency manager: |
| |
| .. code:: bash |
| |
| git clone https://github.com/Microsoft/vcpkg.git |
| cd vcpkg |
| ./bootstrap-vcpkg.sh |
| ./vcpkg integrate install |
| ./vcpkg install glog |
| |
| The glog port in vcpkg is kept up to date by Microsoft team members and |
| community contributors. If the version is out of date, please create an |
| issue or pull request on the vcpkg repository. |
| |
| User Guide |
| ---------- |
| |
| glog defines a series of macros that simplify many common logging tasks. |
| You can log messages by severity level, control logging behavior from |
| the command line, log based on conditionals, abort the program when |
| expected conditions are not met, introduce your own verbose logging |
| levels, customize the prefix attached to log messages, and more. |
| |
| Following sections describe the functionality supported by glog. Please note |
| this description may not be complete but limited to the most useful ones. If you |
| want to find less common features, please check header files under `src/glog |
| <src/glog>`__ directory. |
| |
| Severity Levels |
| ~~~~~~~~~~~~~~~ |
| |
| You can specify one of the following severity levels (in increasing |
| order of severity): |
| |
| 1. ``INFO``, |
| 2. ``WARNING``, |
| 3. ``ERROR``, and |
| 4. ``FATAL``. |
| |
| Logging a ``FATAL`` message terminates the program (after the message is |
| logged). |
| |
| .. pull-quote:: |
| [!NOTE] |
| |
| Messages of a given severity are logged not only to corresponding severity |
| logfile but also to other logfiles of lower severity. For instance, a message |
| of severity ``FATAL`` will be logged to logfiles of severity ``FATAL``, |
| ``ERROR``, ``WARNING``, and ``INFO``. |
| |
| The ``DFATAL`` severity logs a ``FATAL`` error in debug mode (i.e., |
| there is no ``NDEBUG`` macro defined), but avoids halting the program in |
| production by automatically reducing the severity to ``ERROR``. |
| |
| Unless otherwise specified, glog uses the format |
| |
| :: |
| |
| <tmp>/<program name>.<hostname>.<user name>.log.<severity level>.<date>-<time>.<pid> |
| |
| for log filenames written to a directory designated as ``<tmp>`` and determined |
| according to the following rules. |
| |
| **Windows** |
| glog uses the |
| `GetTempPathA <https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppatha>`__ |
| API function to retrieve the directory for temporary files with a fallback to |
| |
| 1. ``C:\TMP\`` |
| 2. ``C:\TEMP\`` |
| |
| (in the order given.) |
| |
| **non-Windows** |
| The directory is determined by referencing the environment variables |
| |
| 1. ``TMPDIR`` |
| 2. ``TMP`` |
| |
| if set with a fallback to ``/tmp/``. |
| |
| The default path to a log file on Linux, for instance, could be |
| |
| :: |
| |
| /tmp/hello_world.example.com.hamaji.log.INFO.20080709-222411.10474 |
| |
| By default, glog echos ``ERROR`` and ``FATAL`` messages to standard error in |
| addition to log files. |
| |
| |
| Log Line Prefix Format |
| ~~~~~~~~~~~~~~~~~~~~~~ |
| |
| Log lines have this form: |
| |
| :: |
| |
| Lyyyymmdd hh:mm:ss.uuuuuu threadid file:line] msg... |
| |
| where the fields are defined as follows: |
| |
| ==================== ========================================================================= |
| Placeholder Meaning |
| ==================== ========================================================================= |
| ``L`` A single character, representing the log level (e.g., ``I`` for ``INFO``) |
| ``yyyy`` The year |
| ``mm`` The month (zero padded; i.e., May is ``05``) |
| ``dd`` The day (zero padded) |
| ``hh:mm:ss.uuuuuu`` Time in hours, minutes and fractional seconds |
| ``threadid`` The space-padded thread ID |
| ``file`` The file name |
| ``line`` The line number |
| ``msg`` The user-supplied message |
| ==================== ========================================================================= |
| |
| Example: |
| |
| :: |
| |
| I1103 11:57:31.739339 24395 google.cc:2341] Command line: ./some_prog |
| I1103 11:57:31.739403 24395 google.cc:2342] Process id 24395 |
| |
| .. pull-quote:: |
| [!NOTE] |
| |
| Although microseconds are useful for comparing events on a single machine, |
| clocks on different machines may not be well synchronized. Hence, use with |
| caution when comparing the low bits of timestamps from different machines. |
| |
| |
| Setting Flags |
| ~~~~~~~~~~~~~ |
| |
| Several flags influence glog’s output behavior. If the `Google gflags library |
| <https://github.com/gflags/gflags>`__ is installed on your machine, the build |
| system will automatically detect and use it, allowing you to pass flags on the |
| command line. For example, if you want to activate :cmd:`--logtostderr`, you can |
| start your application with the following command line: |
| |
| .. code:: bash |
| |
| ./your_application --logtostderr=1 |
| |
| If the Google gflags library isn’t installed, you set flags via |
| environment variables, prefixing the flag name with ``GLOG_``, e.g., |
| |
| .. code:: bash |
| |
| GLOG_logtostderr=1 ./your_application |
| |
| The following flags are most commonly used: |
| |
| ``logtostderr`` (``bool``, default=\ ``false``) |
| Log messages to ``stderr`` instead of logfiles. |
| |
| .. pull-quote:: |
| [!TIP] |
| |
| You can set boolean flags to :cpp:`true` by specifying ``1``, :cpp:`true`, |
| or ``yes``. To set boolean flags to :cpp:`false`, specify ``0``, |
| ``false``, or ``no``. In either case the spelling is case-insensitive. |
| |
| ``stderrthreshold`` (``int``, default=2, which is ``ERROR``) |
| Copy log messages at or above this level to stderr in addition to |
| logfiles. The numbers of severity levels ``INFO``, ``WARNING``, |
| ``ERROR``, and ``FATAL`` are 0, 1, 2, and 3, respectively. |
| |
| ``minloglevel`` (``int``, default=0, which is ``INFO``) |
| Log messages at or above this level. Again, the numbers of severity |
| levels ``INFO``, ``WARNING``, ``ERROR``, and ``FATAL`` are 0, 1, 2, |
| and 3, respectively. |
| |
| ``log_dir`` (``string``, default="") |
| If specified, logfiles are written into this directory instead of the |
| default logging directory. |
| |
| ``v`` (``int``, default=0) |
| Show all ``VLOG(m)`` messages for ``m`` less or equal the value of this flag. |
| Overridable by :cmd:`--vmodule`. Refer to `verbose logging <#verbose-logging>`__ |
| for more detail. |
| |
| ``vmodule`` (``string``, default="") |
| Per-module verbose level. The argument has to contain a |
| comma-separated list of ``<module name>=<log level>``. ``<module name>`` is a |
| glob pattern (e.g., ``gfs*`` for all modules whose name starts with |
| "gfs"), matched against the filename base (that is, name ignoring |
| .cc/.h./-inl.h). ``<log level>`` overrides any value given by :cmd:`--v`. |
| See also `verbose logging <#verbose-logging>`__ for more details. |
| |
| Additional flags are defined in `flags.cc <src/flags.cc>`__. Please see the |
| source for their complete list. |
| |
| You can also modify flag values in your program by modifying global |
| variables ``FLAGS_*`` . Most settings start working immediately after |
| you update ``FLAGS_*`` . The exceptions are the flags related to |
| destination files. For example, you might want to set ``FLAGS_log_dir`` |
| before calling :cpp:`google::InitGoogleLogging` . Here is an example: |
| |
| .. code:: cpp |
| |
| LOG(INFO) << "file"; |
| // Most flags work immediately after updating values. |
| FLAGS_logtostderr = 1; |
| LOG(INFO) << "stderr"; |
| FLAGS_logtostderr = 0; |
| // This won’t change the log destination. If you want to set this |
| // value, you should do this before google::InitGoogleLogging . |
| FLAGS_log_dir = "/some/log/directory"; |
| LOG(INFO) << "the same file"; |
| |
| Conditional / Occasional Logging |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| Sometimes, you may only want to log a message under certain conditions. |
| You can use the following macros to perform conditional logging: |
| |
| .. code:: cpp |
| |
| LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; |
| |
| The "Got lots of cookies" message is logged only when the variable |
| ``num_cookies`` exceeds 10. If a line of code is executed many times, it |
| may be useful to only log a message at certain intervals. This kind of |
| logging is most useful for informational messages. |
| |
| .. code:: cpp |
| |
| LOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie"; |
| |
| The above line outputs a log messages on the 1st, 11th, 21st, ... times |
| it is executed. |
| |
| .. pull-quote:: |
| [!NOTE] |
| |
| The placeholder ``google::COUNTER`` identifies the reccuring repetition. |
| |
| You can combine conditional and occasional logging with the following |
| macro. |
| |
| .. code:: cpp |
| |
| LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << google::COUNTER |
| << "th big cookie"; |
| |
| Instead of outputting a message every nth time, you can also limit the |
| output to the first n occurrences: |
| |
| .. code:: cpp |
| |
| LOG_FIRST_N(INFO, 20) << "Got the " << google::COUNTER << "th cookie"; |
| |
| Outputs log messages for the first 20 times it is executed. The |
| ``google::COUNTER`` identifier indicates which repetition is happening. |
| |
| Other times, it is desired to only log a message periodically based on a time. |
| For instance, to log a message every 10ms: |
| |
| .. code:: cpp |
| |
| LOG_EVERY_T(INFO, 0.01) << "Got a cookie"; |
| |
| Or every 2.35s: |
| |
| .. code:: cpp |
| |
| LOG_EVERY_T(INFO, 2.35) << "Got a cookie"; |
| |
| Debug Mode Support |
| ~~~~~~~~~~~~~~~~~~ |
| |
| Special "debug mode" logging macros only have an effect in debug mode |
| and are compiled away to nothing for non-debug mode compiles. Use these |
| macros to avoid slowing down your production application due to |
| excessive logging. |
| |
| .. code:: cpp |
| |
| DLOG(INFO) << "Found cookies"; |
| DLOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; |
| DLOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie"; |
| DLOG_FIRST_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie"; |
| DLOG_EVERY_T(INFO, 0.01) << "Got a cookie"; |
| |
| |
| ``CHECK`` Macros |
| ~~~~~~~~~~~~~~~~ |
| |
| It is a good practice to check expected conditions in your program |
| frequently to detect errors as early as possible. The ``CHECK`` macro |
| provides the ability to abort the application when a condition is not |
| met, similar to the ``assert`` macro defined in the standard C library. |
| |
| ``CHECK`` aborts the application if a condition is not true. Unlike |
| ``assert``, it is \*not\* controlled by ``NDEBUG``, so the check will be |
| executed regardless of compilation mode. Therefore, ``fp->Write(x)`` in |
| the following example is always executed: |
| |
| .. code:: cpp |
| |
| CHECK(fp->Write(x) == 4) << "Write failed!"; |
| |
| There are various helper macros for equality/inequality checks - |
| ``CHECK_EQ``, ``CHECK_NE``, ``CHECK_LE``, ``CHECK_LT``, ``CHECK_GE``, |
| and ``CHECK_GT``. They compare two values, and log a ``FATAL`` message |
| including the two values when the result is not as expected. The values |
| must have :cpp:`operator<<(ostream, ...)` defined. |
| |
| You may append to the error message like so: |
| |
| .. code:: cpp |
| |
| CHECK_NE(1, 2) << ": The world must be ending!"; |
| |
| We are very careful to ensure that each argument is evaluated exactly |
| once, and that anything which is legal to pass as a function argument is |
| legal here. In particular, the arguments may be temporary expressions |
| which will end up being destroyed at the end of the apparent statement, |
| for example: |
| |
| .. code:: cpp |
| |
| CHECK_EQ(string("abc")[1], ’b’); |
| |
| The compiler reports an error if one of the arguments is a pointer and the other |
| is :cpp:`nullptr`. To work around this, simply :cpp:`static_cast` :cpp:`nullptr` to |
| the type of the desired pointer. |
| |
| .. code:: cpp |
| |
| CHECK_EQ(some_ptr, static_cast<SomeType*>(nullptr)); |
| |
| Better yet, use the ``CHECK_NOTNULL`` macro: |
| |
| .. code:: cpp |
| |
| CHECK_NOTNULL(some_ptr); |
| some_ptr->DoSomething(); |
| |
| Since this macro returns the given pointer, this is very useful in |
| constructor initializer lists. |
| |
| .. code:: cpp |
| |
| struct S { |
| S(Something* ptr) : ptr_(CHECK_NOTNULL(ptr)) {} |
| Something* ptr_; |
| }; |
| |
| |
| .. pull-quote:: |
| [!WARNING] |
| |
| Due to the argument forwarding, ``CHECK_NOTNULL`` cannot be used to |
| simultaneously stream an additional custom message. To provide a custom |
| message, one can use the macro ``CHECK_EQ`` prior to the failing check. |
| |
| If you are comparing C strings (:cpp:`char *`), a handy set of macros performs |
| both case sensitive and insensitive comparisons - ``CHECK_STREQ``, |
| ``CHECK_STRNE``, ``CHECK_STRCASEEQ``, and ``CHECK_STRCASENE``. The |
| ``CHECK_*CASE*`` macro variants are case-insensitive. You can safely pass |
| :cpp:`nullptr` pointers to this macro. They treat :cpp:`nullptr` and any |
| non-:cpp:`nullptr` string as not equal. Two :cpp:`nullptr`\ s are equal. |
| |
| .. pull-quote:: |
| [!NOTE] |
| |
| Both arguments may be temporary objects which are destructed at the end of |
| the current "full expression", such as |
| |
| .. code:: cpp |
| |
| CHECK_STREQ(Foo().c_str(), Bar().c_str()); |
| |
| where ``Foo`` and ``Bar`` return :cpp:`std::string`. |
| |
| The ``CHECK_DOUBLE_EQ`` macro checks the equality of two floating point |
| values, accepting a small error margin. ``CHECK_NEAR`` accepts a third |
| floating point argument, which specifies the acceptable error margin. |
| |
| Verbose Logging |
| ~~~~~~~~~~~~~~~ |
| |
| When you are chasing difficult bugs, thorough log messages are very useful. |
| However, you may want to ignore too verbose messages in usual development. For |
| such verbose logging, glog provides the ``VLOG`` macro, which allows you to |
| define your own numeric logging levels. The :cmd:`--v` command line option |
| controls which verbose messages are logged: |
| |
| .. code:: cpp |
| |
| VLOG(1) << "I’m printed when you run the program with --v=1 or higher"; |
| VLOG(2) << "I’m printed when you run the program with --v=2 or higher"; |
| |
| With ``VLOG``, the lower the verbose level, the more likely messages are to be |
| logged. For example, if :cmd:`--v==1`, ``VLOG(1)`` will log, but ``VLOG(2)`` |
| will not log. |
| |
| .. pull-quote:: |
| [!CAUTION] |
| |
| The ``VLOG`` behavior is opposite of the severity level logging, where |
| ``INFO``, ``ERROR``, etc. are defined in increasing order and thus |
| :cmd:`--minloglevel` of 1 will only log ``WARNING`` and above. |
| |
| Though you can specify any integers for both ``VLOG`` macro and :cmd:`--v` flag, |
| the common values for them are small positive integers. For example, if you |
| write ``VLOG(0)``, you should specify :cmd:`--v=-1` or lower to silence it. This |
| is less useful since we may not want verbose logs by default in most cases. The |
| ``VLOG`` macros always log at the ``INFO`` log level (when they log at all). |
| |
| Verbose logging can be controlled from the command line on a per-module |
| basis: |
| |
| .. code:: bash |
| |
| --vmodule=mapreduce=2,file=1,gfs*=3 --v=0 |
| |
| Specifying these options will specficially: |
| |
| 1. Print ``VLOG(2)`` and lower messages from mapreduce.{h,cc} |
| 2. Print ``VLOG(1)`` and lower messages from file.{h,cc} |
| 3. Print ``VLOG(3)`` and lower messages from files prefixed with "gfs" |
| 4. Print ``VLOG(0)`` and lower messages from elsewhere |
| |
| The wildcarding functionality 3. supports both ``*`` (matches 0 |
| or more characters) and ``?`` (matches any single character) wildcards. |
| Please also refer to `command line flags <#setting-flags>`__ for more |
| information. |
| |
| There’s also ``VLOG_IS_ON(n)`` "verbose level" condition macro. This macro |
| returns ``true`` when the :cmd:`--v` is equal to or greater than ``n``. The |
| macro can be used as follows: |
| |
| .. code:: cpp |
| |
| if (VLOG_IS_ON(2)) { |
| // do some logging preparation and logging |
| // that can’t be accomplished with just VLOG(2) << ...; |
| } |
| |
| Verbose level condition macros ``VLOG_IF``, ``VLOG_EVERY_N`` and |
| ``VLOG_IF_EVERY_N`` behave analogous to ``LOG_IF``, ``LOG_EVERY_N``, |
| ``LOF_IF_EVERY``, but accept a numeric verbosity level as opposed to a |
| severity level. |
| |
| .. code:: cpp |
| |
| VLOG_IF(1, (size > 1024)) |
| << "I’m printed when size is more than 1024 and when you run the " |
| "program with --v=1 or more"; |
| VLOG_EVERY_N(1, 10) |
| << "I’m printed every 10th occurrence, and when you run the program " |
| "with --v=1 or more. Present occurrence is " << google::COUNTER; |
| VLOG_IF_EVERY_N(1, (size > 1024), 10) |
| << "I’m printed on every 10th occurrence of case when size is more " |
| " than 1024, when you run the program with --v=1 or more. "; |
| "Present occurrence is " << google::COUNTER; |
| |
| |
| Custom Log Prefix Format |
| ~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| glog supports changing the format of the prefix attached to log messages by |
| receiving a user-provided callback that generates such strings. |
| |
| For each log entry, the callback will be invoked with a ``LogMessageInfo`` |
| struct containing the severity, filename, line number, thread ID, and time of |
| the event. It will also be given a reference to the output stream, whose |
| contents will be prepended to the actual message in the final log line. |
| |
| For example, the following function outputs a prefix that matches glog's default |
| format. The third parameter ``data`` can be used to access user-supplied data |
| which unless specified defaults to :cpp:`nullptr`. |
| |
| .. code:: cpp |
| |
| void CustomPrefix(std::ostream& s, const LogMessageInfo& l, void* /*data*/) { |
| s << l.severity[0] |
| << setw(4) << 1900 + l.time.year() |
| << setw(2) << 1 + l.time.month() |
| << setw(2) << l.time.day() |
| << ' ' |
| << setw(2) << l.time.hour() << ':' |
| << setw(2) << l.time.min() << ':' |
| << setw(2) << l.time.sec() << "." |
| << setw(6) << l.time.usec() |
| << ' ' |
| << setfill(' ') << setw(5) |
| << l.thread_id << setfill('0') |
| << ' ' |
| << l.filename << ':' << l.line_number << "]"; |
| } |
| |
| |
| To enable the use of a custom prefix, use the |
| |
| .. code:: cpp |
| |
| InitGoogleLogging(argv[0], &CustomPrefix); |
| |
| overload to pass a pointer to the corresponding :cpp:`CustomPrefix` function during |
| initialization. :cpp:`InitGoogleLogging()` takes a third optional argument of |
| type :cpp:`void*` that allows supplying user data to the callback. |
| |
| Failure Signal Handler |
| ~~~~~~~~~~~~~~~~~~~~~~ |
| |
| The library provides a convenient signal handler that will dump useful |
| information when the program crashes on certain signals such as ``SIGSEGV``. The |
| signal handler can be installed by :cpp:`google::InstallFailureSignalHandler()`. |
| The following is an example of output from the signal handler. |
| |
| :: |
| |
| *** Aborted at 1225095260 (unix time) try "date -d @1225095260" if you are using GNU date *** |
| *** SIGSEGV (@0x0) received by PID 17711 (TID 0x7f893090a6f0) from PID 0; stack trace: *** |
| PC: @ 0x412eb1 TestWaitingLogSink::send() |
| @ 0x7f892fb417d0 (unknown) |
| @ 0x412eb1 TestWaitingLogSink::send() |
| @ 0x7f89304f7f06 google::LogMessage::SendToLog() |
| @ 0x7f89304f35af google::LogMessage::Flush() |
| @ 0x7f89304f3739 google::LogMessage::~LogMessage() |
| @ 0x408cf4 TestLogSinkWaitTillSent() |
| @ 0x4115de main |
| @ 0x7f892f7ef1c4 (unknown) |
| @ 0x4046f9 (unknown) |
| |
| By default, the signal handler writes the failure dump to the standard |
| error. You can customize the destination by :cpp:`InstallFailureWriter()`. |
| |
| Performance of Messages |
| ~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| The conditional logging macros provided by glog (e.g., ``CHECK``, |
| ``LOG_IF``, ``VLOG``, etc.) are carefully implemented and don’t execute |
| the right hand side expressions when the conditions are false. So, the |
| following check may not sacrifice the performance of your application. |
| |
| .. code:: cpp |
| |
| CHECK(obj.ok) << obj.CreatePrettyFormattedStringButVerySlow(); |
| |
| User-defined Failure Function |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| ``FATAL`` severity level messages or unsatisfied ``CHECK`` condition |
| terminate your program. You can change the behavior of the termination |
| by :cpp:`InstallFailureFunction`. |
| |
| .. code:: cpp |
| |
| void YourFailureFunction() { |
| // Reports something... |
| exit(EXIT_FAILURE); |
| } |
| |
| int main(int argc, char* argv[]) { |
| google::InstallFailureFunction(&YourFailureFunction); |
| } |
| |
| By default, glog tries to dump the stacktrace and calls :cpp:`std::abort`. The |
| stacktrace is generated only when running the application on a system supported |
| by glog. Currently, glog supports x86, x86_64, PowerPC architectures, |
| ``libunwind``, and the Debug Help Library (``dbghelp``) on Windows for |
| extracting the stack trace. |
| |
| |
| Raw Logging |
| ~~~~~~~~~~~ |
| |
| The header file ``<glog/raw_logging.h>`` can be used for thread-safe logging, |
| which does not allocate any memory or acquire any locks. Therefore, the macros |
| defined in this header file can be used by low-level memory allocation and |
| synchronization code. Please check |
| `src/glog/raw_logging.h <src/glog/raw_logging.h>`__ for detail. |
| |
| Google Style ``perror()`` |
| ~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| ``PLOG()`` and ``PLOG_IF()`` and ``PCHECK()`` behave exactly like their |
| ``LOG*`` and ``CHECK`` equivalents with the addition that they append a |
| description of the current state of errno to their output lines. E.g. |
| |
| .. code:: cpp |
| |
| PCHECK(write(1, nullptr, 2) >= 0) << "Write nullptr failed"; |
| |
| This check fails with the following error message. |
| |
| :: |
| |
| F0825 185142 test.cc:22] Check failed: write(1, nullptr, 2) >= 0 Write nullptr failed: Bad address [14] |
| |
| Syslog |
| ~~~~~~ |
| |
| ``SYSLOG``, ``SYSLOG_IF``, and ``SYSLOG_EVERY_N`` macros are available. |
| These log to syslog in addition to the normal logs. Be aware that |
| logging to syslog can drastically impact performance, especially if |
| syslog is configured for remote logging! Make sure you understand the |
| implications of outputting to syslog before you use these macros. In |
| general, it’s wise to use these macros sparingly. |
| |
| Strip Logging Messages |
| ~~~~~~~~~~~~~~~~~~~~~~ |
| |
| Strings used in log messages can increase the size of your binary and |
| present a privacy concern. You can therefore instruct glog to remove all |
| strings which fall below a certain severity level by using the |
| ``GOOGLE_STRIP_LOG`` macro: |
| |
| If your application has code like this: |
| |
| .. code:: cpp |
| |
| #define GOOGLE_STRIP_LOG 1 // this must go before the #include! |
| #include <glog/logging.h> |
| |
| The compiler will remove the log messages whose severities are less than |
| the specified integer value. Since ``VLOG`` logs at the severity level |
| ``INFO`` (numeric value ``0``), setting ``GOOGLE_STRIP_LOG`` to 1 or |
| greater removes all log messages associated with ``VLOG``\ s as well as |
| ``INFO`` log statements. |
| |
| Automatically Remove Old Logs |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| To enable the log cleaner: |
| |
| .. code:: cpp |
| |
| using namespace std::chrono_literals; |
| google::EnableLogCleaner(24h * 3); // keep your logs for 3 days |
| |
| |
| In C++20 (and later) this can be shortened to: |
| |
| .. code:: cpp |
| |
| using namespace std::chrono_literals; |
| google::EnableLogCleaner(3d); // keep your logs for 3 days |
| |
| And then glog will check if there are overdue logs whenever a flush is |
| performed. In this example, any log file from your project whose last |
| modified time is greater than 3 days will be unlink()ed. |
| |
| This feature can be disabled at any time (if it has been enabled) |
| |
| .. code:: cpp |
| |
| google::DisableLogCleaner(); |
| |
| Notes for Windows Users |
| ~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| glog defines a severity level ``ERROR``, which is also defined in |
| ``windows.h`` . You can make glog not define ``INFO``, ``WARNING``, |
| ``ERROR``, and ``FATAL`` by defining ``GLOG_NO_ABBREVIATED_SEVERITIES`` |
| before including ``glog/logging.h`` . Even with this macro, you can |
| still use the iostream like logging facilities: |
| |
| .. code:: cpp |
| |
| #define GLOG_NO_ABBREVIATED_SEVERITIES |
| #include <windows.h> |
| #include <glog/logging.h> |
| |
| // ... |
| |
| LOG(ERROR) << "This should work"; |
| LOG_IF(ERROR, x > y) << "This should be also OK"; |
| |
| However, you cannot use ``INFO``, ``WARNING``, ``ERROR``, and ``FATAL`` |
| anymore for functions defined in ``glog/logging.h`` . |
| |
| .. code:: cpp |
| |
| #define GLOG_NO_ABBREVIATED_SEVERITIES |
| #include <windows.h> |
| #include <glog/logging.h> |
| |
| // ... |
| |
| // This won’t work. |
| // google::FlushLogFiles(google::ERROR); |
| |
| // Use this instead. |
| google::FlushLogFiles(google::GLOG_ERROR); |
| |
| If you don’t need ``ERROR`` defined by ``windows.h``, there are a couple |
| of more workarounds which sometimes don’t work: |
| |
| - :cpp:`#define WIN32_LEAN_AND_MEAN` or :cpp:`NOGDI` **before** |
| :cpp:`#include <windows.h>`. |
| - :cpp:`#undef ERROR` **after** :cpp:`#include <windows.h>`. |
| |
| See `this |
| issue <http://code.google.com/p/google-glog/issues/detail?id=33>`__ for |
| more detail. |
| |
| |
| Installation Notes for 64-bit Linux Systems |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| The glibc built-in stack-unwinder on 64-bit systems has some problems with glog. |
| (In particular, if you are using :cpp:`InstallFailureSignalHandler()`, the |
| signal may be raised in the middle of malloc, holding some malloc-related locks |
| when they invoke the stack unwinder. The built-in stack unwinder may call malloc |
| recursively, which may require the thread to acquire a lock it already holds: |
| deadlock.) |
| |
| For that reason, if you use a 64-bit system and you need |
| :cpp:`InstallFailureSignalHandler()`, we strongly recommend you install |
| ``libunwind`` before trying to configure or install google glog. |
| libunwind can be found |
| `here <http://download.savannah.nongnu.org/releases/libunwind/libunwind-snap-070410.tar.gz>`__. |
| |
| Even if you already have ``libunwind`` installed, you will probably |
| still need to install from the snapshot to get the latest version. |
| |
| Caution: if you install libunwind from the URL above, be aware that you |
| may have trouble if you try to statically link your binary with glog: |
| that is, if you link with ``gcc -static -lgcc_eh ...``. This is because |
| both ``libunwind`` and ``libgcc`` implement the same C++ exception |
| handling APIs, but they implement them differently on some platforms. |
| This is not likely to be a problem on ia64, but may be on x86-64. |
| |
| Also, if you link binaries statically, make sure that you add |
| :cmd:`-Wl,--eh-frame-hdr` to your linker options. This is required so that |
| ``libunwind`` can find the information generated by the compiler required for |
| stack unwinding. |
| |
| Using :cmd:`-static` is rare, though, so unless you know this will affect you it |
| probably won’t. |
| |
| If you cannot or do not wish to install libunwind, you can still try to |
| use two kinds of stack-unwinder: |
| |
| glibc built-in stack-unwinder |
| As we already mentioned, glibc’s unwinder has a deadlock issue. However, if |
| you don’t use :cpp:`InstallFailureSignalHandler()` or you don’t worry about |
| the rare possibilities of deadlocks, you can use this stack-unwinder. If you |
| specify no options and ``libunwind`` isn’t detected on your system, the |
| configure script chooses this unwinder by default. |
| |
| frame pointer based stack-unwinder |
| The frame pointer based stack unwinder requires that your application, the |
| glog library, and system libraries like libc, all be compiled with a frame |
| pointer. This is *not* the default for x86-64. |
| |
| |
| How to Contribute |
| ----------------- |
| |
| We’d love to accept your patches and contributions to this project. |
| There are a just a few small guidelines you need to follow. |
| |
| Contributor License Agreement (CLA) |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| Contributions to any Google project must be accompanied by a Contributor |
| License Agreement. This is not a copyright **assignment**, it simply |
| gives Google permission to use and redistribute your contributions as |
| part of the project. |
| |
| * If you are an individual writing original source code and you’re sure |
| you own the intellectual property, then you’ll need to sign an |
| `individual |
| CLA <https://developers.google.com/open-source/cla/individual>`__. |
| * If you work for a company that wants to allow you to contribute your |
| work, then you’ll need to sign a `corporate |
| CLA <https://developers.google.com/open-source/cla/corporate>`__. |
| |
| You generally only need to submit a CLA once, so if you’ve already |
| submitted one (even if it was for a different project), you probably |
| don’t need to do it again. |
| |
| Once your CLA is submitted (or if you already submitted one for another |
| Google project), make a commit adding yourself to the |
| `AUTHORS <./AUTHORS>`__ and `CONTRIBUTORS <./CONTRIBUTORS>`__ files. This |
| commit can be part of your first `pull |
| request <https://help.github.com/articles/creating-a-pull-request>`__. |
| |
| Submitting a Patch |
| ~~~~~~~~~~~~~~~~~~ |
| |
| 1. It’s generally best to start by opening a new issue describing the |
| bug or feature you’re intending to fix. Even if you think it’s |
| relatively minor, it’s helpful to know what people are working on. |
| Mention in the initial issue that you are planning to work on that |
| bug or feature so that it can be assigned to you. |
| 2. Follow the normal process of |
| `forking <https://help.github.com/articles/fork-a-repo>`__ the |
| project, and setup a new branch to work in. It’s important that each |
| group of changes be done in separate branches in order to ensure that |
| a pull request only includes the commits related to that bug or |
| feature. |
| 3. Do your best to have `well-formed commit |
| messages <http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html>`__ |
| for each change. This provides consistency throughout the project, |
| and ensures that commit messages are able to be formatted properly by |
| various git tools. |
| 4. Finally, push the commits to your fork and submit a `pull |
| request <https://help.github.com/articles/creating-a-pull-request>`__. |
| |
| |
| .. |Linux Github actions| image:: https://github.com/google/glog/actions/workflows/linux.yml/badge.svg |
| :target: https://github.com/google/glog/actions |
| .. |Windows Github actions| image:: https://github.com/google/glog/actions/workflows/windows.yml/badge.svg |
| :target: https://github.com/google/glog/actions |
| .. |macOS Github actions| image:: https://github.com/google/glog/actions/workflows/macos.yml/badge.svg |
| :target: https://github.com/google/glog/actions |
| .. |Codecov| image:: https://codecov.io/gh/google/glog/branch/master/graph/badge.svg?token=8an420vNju |
| :target: https://codecov.io/gh/google/glog |