Enregistrement

Voir la page de journalisation pour plus de détails sur les fonctionnalités disponibles.

Utilisation des instructions de journal dans le code

Journalisation de base

Le code suivant affichera un message de journal à partir d’un nœud ROS 2 avec la gravité DEBUG :

// printf style
RCLCPP_DEBUG(node->get_logger(), "My log message %d", 4);

// C++ stream style
RCLCPP_DEBUG_STREAM(node->get_logger(), "My log message " << 4);

Notez que dans les deux cas, aucune nouvelle ligne de fin n’est ajoutée, car l’infrastructure de journalisation en ajoutera automatiquement une.

Se connecter uniquement la première fois

Le code suivant affichera un message de journal d’un nœud ROS 2 avec la gravité INFO, mais uniquement la première fois qu’il est atteint :

// printf style
RCLCPP_INFO_ONCE(node->get_logger(), "My log message %d", 4);

// C++ stream style
RCLCPP_INFO_STREAM_ONCE(node->get_logger(), "My log message " << 4);

Journaliser tout sauf la première fois

Le code suivant affichera un message de journal d’un nœud ROS 2 avec la gravité WARN, mais pas la toute première fois qu’il est atteint :

// printf style
RCLCPP_WARN_SKIPFIRST(node->get_logger(), "My log message %d", 4);

// C++ stream style
RCLCPP_WARN_STREAM_SKIPFIRST(node->get_logger(), "My log message " << 4);

Journalisation limitée

Le code suivant affichera un message de journal d’un nœud ROS 2 avec la gravité ERROR, mais pas plus d’une fois par seconde.

Le paramètre d’intervalle spécifiant les millisecondes entre les messages doit avoir un type de données entier afin qu’il puisse être converti en rcutils_duration_value_t (un int64_t) :

// printf style
RCLCPP_ERROR_THROTTLE(node->get_logger(), *node->get_clock(), 1000, "My log message %d", 4);

// C++ stream style
RCLCPP_ERROR_STREAM_THROTTLE(node->get_logger(), *node->get_lock(), 1000, "My log message " << 4);

// For now, use the nanoseconds() method to use an existing rclcpp::Duration value, see https://github.com/ros2/rclcpp/issues/1929
RCLCPP_ERROR_STREAM_THROTTLE(node->get_logger(), *node->get_clock(), msg_interval.nanoseconds()/1000000, "My log message " << 4);

La journalisation a été étranglée sauf la première fois

Le code suivant affichera un message de journal d’un nœud ROS 2 à la gravité DEBUG, pas plus d’une fois par seconde, en ignorant la toute première fois qu’il est atteint :

// printf style
RCLCPP_DEBUG_SKIPFIRST_THROTTLE(node->get_logger(), *node->get_clock(), 1000, "My log message %d", 4);

RCLCPP_DEBUG_SKIPFIRST_THROTTLE(node->get_logger(), *node->get_clock(), 1000, "My log message " << 4);

Démo de journalisation

Dans cette démo, différents types d’appels de journal sont affichés et le niveau de gravité des différents enregistreurs est configuré localement et en externe.

Démarrez la démo avec :

ros2 run logging_demo logging_demo_main

Au fil du temps, vous verrez la sortie de divers appels de journal avec différentes propriétés. Pour commencer, vous ne verrez que la sortie des appels de journal avec la sévérité INFO et supérieure (WARN, ERROR, FATAL). Notez que le premier message ne sera enregistré qu’une seule fois, bien que la ligne soit atteinte à chaque itération, car il s’agit d’une propriété de l’appel de journal utilisé pour ce message.

Configuration du répertoire de journalisation

Le répertoire de journalisation peut être configuré via deux variables d’environnement : ROS_LOG_DIR et ROS_HOME. La logique est la suivante:

  • Utilisez $ROS_LOG_DIR si ROS_LOG_DIR est défini et non vide.

  • Sinon, utilisez $ROS_HOME/log, en utilisant ~/.ros pour ROS_HOME s’il n’est pas défini ou s’il est vide.

Par exemple, pour définir le répertoire de journalisation sur ~/my_logs :

export ROS_LOG_DIR=~/my_logs
ros2 run logging_demo logging_demo_main

Vous trouverez alors les logs sous ~/my_logs/.

Alternativement, vous pouvez définir ROS_HOME et le répertoire de journalisation lui sera relatif ($ROS_HOME/log). ROS_HOME est destiné à être utilisé par tout ce qui a besoin d’un répertoire de base. Notez que ROS_LOG_DIR doit être non défini ou vide. Par exemple, avec ROS_HOME défini sur ~/my_ros_home :

export ROS_HOME=~/my_ros_home
ros2 run logging_demo logging_demo_main

Vous trouverez alors les logs sous ~/my_ros_home/log/.

Configuration au niveau de l’enregistreur : par programmation

Après 10 itérations, le niveau de l’enregistreur sera défini sur DEBUG, ce qui entraînera la journalisation de messages supplémentaires.

Certains de ces messages de débogage entraînent l’évaluation de fonctions/expressions supplémentaires, qui étaient auparavant ignorées car les appels de journal DEBUG n’étaient pas activés. Voir le code source de la démo pour plus d’explications sur les appels utilisés, et voir la documentation de journalisation rclcpp pour une liste complète des appels de journalisation pris en charge.

Configuration au niveau de l’enregistreur : externe

À l’avenir, il y aura une approche généralisée de la configuration externe des enregistreurs au moment de l’exécution (similaire à la façon dont rqt_logger_level dans ROS 1 permet la configuration des enregistreurs via des appels procéduraux à distance). Ce concept n’est pas encore officiellement pris en charge dans ROS 2. En attendant, cette démo fournit un exemple de service qui peut être appelé en externe pour demander la configuration des niveaux d’enregistrement pour les noms connus des enregistreurs dans le processus.

