Unit 10 · lesson

WPILib Logs and ROS 2 Logs: Read the Runtime Before You Merge the Story

Robot systems often contain more than one logging system.

A Java/WPILib application can record telemetry and events with WPILib data logs. A ROS 2 node can produce ROS log messages with logger names and severity levels. Both records can help explain a failure, but they are created by different runtimes and should not be merged into one story without evidence connecting them.

This lesson teaches you how to read both kinds of record.

WPILib data logs preserve robot-application telemetry

From the previous lesson, a WPILib Java application can start managed logging with:

DataLogManager.start();

and record a text event with:

DataLogManager.log(
    "range update rejected"
    + " id=range-front"
    + " value=3.70 m"
);

It can also append typed numeric values through entries such as DoubleLogEntry.

WPILib data logs are built for robot telemetry. They can preserve timestamped records that are useful after a run.

A WPILib log entry answers questions about what the WPILib application chose to record.

It does not automatically tell you what a ROS 2 node logged.

ROS 2 has its own logging subsystem

ROS 2 Jazzy nodes use the ROS logging infrastructure.

The official ROS 2 logging documentation defines these severity levels, from least to most severe:

DEBUG
INFO
WARN
ERROR
FATAL

A logger processes messages at or above its configured severity threshold.

A ROS node has a logger associated with its node name and namespace. Logging output can be sent to targets including:

  • the console;
  • log files on disk;
  • the /rosout topic on the ROS 2 network.

Those destinations are part of the ROS runtime, not WPILib's DataLogManager.

Severity communicates importance, not certainty

A message at ERROR severity is more severe than an INFO message. That does not make the statement inside the message automatically true.

For example:

[ERROR] [motor_guard]: motor response missing

is evidence that a logger produced an error-level message with that text.

You still need to inspect what condition caused the logger to emit it.

Severity helps operators filter and prioritize records. It does not replace technical verification.

What a ROS log message carries

ROS 2 exposes a log message definition through rcl_interfaces/msg/Log.

Important fields include:

  • timestamp;
  • severity level;
  • logger name;
  • message text;
  • source file;
  • source function;
  • source line.

That combination can give a much richer record than a bare print statement.

A simplified log record might be presented as:

time=42.140
level=WARN
name=sensor_bridge
msg="range input outside declared interval"

The exact console formatting can vary. The semantic information is what matters.

Source identity matters

Compare these two messages:

range update rejected value=3.70 m
range update rejected value=3.70 m

The text is identical.

If the first came from a WPILib DataLogManager message and the second came from a ROS logger named sensor_bridge, they are still separate observations.

Do not assume one system copied the value from the other unless the architecture and runtime evidence show that data path.

A strong diagnosis records the source of every log line.

Compare the two logging systems

QuestionWPILib data logROS 2 log
RuntimeWPILib robot applicationROS 2 logging subsystem
Common Java entry point in this courseDataLogManager / typed log entriesnot a WPILib Java API
Useful contexttimestamp, entry name, typed value or messagetimestamp, severity, logger name, message, source context
Typical userobot telemetry and event recordingnode/runtime diagnostic messages
Network-visible log pathnot /rosout/rosout may carry logs when enabled
Proves physical recovery?nono

The systems can coexist in a larger robot architecture. The table prevents vocabulary from turning coexistence into false equivalence.

A log should let you ask the next question

Suppose WPILib records:

12.140 rawRangeMeters=3.70
12.141 message="range update rejected id=range-front"
12.141 sourceHealthy=false

The next question may be:

Where did the raw value come from?

Suppose a ROS log separately records:

12.138 WARN sensor_bridge "input queue delayed"

Now the timing is interesting. The ROS warning occurred shortly before the Java-side rejection.

But timing proximity is not enough to conclude:

The delayed ROS queue caused the Java value 3.70.

You would need evidence connecting the systems and the specific data item.

Logs help form hypotheses. They do not grant causation automatically.

Logger names make multi-node systems easier to inspect

Imagine a ROS system with:

sensor_bridge
motor_guard
navigation

A message from sensor_bridge and a message from motor_guard may refer to the same high-level incident but come from different responsibilities.

For example:

WARN sensor_bridge: range sample rejected
INFO motor_guard: movement inhibited

The logger names help separate observation from response.

A weak report might say:

ROS logged a sensor error and stopped the robot.

A stronger report keeps the records distinct:

sensor_bridge emitted a warning about a rejected range sample. motor_guard separately logged that its movement-inhibit state became active.

Physical stopping still requires physical or controller-response evidence.

Log level configuration changes what you can see

ROS loggers can filter messages by severity.

If the logger is configured to show INFO and above, DEBUG messages may not appear.

That means absence of a debug line does not necessarily prove the code path never executed. The message may have been filtered.

This is an important diagnostic lesson:

An observation can be missing because the event did not occur, or because your instrumentation did not record/show it.

Always understand the logging configuration before using absence as evidence.

WPILib logging has instrumentation choices too

A WPILib application only records the values and events its logging design actually captures.

If you never create a log entry for raw range input, the data log cannot later reconstruct the raw input history from nowhere.

A missing record may mean:

  • the event did not happen;
  • the code never reached the logging call;
  • logging was not started;
  • the data was never instrumented;
  • a different logging source contains the evidence.

Good instrumentation is part of testable system design.

Do not log secrets or unnecessary personal data

Technical logs can become long-lived artifacts. They may be copied, uploaded, or shared during debugging.

Do not put credentials, tokens, passwords, student personal information, or unrelated private data into log messages.

For this course, appropriate context includes component IDs, controlled sensor values, units, thresholds, software states, logger names, and timestamps.

Worked cross-runtime review

You receive these records:

WPILib data log

42.120 /sensors/front/rawRangeMeters 3.70
42.121 messages "range update rejected id=range-front"
42.121 /sensors/front/healthy false

ROS 2 log

42.100 WARN sensor_bridge "range source timeout count=1"

ROS graph inspection

/sensor_bridge
/motor_guard

What can you defend?

You can say the WPILib application recorded a raw 3.70 value, a rejection event, and an unhealthy modeled state. You can say a ROS logger named sensor_bridge produced the supplied warning. You can say two node names were visible in the inspected graph state.

What remains unproven?

You cannot yet prove that the ROS timeout produced the WPILib raw value, that the two applications are directly connected, or that a physical sensor failed.

That is the discipline you will use in the lab.

Your turn

Classify each record by its evidence source:

DataLogManager.log("movement inhibited")

WARN motor_guard "movement inhibited"

ros2 node list -> /motor_guard

wheel encoder measured 0 rpm

For each one, write:

  • source/runtime;
  • strongest supported claim;
  • one stronger claim it does not establish by itself.

In the final lesson, you will combine exception, test, log, and runtime records into an evidence timeline without allowing the timeline to turn correlation into a made-up cause.