mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-24 20:24:05 -08:00
⚡ Tweaks to diagnostic events (#2544)
* Tweaks to events * more tweaks and fixes
This commit is contained in:
parent
75c7b5ed97
commit
2125f25791
|
@ -11,6 +11,7 @@ import {
|
||||||
CredentialTypes,
|
CredentialTypes,
|
||||||
Db,
|
Db,
|
||||||
ExternalHooks,
|
ExternalHooks,
|
||||||
|
GenericHelpers,
|
||||||
InternalHooksManager,
|
InternalHooksManager,
|
||||||
IWorkflowBase,
|
IWorkflowBase,
|
||||||
IWorkflowExecutionDataProcess,
|
IWorkflowExecutionDataProcess,
|
||||||
|
@ -125,7 +126,8 @@ export class Execute extends Command {
|
||||||
await externalHooks.init();
|
await externalHooks.init();
|
||||||
|
|
||||||
const instanceId = await UserSettings.getInstanceId();
|
const instanceId = await UserSettings.getInstanceId();
|
||||||
InternalHooksManager.init(instanceId);
|
const { cli } = await GenericHelpers.getVersions();
|
||||||
|
InternalHooksManager.init(instanceId, cli);
|
||||||
|
|
||||||
// Add the found types to an instance other parts of the application can use
|
// Add the found types to an instance other parts of the application can use
|
||||||
const nodeTypes = NodeTypes();
|
const nodeTypes = NodeTypes();
|
||||||
|
|
|
@ -28,6 +28,7 @@ import {
|
||||||
CredentialTypes,
|
CredentialTypes,
|
||||||
Db,
|
Db,
|
||||||
ExternalHooks,
|
ExternalHooks,
|
||||||
|
GenericHelpers,
|
||||||
InternalHooksManager,
|
InternalHooksManager,
|
||||||
IWorkflowDb,
|
IWorkflowDb,
|
||||||
IWorkflowExecutionDataProcess,
|
IWorkflowExecutionDataProcess,
|
||||||
|
@ -305,7 +306,8 @@ export class ExecuteBatch extends Command {
|
||||||
await externalHooks.init();
|
await externalHooks.init();
|
||||||
|
|
||||||
const instanceId = await UserSettings.getInstanceId();
|
const instanceId = await UserSettings.getInstanceId();
|
||||||
InternalHooksManager.init(instanceId);
|
const { cli } = await GenericHelpers.getVersions();
|
||||||
|
InternalHooksManager.init(instanceId, cli);
|
||||||
|
|
||||||
// Add the found types to an instance other parts of the application can use
|
// Add the found types to an instance other parts of the application can use
|
||||||
const nodeTypes = NodeTypes();
|
const nodeTypes = NodeTypes();
|
||||||
|
|
|
@ -153,17 +153,6 @@ export class Start extends Command {
|
||||||
LoggerProxy.init(logger);
|
LoggerProxy.init(logger);
|
||||||
logger.info('Initializing n8n process');
|
logger.info('Initializing n8n process');
|
||||||
|
|
||||||
logger.info(
|
|
||||||
'\n' +
|
|
||||||
'****************************************************\n' +
|
|
||||||
'* *\n' +
|
|
||||||
'* n8n now sends selected, anonymous telemetry. *\n' +
|
|
||||||
'* For more details (and how to opt out): *\n' +
|
|
||||||
'* https://docs.n8n.io/reference/telemetry.html *\n' +
|
|
||||||
'* *\n' +
|
|
||||||
'****************************************************\n',
|
|
||||||
);
|
|
||||||
|
|
||||||
// Start directly with the init of the database to improve startup time
|
// Start directly with the init of the database to improve startup time
|
||||||
const startDbInitPromise = Db.init().catch((error: Error) => {
|
const startDbInitPromise = Db.init().catch((error: Error) => {
|
||||||
logger.error(`There was an error initializing DB: "${error.message}"`);
|
logger.error(`There was an error initializing DB: "${error.message}"`);
|
||||||
|
@ -313,7 +302,8 @@ export class Start extends Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
const instanceId = await UserSettings.getInstanceId();
|
const instanceId = await UserSettings.getInstanceId();
|
||||||
InternalHooksManager.init(instanceId);
|
const { cli } = await GenericHelpers.getVersions();
|
||||||
|
InternalHooksManager.init(instanceId, cli);
|
||||||
|
|
||||||
await Server.start();
|
await Server.start();
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,8 @@ export class Webhook extends Command {
|
||||||
await startDbInitPromise;
|
await startDbInitPromise;
|
||||||
|
|
||||||
const instanceId = await UserSettings.getInstanceId();
|
const instanceId = await UserSettings.getInstanceId();
|
||||||
InternalHooksManager.init(instanceId);
|
const { cli } = await GenericHelpers.getVersions();
|
||||||
|
InternalHooksManager.init(instanceId, cli);
|
||||||
|
|
||||||
if (config.get('executions.mode') === 'queue') {
|
if (config.get('executions.mode') === 'queue') {
|
||||||
const redisHost = config.get('queue.bull.redis.host');
|
const redisHost = config.get('queue.bull.redis.host');
|
||||||
|
|
|
@ -271,10 +271,10 @@ export class Worker extends Command {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
Worker.jobQueue.process(flags.concurrency, async (job) => this.runJob(job, nodeTypes));
|
Worker.jobQueue.process(flags.concurrency, async (job) => this.runJob(job, nodeTypes));
|
||||||
|
|
||||||
const instanceId = await UserSettings.getInstanceId();
|
|
||||||
InternalHooksManager.init(instanceId);
|
|
||||||
|
|
||||||
const versions = await GenericHelpers.getVersions();
|
const versions = await GenericHelpers.getVersions();
|
||||||
|
const instanceId = await UserSettings.getInstanceId();
|
||||||
|
|
||||||
|
InternalHooksManager.init(instanceId, versions.cli);
|
||||||
|
|
||||||
console.info('\nn8n worker is now ready');
|
console.info('\nn8n worker is now ready');
|
||||||
console.info(` * Version: ${versions.cli}`);
|
console.info(` * Version: ${versions.cli}`);
|
||||||
|
|
|
@ -314,7 +314,10 @@ export interface IDiagnosticInfo {
|
||||||
|
|
||||||
export interface IInternalHooksClass {
|
export interface IInternalHooksClass {
|
||||||
onN8nStop(): Promise<void>;
|
onN8nStop(): Promise<void>;
|
||||||
onServerStarted(diagnosticInfo: IDiagnosticInfo): Promise<unknown[]>;
|
onServerStarted(
|
||||||
|
diagnosticInfo: IDiagnosticInfo,
|
||||||
|
firstWorkflowCreatedAt?: Date,
|
||||||
|
): Promise<unknown[]>;
|
||||||
onPersonalizationSurveySubmitted(answers: IPersonalizationSurveyAnswers): Promise<void>;
|
onPersonalizationSurveySubmitted(answers: IPersonalizationSurveyAnswers): Promise<void>;
|
||||||
onWorkflowCreated(workflow: IWorkflowBase): Promise<void>;
|
onWorkflowCreated(workflow: IWorkflowBase): Promise<void>;
|
||||||
onWorkflowDeleted(workflowId: string): Promise<void>;
|
onWorkflowDeleted(workflowId: string): Promise<void>;
|
||||||
|
|
|
@ -9,9 +9,16 @@ import {
|
||||||
import { Telemetry } from './telemetry';
|
import { Telemetry } from './telemetry';
|
||||||
|
|
||||||
export class InternalHooksClass implements IInternalHooksClass {
|
export class InternalHooksClass implements IInternalHooksClass {
|
||||||
constructor(private telemetry: Telemetry) {}
|
private versionCli: string;
|
||||||
|
|
||||||
async onServerStarted(diagnosticInfo: IDiagnosticInfo): Promise<unknown[]> {
|
constructor(private telemetry: Telemetry, versionCli: string) {
|
||||||
|
this.versionCli = versionCli;
|
||||||
|
}
|
||||||
|
|
||||||
|
async onServerStarted(
|
||||||
|
diagnosticInfo: IDiagnosticInfo,
|
||||||
|
earliestWorkflowCreatedAt?: Date,
|
||||||
|
): Promise<unknown[]> {
|
||||||
const info = {
|
const info = {
|
||||||
version_cli: diagnosticInfo.versionCli,
|
version_cli: diagnosticInfo.versionCli,
|
||||||
db_type: diagnosticInfo.databaseType,
|
db_type: diagnosticInfo.databaseType,
|
||||||
|
@ -25,7 +32,10 @@ export class InternalHooksClass implements IInternalHooksClass {
|
||||||
|
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
this.telemetry.identify(info),
|
this.telemetry.identify(info),
|
||||||
this.telemetry.track('Instance started', info),
|
this.telemetry.track('Instance started', {
|
||||||
|
...info,
|
||||||
|
earliest_workflow_created: earliestWorkflowCreatedAt,
|
||||||
|
}),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,9 +49,11 @@ export class InternalHooksClass implements IInternalHooksClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
async onWorkflowCreated(workflow: IWorkflowBase): Promise<void> {
|
async onWorkflowCreated(workflow: IWorkflowBase): Promise<void> {
|
||||||
|
const { nodeGraph } = TelemetryHelpers.generateNodesGraph(workflow);
|
||||||
return this.telemetry.track('User created workflow', {
|
return this.telemetry.track('User created workflow', {
|
||||||
workflow_id: workflow.id,
|
workflow_id: workflow.id,
|
||||||
node_graph: TelemetryHelpers.generateNodesGraph(workflow).nodeGraph,
|
node_graph: nodeGraph,
|
||||||
|
node_graph_string: JSON.stringify(nodeGraph),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,9 +64,13 @@ export class InternalHooksClass implements IInternalHooksClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
async onWorkflowSaved(workflow: IWorkflowBase): Promise<void> {
|
async onWorkflowSaved(workflow: IWorkflowBase): Promise<void> {
|
||||||
|
const { nodeGraph } = TelemetryHelpers.generateNodesGraph(workflow);
|
||||||
|
|
||||||
return this.telemetry.track('User saved workflow', {
|
return this.telemetry.track('User saved workflow', {
|
||||||
workflow_id: workflow.id,
|
workflow_id: workflow.id,
|
||||||
node_graph: TelemetryHelpers.generateNodesGraph(workflow).nodeGraph,
|
node_graph: nodeGraph,
|
||||||
|
node_graph_string: JSON.stringify(nodeGraph),
|
||||||
|
version_cli: this.versionCli,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +78,7 @@ export class InternalHooksClass implements IInternalHooksClass {
|
||||||
const properties: IDataObject = {
|
const properties: IDataObject = {
|
||||||
workflow_id: workflow.id,
|
workflow_id: workflow.id,
|
||||||
is_manual: false,
|
is_manual: false,
|
||||||
|
version_cli: this.versionCli,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (runData !== undefined) {
|
if (runData !== undefined) {
|
||||||
|
@ -92,6 +109,8 @@ export class InternalHooksClass implements IInternalHooksClass {
|
||||||
if (properties.is_manual) {
|
if (properties.is_manual) {
|
||||||
const nodeGraphResult = TelemetryHelpers.generateNodesGraph(workflow);
|
const nodeGraphResult = TelemetryHelpers.generateNodesGraph(workflow);
|
||||||
properties.node_graph = nodeGraphResult.nodeGraph;
|
properties.node_graph = nodeGraphResult.nodeGraph;
|
||||||
|
properties.node_graph_string = JSON.stringify(nodeGraphResult.nodeGraph);
|
||||||
|
|
||||||
if (errorNodeName) {
|
if (errorNodeName) {
|
||||||
properties.error_node_id = nodeGraphResult.nameIndices[errorNodeName];
|
properties.error_node_id = nodeGraphResult.nameIndices[errorNodeName];
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,12 @@ export class InternalHooksManager {
|
||||||
throw new Error('InternalHooks not initialized');
|
throw new Error('InternalHooks not initialized');
|
||||||
}
|
}
|
||||||
|
|
||||||
static init(instanceId: string): InternalHooksClass {
|
static init(instanceId: string, versionCli: string): InternalHooksClass {
|
||||||
if (!this.internalHooksInstance) {
|
if (!this.internalHooksInstance) {
|
||||||
this.internalHooksInstance = new InternalHooksClass(new Telemetry(instanceId));
|
this.internalHooksInstance = new InternalHooksClass(
|
||||||
|
new Telemetry(instanceId, versionCli),
|
||||||
|
versionCli,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.internalHooksInstance;
|
return this.internalHooksInstance;
|
||||||
|
|
|
@ -2896,7 +2896,14 @@ export async function start(): Promise<void> {
|
||||||
deploymentType: config.get('deployment.type'),
|
deploymentType: config.get('deployment.type'),
|
||||||
};
|
};
|
||||||
|
|
||||||
void InternalHooksManager.getInstance().onServerStarted(diagnosticInfo);
|
void Db.collections
|
||||||
|
.Workflow!.findOne({
|
||||||
|
select: ['createdAt'],
|
||||||
|
order: { createdAt: 'ASC' },
|
||||||
|
})
|
||||||
|
.then(async (workflow) =>
|
||||||
|
InternalHooksManager.getInstance().onServerStarted(diagnosticInfo, workflow?.createdAt),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ import {
|
||||||
CredentialTypes,
|
CredentialTypes,
|
||||||
Db,
|
Db,
|
||||||
ExternalHooks,
|
ExternalHooks,
|
||||||
|
GenericHelpers,
|
||||||
IWorkflowExecuteProcess,
|
IWorkflowExecuteProcess,
|
||||||
IWorkflowExecutionDataProcessWithExecution,
|
IWorkflowExecutionDataProcessWithExecution,
|
||||||
NodeTypes,
|
NodeTypes,
|
||||||
|
@ -137,7 +138,8 @@ export class WorkflowRunnerProcess {
|
||||||
await externalHooks.init();
|
await externalHooks.init();
|
||||||
|
|
||||||
const instanceId = (await UserSettings.prepareUserSettings()).instanceId ?? '';
|
const instanceId = (await UserSettings.prepareUserSettings()).instanceId ?? '';
|
||||||
InternalHooksManager.init(instanceId);
|
const { cli } = await GenericHelpers.getVersions();
|
||||||
|
InternalHooksManager.init(instanceId, cli);
|
||||||
|
|
||||||
// Credentials should now be loaded from database.
|
// Credentials should now be loaded from database.
|
||||||
// We check if any node uses credentials. If it does, then
|
// We check if any node uses credentials. If it does, then
|
||||||
|
|
|
@ -5,28 +5,57 @@ import { IDataObject, LoggerProxy } from 'n8n-workflow';
|
||||||
import config = require('../../config');
|
import config = require('../../config');
|
||||||
import { getLogger } from '../Logger';
|
import { getLogger } from '../Logger';
|
||||||
|
|
||||||
interface IExecutionCountsBufferItem {
|
type CountBufferItemKey =
|
||||||
manual_success_count: number;
|
| 'manual_success_count'
|
||||||
manual_error_count: number;
|
| 'manual_error_count'
|
||||||
prod_success_count: number;
|
| 'prod_success_count'
|
||||||
prod_error_count: number;
|
| 'prod_error_count';
|
||||||
}
|
|
||||||
|
type FirstExecutionItemKey =
|
||||||
|
| 'first_manual_success'
|
||||||
|
| 'first_manual_error'
|
||||||
|
| 'first_prod_success'
|
||||||
|
| 'first_prod_error';
|
||||||
|
|
||||||
|
type IExecutionCountsBufferItem = {
|
||||||
|
[key in CountBufferItemKey]: number;
|
||||||
|
};
|
||||||
|
|
||||||
interface IExecutionCountsBuffer {
|
interface IExecutionCountsBuffer {
|
||||||
[workflowId: string]: IExecutionCountsBufferItem;
|
[workflowId: string]: IExecutionCountsBufferItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type IFirstExecutions = {
|
||||||
|
[key in FirstExecutionItemKey]: Date | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface IExecutionsBuffer {
|
||||||
|
counts: IExecutionCountsBuffer;
|
||||||
|
firstExecutions: IFirstExecutions;
|
||||||
|
}
|
||||||
|
|
||||||
export class Telemetry {
|
export class Telemetry {
|
||||||
private client?: TelemetryClient;
|
private client?: TelemetryClient;
|
||||||
|
|
||||||
private instanceId: string;
|
private instanceId: string;
|
||||||
|
|
||||||
|
private versionCli: string;
|
||||||
|
|
||||||
private pulseIntervalReference: NodeJS.Timeout;
|
private pulseIntervalReference: NodeJS.Timeout;
|
||||||
|
|
||||||
private executionCountsBuffer: IExecutionCountsBuffer = {};
|
private executionCountsBuffer: IExecutionsBuffer = {
|
||||||
|
counts: {},
|
||||||
|
firstExecutions: {
|
||||||
|
first_manual_error: undefined,
|
||||||
|
first_manual_success: undefined,
|
||||||
|
first_prod_error: undefined,
|
||||||
|
first_prod_success: undefined,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
constructor(instanceId: string) {
|
constructor(instanceId: string, versionCli: string) {
|
||||||
this.instanceId = instanceId;
|
this.instanceId = instanceId;
|
||||||
|
this.versionCli = versionCli;
|
||||||
|
|
||||||
const enabled = config.get('diagnostics.enabled') as boolean;
|
const enabled = config.get('diagnostics.enabled') as boolean;
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
|
@ -53,33 +82,41 @@ export class Telemetry {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
const allPromises = Object.keys(this.executionCountsBuffer).map(async (workflowId) => {
|
const allPromises = Object.keys(this.executionCountsBuffer.counts).map(async (workflowId) => {
|
||||||
const promise = this.track('Workflow execution count', {
|
const promise = this.track('Workflow execution count', {
|
||||||
|
version_cli: this.versionCli,
|
||||||
workflow_id: workflowId,
|
workflow_id: workflowId,
|
||||||
...this.executionCountsBuffer[workflowId],
|
...this.executionCountsBuffer.counts[workflowId],
|
||||||
|
...this.executionCountsBuffer.firstExecutions,
|
||||||
});
|
});
|
||||||
this.executionCountsBuffer[workflowId].manual_error_count = 0;
|
|
||||||
this.executionCountsBuffer[workflowId].manual_success_count = 0;
|
this.executionCountsBuffer.counts[workflowId].manual_error_count = 0;
|
||||||
this.executionCountsBuffer[workflowId].prod_error_count = 0;
|
this.executionCountsBuffer.counts[workflowId].manual_success_count = 0;
|
||||||
this.executionCountsBuffer[workflowId].prod_success_count = 0;
|
this.executionCountsBuffer.counts[workflowId].prod_error_count = 0;
|
||||||
|
this.executionCountsBuffer.counts[workflowId].prod_success_count = 0;
|
||||||
|
|
||||||
return promise;
|
return promise;
|
||||||
});
|
});
|
||||||
|
|
||||||
allPromises.push(this.track('pulse'));
|
allPromises.push(this.track('pulse', { version_cli: this.versionCli }));
|
||||||
return Promise.all(allPromises);
|
return Promise.all(allPromises);
|
||||||
}
|
}
|
||||||
|
|
||||||
async trackWorkflowExecution(properties: IDataObject): Promise<void> {
|
async trackWorkflowExecution(properties: IDataObject): Promise<void> {
|
||||||
if (this.client) {
|
if (this.client) {
|
||||||
const workflowId = properties.workflow_id as string;
|
const workflowId = properties.workflow_id as string;
|
||||||
this.executionCountsBuffer[workflowId] = this.executionCountsBuffer[workflowId] ?? {
|
this.executionCountsBuffer.counts[workflowId] = this.executionCountsBuffer.counts[
|
||||||
|
workflowId
|
||||||
|
] ?? {
|
||||||
manual_error_count: 0,
|
manual_error_count: 0,
|
||||||
manual_success_count: 0,
|
manual_success_count: 0,
|
||||||
prod_error_count: 0,
|
prod_error_count: 0,
|
||||||
prod_success_count: 0,
|
prod_success_count: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let countKey: CountBufferItemKey;
|
||||||
|
let firstExecKey: FirstExecutionItemKey;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
properties.success === false &&
|
properties.success === false &&
|
||||||
properties.error_node_type &&
|
properties.error_node_type &&
|
||||||
|
@ -89,15 +126,28 @@ export class Telemetry {
|
||||||
void this.track('Workflow execution errored', properties);
|
void this.track('Workflow execution errored', properties);
|
||||||
|
|
||||||
if (properties.is_manual) {
|
if (properties.is_manual) {
|
||||||
this.executionCountsBuffer[workflowId].manual_error_count++;
|
firstExecKey = 'first_manual_error';
|
||||||
|
countKey = 'manual_error_count';
|
||||||
} else {
|
} else {
|
||||||
this.executionCountsBuffer[workflowId].prod_error_count++;
|
firstExecKey = 'first_prod_error';
|
||||||
|
countKey = 'prod_error_count';
|
||||||
}
|
}
|
||||||
} else if (properties.is_manual) {
|
} else if (properties.is_manual) {
|
||||||
this.executionCountsBuffer[workflowId].manual_success_count++;
|
countKey = 'manual_success_count';
|
||||||
|
firstExecKey = 'first_manual_success';
|
||||||
} else {
|
} else {
|
||||||
this.executionCountsBuffer[workflowId].prod_success_count++;
|
countKey = 'prod_success_count';
|
||||||
|
firstExecKey = 'first_prod_success';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!this.executionCountsBuffer.firstExecutions[firstExecKey] &&
|
||||||
|
this.executionCountsBuffer.counts[workflowId][countKey] === 0
|
||||||
|
) {
|
||||||
|
this.executionCountsBuffer.firstExecutions[firstExecKey] = new Date();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.executionCountsBuffer.counts[workflowId][countKey]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,14 +14,20 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
import Telemetry from './components/Telemetry.vue';
|
import Telemetry from './components/Telemetry.vue';
|
||||||
|
|
||||||
export default {
|
export default Vue.extend({
|
||||||
name: 'App',
|
name: 'App',
|
||||||
components: {
|
components: {
|
||||||
Telemetry,
|
Telemetry,
|
||||||
},
|
},
|
||||||
};
|
watch: {
|
||||||
|
'$route'(route) {
|
||||||
|
this.$telemetry.page('Editor', route.name);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|
|
@ -66,6 +66,12 @@ class Telemetry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
page(category?: string, name?: string | undefined | null) {
|
||||||
|
if (this.telemetry) {
|
||||||
|
this.telemetry.page(category, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
trackNodesPanel(event: string, properties: IDataObject = {}) {
|
trackNodesPanel(event: string, properties: IDataObject = {}) {
|
||||||
if (this.telemetry) {
|
if (this.telemetry) {
|
||||||
properties.nodes_panel_session_id = this.userNodesPanelSession.sessionId;
|
properties.nodes_panel_session_id = this.userNodesPanelSession.sessionId;
|
||||||
|
|
|
@ -2526,6 +2526,7 @@ export default mixins(
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$externalHooks().run('nodeView.mount');
|
this.$externalHooks().run('nodeView.mount');
|
||||||
|
this.$telemetry.page('Editor', this.$route.name);
|
||||||
},
|
},
|
||||||
|
|
||||||
destroyed () {
|
destroyed () {
|
||||||
|
|
Loading…
Reference in a new issue