Skip to content

Commit

Permalink
Fix time calculation in Trace Graph view
Browse files Browse the repository at this point in the history
Resolves jaegertracing#1918
Now the total duration is calculating as
the duration of the union of spans.

Signed-off-by: Maksim Gaponov <gaponovmaxev@gmail.com>
  • Loading branch information
maxgaponov committed Oct 30, 2023
1 parent 6174590 commit 81ee2b6
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ describe('<OpNode>', () => {
selfTime: 180000,
service: 'service1',
time: 200000,
totalTime: 200000,
};
wrapper = shallow(<OpNode {...props} mode={mode} />);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ export function round2(percent: number) {

export default class OpNode extends React.PureComponent<Props> {
render() {
const { count, errors, time, percent, selfTime, percentSelfTime, operation, service, mode } = this.props;
const { count, errors, time, totalTime, percent, selfTime, percentSelfTime, operation, service, mode } =
this.props;

// Spans over 20 % time are full red - we have probably to reconsider better approach
let backgroundColor;
Expand Down Expand Up @@ -99,7 +100,7 @@ export default class OpNode extends React.PureComponent<Props> {
tooltipTitle="Copy label"
/>
</td>
<td className="OpNode--metricCell OpNode--avg">{round2(time / 1000 / count)} ms</td>
<td className="OpNode--metricCell OpNode--avg">{round2(totalTime / 1000 / count)} ms</td>
</tr>
<tr>
<td className="OpNode--metricCell OpNode--time">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import testTrace from './testTrace.json';

const transformedTrace = transformTraceData(testTrace);

function assertData(nodes, service, operation, count, errors, time, percent, selfTime) {
function assertData(nodes, service, operation, count, errors, time, totalTime, percent, selfTime) {
const d = nodes.find(({ data: n }) => n.service === service && n.operation === operation).data;
expect(d).toBeDefined();
expect(d.count).toBe(count);
Expand All @@ -34,18 +34,18 @@ describe('calculateTraceDagEV', () => {
const traceDag = calculateTraceDagEV(transformedTrace);
const { vertices: nodes } = traceDag;
expect(nodes.length).toBe(9);
assertData(nodes, 'service1', 'op1', 1, 0, 390, 39, 224);
assertData(nodes, 'service1', 'op1', 1, 0, 390, 390, 39, 224);
// accumulate data (count,times)
assertData(nodes, 'service1', 'op2', 2, 1, 70, 7, 70);
assertData(nodes, 'service1', 'op2', 2, 1, 70, 70, 7, 70);
// self-time is substracted from child
assertData(nodes, 'service1', 'op3', 1, 0, 66, 6.6, 46);
assertData(nodes, 'service2', 'op1', 1, 0, 20, 2, 2);
assertData(nodes, 'service2', 'op2', 1, 0, 18, 1.8, 18);
assertData(nodes, 'service1', 'op3', 1, 0, 66, 66, 6.6, 46);
assertData(nodes, 'service2', 'op1', 1, 0, 20, 20, 2, 2);
assertData(nodes, 'service2', 'op2', 1, 0, 18, 18, 1.8, 18);
// follows_from relation will not influence self-time
assertData(nodes, 'service1', 'op4', 1, 0, 20, 2, 20);
assertData(nodes, 'service2', 'op3', 1, 0, 200, 20, 200);
assertData(nodes, 'service1', 'op4', 1, 0, 20, 20, 2, 20);
assertData(nodes, 'service2', 'op3', 1, 0, 200, 200, 20, 200);
// fork-join self-times are calculated correctly (self-time drange)
assertData(nodes, 'service1', 'op6', 1, 0, 10, 1, 1);
assertData(nodes, 'service1', 'op7', 2, 0, 17, 1.7, 17);
assertData(nodes, 'service1', 'op6', 1, 0, 10, 10, 1, 1);
assertData(nodes, 'service1', 'op7', 2, 0, 9, 17, 0.9, 9);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,12 @@ export function calculateTraceDag(trace: Trace): TraceDag<TSumSpan & TDenseSpanM
const dag = new TraceDag<TSumSpan & TDenseSpanMembers>();

baseDag.nodesMap.forEach(node => {
const ntime = node.members.reduce((p, m) => p + m.span.duration, 0);
const ntime = node.members.reduce(
(mdr, m) =>
mdr.add(m.span.startTime, m.span.startTime + (m.span.duration <= 0 ? 0 : m.span.duration - 1)),
new DRange()
).length;
const totalTime = node.members.reduce((p, m) => p + m.span.duration, 0);
const numErrors = node.members.reduce((p, m) => (p + isError(m.span.tags) ? 1 : 0), 0);
const childDurationsDRange = node.members.reduce((p, m) => {
// Using DRange to handle overlapping spans (fork-join)
Expand All @@ -96,6 +101,7 @@ export function calculateTraceDag(trace: Trace): TraceDag<TSumSpan & TDenseSpanM
count: node.members.length,
errors: numErrors,
time: ntime,
totalTime: totalTime,
percent: (100 / trace.duration) * ntime,
selfTime: stime,
percentSelfTime: (100 / ntime) * stime,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export type TSumSpan = {
percentSelfTime: number;
selfTime: number;
time: number;
totalTime: number;
};

export type TEv = {
Expand Down

0 comments on commit 81ee2b6

Please sign in to comment.