PromucFlow_constructor/app/client/src/utils/PerformanceTracker.ts

189 lines
5.6 KiB
TypeScript
Raw Normal View History

import * as Sentry from "@sentry/react";
import { Span, SpanStatus } from "@sentry/tracing";
import _ from "lodash";
import * as log from "loglevel";
export enum PerformanceTransactionName {
DEPLOY_APPLICATION = "DEPLOY_APPLICATION",
RUN_ACTION = "RUN_ACTION",
PAGE_SWITCH_EDIT = "PAGE_SWITCH_EDIT",
PAGE_SWITCH_VIEW = "PAGE_SWITCH_VIEW",
CREATE_ACTION = "CREATE_ACTION",
CURL_IMPORT = "CURL_IMPORT",
EXECUTE_WIDGET_ACTION = "EXECUTE_WIDGET_ACTION",
RUN_ACTION_WAIT_FOR_SAVE = "RUN_ACTION_WAIT_FOR_SAVE",
DATA_TREE_EVALUATION = "DATA_TREE_EVALUATION",
CONSTRUCT_UNEVAL_TREE = "CONSTRUCT_UNEVAL_TREE",
CONSTRUCT_CANVAS_DSL = "CONSTRUCT_CANVAS_DSL",
CREATE_DEPENDENCIES = "CREATE_DEPENDENCIES",
SORTED_DEPENDENCY_EVALUATION = "SORTED_DEPENDENCY_EVALUATION",
SET_WIDGET_LOADING = "SET_WIDGET_LOADING",
VALIDATE_DATA_TREE = "VALIDATE_DATA_TREE",
EXECUTE_PAGE_LOAD_ACTIONS = "EXECUTE_PAGE_LOAD_ACTIONS",
SAVE_PAGE_LAYOUT = "SAVE_PAGE_LAYOUT",
SAVE_ACTION = "SAVE_ACTION",
EVALUATE_BINDING = "EVALUATE_BINDING",
GENERATE_PROPERTY_PANE_PROPS = "GENERATE_PROPERTY_PANE_PROPS",
GENERATE_VIEW_MODE_PROPS = "GENERATE_VIEW_MODE_PROPS",
GENERATE_WIDGET_EDITOR_PROPS = "GENERATE_WIDGET_EDITOR_PROPS",
ENTITY_EXPLORER_ENTITY = "ENTITY_EXPLORER_ENTITY",
ENTITY_EXPLORER = "ENTITY_EXPLORER",
CLOSE_API = "CLOSE_API",
OPEN_API = "OPEN_API",
EDITOR_MOUNT = "EDITOR_MOUNT",
SIDE_BAR_MOUNT = "SIDE_BAR_MOUNT",
CANVAS_MOUNT = "CANVAS_MOUNT",
GENERATE_API_PROPS = "GENERATE_API_PROPS",
CHANGE_API_SAGA = "CHANGE_API_SAGA",
SYNC_PARAMS_SAGA = "SYNC_PARAMS_SAGA",
}
export enum PerformanceTagNames {
PAGE_ID = "pageId",
APP_ID = "appId",
APP_MODE = "appMode",
TRANSACTION_SUCCESS = "transaction.success",
}
export interface PerfLog {
sentrySpan: Span;
skipLog?: boolean;
eventName: string;
}
class PerformanceTracker {
private static perfLogQueue: PerfLog[] = [];
static startTracking = (
eventName: PerformanceTransactionName,
data?: any,
skipLog = false,
) => {
const currentTransaction = Sentry.getCurrentHub()
.getScope()
?.getTransaction();
if (
PerformanceTracker.perfLogQueue.length === 0 &&
currentTransaction !== undefined &&
currentTransaction.status === SpanStatus.Ok
) {
PerformanceTracker.perfLogQueue.push({
sentrySpan: currentTransaction,
skipLog: skipLog,
eventName: eventName,
});
}
if (PerformanceTracker.perfLogQueue.length === 0) {
if (!skipLog) {
log.debug(
PerformanceTracker.generateSpaces(
PerformanceTracker.perfLogQueue.length + 1,
) +
eventName +
" Track Transaction ",
);
}
const newTransaction = Sentry.startTransaction({ name: eventName });
Sentry.getCurrentHub().configureScope(scope =>
scope.setSpan(newTransaction),
);
PerformanceTracker.perfLogQueue.push({
sentrySpan: newTransaction,
skipLog: skipLog,
eventName: eventName,
});
} else {
if (!skipLog) {
log.debug(
PerformanceTracker.generateSpaces(
PerformanceTracker.perfLogQueue.length + 1,
) +
eventName +
" Track Span ",
);
}
const currentPerfLog =
PerformanceTracker.perfLogQueue[
PerformanceTracker.perfLogQueue.length - 1
];
const currentRunningSpan = currentPerfLog.sentrySpan;
const span = currentRunningSpan.startChild({ op: eventName, data: data });
PerformanceTracker.perfLogQueue.push({
sentrySpan: span,
skipLog: skipLog,
eventName: eventName,
});
}
};
static stopTracking = (
data?: any,
eventName?: PerformanceTransactionName,
) => {
if (eventName) {
const index = _.findLastIndex(
PerformanceTracker.perfLogQueue,
(perfLog, i) => {
return perfLog.eventName === eventName;
},
);
if (index !== -1) {
for (let i = PerformanceTracker.perfLogQueue.length - 1; i >= 0; i--) {
const perfLog = PerformanceTracker.perfLogQueue[i];
if (i >= index) {
const currentSpan = perfLog.sentrySpan;
currentSpan.finish();
if (!perfLog?.skipLog) {
PerformanceTracker.printDuration(
perfLog.eventName,
i + 1,
currentSpan.startTimestamp,
currentSpan.endTimestamp,
);
}
}
}
PerformanceTracker.perfLogQueue = PerformanceTracker.perfLogQueue.splice(
index,
);
}
} else {
const perfLog = PerformanceTracker.perfLogQueue.pop();
if (perfLog) {
const currentRunningSpan = perfLog?.sentrySpan;
currentRunningSpan.setData("endData", data);
currentRunningSpan.finish();
if (!perfLog?.skipLog) {
PerformanceTracker.printDuration(
perfLog.eventName,
PerformanceTracker.perfLogQueue.length + 1,
currentRunningSpan.startTimestamp,
currentRunningSpan.endTimestamp,
);
}
}
}
};
static generateSpaces(num: number) {
let str = "";
for (let i = 0; i < num; i++) {
str += "\t";
}
return str;
}
static printDuration(
eventName: string,
level: number,
startTime: number,
endTime?: number,
) {
const duration = ((endTime || 0) - startTime) * 1000;
const spaces = PerformanceTracker.generateSpaces(level);
log.debug(spaces + eventName + " Finish Tracking in " + duration + "ms");
}
}
export default PerformanceTracker;