Using the Profiling Trace service¶
The Profiling Trace service collects runtime profiling data from the Kanzi Engine and writes it to a JSON trace file compatible with the Perfetto trace viewer.
Platform support¶
The Profiling Trace service builds from sources on all known Kanzi target platforms. The target platform must support writing files to the filesystem and allow developers to obtain those files from the filesystem.
How the Trace service works¶
The Trace service operates as a three-stage pipeline:
Collect – The service copies profiling samples from the Kanzi Engine profilers into internal storage.
Store – Samples accumulate in storage until a write trigger occurs.
Write – The service writes all stored samples to a JSON trace file.
You can trigger collection and writing independently using timers, commands, or events.
Understanding trace data¶
The amount of profiling data available in the trace depends on the build configuration of the Kanzi Engine. The built-in instrumentation of the Kanzi Engine uses compile-time profiling category flags that control whether profilers produce data.
Profiling build¶
In a Profiling build, the compiler enables all profiling categories and the trace contains the full set of data:
Startup profiling – Application startup timing (requires Application registration)
Main loop profiling – Frame timing, stage durations (Input, User, Render)
Domain node profiling – Node operations
Domain layout profiling – Layout operations
Domain render profiling – Render operations
Resource profiling – Resource loading timing
Default registry profiling – All interval profilers registered in the default profiling registry
Named interval profiling – Named interval profilers from the default profiling registry
Custom collection tasks – Any additional profiling data registered through the API, such as Performance Service counters and Log Service entries
Debug and Release builds¶
In Debug and Release builds, the compiler disables the built-in profiling categories of the Kanzi Engine. The Kanzi Engine profilers exist but produce no samples. The trace contains only:
Default registry profiling – All interval profilers registered in the default profiling registry
Named interval profiling – Named interval profilers from the default profiling registry
Custom collection tasks – Any additional profiling data registered through the API
To get the most detailed trace data, use a Profiling build of your application.
Triggering a trace write¶
There are several ways to trigger a trace write:
On-demand command – Use the
tracecommand from the local or remote console. This collects and writes immediately.One-shot timer (
WritingTimerOnceInterval) – Writes the trace once after a specified delay in milliseconds. Use this to capture startup behavior.Repeating timer (
WritingTimerRepeatInterval) – Writes the trace at regular intervals. Use this for continuous monitoring.On exit (
WritingOnExitEnabled) – Writes the trace when the application shuts down.Frame duration threshold (
WritingOnFrameDurationTreshold) – Writes the trace when a frame exceeds the specified duration in milliseconds. Use this to catch performance spikes. Kanzi Monitor disables this trigger when running in Kanzi Studio Preview.
Controlling sample collection and storage¶
By default, each collection replaces the previously stored samples. This means the trace file contains only the most recent data from each profiler buffer.
To accumulate samples over time, enable CollectWithAppendingEnabled. When appending is enabled, each collection adds new samples to the existing storage instead of replacing it. This builds up a longer trace at the cost of increased memory usage.
When CollectWithAppendingEnabled is enabled, you can also use CollectingOnFullSampleBufferEnabled (enabled by default). This automatically collects samples from a profiler when its sample buffer becomes full, preventing data loss when profilers produce data faster than the collection timer runs.
The CollectingTimerRepeatInterval setting controls how often samples are collected independently of writing. This is useful when you want to collect frequently to avoid losing samples, but write less often.
Understanding output files¶
The trace output file is named using the pattern:
<SessionLabel>_<timestamp>_<sequence>.json
Where <SessionLabel> is the configured session label (default: tracing_output), <timestamp> is the session start time, and <sequence> is incremented for each write within the session.
On Windows and platforms other than Android, the output file is written to the current working directory.
On Android, the output file is written to
/sdcard/.
To view the output file, open it in the Perfetto trace viewer.
Adding custom collection tasks¶
You can register custom collection tasks to include additional profiling data in the trace output. A collection task is a callback that the Trace service invokes when collecting samples. The callback writes profiler data into the sample storage, which is then exported to the trace file.
Each collection task has an event type that determines how the data appears in the trace viewer:
"duration"– Time intervals with a start and end. Use for profiling scoped operations such as function durations and stage timings. Appears as spans in the trace timeline."instant"– Single points in time with no duration. Use for events such as log messages. Appears as markers in the trace timeline."counter"– Numeric values over time. Use for metrics such as FPS and memory usage. Appears as counter tracks in the trace viewer.
To register a custom collection task:
#include "profilinghelper_collector.hpp"
void onCollectMyData(SampleDataStorage& storage)
{
// Write profiler registry data into the storage.
storage.writeRegistry<MyProfilerType>(myProfilerRegistry);
}
ThreadIndex mainThreadIndex = SampleCollector::getKanziMainThreadIndex();
SampleCollector::registerGeneralCollectionTask(
"my_custom_profiling", // Name for the data storage
onCollectMyData, // Callback invoked during collection
mainThreadIndex, // Thread index for trace visualization
"duration"); // Event type: "duration", "instant", or "counter"
Available commands¶
Command |
Description |
|---|---|
|
Write trace to file. |
kzTrace: engine-native tracing¶
In addition to the Monitor profiling trace, Kanzi Monitor supports Kanzi engine-native tracing through the overwatch.kztrace command. This uses the kanzi::logTraceToFile() API from the Kanzi Engine tracing subsystem (kanzi/core/tracing/tracing.hpp).
kzTrace captures data from the Kanzi Engine kzTrace scope macros, covering frame stages, rendering, resource loading, and node operations. Like the Monitor profiling trace, kzTrace includes engine-internal instrumentation, but the two systems collect data independently using different mechanisms. It produces Chrome Trace JSON that you can view in Perfetto alongside Monitor profiling traces.
See the Tracing API reference and Tracing application configuration in the Kanzi Engine documentation.
Note
kzTrace is only available in Debug and Profiling builds (KANZI_TRACING_BUILD). In Release builds, overwatch.kztrace returns an error message.
kzTrace output files are named kztrace_<timestamp>_<sequence>.json and are written to the same output directory as Monitor profiling traces.
See Using the Overwatch service for the overwatch.kztrace and overwatch.fetchkztrace command reference.