Skip to content

[FEATURE] add trace heatmap chart plugin - #724

Open
shahrokni wants to merge 1 commit into
mainfrom
feat/tracheheatmapchart2
Open

[FEATURE] add trace heatmap chart plugin#724
shahrokni wants to merge 1 commit into
mainfrom
feat/tracheheatmapchart2

Conversation

@shahrokni

@shahrokni shahrokni commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Relates to perses/perses#3942

This is the bare minimum trace heat map chart. All it needs is traces and the exponential base (default 2) to bucketize the traces according to their time and duration.

The x-axis and y-axis represent the time and duration buckets respectively. Both buckets are generated dynamically.
The following picture shows a base 2 bucketing.
It also supports base 10. Choosing a proper base may vary by different cases.

Demo

image

Same queries and traces, different bases

image

Next Steps?

Checklist

  • Pull request has a descriptive title and context useful to a reviewer.
  • Pull request title follows the [<catalog_entry>] <commit message> naming convention using one of the
    following catalog_entry values: FEATURE, ENHANCEMENT, BUGFIX, BREAKINGCHANGE, DOC,IGNORE.
  • All commits have DCO signoffs.

UI Changes

  • Changes that impact the UI include screenshots and/or screencasts of the relevant changes.
  • Code follows the UI guidelines.

@shahrokni
shahrokni force-pushed the feat/tracheheatmapchart2 branch 3 times, most recently from c40e966 to 139f2ea Compare July 16, 2026 12:35
@shahrokni
shahrokni force-pushed the feat/tracheheatmapchart2 branch 5 times, most recently from b33097f to cad2d04 Compare July 21, 2026 12:18
Comment thread traceheatmapchart/schemas/traceheatmapchart.json Outdated
Comment thread traceheatmapchart/src/traceheatmap-chart-model.ts Outdated
Comment thread traceheatmapchart/src/traceheatmap-time-bucket-util.ts
Comment thread traceheatmapchart/src/traceheatmap-time-bucket-util.ts
@shahrokni
shahrokni force-pushed the feat/tracheheatmapchart2 branch 3 times, most recently from e90da96 to 30c30f1 Compare July 21, 2026 21:57
@shahrokni
shahrokni force-pushed the feat/tracheheatmapchart2 branch from 30c30f1 to 69d4258 Compare July 21, 2026 22:01
@shahrokni
shahrokni marked this pull request as ready for review July 21, 2026 22:07
@shahrokni
shahrokni requested review from a team, AntoineThebaud and Nexucis as code owners July 21, 2026 22:07
@shahrokni
shahrokni force-pushed the feat/tracheheatmapchart2 branch from 69d4258 to ec0a324 Compare July 24, 2026 09:33
Comment thread scripts/npm/npm.go Outdated

func MustGetWorkspaces(dirPath string) []string {
excludedWorkspaces := []string{"e2e"}
excludedWorkspaces := []string{"e2e", "traceheatmapchart"}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

@shahrokni shahrokni Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the moment this plugin does not include any Go files. Therefore, the pipeline throws an exception. For now, we can exclude the plugin from this part of the pipeline.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure why the plugin should not include go files. At least the sdk related files should exist.

Comment thread traceheatmapchart/.cjs.swcrc Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need these files as they are included in the repo root.

Comment thread traceheatmapchart/.swcrc Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need these files as they are included in the repo root.

Comment thread traceheatmapchart/.gitignore Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need these files as they are included in the repo root.

Comment thread traceheatmapchart/.eslintrc.js Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need these files as they are included in the repo root.

Comment thread traceheatmapchart/LICENSE Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need these files as they are included in the repo root.

Comment thread traceheatmapchart/go.mod Outdated
@@ -0,0 +1,30 @@
module github.com/perses/plugins/prometheus

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
module github.com/perses/plugins/prometheus
module github.com/perses/plugins/traceheatmapchart

Comment thread traceheatmapchart/cue.mod/module.cue Outdated
@@ -0,0 +1,17 @@
module: "github.com/perses/traceheatmapchart@v0"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
module: "github.com/perses/traceheatmapchart@v0"
module: "github.com/perses/plugins/traceheatmapchart@v0"

Comment thread traceheatmapchart/package.json Outdated
@@ -0,0 +1,63 @@
{
"name": "@perses/traceheatmap-chart-plugin",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"name": "@perses/traceheatmap-chart-plugin",
"name": "@perses-dev/traceheatmap-chart-plugin",

})(),
});