La démo démarrée précédemment exécute déjà cet exemple de service. Pour remettre le niveau de l’enregistreur de la démo sur INFO, appelez le service avec :

ros2 service call /config_logger logging_demo/srv/ConfigLogger "{logger_name: 'logger_usage_demo', level: INFO}"

Cet appel de service fonctionnera sur n’importe quel enregistreur en cours d’exécution dans le processus à condition que vous connaissiez son nom. Cela inclut les enregistreurs du noyau ROS 2, tels que rcl (le package de bibliothèque client commun). Pour activer la journalisation de débogage pour rcl, appelez :

ros2 service call /config_logger logging_demo/srv/ConfigLogger "{logger_name: 'rcl', level: DEBUG}"

Vous devriez voir la sortie de débogage de rcl commencer à s’afficher.

Utilisation du composant de configuration de l’enregistreur

Le serveur qui répond aux requêtes de configuration de l’enregistreur a été développé en tant que composant afin qu’il puisse être ajouté à un système existant basé sur la composition. Par exemple, si vous utilisez un conteneur pour exécuter vos nœuds, pour pouvoir configurer vos loggers, il vous suffit de lui demander de charger en plus le composant logging_demo::LoggerConfig dans le conteneur.

Par exemple, si vous souhaitez déboguer la démo composition::Talker, vous pouvez démarrer le talker normalement avec :

Coque 1 :

ros2 run rclcpp_components component_container

Coque 2 :

ros2 component load /ComponentManager composition composition::Talker

Et ensuite, lorsque vous souhaitez activer la journalisation de débogage, chargez le composant LoggerConfig avec :

Coque 2

ros2 component load /ComponentManager logging_demo logging_demo::LoggerConfig

Et enfin, configurez tous les enregistreurs non définis sur la gravité de débogage en adressant l’enregistreur nommé vide. Notez que les enregistreurs qui ont été spécifiquement configurés pour utiliser une gravité particulière ne seront pas affectés par cet appel.

Coque 2 :

ros2 service call /config_logger logging_demo/srv/ConfigLogger "{logger_name: '', level: DEBUG}"

Vous devriez voir la sortie de débogage de tous les enregistreurs précédemment non définis dans le processus commencer à apparaître, y compris à partir du noyau ROS 2.

Configuration au niveau du journal : ligne de commande

À partir de la version Bouncy ROS 2, le niveau de gravité des enregistreurs dont la gravité n’a pas été définie explicitement peut être configuré à partir de la ligne de commande. Redémarrez la démo en incluant l’argument de ligne de commande suivant :

ros2 run logging_demo logging_demo_main --ros-args --log-level debug

Cela configure la gravité par défaut pour tout enregistreur non défini au niveau de gravité de débogage. Vous devriez voir la sortie de débogage des enregistreurs de la démo elle-même et du noyau ROS 2.

Le niveau de gravité des enregistreurs individuels peut être configuré à partir de la ligne de commande. Redémarrez la démo en incluant les arguments de ligne de commande suivants :

ros2 run logging_demo logging_demo_main --ros-args --log-level logger_usage_demo:=debug

Formatage de la sortie de la console

Si vous souhaitez un formatage plus ou moins verbeux, vous pouvez utiliser la variable d’environnement RCUTILS_CONSOLE_OUTPUT_FORMAT. Par exemple, pour obtenir en plus l’horodatage et l’emplacement des appels de journal, arrêtez la démo et redémarrez-la avec la variable d’environnement définie :

export RCUTILS_CONSOLE_OUTPUT_FORMAT="[{severity} {time}] [{name}]: {message} ({function_name}() at {file_name}:{line_number})"

Vous devriez voir l’horodatage en secondes et le nom de la fonction, le nom du fichier et le numéro de ligne imprimés en plus avec chaque message. L’option ``time`` n’est prise en charge qu’à partir de la version ROS 2 Bouncy.

Colorisation de la sortie de la console

Par défaut, la sortie est colorisée lorsqu’elle cible un terminal. Si vous souhaitez forcer son activation ou sa désactivation, vous pouvez utiliser la variable d’environnement RCUTILS_COLORIZED_OUTPUT. Par exemple:

export RCUTILS_COLORIZED_OUTPUT=0  # 1 for forcing it

Vous devriez voir que les journaux de débogage, d’avertissement, d’erreur et fatal ne sont plus colorisés maintenant.

Note

Sous Linux et MacOS, forcer la sortie colorisée signifie que si vous redirigez la sortie vers un fichier, les codes de couleur d’échappement ansi apparaîtront dessus. Dans Windows, la méthode de colorisation repose sur les API de la console. S’il est forcé, vous recevrez un nouvel avertissement indiquant que la colorisation a échoué. Le comportement par défaut vérifie déjà si la sortie est une console ou non, il n’est donc pas recommandé de forcer la colorisation.

Flux par défaut pour la sortie de la console

Dans Foxy et versions ultérieures, la sortie de tous les niveaux de débogage va à stderr par défaut. Il est possible de forcer toutes les sorties à aller sur stdout en définissant la variable d’environnement RCUTILS_LOGGING_USE_STDOUT sur 1. Par exemple:

export RCUTILS_LOGGING_USE_STDOUT=1

Sortie de console en mémoire tampon de ligne

Par défaut, toutes les sorties de journalisation ne sont pas mises en mémoire tampon. Vous pouvez forcer sa mise en mémoire tampon en définissant la variable d’environnement RCUTILS_LOGGING_BUFFERED_STREAM sur 1. Par exemple :

export RCUTILS_LOGGING_BUFFERED_STREAM=1

Exécutez ensuite :

ros2 run logging_demo logging_demo_main