1Gecko Logging 2============= 3 4A minimal C++ logging framework is provided for use in core Gecko code. It is enabled for all builds and is thread-safe. 5 6Declaring a Log Module 7---------------------- 8 9``LazyLogModule`` defers the creation the backing ``LogModule`` in a thread-safe manner and is the preferred method to declare a log module. Multiple ``LazyLogModules`` with the same name can be declared, all will share the same backing ``LogModule``. This makes it much simpler to share a log module across multiple translation units. ``LazyLogLodule`` provides a conversion operator to ``LogModule*`` and is suitable for passing into the logging macros detailed below. 10 11Note: Log module names can only contain specific characters. The first character must be a lowercase or uppercase ASCII char, underscore, dash, or dot. Subsequent characters may be any of those, or an ASCII digit. 12 13.. code-block:: c++ 14 15 #include "mozilla/Logging.h" 16 17 static mozilla::LazyLogModule sFooLog("foo"); 18 19 20Logging interface 21----------------- 22 23A basic interface is provided in the form of 2 macros and an enum class. 24 25+----------------------------------------+----------------------------------------------------------------------------+ 26| MOZ_LOG(module, level, message) | Outputs the given message if the module has the given log level enabled: | 27| | | 28| | * module: The log module to use. | 29| | * level: The log level of the message. | 30| | * message: A printf-style message to output. Must be enclosed in | 31| | parentheses. | 32+----------------------------------------+----------------------------------------------------------------------------+ 33| MOZ_LOG_TEST(module, level) | Checks if the module has the given level enabled: | 34| | | 35| | * module: The log module to use. | 36| | * level: The output level of the message. | 37+----------------------------------------+----------------------------------------------------------------------------+ 38 39 40+-----------+---------------+-----------------------------------------------------------------------------------------+ 41| Log Level | Numeric Value | Purpose | 42+===========+===============+=========================================================================================+ 43| Disabled | 0 | Indicates logging is disabled. This should not be used directly in code. | 44+-----------+---------------+-----------------------------------------------------------------------------------------+ 45| Error | 1 | An error occurred, generally something you would consider asserting in a debug build. | 46+-----------+---------------+-----------------------------------------------------------------------------------------+ 47| Warning | 2 | A warning often indicates an unexpected state. | 48+-----------+---------------+-----------------------------------------------------------------------------------------+ 49| Info | 3 | An informational message, often indicates the current program state. | 50+-----------+---------------+-----------------------------------------------------------------------------------------+ 51| Debug | 4 | A debug message, useful for debugging but too verbose to be turned on normally. | 52+-----------+---------------+-----------------------------------------------------------------------------------------+ 53| Verbose | 5 | A message that will be printed a lot, useful for debugging program flow and will | 54| | | probably impact performance. | 55+-----------+---------------+-----------------------------------------------------------------------------------------+ 56 57Example Usage 58------------- 59 60.. code-block:: c++ 61 62 #include "mozilla/Logging.h" 63 64 using mozilla::LogLevel; 65 66 static mozilla::LazyLogModule sLogger("example_logger"); 67 68 static void DoStuff() 69 { 70 MOZ_LOG(sLogger, LogLevel::Info, ("Doing stuff.")); 71 72 int i = 0; 73 int start = Time::NowMS(); 74 MOZ_LOG(sLogger, LogLevel::Debug, ("Starting loop.")); 75 while (i++ < 10) { 76 MOZ_LOG(sLogger, LogLevel::Verbose, ("i = %d", i)); 77 } 78 79 // Only calculate the elapsed time if the Warning level is enabled. 80 if (MOZ_LOG_TEST(sLogger, LogLevel::Warning)) { 81 int elapsed = Time::NowMS() - start; 82 if (elapsed > 1000) { 83 MOZ_LOG(sLogger, LogLevel::Warning, ("Loop took %dms!", elapsed)); 84 } 85 } 86 87 if (i != 10) { 88 MOZ_LOG(sLogger, LogLevel::Error, ("i should be 10!")); 89 } 90 } 91 92Enabling Logging 93---------------- 94 95The log level for a module is controlled by setting an environment variable before launching the application. It can also be adjusted by setting prefs. By default all logging output is disabled. 96 97:: 98 99 set MOZ_LOG="example_logger:3" 100 101In the Windows Command Prompt (`cmd.exe`), don't use quotes: 102 103:: 104 105 set MOZ_LOG=example_logger:3 106 107If you want this on GeckoView example, use the following adb command to launch process: 108 109:: 110 111 adb shell am start -n org.mozilla.geckoview_example/.GeckoViewActivity --es env0 "MOZ_LOG=example_logger:3" 112 113There are special module names to change logging behavior. You can specify one or more special module names without logging level. 114 115+-------------------------+-------------------------------------------------------------------------------------------+ 116| Special module name | Action | 117+=========================+===========================================================================================+ 118| append | Append new logs to existing log file. | 119+-------------------------+-------------------------------------------------------------------------------------------+ 120| sync | Print each log synchronously, this is useful to check behavior in real time or get logs | 121| | immediately before crash. | 122+-------------------------+-------------------------------------------------------------------------------------------+ 123| raw | Print exactly what has been specified in the format string, without the | 124| | process/thread/timestamp, etc. prefix. | 125+-------------------------+-------------------------------------------------------------------------------------------+ 126| timestamp | Insert timestamp at start of each log line. | 127+-------------------------+-------------------------------------------------------------------------------------------+ 128| rotate: **N** | | This limits the produced log files' size. Only most recent **N megabytes** of log data | 129| | | is saved. We rotate four log files with .0, .1, .2, .3 extensions. Note: this option | 130| | | disables 'append' and forces 'timestamp'. | 131+-------------------------+-------------------------------------------------------------------------------------------+ 132 133For example, if you want to specify `sync`, `timestamp` and `rotate`: 134 135:: 136 137 set MOZ_LOG="example_logger:3,timestamp,sync,rotate:10" 138 139To adjust the logging after Firefox has started, you can set prefs under the `logging.` prefix. For example, setting `logging.foo` to `3` will set the log module `foo` to start logging at level 3. The special boolean prefs `logging.config.sync` and `logging.config.add_timestamp` can be used to control the `sync` and `timestamp` properties described above. 140 141.. warning:: 142 A sandboxed content process cannot write to stderr or any file. The easiest way to log these processes is to disable the content sandbox by setting the preference `security.sandbox.content.level` to `0`. On Windows, you can still see child process messages by using DOS (not the `MOZ_LOG_FILE` variable defined below) to redirect output to a file. For example: `MOZ_LOG="CameraChild:5" mach run >& my_log_file.txt` will include debug messages from the camera's child actor that lives in a (sandboxed) content process. 143 144Redirecting logging output to a file 145------------------------------------ 146 147Logging output can be redirected to a file by passing its path via an environment variable. 148 149.. note:: 150 By default logging output goes to `stderr`. 151 152:: 153 154 set MOZ_LOG_FILE="log.txt" 155 156The `rotate` and `append` options described above only apply when logging to a file. 157 158The special pref `logging.config.LOG_FILE` can be set at runtime to change the log file being output to. 159 160Logging Rust 161------------ 162 163We're gradually adding more Rust code to Gecko, and Rust crates typically use a different approach to logging. Many Rust libraries use the `log <https://docs.rs/log>`_ crate to log messages, which works together with `env_logger <https://docs.rs/env_logger>`_ at the application level to control what's actually printed via `RUST_LOG`. 164 165You can set an overall logging level, though it could be quite verbose: 166 167:: 168 169 set RUST_LOG="debug" 170 171You can also target individual modules by path: 172 173:: 174 175 set RUST_LOG="style::style_resolver=debug" 176 177.. note:: 178 For Linux/MacOS users, you need to use `export` rather than `set`. 179 180.. note:: 181 Sometimes it can be useful to only log child processes and ignore the parent process. In Firefox 57 and later, you can use `RUST_LOG_CHILD` instead of `RUST_LOG` to specify log settings that will only apply to child processes. 182 183The `log` crate lists the available `log levels <https://docs.rs/log/0.3.8/log/enum.LogLevel.html>`_: 184 185+-----------+---------------------------------------------------------------------------------------------------------+ 186| Log Level | Purpose | 187+===========+=========================================================================================================+ 188| error | Designates very serious errors. | 189+-----------+---------------------------------------------------------------------------------------------------------+ 190| warn | Designates hazardous situations. | 191+-----------+---------------------------------------------------------------------------------------------------------+ 192| info | Designates useful information. | 193+-----------+---------------------------------------------------------------------------------------------------------+ 194| debug | Designates lower priority information. | 195+-----------+---------------------------------------------------------------------------------------------------------+ 196| trace | Designates very low priority, often extremely verbose, information. | 197+-----------+---------------------------------------------------------------------------------------------------------+ 198 199It is common for debug and trace to be disabled at compile time in release builds, so you may need a debug build if you want logs from those levels. 200 201Check the `env_logger <https://docs.rs/env_logger>`_ docs for more details on logging options. 202