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