chore: Log JS Function execution (#24163)
This commit is contained in:
parent
1c701ba1f7
commit
5db37b871e
|
|
@ -5,6 +5,7 @@ import type {
|
|||
ExecuteTriggerPayload,
|
||||
TriggerSource,
|
||||
} from "constants/AppsmithActionConstants/ActionConstants";
|
||||
import { TriggerKind } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
import * as log from "loglevel";
|
||||
import { all, call, put, takeEvery, takeLatest } from "redux-saga/effects";
|
||||
import {
|
||||
|
|
@ -37,6 +38,7 @@ import type { ActionDescription } from "@appsmith/workers/Evaluation/fns";
|
|||
export type TriggerMeta = {
|
||||
source?: TriggerSource;
|
||||
triggerPropertyName?: string;
|
||||
triggerKind?: TriggerKind;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -123,7 +125,11 @@ export function* executeAppAction(payload: ExecuteTriggerPayload): any {
|
|||
evaluateAndExecuteDynamicTrigger,
|
||||
dynamicString,
|
||||
type,
|
||||
{ source, triggerPropertyName },
|
||||
{
|
||||
source,
|
||||
triggerPropertyName,
|
||||
triggerKind: TriggerKind.EVENT_EXECUTION,
|
||||
},
|
||||
callbackData,
|
||||
globalContext,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@ export type TriggerSource = {
|
|||
isJSAction?: boolean;
|
||||
actionId?: string;
|
||||
};
|
||||
export enum TriggerKind {
|
||||
EVENT_EXECUTION = "EVENT_EXECUTION", // Eg. Button onClick
|
||||
JS_FUNCTION_EXECUTION = "JS_FUNCTION_EXECUTION", // Executing js function from jsObject page
|
||||
}
|
||||
|
||||
export type ExecuteTriggerPayload = {
|
||||
dynamicString: string;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ export type UpdateDataTreeMessageData = {
|
|||
|
||||
import { sortJSExecutionDataByCollectionId } from "workers/Evaluation/JSObject/utils";
|
||||
import type { LintTreeSagaRequestData } from "workers/Linting/types";
|
||||
import AnalyticsUtil from "utils/AnalyticsUtil";
|
||||
|
||||
export function* handleEvalWorkerRequestSaga(listenerChannel: Channel<any>) {
|
||||
while (true) {
|
||||
|
|
@ -110,6 +111,19 @@ export function* processTriggerHandler(message: any) {
|
|||
if (messageType === MessageType.REQUEST)
|
||||
yield call(evalWorker.respond, message.messageId, result);
|
||||
}
|
||||
export function* handleJSExecutionLog(data: TMessage<{ data: string[] }>) {
|
||||
const {
|
||||
body: { data: executedFns },
|
||||
} = data;
|
||||
|
||||
for (const executedFn of executedFns) {
|
||||
AnalyticsUtil.logEvent("EXECUTE_ACTION", {
|
||||
type: "JS",
|
||||
name: executedFn,
|
||||
});
|
||||
}
|
||||
yield call(logJSFunctionExecution, data);
|
||||
}
|
||||
|
||||
export function* handleEvalWorkerMessage(message: TMessage<any>) {
|
||||
const { body } = message;
|
||||
|
|
@ -136,7 +150,7 @@ export function* handleEvalWorkerMessage(message: TMessage<any>) {
|
|||
break;
|
||||
}
|
||||
case MAIN_THREAD_ACTION.LOG_JS_FUNCTION_EXECUTION: {
|
||||
yield call(logJSFunctionExecution, message);
|
||||
yield call(handleJSExecutionLog, message);
|
||||
break;
|
||||
}
|
||||
case MAIN_THREAD_ACTION.PROCESS_BATCHED_TRIGGERS: {
|
||||
|
|
|
|||
|
|
@ -65,7 +65,10 @@ import {
|
|||
} from "actions/globalSearchActions";
|
||||
import type { TriggerMeta } from "@appsmith/sagas/ActionExecution/ActionExecutionSagas";
|
||||
import { executeActionTriggers } from "@appsmith/sagas/ActionExecution/ActionExecutionSagas";
|
||||
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
import {
|
||||
EventType,
|
||||
TriggerKind,
|
||||
} from "constants/AppsmithActionConstants/ActionConstants";
|
||||
import {
|
||||
createMessage,
|
||||
SNIPPET_EXECUTION_FAILED,
|
||||
|
|
@ -401,6 +404,7 @@ function* executeAsyncJSFunction(
|
|||
type: ENTITY_TYPE.JSACTION,
|
||||
},
|
||||
triggerPropertyName: `${collectionName}.${action.name}`,
|
||||
triggerKind: TriggerKind.JS_FUNCTION_EXECUTION,
|
||||
};
|
||||
const eventType = EventType.ON_JS_FUNCTION_EXECUTE;
|
||||
const response: JSFunctionExecutionResponse = yield call(
|
||||
|
|
|
|||
|
|
@ -23,11 +23,13 @@ export default class ExecutionMetaData {
|
|||
}
|
||||
}
|
||||
static getExecutionMetaData() {
|
||||
const { source, triggerPropertyName } = ExecutionMetaData.triggerMeta || {};
|
||||
const { source, triggerKind, triggerPropertyName } =
|
||||
ExecutionMetaData.triggerMeta || {};
|
||||
return {
|
||||
triggerMeta: {
|
||||
source: { ...source } as TriggerSource,
|
||||
triggerPropertyName,
|
||||
triggerKind,
|
||||
},
|
||||
eventType: ExecutionMetaData.eventType,
|
||||
enableJSVarUpdateTracking: ExecutionMetaData.enableJSVarUpdateTracking,
|
||||
|
|
|
|||
|
|
@ -147,13 +147,15 @@ TriggerEmitter.on(
|
|||
jsVariableUpdatesHandlerWrapper,
|
||||
);
|
||||
|
||||
export const fnInvokeLogHandler = priorityBatchedActionHandler((data) => {
|
||||
const set = new Set([...data]);
|
||||
WorkerMessenger.ping({
|
||||
method: MAIN_THREAD_ACTION.LOG_JS_FUNCTION_EXECUTION,
|
||||
data: [...set],
|
||||
});
|
||||
});
|
||||
export const fnInvokeLogHandler = priorityBatchedActionHandler<string>(
|
||||
(data) => {
|
||||
const set = new Set([...data]);
|
||||
WorkerMessenger.ping({
|
||||
method: MAIN_THREAD_ACTION.LOG_JS_FUNCTION_EXECUTION,
|
||||
data: [...set],
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
TriggerEmitter.on(BatchKey.process_batched_fn_invoke_log, fnInvokeLogHandler);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { isPromise } from "workers/Evaluation/JSObject/utils";
|
|||
import { postJSFunctionExecutionLog } from "@appsmith/workers/Evaluation/JSObject/postJSFunctionExecution";
|
||||
import TriggerEmitter, { BatchKey } from "./TriggerEmitter";
|
||||
import ExecutionMetaData from "./ExecutionMetaData";
|
||||
import { TriggerKind } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
|
|
@ -11,48 +12,91 @@ declare global {
|
|||
) => any;
|
||||
}
|
||||
}
|
||||
export type PostProcessorArg = {
|
||||
executionMetaData: ReturnType<typeof ExecutionMetaData.getExecutionMetaData>;
|
||||
jsFnFullName: string;
|
||||
executionResponse: unknown;
|
||||
};
|
||||
|
||||
export type PostProcessor = (args: PostProcessorArg) => void;
|
||||
export interface JSExecutionData {
|
||||
data: unknown;
|
||||
funcName: string;
|
||||
}
|
||||
|
||||
function saveExecutionData(name: string, data: unknown) {
|
||||
function saveExecutionData({
|
||||
executionResponse,
|
||||
jsFnFullName,
|
||||
}: PostProcessorArg) {
|
||||
TriggerEmitter.emit(BatchKey.process_batched_fn_execution, {
|
||||
name,
|
||||
data,
|
||||
name: jsFnFullName,
|
||||
data: executionResponse,
|
||||
});
|
||||
}
|
||||
|
||||
function logJSExecution({ executionMetaData, jsFnFullName }: PostProcessorArg) {
|
||||
switch (executionMetaData.triggerMeta.triggerKind) {
|
||||
case TriggerKind.EVENT_EXECUTION: {
|
||||
TriggerEmitter.emit(BatchKey.process_batched_fn_invoke_log, jsFnFullName);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
postJSFunctionExecutionLog(jsFnFullName);
|
||||
}
|
||||
|
||||
export function jsObjectFunctionFactory<P extends ReadonlyArray<unknown>>(
|
||||
fn: (...args: P) => unknown,
|
||||
name: string,
|
||||
postProcessors: Array<(name: string, res: unknown) => void> = [
|
||||
saveExecutionData,
|
||||
postJSFunctionExecutionLog,
|
||||
],
|
||||
postProcessors: PostProcessor[] = [saveExecutionData, logJSExecution],
|
||||
) {
|
||||
return function (this: unknown, ...args: P) {
|
||||
if (!ExecutionMetaData.getExecutionMetaData().enableJSFnPostProcessors) {
|
||||
return fn.call(this, ...args);
|
||||
}
|
||||
const executionMetaData = ExecutionMetaData.getExecutionMetaData();
|
||||
try {
|
||||
const result = fn.call(this, ...args);
|
||||
if (isPromise(result)) {
|
||||
result.then((res) => {
|
||||
postProcessors.forEach((p) => p(name, res));
|
||||
postProcessors.forEach((p) =>
|
||||
p({
|
||||
executionMetaData,
|
||||
jsFnFullName: name,
|
||||
executionResponse: res,
|
||||
}),
|
||||
);
|
||||
return res;
|
||||
});
|
||||
result.catch((e) => {
|
||||
postProcessors.forEach((p) => p(name, undefined));
|
||||
postProcessors.forEach((p) =>
|
||||
p({
|
||||
executionMetaData,
|
||||
jsFnFullName: name,
|
||||
executionResponse: undefined,
|
||||
}),
|
||||
);
|
||||
throw e;
|
||||
});
|
||||
} else {
|
||||
postProcessors.forEach((p) => p(name, result));
|
||||
postProcessors.forEach((p) =>
|
||||
p({
|
||||
executionMetaData,
|
||||
jsFnFullName: name,
|
||||
executionResponse: result,
|
||||
}),
|
||||
);
|
||||
}
|
||||
return result;
|
||||
} catch (e) {
|
||||
postProcessors.forEach((postProcessor) => {
|
||||
postProcessor(name, undefined);
|
||||
postProcessor({
|
||||
executionMetaData,
|
||||
jsFnFullName: name,
|
||||
executionResponse: undefined,
|
||||
});
|
||||
});
|
||||
throw e;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user