Commit 8110e8de authored by Marius Vlad's avatar Marius Vlad

doc/sphinx: Add documentation for the logging/debugging framework

This details the logging/debugging framework with the latest changes,
making use of the groups added by "weston-log: Start adding
documentation" and "libweston/log: Add 'wlog' group".
Signed-off-by: Marius Vlad's avatarMarius Vlad <>
parent 35ff4a8d
Pipeline #49724 passed with stages
in 2 minutes and 57 seconds
......@@ -8,6 +8,7 @@ Libweston
`Libweston` is an effort to separate the re-usable parts of Weston into a
library. `Libweston` provides most of the boring and tedious bits of correctly
Weston's printf
Logging in weston takes place through :func:`weston_log()` function, which
calls a log handler (:var:`log_handler`) that has to be installed before
actually calling :func:`weston_log()`. In weston, the log handler makes use of
the logging framework which is (mostly) comprised of :ref:`log scopes` (produces
of data) and :ref:`subscribers`.
Logging context
Management of the logging framework in weston happens under the
:type:`weston_log_context` object and is entirely separated from the main
compositor instance (:type:`weston_compositor`). The compositor
instance can be brought up much more later, but in the same time logging can
take place much earlier without the need of a compositor instance.
Instantiation of the :type:`weston_log_context` object takes place using
:func:`weston_log_ctx_compositor_create()` and clean-up/destroy with
Log scopes
A scope represents a source for a data stream (i.e., a producer). You'll require
one as a way to generate data. Creating a log scope is done using
:func:`weston_compositor_add_log_scope()`. You can customize the scope
behaviour and you'll require at least a name and a description for the
.. note::
A scope **name** identifies that scope. Scope retrieval from the
:type:`weston_log_context` is done using the scope name. The name is
important for the subscription part, detailed bit later.
Log scopes are managed **explicitly**, and destroying the scope is done using
Available scopes in weston
Weston has a few scopes worth mentioning:
- **log** - a debug scope for generic logging, upon which :func:`weston_log`
re-routes its data.
- **proto** - debug scope that displays the protocol communication. It is
similar to WAYLAND_DEBUG=server environmental variable but has the ability to
distinguish multiple clients.
- **scene-graph** - an one-shot debug scope which describes the current scene
graph comprising of layers (containers of views), views (which represent a
window), their surfaces, sub-surfaces, buffer type and format, both in
:samp:`DRM_FOURCC` type and human-friendly form.
- **drm-backend** - Weston uses DRM (Direct Rendering Manager) as one of its
backends and this debug scope display information related to that: details
the transitions of a view as it takes before being assigned to a hardware
plane or to a renderer, current assignments of views, the compositing mode
Weston is using for rendering the scene-graph, describes the current hardware
plane properties like CRTC_ID, FB_ID, FORMAT when doing a commit or a
page-flip. It incorporates the scene-graph scope as well.
- **xwm-wm-x11** - a scope for the X11 window manager in Weston for supporting
Xwayland, printing some X11 protocol actions.
- **content-protection-debug** - scope for debugging HDCP issues.
.. note::
Besides 'log' scope, which is a generic scope, intended for usage through
:func:`weston_log`, all the others scopes listed above could suffer various
modifications and might not represent a current list on which one should
rely upon.
Besides creating a creating a scope, a subscriber (:type:`weston_log_subscriber`)
object needs to be created. The subscriber object is an opaque
object (private) and allows customization of the back-end side of libweston.
The subscriber object can define its own methods. Users wanting to define
a new data stream should extend this :type:`weston_log_subscriber`.
For example libweston make uses of several type of subscribers, specific to the
data streams they will be generating:
- a **'logger'** type created by :func:`weston_log_subscriber_create_log()`
- a **'flight-recoder'** type created by :func:`weston_log_subscriber_destroy_flight_rec()`
- for the **'weston-debug'** protocol, which is private/hidden created whenever a
client connects
Like log scopes, the subscribers are also manged **explicitly** and both of the
subscriber types above have their destroy counter-parts. `weston-debug`
protocol is a bit special in this regard as the destroying part is handled
implicitly using wayland protocol specifics.
Once the subscriber has been created there needs to be a subscription process
in which we establish a relationship between the subscriber and the scope.
To create a subscription we use :func:`weston_log_subscribe` which uses the
subscriber created previously and the scope name. If the scope was not created
at the time, the subscription will be (at least for a time) a *pending
subscription*. Once the scope is created the *pending subscription* is
destroyed, not before creating a new subscription to accommodate the
initial/original one.
.. note::
The subscription process is (an) internal API and is managed implictly.
When a scope is being destroyed the subscriptions for this scope will be
destroyed as well.
weston uses a logger type of a subscriber for logging everyhing in the code
(through the help of :func:`weston_log()`). The subscriber method
(:func:`weston_log_subscriber_create_log()`) takes an :samp:`FILE *` as an
argument in case the std :samp:`stdout` file-descriptor is not where the data
should be sent to.
Additionally, specifying which scopes to subscribe to can be done using
:samp:`--logger-scopes` command line option. As log scopes are already created
in the code, this merely subscribes to them. Default, the 'log' scope is being
subscribr to the logger subscriber.
Flight recorder
The flight recorder acts like a black box found in airplanes: it accumulates
data until the user wants to display its contents. The backed up storage is a
simple ring-buffer of a compiled-time fixed size value, and the memory is
forcibly-mapped such that we make sure the kernel allocated storage for it.
The user can use the debug keybinding :samp:`KEY_D` (shift+mod+space-d) to
force the contents to be printed on :samp:`stdout` file-descriptor.
The user has first to specify which log scope to subscribe to.
Specifying which scopes to subscribe for the flight-recorder can be done using
:samp:`--flight-rec-scopes`. By default, the 'log' scope and 'drm-backend' are
the scopes subscribed to.
weston-debug protocol
Weston-debug protocol is only present in the weston compositor (i.e., a weston
specific compositor). It make uses of the the logging framework presented
above, with the exception that the subscription happens automatically rather
than manually with :func:`weston_log_subscribe()` in case of the other two
types of subscribers. Also the subscriber is created once the client has
connected and requested data from a log scope. This means that each time a
client connects a new subscriber will be created. For each stream subscribed a
subscription will be created. Enabling the debug-protocol happens using the
:samp:`--debug` command line.
.. doxygengroup:: debug-protocol
Weston Log API
.. doxygengroup:: wlog
Logging API
.. doxygengroup:: log
Internal logging API
.. note::
The following is mean to be internal API and aren't exposed in libweston!
.. doxygengroup:: internal-log
# you need to add here any files you add to the toc directory as well
files = [ 'compositor.rst', 'head.rst', 'output.rst' ]
files = [ 'compositor.rst', 'head.rst', 'output.rst', 'log.rst' ]
foreach file : files
configure_file(input: file, output: file, copy: true)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment