Common Vision Blox 15.0
Loading...
Searching...
No Matches
Logging & Telemetry

Telemetry in Common Vision Blox (CVB) enables the collection, logging, and tracing of runtime information to support diagnostics, performance monitoring, and product improvement. CVB uses OpenTelemetry standards for its telemetry infrastructure, ensuring compatibility with modern monitoring tools.

Overview

Telemetry covers:

  • Logging: Captures events, warnings, and errors during operation.
  • Tracing: Records execution paths and performance metrics.

Telemetry in CVB has two main use cases:

  • Creation of CVB debug information: CVB modules collect traces and logs that can be sent to the Stemmer Imaging support to help with identifying user issues and bugs.
  • Implementing telemetry in user code: This gives users easy access to a tracing framework to use in their own applications.

The created log files can be viewed using the LogGUI, which is found under %CVB%Applications (Windows) and /opt/cvb/bin (Linux, available in PATH by default).

Configuration

CVB telemetry can be configured using the TelemetryCLI tool, which is located under %CVB%Applications (Windows) and /opt/cvb/bin (Linux, available in PATH by default). Using this tool you can enable/disable logging and tracing for individual modules, and define how logs and traces should be collected using the Open Telemetry Collector (cvotelcol.exe). The cvotelcol.exe needs to be running for logs/traces to be collected. It is located in the same directory as the TelemetryCLI and can also be started using the TelemetryCLI.

Enabling logging or tracing in CVB modules introduces only a minimal performance overhead. When telemetry is turned off, the related code paths are effectively no-ops, with only an additional if-check performed in some cases. This ensures that disabled telemetry does not impact application performance.

Module Configuration

Modules are DLLs or executables that can produce logs or traces. This includes CVB modules but also user modules.

List built-in modules e.g. GenICam.vin, CVFactory etc:

TelemetryCLI modules list

Print configuration in json format (loaded on startup):

TelemetryCLI modules config

Add MyApp to the modules configuration:

TelemetryCLI modules MyApp add

Remove MyApp from the modules configuration:

TelemetryCLI modules MyApp remove

Logging options for MyApp in the modules configuration:

TelemetryCLI modules MyApp logging on
TelemetryCLI modules MyApp logging off
TelemetryCLI modules MyApp logging global

Set the log level for MyApp (case insensitive):

TelemetryCLI modules MyApp loglevel DEBUG

Tracing options for MyApp in the modules configuration:

TelemetryCLI modules MyApp tracing on
TelemetryCLI modules MyApp tracing off

Global logging options in the modules configuration:

TelemetryCLI global logging on
TelemetryCLI global logging off

Global log level in the modules configuration (case insensitive):

TelemetryCLI global loglevel DEBUG

Global tracing options in the modules configuration:

TelemetryCLI global tracing on
TelemetryCLI global tracing off

Component Configuration

Components are Open Telemetry Collector components that can either be receivers or exporters. They may either be on or off. Some can have an additional configuration.

List all available components:

TelemetryCLI components list

Print configuration in yaml format (loaded on startup if available):

TelemetryCLI components config

Options for otlpjsonfile/logs in the components configuration:

TelemetryCLI components otlpjsonfile/logs on
TelemetryCLI components otlpjsonfile/logs off
TelemetryCLI components otlpjsonfile/logs include <folder_path>

Options for otlpjsonfile/traces in the components configuration:

TelemetryCLI components otlpjsonfile/traces on
TelemetryCLI components otlpjsonfile/traces off
TelemetryCLI components otlpjsonfile/traces include <folder_path>

Enable writing logs and traces to file:

TelemetryCLI components file/logs on
TelemetryCLI components file/logs path <file_path>
TelemetryCLI components file/traces on
TelemetryCLI components file/traces path <file_path>

Run cvotelcol.exe with the current modules and component configuration (run is the default argument). This will start the collection of logs / traces using the configured components:

TelemetryCLI run

CVOtelCol