return `<div style="

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this HTML is invalid, was this ran to check?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surprisingly the HTML works just fine although it has some syntax issue, funny! Let me check.
I also found out this can fall under the XSS attack! Let's see if I can improve it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

scale: 'hourly',
getBuckets: (start, end, local) => {
const generateHourlyLabels = (ts: number) => {
const formatter = new Intl.DateTimeFormat('en-US', { hour: 'numeric' });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we avoid to hardcode the en-US locale?

elementId: generateId(column, row, 'min'),
value: ((): string | undefined => {
const indexes = bucketToFlatResultsMap[column]?.[row];
if (!indexes) return undefined;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since this does not guard against empty arrays, what would be displayed?

@shahrokni shahrokni Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understood your point right,
That should be fine to return undefined. When the Tooltip html is being built the undefined values are scaped by the filter

 return bucketDetails
                    .filter((i) => i.value)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I meant is that indexes can be [] which is thuthy

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After the fix

image

// See the License for the specific language governing permissions and
// limitations under the License.

export { getPluginModule } from './getPluginModule';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are missing component exports here.

Comment thread traceheatmapchart/package.json Outdated
"dev": "rsbuild dev",
"build": "npm run build-mf && concurrently \"npm:build:*\"",
"build-mf": "rsbuild build",
"build:cjs": "swc ./src -d dist/lib/cjs --strip-leading-paths --config-file .cjs.swcrc",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure why are we re defining the cjs.swcrc if there is one at the root that can be re used, like other plugins already do.

resultsStartTimes: Array<Pick<TraceSearchResult, 'startTimeUnixMs' | 'durationMs'>>,
local?: string
): TraceHeatMapTimeBucket => {
const startTimeStamp = min(...resultsStartTimes.map((i) => i.startTimeUnixMs));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could create a stack overflow with many traces, the min and max functions don't take arrays, they are expanded as variadic parameters, but the V8's has limits on how many parameters you can add. It will be better to use a plain loop and calculate the max and min at the same time.

@shahrokni
shahrokni force-pushed the feat/tracheheatmapchart2 branch 4 times, most recently from bb8b075 to 862d55b Compare August 5, 2026 15:16
Signed-off-by: Mahmoud Shahrokni <seyedmahmoud.shahrokni@amadeus.com>

Signed-off-by: Mahmoud Shahrokni <seyedmahmoud.shahrokni@amadeus.com>

Signed-off-by: Mahmoud Shahrokni <seyedmahmoud.shahrokni@amadeus.com>

Signed-off-by: Mahmoud Shahrokni <seyedmahmoud.shahrokni@amadeus.com>

Signed-off-by: Mahmoud Shahrokni <seyedmahmoud.shahrokni@amadeus.com>

Signed-off-by: Mahmoud Shahrokni <seyedmahmoud.shahrokni@amadeus.com>

Signed-off-by: Mahmoud Shahrokni <seyedmahmoud.shahrokni@amadeus.com>

Signed-off-by: Mahmoud Shahrokni <seyedmahmoud.shahrokni@amadeus.com>

Signed-off-by: Mahmoud Shahrokni <seyedmahmoud.shahrokni@amadeus.com>

Signed-off-by: Mahmoud Shahrokni <seyedmahmoud.shahrokni@amadeus.com>

Signed-off-by: Seyed Mahmoud Shahrokni <39291137+shahrokni@users.noreply.github.com>

Signed-off-by: Seyed Mahmoud Shahrokni <39291137+shahrokni@users.noreply.github.com>

Signed-off-by: Seyed Mahmoud Shahrokni <39291137+shahrokni@users.noreply.github.com>

Signed-off-by: Seyed Mahmoud Shahrokni <39291137+shahrokni@users.noreply.github.com>

Signed-off-by: Seyed Mahmoud Shahrokni <39291137+shahrokni@users.noreply.github.com>

Signed-off-by: Seyed Mahmoud Shahrokni <39291137+shahrokni@users.noreply.github.com>

Signed-off-by: Seyed Mahmoud Shahrokni <39291137+shahrokni@users.noreply.github.com>

Signed-off-by: Seyed Mahmoud Shahrokni <39291137+shahrokni@users.noreply.github.com>

Signed-off-by: Seyed Mahmoud Shahrokni <39291137+shahrokni@users.noreply.github.com>

Signed-off-by: Seyed Mahmoud Shahrokni <39291137+shahrokni@users.noreply.github.com>

Signed-off-by: Seyed Mahmoud Shahrokni <39291137+shahrokni@users.noreply.github.com>

Signed-off-by: Seyed Mahmoud Shahrokni <39291137+shahrokni@users.noreply.github.com>

Signed-off-by: Seyed Mahmoud Shahrokni <39291137+shahrokni@users.noreply.github.com>

Signed-off-by: Seyed Mahmoud Shahrokni <39291137+shahrokni@users.noreply.github.com>

Signed-off-by: Seyed Mahmoud Shahrokni <39291137+shahrokni@users.noreply.github.com>

Signed-off-by: Seyed Mahmoud Shahrokni <39291137+shahrokni@users.noreply.github.com>

Signed-off-by: Seyed Mahmoud Shahrokni <39291137+shahrokni@users.noreply.github.com>
@shahrokni
shahrokni force-pushed the feat/tracheheatmapchart2 branch from 862d55b to 62c94d1 Compare August 5, 2026 15:27
@shahrokni
shahrokni requested a review from jgbernalp August 5, 2026 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants