mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
⚡ Support telemetry page (#2756)
* support telemetry page events * add log level to FE settings * add debug logging * fix types * state fix * move call
This commit is contained in:
parent
0bf554394a
commit
7bdb7e2a25
|
@ -409,6 +409,7 @@ export interface IN8nUISettings {
|
||||||
telemetry: ITelemetrySettings;
|
telemetry: ITelemetrySettings;
|
||||||
personalizationSurvey: IPersonalizationSurvey;
|
personalizationSurvey: IPersonalizationSurvey;
|
||||||
defaultLocale: string;
|
defaultLocale: string;
|
||||||
|
logLevel: 'info' | 'debug' | 'warn' | 'error' | 'verbose';
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IPersonalizationSurveyAnswers {
|
export interface IPersonalizationSurveyAnswers {
|
||||||
|
|
|
@ -288,6 +288,7 @@ class App {
|
||||||
shouldShow: false,
|
shouldShow: false,
|
||||||
},
|
},
|
||||||
defaultLocale: config.get('defaultLocale'),
|
defaultLocale: config.get('defaultLocale'),
|
||||||
|
logLevel: config.get('logs.level'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,9 @@ export default Vue.extend({
|
||||||
components: {
|
components: {
|
||||||
Telemetry,
|
Telemetry,
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
this.$telemetry.page('Editor', this.$route.name);
|
||||||
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'$route'(route) {
|
'$route'(route) {
|
||||||
this.$telemetry.page('Editor', route.name);
|
this.$telemetry.page('Editor', route.name);
|
||||||
|
|
|
@ -536,6 +536,7 @@ export interface IN8nUISettings {
|
||||||
personalizationSurvey?: IPersonalizationSurvey;
|
personalizationSurvey?: IPersonalizationSurvey;
|
||||||
telemetry: ITelemetrySettings;
|
telemetry: ITelemetrySettings;
|
||||||
defaultLocale: string;
|
defaultLocale: string;
|
||||||
|
logLevel: ILogLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IWorkflowSettings extends IWorkflowSettingsWorkflow {
|
export interface IWorkflowSettings extends IWorkflowSettingsWorkflow {
|
||||||
|
@ -680,7 +681,6 @@ export interface IRootState {
|
||||||
workflow: IWorkflowDb;
|
workflow: IWorkflowDb;
|
||||||
sidebarMenuItems: IMenuItem[];
|
sidebarMenuItems: IMenuItem[];
|
||||||
instanceId: string;
|
instanceId: string;
|
||||||
telemetry: ITelemetrySettings | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICredentialTypeMap {
|
export interface ICredentialTypeMap {
|
||||||
|
@ -718,6 +718,8 @@ export interface IUiState {
|
||||||
isPageLoading: boolean;
|
isPageLoading: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ILogLevel = 'info' | 'debug' | 'warn' | 'error' | 'verbose';
|
||||||
|
|
||||||
export interface ISettingsState {
|
export interface ISettingsState {
|
||||||
settings: IN8nUISettings;
|
settings: IN8nUISettings;
|
||||||
promptsData: IN8nPrompts;
|
promptsData: IN8nPrompts;
|
||||||
|
|
|
@ -10,12 +10,12 @@ import { mapGetters } from 'vuex';
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
name: 'Telemetry',
|
name: 'Telemetry',
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['telemetry']),
|
...mapGetters('settings', ['telemetry']),
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
telemetry(opts) {
|
telemetry(opts) {
|
||||||
if (opts.enabled) {
|
if (opts && opts.enabled) {
|
||||||
this.$telemetry.init(opts, this.$store.getters.instanceId);
|
this.$telemetry.init(opts, this.$store.getters.instanceId, this.$store.getters['settings/logLevel']);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { ActionContext, Module } from 'vuex';
|
import { ActionContext, Module } from 'vuex';
|
||||||
import {
|
import {
|
||||||
|
ILogLevel,
|
||||||
IN8nPrompts,
|
IN8nPrompts,
|
||||||
IN8nUISettings,
|
IN8nUISettings,
|
||||||
IN8nValueSurveyData,
|
IN8nValueSurveyData,
|
||||||
|
@ -11,6 +12,7 @@ import { getPromptsData, getSettings, submitValueSurvey, submitPersonalizationSu
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { getPersonalizedNodeTypes } from './helper';
|
import { getPersonalizedNodeTypes } from './helper';
|
||||||
import { CONTACT_PROMPT_MODAL_KEY, PERSONALIZATION_MODAL_KEY, VALUE_SURVEY_MODAL_KEY } from '@/constants';
|
import { CONTACT_PROMPT_MODAL_KEY, PERSONALIZATION_MODAL_KEY, VALUE_SURVEY_MODAL_KEY } from '@/constants';
|
||||||
|
import { ITelemetrySettings } from 'n8n-workflow';
|
||||||
|
|
||||||
const module: Module<ISettingsState, IRootState> = {
|
const module: Module<ISettingsState, IRootState> = {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
|
@ -30,6 +32,15 @@ const module: Module<ISettingsState, IRootState> = {
|
||||||
getPromptsData(state: ISettingsState) {
|
getPromptsData(state: ISettingsState) {
|
||||||
return state.promptsData;
|
return state.promptsData;
|
||||||
},
|
},
|
||||||
|
telemetry: (state): ITelemetrySettings => {
|
||||||
|
return state.settings.telemetry;
|
||||||
|
},
|
||||||
|
logLevel: (state): ILogLevel => {
|
||||||
|
return state.settings.logLevel;
|
||||||
|
},
|
||||||
|
isTelemetryEnabled: (state) => {
|
||||||
|
return state.settings.telemetry && state.settings.telemetry.enabled;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
setSettings(state: ISettingsState, settings: IN8nUISettings) {
|
setSettings(state: ISettingsState, settings: IN8nUISettings) {
|
||||||
|
@ -66,7 +77,6 @@ const module: Module<ISettingsState, IRootState> = {
|
||||||
context.commit('setN8nMetadata', settings.n8nMetadata || {}, {root: true});
|
context.commit('setN8nMetadata', settings.n8nMetadata || {}, {root: true});
|
||||||
context.commit('setDefaultLocale', settings.defaultLocale, {root: true});
|
context.commit('setDefaultLocale', settings.defaultLocale, {root: true});
|
||||||
context.commit('versions/setVersionNotificationSettings', settings.versionNotifications, {root: true});
|
context.commit('versions/setVersionNotificationSettings', settings.versionNotifications, {root: true});
|
||||||
context.commit('setTelemetry', settings.telemetry, {root: true});
|
|
||||||
|
|
||||||
const showPersonalizationsModal = settings.personalizationSurvey && settings.personalizationSurvey.shouldShow && !settings.personalizationSurvey.answers;
|
const showPersonalizationsModal = settings.personalizationSurvey && settings.personalizationSurvey.shouldShow && !settings.personalizationSurvey.answers;
|
||||||
|
|
||||||
|
@ -81,7 +91,7 @@ const module: Module<ISettingsState, IRootState> = {
|
||||||
context.commit('setPersonalizationAnswers', results);
|
context.commit('setPersonalizationAnswers', results);
|
||||||
},
|
},
|
||||||
async fetchPromptsData(context: ActionContext<ISettingsState, IRootState>) {
|
async fetchPromptsData(context: ActionContext<ISettingsState, IRootState>) {
|
||||||
if (!context.rootGetters.isTelemetryEnabled) {
|
if (!context.getters.isTelemetryEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import {
|
||||||
ITelemetrySettings,
|
ITelemetrySettings,
|
||||||
IDataObject,
|
IDataObject,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import { INodeCreateElement } from "@/Interface";
|
import { ILogLevel, INodeCreateElement } from "@/Interface";
|
||||||
|
|
||||||
declare module 'vue/types/vue' {
|
declare module 'vue/types/vue' {
|
||||||
interface Vue {
|
interface Vue {
|
||||||
|
@ -35,6 +35,8 @@ interface IUserNodesPanelSession {
|
||||||
|
|
||||||
class Telemetry {
|
class Telemetry {
|
||||||
|
|
||||||
|
private pageEventQueue: Array<{category?: string, name?: string | null}>;
|
||||||
|
|
||||||
private get telemetry() {
|
private get telemetry() {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return window.rudderanalytics;
|
return window.rudderanalytics;
|
||||||
|
@ -49,14 +51,20 @@ class Telemetry {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
init(options: ITelemetrySettings, instanceId: string) {
|
constructor() {
|
||||||
|
this.pageEventQueue = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
init(options: ITelemetrySettings, instanceId: string, logLevel?: ILogLevel) {
|
||||||
if (options.enabled && !this.telemetry) {
|
if (options.enabled && !this.telemetry) {
|
||||||
if(!options.config) {
|
if(!options.config) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loadTelemetryLibrary(options.config.key, options.config.url, { integrations: { All: false }, loadIntegration: false });
|
const logging = logLevel === 'debug' ? { logLevel: 'DEBUG'} : {};
|
||||||
|
this.loadTelemetryLibrary(options.config.key, options.config.url, { integrations: { All: false }, loadIntegration: false, ...logging});
|
||||||
this.telemetry.identify(instanceId);
|
this.telemetry.identify(instanceId);
|
||||||
|
this.flushPageEvents();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,10 +74,26 @@ class Telemetry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
page(category?: string, name?: string | undefined | null) {
|
page(category?: string, name?: string | null) {
|
||||||
if (this.telemetry) {
|
if (this.telemetry) {
|
||||||
this.telemetry.page(category, name);
|
this.telemetry.page(category, name);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
this.pageEventQueue.push({
|
||||||
|
category,
|
||||||
|
name,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
flushPageEvents() {
|
||||||
|
const queue = this.pageEventQueue;
|
||||||
|
this.pageEventQueue = [];
|
||||||
|
queue.forEach(({category, name}) => {
|
||||||
|
if (this.telemetry) {
|
||||||
|
this.telemetry.page(category, name);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
trackNodesPanel(event: string, properties: IDataObject = {}) {
|
trackNodesPanel(event: string, properties: IDataObject = {}) {
|
||||||
|
|
|
@ -12,7 +12,6 @@ import {
|
||||||
INodeIssueData,
|
INodeIssueData,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
IRunData,
|
IRunData,
|
||||||
ITelemetrySettings,
|
|
||||||
ITaskData,
|
ITaskData,
|
||||||
IWorkflowSettings,
|
IWorkflowSettings,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
@ -89,7 +88,6 @@ const state: IRootState = {
|
||||||
},
|
},
|
||||||
sidebarMenuItems: [],
|
sidebarMenuItems: [],
|
||||||
instanceId: '',
|
instanceId: '',
|
||||||
telemetry: null,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const modules = {
|
const modules = {
|
||||||
|
@ -545,9 +543,6 @@ export const store = new Vuex.Store({
|
||||||
setInstanceId(state, instanceId: string) {
|
setInstanceId(state, instanceId: string) {
|
||||||
Vue.set(state, 'instanceId', instanceId);
|
Vue.set(state, 'instanceId', instanceId);
|
||||||
},
|
},
|
||||||
setTelemetry(state, telemetry: ITelemetrySettings) {
|
|
||||||
Vue.set(state, 'telemetry', telemetry);
|
|
||||||
},
|
|
||||||
setOauthCallbackUrls(state, urls: IDataObject) {
|
setOauthCallbackUrls(state, urls: IDataObject) {
|
||||||
Vue.set(state, 'oauthCallbackUrls', urls);
|
Vue.set(state, 'oauthCallbackUrls', urls);
|
||||||
},
|
},
|
||||||
|
@ -659,10 +654,6 @@ export const store = new Vuex.Store({
|
||||||
return state.workflow.id === PLACEHOLDER_EMPTY_WORKFLOW_ID;
|
return state.workflow.id === PLACEHOLDER_EMPTY_WORKFLOW_ID;
|
||||||
},
|
},
|
||||||
|
|
||||||
isTelemetryEnabled: (state) => {
|
|
||||||
return state.telemetry && state.telemetry.enabled;
|
|
||||||
},
|
|
||||||
|
|
||||||
currentWorkflowHasWebhookNode: (state: IRootState): boolean => {
|
currentWorkflowHasWebhookNode: (state: IRootState): boolean => {
|
||||||
return !!state.workflow.nodes.find((node: INodeUi) => !!node.webhookId);
|
return !!state.workflow.nodes.find((node: INodeUi) => !!node.webhookId);
|
||||||
},
|
},
|
||||||
|
@ -730,9 +721,6 @@ export const store = new Vuex.Store({
|
||||||
versionCli: (state): string => {
|
versionCli: (state): string => {
|
||||||
return state.versionCli;
|
return state.versionCli;
|
||||||
},
|
},
|
||||||
telemetry: (state): ITelemetrySettings | null => {
|
|
||||||
return state.telemetry;
|
|
||||||
},
|
|
||||||
oauthCallbackUrls: (state): object => {
|
oauthCallbackUrls: (state): object => {
|
||||||
return state.oauthCallbackUrls;
|
return state.oauthCallbackUrls;
|
||||||
},
|
},
|
||||||
|
|
|
@ -2752,7 +2752,6 @@ 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