The cvotelcol.exe is used for the actual collection (and processing) of traces and logs that applications emit. It can be started, as mentioned in the configuration section, by calling TelemetryCLI run. The cvotelcol.exe is able to export in otlpjson format, which is based on the OTLP Format and can be used together with other applications that support this format. An example for such an application would be Jaeger, which is used for analyzing and visualizing Open Telemetry traces.

Using Telemetry in your own application

For C++ you will need to include CVB++. For .NET you will need to reference CVB.NET (Stemmer.Cvb.dll and Stemmer.Cvb.Telemetry.dll).

Below are a few examples, for more information have a look at the Telemetry API documentation for CVB++ or CVB.NET.

Creating the module

First, a Telemetry module has to be defined in the application. After a module has been created, its configuration is immutable, as it is only read on module creation.

#include <CVTelemetry/telemetry.hpp>
// use this macro at the top of your entry point file
CVB_TELEMETRY_MODULE_("MyApp", "1.0.0")

using System;
namespace MyApp
{
public static class MyAppLogging
{
// there should only be a single module for the application
public static Module TelemetryModule { get; } = new Module("MyApp", new Version(1, 0, 0));
}
}

After you have created your module, you can use it to create logs or traces.

Logs

Logs have a LogLevel, a Message and an arbitrary amount of Attributes. Attributes are a list of key-value-pairs, where the values can be long, double, string or bool values.

#include <CVTelemetry/telemetry.hpp>
void MyApp::SomeFunction()
{
// log a message
CVB_LOG_INFO << "some info message";
CVB_LOG_DEBUG << "some debug message";
// log a message and an attribute
CVB_LOG_DEBUG << "some debug message" << ("stringKey", "some string value");
}

using Logger = MyAppLogging.TelemetryModule;
public void SomeFunction()
{
// simple logging (log is immediately sent)
Logger.LogDebug("Some Debug Message");
Logger.LogInfo("Some Info Message");
Logger.Log(LogLevel.Info, "Some Info Message");
// extended logging
using (var log = Logger.LogExtended(LogLevel.Info)
.AddMessage("Some Info Message")
.AddAttribute("stringKey", "some string value"))
{
if (something)
log.AddAttribute("intKey", 42);
else
log.AddAttribute("boolKey", false);
} // log is sent once disposed
}

Traces

Traces allow you to record the execution flow of specific operations in your application. Each trace represents a span, which can include attributes, success/failure status, and return values.

#include <CVTelemetry/telemetry.hpp>
void MyApp::SimpleFunction()
{
// create span with name "SimpleFunction". Spans use the function name as name if no custom name is provided.
CVB_TRACE;
// some code...
// sets the spans status to success/ok.
CVB_TRACE_SUCCEED;
}
void MyApp::LoadImage(std::string format)
{
// create span with name "LoadImage". Spans use the function name as name if no custom name is provided.
CVB_TRACE;
try
{
// add the format parameter as attribute
span("format", format);
// some code...
span.Succeed();
}
catch (...)
{
span.Fail();
}
}
bool MyApp::IsSuccess()
{
// create span with name "IsSuccess". Spans use the function name as name if no custom name is provided.
CVB_TRACE;
// some code...
bool success = true;
// ReturnBool automatically sets the span status depending on the boolean.
span.ReturnBool(success);
}

using Logger = MyAppLogging.TelemetryModule;
public void SimpleFunction()
{
// create span with name "SimpleFunction". Spans use the function name as name if no custom name is provided.
using (var span = Logger.StartSpan())
{
// some code...
span.Succeed();
}
}
public void LoadImage(string format)
{
// create span with name "LoadImage". Spans use the function name as name if no custom name is provided.
using (var span = Logger.StartSpan())
{
try
{
// add the format parameter as attribute
span.AddAttribute("format", format);
// some code...
span.Succeed(); // set span status to success/ok
}
catch
{
span.Fail(); // set span status to error
}
} // trace is sent once disposed
}
public bool IsSuccess()
{
// create span with name "IsSuccess". Spans use the function name as name if no custom name is provided.
using (var span = Module.StartSpan())
{
// some code...
bool success = true;
// ReturnBool automatically sets the span status depending on the boolean.
return span.ReturnBool(success);
}
}
Span StartSpan([CallerMemberName] string name="")