Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Column totals for Grouped rows will now be shown inside the groups instead of on a seperate row ([#583][#583]).
- Table actions: Copy to clipboard and Export to CSV directly from the button above the Analysis and Database table ([#589]).
- Replace the Rows column on the Call Tree with two seperate columns, DML rows and SOQL rows ([#93]).
- Replace Rows count on the Timeline tooltip with two new counts, DML rows and SOQL rows ([#93]).

### Changed

Expand Down Expand Up @@ -388,6 +390,7 @@ Skipped due to adopting odd numbering for pre releases and even number for relea
[#583]: https://github.com/certinia/debug-log-analyzer/issues/583
[#589]: https://github.com/certinia/debug-log-analyzer/issues/589
[#590]: https://github.com/certinia/debug-log-analyzer/issues/590
[#93]: https://github.com/certinia/debug-log-analyzer/issues/93

<!-- 1.16.1 -->

Expand Down
182 changes: 181 additions & 1 deletion log-viewer/modules/__tests__/ApexLogParser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,8 @@ describe('parseLog tests', () => {
parent: execEvent,
type: 'SOQL_EXECUTE_BEGIN',
aggregations: 2,
rowCount: { self: 50, total: 50 },
soqlRowCount: { self: 50, total: 50 },
soqlCount: { self: 1, total: 1 },
});

const soqlExplain = soqlLine.children[0] as SOQLExecuteExplainLine;
Expand Down Expand Up @@ -1179,3 +1180,182 @@ describe('Line Type Tests', () => {
expect(qp.sObjectType).toBe(null);
});
});

describe('Aggregating Totals', () => {
it('should sum from child to parent', () => {
const logArray = [
'01:02:03.04 (0)|EXECUTION_STARTED',
'01:02:03.04 (1)|METHOD_ENTRY|[1]|a00000000000000|ns.MyClass.myMethod()',
'01:02:03.04 (2)|METHOD_ENTRY|[1]|a00000000000000|ns.MyClass.soql()',
'01:02:03.04 (3)|SOQL_EXECUTE_BEGIN|[2]|Aggregations:0|SELECT ID FROM MyObject__c',
'01:02:03.04 (4)|SOQL_EXECUTE_END|[2]|Rows:1',
'01:02:03.04 (5)|SOQL_EXECUTE_BEGIN|[2]|Aggregations:0|SELECT ID FROM MyObject__c',
'01:02:03.04 (6)|SOQL_EXECUTE_END|[2]|Rows:2',
'01:02:03.04 (7)|METHOD_EXIT|[1]|a00000000000000|ns.MyClass.soql()',
'01:02:03.04 (8)|METHOD_ENTRY|[1]|a00000000000000|ns.MyClass.dml()',
'01:02:03.04 (9)|DML_BEGIN|[194]|Op:Update|Type:ns2__MyObject__c|Rows:1',
'01:02:03.04 (10)|DML_END|[194]',
'01:02:03.04 (11)|DML_BEGIN|[194]|Op:Update|Type:ns2__MyObject__c|Rows:4',
'01:02:03.04 (12)|DML_END|[194]',
'01:02:03.04 (13)|METHOD_EXIT|[1]|a00000000000000|ns.MyClass.dml()',
'01:02:03.04 (14)|METHOD_ENTRY|[1]|a00000000000000|ns.MyClass.sosl()',
"01:02:03.04 (15)|SOSL_EXECUTE_BEGIN|[1]|FIND 'hello*' IN ALL FIELDS RETURNING account(Id, Name)",
'01:02:03.04 (16)|SOSL_EXECUTE_END|[1]|Rows:250',
"01:02:03.04 (17)|SOSL_EXECUTE_BEGIN|[1]|FIND 'hello*' IN ALL FIELDS RETURNING account(Id, Name)",
'01:02:03.04 (18)|SOSL_EXECUTE_END|[1]|Rows:150',
'01:02:03.04 (19)|EXCEPTION_THROWN|[60]|System.LimitException: c2g:Too many SOQL queries: 101',
'01:02:03.04 (20)|METHOD_EXIT|[1]|a00000000000000|ns.MyClass.sosl()',
'01:02:03.04 (21)|EXCEPTION_THROWN|[60]|System.LimitException: c2g:Too many SOQL queries: 101',
'01:02:03.04 (22)|EXCEPTION_THROWN|[60]|System.LimitException: c2g:Too many SOQL queries: 101',
'01:02:03.04 (23)|METHOD_EXIT|[1]|a00000000000000|ns.MyClass.myMethod()',
'01:02:03.04 (24)|EXECUTION_FINISHED',
];
const log1 = logArray.join('\n');

const defaultCounts = {
dmlCount: { total: 0, self: 0 },
soqlCount: { total: 0, self: 0 },
soslCount: { total: 0, self: 0 },
dmlRowCount: { total: 0, self: 0 },
soqlRowCount: { total: 0, self: 0 },
soslRowCount: { total: 0, self: 0 },
totalThrownCount: 0,
};

const apexLog = parse(log1);
expect(apexLog).toMatchObject(
// EXECUTION_STARTED
{
duration: { total: 24, self: 0 },
dmlCount: { total: 2, self: 0 },
soqlCount: { total: 2, self: 0 },
soslCount: { total: 2, self: 0 },
dmlRowCount: { total: 5, self: 0 },
soqlRowCount: { total: 3, self: 0 },
soslRowCount: { total: 400, self: 0 },
type: null,
children: [
{
duration: { total: 24, self: 2 },
dmlCount: { total: 2, self: 0 },
soqlCount: { total: 2, self: 0 },
soslCount: { total: 2, self: 0 },
dmlRowCount: { total: 5, self: 0 },
soqlRowCount: { total: 3, self: 0 },
soslRowCount: { total: 400, self: 0 },
totalThrownCount: 3,
logLine: logArray[0],
children: [
// ns.MyClass.myMethod()
{
duration: { total: 22, self: 6 },
dmlCount: { total: 2, self: 0 },
soqlCount: { total: 2, self: 0 },
soslCount: { total: 2, self: 0 },
dmlRowCount: { total: 5, self: 0 },
soqlRowCount: { total: 3, self: 0 },
soslRowCount: { total: 400, self: 0 },
totalThrownCount: 3,
logLine: logArray[1],
children: [
// ns.MyClass.soql()
{
...defaultCounts,
duration: { total: 5, self: 3 },
logLine: logArray[2],
soqlCount: { total: 2, self: 0 },
soqlRowCount: { total: 3, self: 0 },
children: [
//SELECT ID FROM MyObject__c
{
...defaultCounts,
duration: { total: 1, self: 1 },
soqlCount: { total: 1, self: 1 },
soqlRowCount: { total: 1, self: 1 },
logLine: logArray[3],
},
// SELECT ID FROM MyObject__c
{
...defaultCounts,
duration: { total: 1, self: 1 },
soqlCount: { total: 1, self: 1 },
soqlRowCount: { total: 2, self: 2 },
logLine: logArray[5],
},
],
},
// ns.MyClass.dml()
{
...defaultCounts,
duration: { total: 5, self: 3 },
dmlCount: { total: 2, self: 0 },
dmlRowCount: { total: 5, self: 0 },
logLine: logArray[8],
children: [
{
...defaultCounts,
duration: { total: 1, self: 1 },
dmlCount: { total: 1, self: 1 },
dmlRowCount: { total: 1, self: 1 },
logLine: logArray[9],
},
{
...defaultCounts,
duration: { total: 1, self: 1 },
dmlCount: { total: 1, self: 1 },
dmlRowCount: { total: 4, self: 4 },
logLine: logArray[11],
},
],
},
//ns.MyClass.sosl()
{
...defaultCounts,
duration: { total: 6, self: 4 },
soslCount: { total: 2, self: 0 },
soslRowCount: { total: 400, self: 0 },
totalThrownCount: 1,
logLine: logArray[14],
children: [
{
...defaultCounts,
duration: { total: 1, self: 1 },
soslCount: { total: 1, self: 1 },
soslRowCount: { total: 250, self: 250 },
totalThrownCount: 0,
logLine: logArray[15],
},
{
...defaultCounts,
duration: { total: 1, self: 1 },
soslCount: { total: 1, self: 1 },
soslRowCount: { total: 150, self: 150 },
totalThrownCount: 0,
logLine: logArray[17],
},
// Exception
{
...defaultCounts,
totalThrownCount: 1,
},
],
},
// Exception
{
...defaultCounts,
totalThrownCount: 1,
},
// Exception
{
...defaultCounts,
totalThrownCount: 1,
},
],
},
],
},
],
},
);
});
});
54 changes: 34 additions & 20 deletions log-viewer/modules/components/calltree-view/CalltreeView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ export class CalltreeView extends LitElement {
},
{
title: 'DML Count',
field: 'totalDmlCount',
field: 'dmlCount.total',
sorter: 'number',
width: 60,
hozAlign: 'right',
Expand All @@ -687,7 +687,7 @@ export class CalltreeView extends LitElement {
},
{
title: 'SOQL Count',
field: 'totalSoqlCount',
field: 'soqlCount.total',
sorter: 'number',
width: 60,
hozAlign: 'right',
Expand All @@ -704,8 +704,17 @@ export class CalltreeView extends LitElement {
bottomCalc: 'max',
},
{
title: 'Rows',
field: 'rows',
title: 'DML Rows',
field: 'dmlRowCount.total',
sorter: 'number',
width: 60,
hozAlign: 'right',
headerHozAlign: 'right',
bottomCalc: 'max',
},
{
title: 'SOQL Rows',
field: 'soqlRowCount.total',
sorter: 'number',
width: 60,
hozAlign: 'right',
Expand All @@ -714,7 +723,7 @@ export class CalltreeView extends LitElement {
},
{
title: 'Total Time (ms)',
field: 'duration',
field: 'duration.total',
sorter: 'number',
headerSortTristate: true,
width: 150,
Expand All @@ -736,7 +745,7 @@ export class CalltreeView extends LitElement {
},
{
title: 'Self Time (ms)',
field: 'selfTime',
field: 'duration.self',
sorter: 'number',
headerSortTristate: true,
width: 150,
Expand All @@ -753,7 +762,10 @@ export class CalltreeView extends LitElement {
},
headerFilter: MinMaxEditor,
headerFilterFunc: MinMaxFilter,
headerFilterFuncParams: { columnName: 'selfTime', filterCache: selfTimeFilterCache },
headerFilterFuncParams: {
columnName: 'duration.self',
filterCache: selfTimeFilterCache,
},
headerFilterLiveFilter: false,
},
],
Expand Down Expand Up @@ -829,16 +841,16 @@ export class CalltreeView extends LitElement {
const children = node.children.length ? this._toCallTree(node.children) : null;
results.push({
id: node.timestamp + '-' + i,
originalData: node,
_children: children,
text: node.text,
namespace: node.namespace,
duration: node.duration.total,
selfTime: node.duration.self,
_children: children,
totalDmlCount: node.dmlCount.total,
totalSoqlCount: node.soqlCount.total,
duration: node.duration,
dmlCount: node.dmlCount,
soqlCount: node.soqlCount,
dmlRowCount: node.dmlRowCount,
soqlRowCount: node.soqlRowCount,
totalThrownCount: node.totalThrownCount,
rows: node.rowCount.total,
originalData: node,
});
}
return results;
Expand Down Expand Up @@ -888,17 +900,19 @@ export class CalltreeView extends LitElement {
interface CalltreeRow {
id: string;
originalData: LogLine;
_children: CalltreeRow[] | undefined | null;
text: string;
duration: number;
duration: CountTotals;
namespace: string;
selfTime: number;
_children: CalltreeRow[] | undefined | null;
totalDmlCount: number;
totalSoqlCount: number;
dmlCount: CountTotals;
soqlCount: CountTotals;
dmlRowCount: CountTotals;
soqlRowCount: CountTotals;
totalThrownCount: number;
rows: number;
}

type CountTotals = { self: number; total: number };

export async function goToRow(timestamp: number) {
document.dispatchEvent(
new CustomEvent('calltree-go-to-row', { detail: { timestamp: timestamp } }),
Expand Down
2 changes: 1 addition & 1 deletion log-viewer/modules/components/database-view/DMLView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ export class DMLView extends LitElement {
for (const dml of dmlLines) {
dmlData.push({
dml: dml.text,
rowCount: dml.rowCount.self,
rowCount: dml.dmlRowCount.self,
timeTaken: dml.duration.total,
timestamp: dml.timestamp,
_children: [{ timestamp: dml.timestamp, isDetail: true }],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export class DatabaseSection extends LitElement {
const totalCount = this.dbLines.length;
let totalRows = 0;
this.dbLines.forEach((value) => {
totalRows += value.rowCount.self || 0;
totalRows += value.dmlRowCount.self || value.soqlRowCount.self || 0;
});

return html`
Expand Down
2 changes: 1 addition & 1 deletion log-viewer/modules/components/database-view/SOQLView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ export class SOQLView extends LitElement {
relativeCost: explainLine?.relativeCost,
soql: soql.text,
namespace: soql.namespace,
rowCount: soql.rowCount.self,
rowCount: soql.soqlRowCount.self,
timeTaken: soql.duration.total,
aggregations: soql.aggregations,
timestamp: soql.timestamp,
Expand Down
Loading