APM Desktop Viewer
A simple desktop application built using Qt for viewing APM data in a more natural hierarchical manner.
The raw APM data from QuestDB returns the APM data in a flat tabular form. This format does not reflect the hierarchical function call chain when responding to a REST API request. This application parses the flat CSV data and renders a forrest of trees, where each tree represents the function call chain for a specific REST API request.
Download
The project uses only Qt, and no other dependencies are needed (other than a build environment if building without using an IDE). Pre-built binary can be downloaded from the github releases page.
Strategy
There are a couple of different ways in which we can convert the flat CSV data into a hierarchical model.
Use the
caller_function
property to determine the caller of the current APM Process line, and build the hierarchy based on it.Compute the end time from the standard
timestamp
andduration
properties. Any function call that ends before a previously parsed process record is a child of that record. I have used this strategy to build the hierarchical tree model.
CSV Data
CSV data can be exported from QuestDB. I used our Grafana dashboard that displays APM data to export the necessary APM data as CSV. The following example query is how I exported the latest APM data to CSV.
Variable
I tried to use with
to retrieve the id
s for the root APM records (each record corresponds to a REST API endpoint), and then retrieve all the APM process records for those root records. This ran into a bug/limitation in QuestDb. QuestDB does not support join queries on non-timestamp or symbol columns. Our APM records have a BSON ObjectId as the id
, and since there will be millions of these, we cannot make that a symbol
type column. To get around this limitation, I created a variable in Grafana with the latest APM ids with the following query:
Note that, this variable references other variables already defined in the dashboard.
Full data
The full APM records can then be retrieved using the following query:
We also add an extra timestamp_iso
column in the output which gives the timestamp
with micro-second precision. The standard timestamp
is stored in QuestDB with micro-second precision, but standard SQL export only provides second level precision. We need the full precision to build the call chain hierarchy properly.
Note: Using the /exp
REST API to dump the table does return timestamps in ISO format with micro-second precision. That option is more useful for full data exports, not small exports based on query filters.
User Interface
The interface is extremely simple. The window displays a QTreeView and QTableView to render the APM data. The tree view displays the function call chain when responding to REST API endpoints. The table view displays additional APM data that was collected for each process.

Application running on Windows.
