Exporting Debug Information

Since EnsensoSDK 2.1 a more feature rich method to debug an NxLib based application is available with the NxProfiler tool. NxProfiler can open and visualize *.nxlog files which consist of collected debug information in a proprietary binary format.

General working principle

  • Each internal NxLib threads will write debug information according to the global logging level /Debug/Level into a ring buffer. Each thread has its own buffer with the size specified in /Debug/BufferSize.

  • The application should call nxLibGetDebugBuffer to collect the buffered data from all threads and write it into binary file with extension ‘.nxlog’.

    • Repeated calls to nxLibGetDebugBuffer can retrieve more data which can be simply append to the binary file

  • The NxProfiler application can then open the .nxlog file and visualize the debug data on a timeline.

Debug levels

There are 4 different debug levels:

  • Off: Disables profiling outputs.

  • Info: Outputs only basic information like command executions. Can be used without measurable influence on the application performance.

  • Debug: Outputs more information about sub steps of commands or helper threads.

  • Trace: Full logging including all API calls and parameter values. We recommend to use this level only for debugging purposes.

NxLibItem debug = NxLibItem()[itmDebug];

// Set desired debug level
debug[itmLevel] = valInfo;

Generate custom debug information

A user application can insert its own debug information into the NxLib’s internal logging mechanism. This allows to easily debug multithreaded timings and interactions and between NxLib and application specific code in NxProfiler.

// The scope will determine the lifetime of the following NxLibDebugBlocks
{
	// To track a certain function or code segment simply create a NxLibDebugBlock object
	// The lifespan of this DebugBlock will be visible in the NxProfiler
	NxLibDebugBlock db1("Example Block 1", nxdDebug);

	// Simple message prints will inherit the debug level of its parent block
	nxLibWriteDebugMessage("Example Message");

	// do stuff...

	// It's possible to nest the blocks into each other:
	NxLibDebugBlock db2("Example Block 2");

	// do more stuff...

	// db1 and db2 will be destroyed here and the blocks will be implicitly closed
}

Debug Log Files with Automatic Rotation

Since EnsensoSDK 2.2.129 you can also use the /Debug/FileOutput node to let NxLib automatically write log files onto the hard disk. When starting the logging or after the current log file has reached MaxFileSize a new log file will be created automatically based on FolderPath and FilePrefix. Old log files will be deleted if the size of old logs with the same prefix exceeds MaxTotalSize.

NxLibItem debugOut = NxLibItem()[itmDebug][itmFileOutput];

// Set output directory
debugOut[itmFolderPath] = "C:\\my_log_folder";

// Keep 100MB of logging data
debugOut[itmMaxTotalSize] = 100e6;

// enable automatic writing of log files
debugOut[itmEnabled] = true;

Retrieving debug information

There are two ways of retrieving the debug information.

  • The first option is to copy the debug buffer directly with nxLibGetDebugBuffer. With this method the debug information is still in binary form and can be interpreted by NxProfiler.

    Note

    You can freely concatenate several retrieved buffers as long as they originate from the same NxLib instance.

  • The second option is to get the information in text form with nxLibGetDebugMessages, but we recommend to use nxLibGetDebugBuffer because the text format cannot hold all raw debug data and cannot be interpreted by NxProfiler. Further more NxProfiler can later generate this text output format from the binary data returned by nxLibGetDebugBuffer.

// variant 1: binary format
std::vector<char> dbgBuffer;
bool bufferOverflow;
nxLibGetDebugBuffer(dbgBuffer, true, &bufferOverflow);

// write buffer to file
std::ofstream debugFile("debugData.nxlog", std::ios::out | std::ios::binary);
if (!dbgBuffer.empty()) debugFile.write((char*)&dbgBuffer[0], dbgBuffer.size() * sizeof(dbgBuffer[0]));
debugFile.close();

// variant 2: text output
std::string text = nxLibGetDebugMessages();
* variant 1: write buffer to file
set_framegrabber_param(Handle'do_export_debug_buffer', ['append''C:/path/to/file.nxlog'])

* variant 2: text output
get_framegrabber_param(Handle'debug_messages'Messages)