Skip to content
This repository was archived by the owner on May 3, 2024. It is now read-only.

Logging

Cai Biesinger edited this page Jun 25, 2018 · 2 revisions

For very quick debugging, when you don't feel like bringing out the debugger, you might be inclined to just output some stuff to the console. At least, that's what we did previously in our Python-based project (also because there was no decent debugger). This led to console output coming from random places later on that we didn't want, and was a general mess.

To avoid this, we made a nice logging system. The purpose is that you write debug output into your code in logical places, and then you simply only turn on that output when you need it. This requires two things to work correctly:

Preparation

Before sending messages to the log, you'll need to initialize it by calling this function:
Log.Begin();

Setting the output destination

This sets the destination of the logging output. Either to a file or to a console.
The file name will be the date and ".log" like YYYY-MM-DD-HH-MM-SS.log
Log.Destination = WriteDestination.CONSOLE (Default)

WriteDestination Description
ALL Writes logging to both a file and the console
FILE Writes logging info to a file only
CONSOLE Writes logging to the console only

Sending messages to the log

When outputting a statement, variable, or data, use this:
Log.Output(Log.Severity.<Severity>, Log.Source.<Source>, "Your output here");

Replace the severity and source with the appropriate values. Our guidelines are as follows:

Severity Description Example
DEBUG Used for program flow debugging and light troubleshooting "Starting distance sensor handler"
INFO Used for troubleshooting "Distance sensor initialized successfully"
WARNING When an issue arises, but functionality sees little to no impact "Distance sensor took longer than expected to find value"
ERROR When an issue arises that causes significant loss of functionality to one system "Failed to tare motor, turning off"
FATAL When an issue arises that causes loss of functionality to multiple systems or complete shutdown "Current limit reached, shutting down all motors"
Source Notes
ALL Don't use this for outputting, only for setting display level.
MOTORS Motors and their controllers
NETWORK Anything that sends, receives, or handles packets or connections
GUI Anything directly regarding the UI that the user interacts with, or input devices
SENSORS Anything relating to sensors
CAMERAS Anything relating to cameras or images thereof
SUBSYSTEM Messages that come from subsystem handlers, that don't fit into an above category
HARDWAREIO Anything that directly interfaces with hardware, like communications buses
OTHER For anything that doesn't have a place. Find yourself using this often? Feel free to suggest another source!

Setting Output

Now that you have log output in all the relevant places, how do you configure the logger to output only what you want?
Remember back in Getting Started we set up the logger? That's where you need to configure output (it can also be changed during runtime, so you can have it dynamically change if you'd like, but this may be confusing).
Set these two values accordingly:
Log.SetGlobalOutputLevel(Log.Severity.INFO);
This determines the lowest severity messages that will be output (i.e. setting this to INFO will prevent all DEBUG messages from being output). Anything WARNING and up will always be output, regardless of this setting.
This is configurable on a per-source basis. If you are working on something motor-related, you can set MOTORS to DEBUG, and leave everything else as INFO to get only relevant output. This would be done as such:
Log.SetSingleOutputLevel(Log.Source.MOTORS, Log.Severity.DEBUG);
You can also do the opposite (for example, set the global level to DEBUG, but mute debug output from one system by setting it to INFO).

As a side note: if you are interested in seeing the watchdog timers be sent on the network, call:
Server.OutputWatchdogDebug = true;
or
Client.OutputWatchdogDebug = true;

Please note: WARNING, ERROR, and FATAL messages will always be output from any system, regardless of these settings. They are meant to switch DEBUG or INFORMATION output on/off for specific systems to help with debugging.

Exceptions

When you encounter an Exception in your code, we recommend that you output a log message with WARNING, ERROR, or FATAL (depending on how serious this error is), along with a message describing when the error occurred. Right after, you should output the Exception & stack trace using Log.Exception(). Here's a code snippet showing how this is intended to be done:

try
{
    // Some code that goes wrong.
}
catch(Exception Exc)
{
    Log.Output(Log.Severity.ERROR, Log.Source.GUI, "Something went wrong while demonstrating the Log output!");
    Log.Exception(Log.Source.GUI, Exc);
}

Trace Logging

This is meant for outputting very detailed messages about a single instance of something, that would create too much noise if DEBUG were used. This usually includes raw communications data, calibration values, and detailed execution information inside a component.

To turn this on within a Scarlet component, simply set <Part>.TraceLogging = true;. All parts inheriting from ISensor, IMotor, and ISubsystem are required to implement this, and some other parts/systems do as well.

To implement this in your own system, simply add a property to your class, as such:
public bool TraceLogging { get; set; }
Then, to output:
if (this.TraceLogging) { Log.Trace(this, "Your message"); }
You must have it configurable via this property, and it must default to false. Make sure to include the if in the output line, otherwise you will always get output.

Trace output shows up in the console with the originating class name and a unique instance ID (the value of the number does not mean anything, but it can be used to differentiate between two instances of the same class). It is output regardless of output level.

Errors

This is meant for when a specific, predictable error occurs that you are sending back to base. In our system, we defined a list of common errors that would get sent back and shown to the operator. The error code contains both the error, and the origin system, so you only need to call this:
Log.Error(0x0403);
This will output the error to the console. Sending the error packet is done separately.

Logo

Quick Links:
NuGet
Pin Diagrams: RPi | BBB
Developers: CaiB, Baldstrom

General Info:
Home
Common Issues
Getting Started
Supported Devices

Sections:
Logging
DataLog
Filters
Hardware I/O:
- BeagleBone Black
- Raspberry Pi
- Pin Diagrams: RPi | BBB
- GPIO: Using | For Beginners
- PWM: Using | For Beginners
- ADC: Using | For Beginners
- I2C: Using | For Beginners
- SPI: Using | For Beginners
- UART: Using | For Beginners
- CAN: Using | For Beginners
Networking
Sensors
StateStore

Other: Interesting Case Studies

Clone this wiki locally