Introduce new logging API, fixes #858
PiperOrigin-RevId: 930744288 Change-Id: I6ec1203b55c031390f3eef23192e2337508ce886
This commit is contained in:
committed by
Copybara-Service
parent
a2abaf7aef
commit
58f6d52491
@@ -32,10 +32,14 @@ you are simulating multiple models in parallel, they use the same set of callbac
|
||||
mju_user_error
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
This is called from within the main error function :ref:`mju_error`. When installed, this function overrides the default
|
||||
error processing. Once it prints error messages (or whatever else the user wants to do), it must **exit** the program.
|
||||
MuJoCo is written with the assumption that mju_error will not return. If it does, the behavior of the software is
|
||||
undefined.
|
||||
.. deprecated::
|
||||
Use :ref:`mju_setLogHandler` instead. See :ref:`siLogHandler`.
|
||||
|
||||
Called by the default log handler when a fatal error occurs. If installed, this function overrides the default error
|
||||
processing. It may ``longjmp`` out or return. MuJoCo is written with the assumption that error handlers will not
|
||||
return; if they do, the behavior of the software is undefined.
|
||||
|
||||
If a custom log handler is installed via :ref:`mju_setLogHandler`, this callback is not consulted.
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
@@ -47,8 +51,11 @@ undefined.
|
||||
mju_user_warning
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
This is called from within the main warning function :ref:`mju_warning`. It is similar to the error handler, but instead
|
||||
it must return without exiting the program.
|
||||
.. deprecated::
|
||||
Use :ref:`mju_setLogHandler` instead. See :ref:`siLogHandler`.
|
||||
|
||||
Called by the default log handler when a warning occurs. If a custom log handler is installed via
|
||||
:ref:`mju_setLogHandler`, this callback is not consulted.
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
@@ -185,9 +192,9 @@ mjcb_time
|
||||
~~~~~~~~~
|
||||
|
||||
Installing this callback enables the built-in profiler, and keeps timing statistics in ``mjData.timer``. The return type
|
||||
is mjtNum, while the time units are up to the user. :ref:`simulate.cc <saSimulate>` assumes the unit is 1 millisecond.
|
||||
In order to be useful, the callback should use high-resolution timers with at least microsecond precision. This is
|
||||
because the computations being timed are very fast.
|
||||
is mjtNum, while the time units are up to the user. Both :ref:`simulate.cc <saSimulate>` and the ``mjTOPIC_TIME_STP``
|
||||
informational :ref:`topic <mjtLogTopic>` assume the unit is 1 millisecond. In order to be useful, the callback should
|
||||
use high-resolution timers with at least microsecond precision.
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
|
||||
@@ -540,6 +540,33 @@ Sleep state of an object.
|
||||
.. mujoco-include:: mjtSleepState
|
||||
|
||||
|
||||
.. _tyLogEnums:
|
||||
|
||||
Logging
|
||||
~~~~~~~
|
||||
|
||||
.. _mjtLogLevel:
|
||||
|
||||
mjtLogLevel
|
||||
"""""""""""
|
||||
|
||||
Log message severity level.
|
||||
|
||||
.. mujoco-include:: mjtLogLevel
|
||||
|
||||
|
||||
.. _mjtLogTopic:
|
||||
|
||||
mjtLogTopic
|
||||
"""""""""""
|
||||
|
||||
Topic identifiers for informational messages. Used with :ref:`mju_info` for topic-based filtering.
|
||||
Topic 0 (``mjTOPIC_NONE``) always passes through the default handler's filter. Other topics must be enabled in
|
||||
the :ref:`mjLogConfig` bitmask. Since topics are 1-indexed, the bitmask for topic ``t`` is ``(1 << (t - 1))``.
|
||||
|
||||
.. mujoco-include:: mjtLogTopic
|
||||
|
||||
|
||||
.. _tyVisEnums:
|
||||
|
||||
Visualization
|
||||
@@ -1059,6 +1086,36 @@ Asset cache used by the compiler to avoid repeated slow recompilation. See :ref:
|
||||
.. mujoco-include:: mjCache
|
||||
|
||||
|
||||
.. _tyLogStructure:
|
||||
|
||||
Logging
|
||||
^^^^^^^
|
||||
|
||||
.. _mjLogMessage:
|
||||
|
||||
mjLogMessage
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Structured log message passed to :ref:`mjfLogHandler` callbacks. Contains the severity level, optional topic for
|
||||
info messages, a one-line subject, an optional multi-line body, and optional source location (function name, file
|
||||
name, line number).
|
||||
|
||||
.. mujoco-include:: mjLogMessage
|
||||
|
||||
|
||||
.. _mjLogConfig:
|
||||
|
||||
mjLogConfig
|
||||
~~~~~~~~~~~
|
||||
|
||||
Configuration for the default log handler. Controls whether messages are printed to the console and/or written to
|
||||
a log file (default: ``MUJOCO_LOG.TXT``). The ``logto_file`` field enables file logging, while ``logfile`` specifies
|
||||
the file path. The ``topics`` field is a bitmask of :ref:`mjtLogTopic` values: bit ``(topic - 1)`` enables
|
||||
that topic. Topic 0 (``mjTOPIC_NONE``) always passes through.
|
||||
|
||||
.. mujoco-include:: mjLogConfig
|
||||
|
||||
|
||||
.. _tyStatStructure:
|
||||
|
||||
Sim statistics
|
||||
@@ -1836,6 +1893,26 @@ mjfCollision
|
||||
This is the function type of the callbacks in the collision table :ref:`mjCOLLISIONFUNC`.
|
||||
|
||||
|
||||
.. _tyLogCallbacks:
|
||||
|
||||
Log Callbacks
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
.. _mjfLogHandler:
|
||||
|
||||
mjfLogHandler
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
typedef void (*mjfLogHandler)(const mjLogMessage*);
|
||||
|
||||
This is the function type of the log handler callback installed via :ref:`mju_setLogHandler`. The handler receives
|
||||
all errors, warnings and informational messages as structured :ref:`mjLogMessage` data. It must be thread-safe.
|
||||
|
||||
It must not call :ref:`mju_error` from within the callback.
|
||||
|
||||
|
||||
.. _tyUICallbacks:
|
||||
|
||||
UI Callbacks
|
||||
|
||||
@@ -1971,7 +1971,9 @@ Error and memory
|
||||
|
||||
.. mujoco-include:: mju_error
|
||||
|
||||
Main error function; does not return to caller.
|
||||
Main error function. The error message is dispatched to the active log handler (see :ref:`mju_setLogHandler`).
|
||||
Errors are always fatal: if the handler returns, the process is terminated with ``exit(EXIT_FAILURE)``. Handlers
|
||||
wishing to recover must ``longjmp`` or otherwise transfer control before returning.
|
||||
|
||||
.. _mju_warning:
|
||||
|
||||
@@ -1980,7 +1982,7 @@ Main error function; does not return to caller.
|
||||
|
||||
.. mujoco-include:: mju_warning
|
||||
|
||||
Main warning function; returns to caller.
|
||||
Main warning function; returns to caller. The warning message is dispatched to the active log handler.
|
||||
|
||||
.. _mju_clearHandlers:
|
||||
|
||||
@@ -1989,7 +1991,114 @@ Main warning function; returns to caller.
|
||||
|
||||
.. mujoco-include:: mju_clearHandlers
|
||||
|
||||
Clear user error and memory handlers.
|
||||
Clear all user handlers and restore defaults. Resets the legacy error/warning/memory callbacks to ``NULL``, restores
|
||||
the default log handler, and resets the log configuration to its defaults (console and file output enabled, all info
|
||||
topics disabled).
|
||||
|
||||
.. _mju_setLogHandler:
|
||||
|
||||
`mju_setLogHandler <#mju_setLogHandler>`__
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. mujoco-include:: mju_setLogHandler
|
||||
|
||||
Set the active global log handler. Returns the previous handler (which is never ``NULL``), intended for save/restore
|
||||
or callback chaining. If ``handler`` is ``NULL``, the default handler is restored. The handler receives all errors,
|
||||
warnings and informational messages as a structured :ref:`mjLogMessage`. See :ref:`siLogHandler` for usage examples.
|
||||
|
||||
.. _mju_getLogConfig:
|
||||
|
||||
`mju_getLogConfig <#mju_getLogConfig>`__
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. mujoco-include:: mju_getLogConfig
|
||||
|
||||
Get the current default handler configuration. See :ref:`mjLogConfig`.
|
||||
|
||||
.. _mju_setLogConfig:
|
||||
|
||||
`mju_setLogConfig <#mju_setLogConfig>`__
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. mujoco-include:: mju_setLogConfig
|
||||
|
||||
Set the default handler configuration. Controls console output, file output, and info topic filtering.
|
||||
See :ref:`mjLogConfig`.
|
||||
|
||||
Example usage (disabling file output):
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
mjLogConfig config = mju_getLogConfig();
|
||||
config.logto_file = false;
|
||||
mju_setLogConfig(config);
|
||||
|
||||
.. _mju_info:
|
||||
|
||||
`mju_info <#mju_info>`__
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. mujoco-include:: mju_info
|
||||
|
||||
Log an informational message with optional topic filtering. The ``topic`` argument is a :ref:`mjtLogTopic` value.
|
||||
Topic 0 (``mjTOPIC_NONE``) always passes through. Other topics must be enabled in the default handler configuration
|
||||
via :ref:`mju_setLogConfig`. Note that topic filtering is implemented in the default handler; custom handlers
|
||||
receive all info messages regardless.
|
||||
|
||||
.. _mju_message:
|
||||
|
||||
`mju_message <#mju_message>`__
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. mujoco-include:: mju_message
|
||||
|
||||
Dispatch a structured :ref:`mjLogMessage` to the active log handler. This is the primary entry point for emitting
|
||||
log messages with full control over all fields. The convenience functions :ref:`mju_error`, :ref:`mju_warning`, and
|
||||
:ref:`mju_info` are thin wrappers that populate an ``mjLogMessage`` and call this function.
|
||||
|
||||
The ``subject`` field is a one-line summary (up to 1024 bytes, inline in the struct). The ``body`` field is an
|
||||
optional ``const char*`` pointer to multi-line detail text, owned by the caller. When ``body`` is ``NULL``, only the
|
||||
subject line is printed.
|
||||
|
||||
The default handler formats the output as follows:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
LEVEL FUNC (FILE:LINE) TIME: SUBJECT
|
||||
BODY
|
||||
|
||||
where:
|
||||
|
||||
- ``LEVEL`` is ``ERROR``, ``WARNING``, ``INFO``, or ``DEBUG``.
|
||||
- ``FUNC`` is present when the ``func`` field is set.
|
||||
- ``(FILE:LINE)`` is present when the ``file`` and ``line`` fields are set.
|
||||
- ``TIME`` is present when the ``timestamp`` field is set or file logging is active.
|
||||
- ``SUBJECT`` is the contents of the ``subject`` field.
|
||||
- ``BODY`` follows on the next line(s), printed raw without indentation or separators, only if non-NULL.
|
||||
|
||||
The default handler appends a trailing blank line after ``ERROR``, ``WARNING``, and ``INFO`` messages for visual
|
||||
separation. ``DEBUG`` messages are printed compactly without a trailing blank line.
|
||||
|
||||
Example usage:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
mjLogMessage msg = {
|
||||
.level = mjLOG_INFO,
|
||||
.timestamp = true,
|
||||
.body = " height: 0.001 m\n velocity: 0.000 m/s\n bounces: 47",
|
||||
};
|
||||
snprintf(msg.subject, sizeof(msg.subject), "The ball has come to rest");
|
||||
mju_message(&msg);
|
||||
|
||||
This produces:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
INFO Mon Jun 9 15:04:05 2026: The ball has come to rest
|
||||
height: 0.001 m
|
||||
velocity: 0.000 m/s
|
||||
bounces: 47
|
||||
|
||||
.. _mju_malloc:
|
||||
|
||||
|
||||
@@ -463,6 +463,102 @@ time, while :ref:`mjui_update` is called only when changes in the UI take place.
|
||||
|
||||
.. _Errorandmemory:
|
||||
|
||||
.. _mju_error:
|
||||
|
||||
Main error function. The error message is dispatched to the active log handler (see :ref:`mju_setLogHandler`).
|
||||
Errors are always fatal: if the handler returns, the process is terminated with ``exit(EXIT_FAILURE)``. Handlers
|
||||
wishing to recover must ``longjmp`` or otherwise transfer control before returning.
|
||||
|
||||
.. _mju_warning:
|
||||
|
||||
Main warning function; returns to caller. The warning message is dispatched to the active log handler.
|
||||
|
||||
.. _mju_clearHandlers:
|
||||
|
||||
Clear all user handlers and restore defaults. Resets the legacy error/warning/memory callbacks to ``NULL``, restores
|
||||
the default log handler, and resets the log configuration to its defaults (console and file output enabled, all info
|
||||
topics disabled).
|
||||
|
||||
.. _mju_setLogHandler:
|
||||
|
||||
Set the active global log handler. Returns the previous handler (which is never ``NULL``), intended for save/restore
|
||||
or callback chaining. If ``handler`` is ``NULL``, the default handler is restored. The handler receives all errors,
|
||||
warnings and informational messages as a structured :ref:`mjLogMessage`. See :ref:`siLogHandler` for usage examples.
|
||||
|
||||
.. _mju_getLogConfig:
|
||||
|
||||
Get the current default handler configuration. See :ref:`mjLogConfig`.
|
||||
|
||||
.. _mju_setLogConfig:
|
||||
|
||||
Set the default handler configuration. Controls console output, file output, and info topic filtering.
|
||||
See :ref:`mjLogConfig`.
|
||||
|
||||
Example usage (disabling file output):
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
mjLogConfig config = mju_getLogConfig();
|
||||
config.logto_file = false;
|
||||
mju_setLogConfig(config);
|
||||
|
||||
.. _mju_info:
|
||||
|
||||
Log an informational message with optional topic filtering. The ``topic`` argument is a :ref:`mjtLogTopic` value.
|
||||
Topic 0 (``mjTOPIC_NONE``) always passes through. Other topics must be enabled in the default handler configuration
|
||||
via :ref:`mju_setLogConfig`. Note that topic filtering is implemented in the default handler; custom handlers
|
||||
receive all info messages regardless.
|
||||
|
||||
.. _mju_message:
|
||||
|
||||
Dispatch a structured :ref:`mjLogMessage` to the active log handler. This is the primary entry point for emitting
|
||||
log messages with full control over all fields. The convenience functions :ref:`mju_error`, :ref:`mju_warning`, and
|
||||
:ref:`mju_info` are thin wrappers that populate an ``mjLogMessage`` and call this function.
|
||||
|
||||
The ``subject`` field is a one-line summary (up to 1024 bytes, inline in the struct). The ``body`` field is an
|
||||
optional ``const char*`` pointer to multi-line detail text, owned by the caller. When ``body`` is ``NULL``, only the
|
||||
subject line is printed.
|
||||
|
||||
The default handler formats the output as follows:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
LEVEL FUNC (FILE:LINE) TIME: SUBJECT
|
||||
BODY
|
||||
|
||||
where:
|
||||
|
||||
- ``LEVEL`` is ``ERROR``, ``WARNING``, ``INFO``, or ``DEBUG``.
|
||||
- ``FUNC`` is present when the ``func`` field is set.
|
||||
- ``(FILE:LINE)`` is present when the ``file`` and ``line`` fields are set.
|
||||
- ``TIME`` is present when the ``timestamp`` field is set or file logging is active.
|
||||
- ``SUBJECT`` is the contents of the ``subject`` field.
|
||||
- ``BODY`` follows on the next line(s), printed raw without indentation or separators, only if non-NULL.
|
||||
|
||||
The default handler appends a trailing blank line after ``ERROR``, ``WARNING``, and ``INFO`` messages for visual
|
||||
separation. ``DEBUG`` messages are printed compactly without a trailing blank line.
|
||||
|
||||
Example usage:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
mjLogMessage msg = {
|
||||
.level = mjLOG_INFO,
|
||||
.timestamp = true,
|
||||
.body = " height: 0.001 m\n velocity: 0.000 m/s\n bounces: 47",
|
||||
};
|
||||
snprintf(msg.subject, sizeof(msg.subject), "The ball has come to rest");
|
||||
mju_message(&msg);
|
||||
|
||||
This produces:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
INFO Mon Jun 9 15:04:05 2026: The ball has come to rest
|
||||
height: 0.001 m
|
||||
velocity: 0.000 m/s
|
||||
bounces: 47
|
||||
|
||||
.. _Standardmath:
|
||||
|
||||
The "functions" in this section are preprocessor macros replaced with the corresponding C standard library math
|
||||
|
||||
Reference in New Issue
Block a user