Skip to content

Commit

Permalink
Merge pull request #2 from leviska/master
Browse files Browse the repository at this point in the history
added percentages and mean
  • Loading branch information
vankop authored Jul 22, 2021
2 parents fc55326 + b462839 commit 2e2613e
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 12 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

All notable changes to this project will be documented in this file.

## v0.4.1

Features:
- add percentage view
- add mean view

## v0.4.0

## v0.1.0
Expand Down
2 changes: 1 addition & 1 deletion dist/module.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/module.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
{"name": "License", "url": "https://github.com/ozonru/flamegraph-grafana-plugin/blob/master/LICENSE"}
],
"screenshots": [],
"version": "0.1.0",
"updated": "2021-02-19"
"version": "0.4.1",
"updated": "2021-07-21"
},
"dependencies": {
"grafanaVersion": "7.x.x",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "flamegraph-grafana-panel",
"version": "0.4.0",
"version": "0.4.1",
"description": "FlameGraph panel",
"scripts": {
"build": "grafana-toolkit plugin:build",
Expand Down
27 changes: 23 additions & 4 deletions src/Panel.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { flamegraph } from 'd3-flame-graph';
import * as d3 from 'd3';
import { LoadingState, PanelProps } from '@grafana/data';
import { LoadingState, PanelProps, toFixed } from '@grafana/data';
import { Options } from 'types';
import { processSeries } from './util';

Expand All @@ -11,6 +11,15 @@ interface Props extends PanelProps<Options> {}

const MS_IN_SECOND = 1000;

function nsToString(v: number): string {
if (v >= MS_IN_SECOND * MS_IN_SECOND) {
return toFixed(v / (MS_IN_SECOND * MS_IN_SECOND), 2) + 's';
} else if (v >= MS_IN_SECOND) {
return toFixed(v / MS_IN_SECOND, 2) + 'ms';
}
return toFixed(v, 2) + 'ns';
}

export class FlameGraphPanel extends React.Component<Props> {
divRef: React.RefObject<HTMLDivElement>;

Expand All @@ -37,13 +46,16 @@ export class FlameGraphPanel extends React.Component<Props> {

const seriesA = [];
const seriesB = [];
const traceCount = [];
const size = data.series.length;

for (let i = 0; i < size; i++) {
const serie = data.series[i];

if (serie.refId === 'A') {
seriesA.push(serie);
} else if (serie.refId === 'count') {
traceCount.push(serie);
} else {
seriesB.push(serie);
}
Expand All @@ -61,11 +73,18 @@ export class FlameGraphPanel extends React.Component<Props> {
.differential(seriesB.length > 0)
.label(
(node) =>
`${node.data.name}: Self value ${(node.data.value / MS_IN_SECOND).toFixed(2)}ms.${
node.data.delta ? `Diff ${(node.data.delta / MS_IN_SECOND).toFixed(2)}ms.` : ''
`${node.data.name}:
mean: ${nsToString(node.data.sum / node.data.cnt)}
perc: ${toFixed(node.data.perc, 1)}%
count: ${toFixed(node.data.cnt, 0)}
sum: ${nsToString(node.data.sum)} ${
node.data.delta
? `
self: ${nsToString(node.data.delta)}`
: ''
}`
);
d3.select(this.divRef.current).datum(processSeries(seriesA, seriesB, this.props.options)).call(fg);
d3.select(this.divRef.current).datum(processSeries(seriesA, seriesB, traceCount, this.props.options)).call(fg);
}

shouldComponentUpdate(nextProps: Readonly<Props>, nextState: Readonly<{}>, nextContext: any): boolean {
Expand Down
65 changes: 62 additions & 3 deletions src/util/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { DataFrame } from '@grafana/data';
import { DataFrame, toFixed } from '@grafana/data';
import { Options } from '../types';

interface Span {
name: string;
value: number;
delta?: number;
perc: number;
sum: number;
cnt: number;
children: Span[];
}

Expand Down Expand Up @@ -71,11 +74,61 @@ function createNode(name: string): Span {
return {
name,
value: 0.0,
perc: 0.0,
sum: 0.0,
cnt: 0.0,
children: [],
};
}

export function processSeries(seriesA: DataFrame[], seriesB: DataFrame[], options: Options): Span | undefined {
// returns sum duration
function countSum(root: Span): number {
for (let obj of root.children) {
root.sum += countSum(obj);
}
root.sum += root.value;
return root.sum;
}

function countPercentage(root: Span, total: number) {
root.perc = (root.sum * 100) / total;
for (let obj of root.children) {
countPercentage(obj, total);
}
}

function setCnt(root: Span, cnt: number) {
root.cnt = cnt;
for (let obj of root.children) {
setCnt(obj, cnt);
}
}

function addPercentagesToName(root: Span) {
root.name += ' ' + toFixed(root.perc, 1) + '%';
for (let obj of root.children) {
addPercentagesToName(obj);
}
}

function countTraceCnt(traceCount: DataFrame[]): number {
let res = 0.0;
for (let i = 0; i < traceCount.length; i++) {
const valueField = traceCount[i].fields.find((f) => f.name === 'Value');
if (!valueField) {
continue;
}
res += valueField.values.get(0);
}
return Math.max(1.0, res);
}

export function processSeries(
seriesA: DataFrame[],
seriesB: DataFrame[],
traceCount: DataFrame[],
options: Options
): Span | undefined {
const byIdSeriesA = new Map();
const cache = new Map();
const ids = new Map();
Expand Down Expand Up @@ -161,5 +214,11 @@ export function processSeries(seriesA: DataFrame[], seriesB: DataFrame[], option
}
}

return cache.get('1;');
let root = cache.get('1;');
let cnt = Math.round(countTraceCnt(traceCount));
setCnt(root, cnt);
countSum(root);
countPercentage(root, root.sum);
addPercentagesToName(root);
return root;
}

0 comments on commit 2e2613e

Please sign in to comment.