n8n
Version:
n8n Workflow Automation Tool
209 lines • 9.9 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Telemetry = void 0;
const axios_1 = __importDefault(require("axios"));
const posthog_1 = require("../posthog");
const typedi_1 = require("typedi");
const n8n_core_1 = require("n8n-core");
const config_1 = __importDefault(require("../config"));
const Logger_1 = require("../Logger");
const License_1 = require("../License");
const constants_1 = require("../constants");
const workflow_repository_1 = require("../databases/repositories/workflow.repository");
const sourceControlPreferences_service_ee_1 = require("../environments/sourceControl/sourceControlPreferences.service.ee");
const user_repository_1 = require("../databases/repositories/user.repository");
const project_repository_1 = require("../databases/repositories/project.repository");
const projectRelation_repository_1 = require("../databases/repositories/projectRelation.repository");
const OnShutdown_1 = require("../decorators/OnShutdown");
let Telemetry = class Telemetry {
constructor(logger, postHog, license, instanceSettings, workflowRepository) {
this.logger = logger;
this.postHog = postHog;
this.license = license;
this.instanceSettings = instanceSettings;
this.workflowRepository = workflowRepository;
this.executionCountsBuffer = {};
}
async init() {
const enabled = config_1.default.getEnv('diagnostics.enabled');
if (enabled) {
const conf = config_1.default.getEnv('diagnostics.config.backend');
const [key, dataPlaneUrl] = conf.split(';');
if (!key || !dataPlaneUrl) {
this.logger.warn('Diagnostics backend config is invalid');
return;
}
const logLevel = config_1.default.getEnv('logs.level');
const { default: RudderStack } = await Promise.resolve().then(() => __importStar(require('@rudderstack/rudder-sdk-node')));
const axiosInstance = axios_1.default.create();
axiosInstance.interceptors.request.use((cfg) => {
cfg.headers.setContentType('application/json', false);
return cfg;
});
this.rudderStack = new RudderStack(key, {
axiosInstance,
logLevel,
dataPlaneUrl,
gzip: false,
});
this.startPulse();
}
}
startPulse() {
this.pulseIntervalReference = setInterval(async () => {
void this.pulse();
}, 6 * 60 * 60 * 1000);
}
async pulse() {
if (!this.rudderStack) {
return;
}
const workflowIdsToReport = Object.keys(this.executionCountsBuffer).filter((workflowId) => {
var _a, _b, _c, _d, _e, _f, _g, _h;
const data = this.executionCountsBuffer[workflowId];
const sum = ((_b = (_a = data.manual_error) === null || _a === void 0 ? void 0 : _a.count) !== null && _b !== void 0 ? _b : 0) +
((_d = (_c = data.manual_success) === null || _c === void 0 ? void 0 : _c.count) !== null && _d !== void 0 ? _d : 0) +
((_f = (_e = data.prod_error) === null || _e === void 0 ? void 0 : _e.count) !== null && _f !== void 0 ? _f : 0) +
((_h = (_g = data.prod_success) === null || _g === void 0 ? void 0 : _g.count) !== null && _h !== void 0 ? _h : 0);
return sum > 0;
});
for (const workflowId of workflowIdsToReport) {
this.track('Workflow execution count', {
event_version: '2',
workflow_id: workflowId,
...this.executionCountsBuffer[workflowId],
});
}
this.executionCountsBuffer = {};
const sourceControlPreferences = typedi_1.Container.get(sourceControlPreferences_service_ee_1.SourceControlPreferencesService).getPreferences();
const pulsePacket = {
plan_name_current: this.license.getPlanName(),
quota: this.license.getTriggerLimit(),
usage: await this.workflowRepository.getActiveTriggerCount(),
role_count: await typedi_1.Container.get(user_repository_1.UserRepository).countUsersByRole(),
source_control_set_up: typedi_1.Container.get(sourceControlPreferences_service_ee_1.SourceControlPreferencesService).isSourceControlSetup(),
branchName: sourceControlPreferences.branchName,
read_only_instance: sourceControlPreferences.branchReadOnly,
team_projects: (await typedi_1.Container.get(project_repository_1.ProjectRepository).getProjectCounts()).team,
project_role_count: await typedi_1.Container.get(projectRelation_repository_1.ProjectRelationRepository).countUsersByRole(),
};
this.track('pulse', pulsePacket);
}
trackWorkflowExecution(properties) {
var _a, _b;
if (this.rudderStack) {
const execTime = new Date();
const workflowId = properties.workflow_id;
this.executionCountsBuffer[workflowId] = (_a = this.executionCountsBuffer[workflowId]) !== null && _a !== void 0 ? _a : {
user_id: properties.user_id,
};
const key = `${properties.is_manual ? 'manual' : 'prod'}_${properties.success ? 'success' : 'error'}`;
const executionTrackDataKey = this.executionCountsBuffer[workflowId][key];
if (!executionTrackDataKey) {
this.executionCountsBuffer[workflowId][key] = {
count: 1,
first: execTime,
};
}
else {
executionTrackDataKey.count++;
}
if (!properties.success &&
properties.is_manual &&
((_b = properties.error_node_type) === null || _b === void 0 ? void 0 : _b.startsWith('n8n-nodes-base'))) {
this.track('Workflow execution errored', properties);
}
}
}
async stopTracking() {
var _a;
clearInterval(this.pulseIntervalReference);
await Promise.all([this.postHog.stop(), (_a = this.rudderStack) === null || _a === void 0 ? void 0 : _a.flush()]);
}
identify(traits) {
if (!this.rudderStack) {
return;
}
const { instanceId } = this.instanceSettings;
this.rudderStack.identify({
userId: instanceId,
traits: { ...traits, instanceId },
});
}
track(eventName, properties = {}, { withPostHog } = { withPostHog: false }) {
var _a;
if (!this.rudderStack) {
return;
}
const { instanceId } = this.instanceSettings;
const { user_id } = properties;
const updatedProperties = {
...properties,
instance_id: instanceId,
version_cli: constants_1.N8N_VERSION,
};
const payload = {
userId: `${instanceId}${user_id ? `#${user_id}` : ''}`,
event: eventName,
properties: updatedProperties,
};
if (withPostHog) {
(_a = this.postHog) === null || _a === void 0 ? void 0 : _a.track(payload);
}
return this.rudderStack.track(payload);
}
getCountsBuffer() {
return this.executionCountsBuffer;
}
};
exports.Telemetry = Telemetry;
__decorate([
(0, OnShutdown_1.OnShutdown)(constants_1.LOWEST_SHUTDOWN_PRIORITY),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", Promise)
], Telemetry.prototype, "stopTracking", null);
exports.Telemetry = Telemetry = __decorate([
(0, typedi_1.Service)(),
__metadata("design:paramtypes", [Logger_1.Logger,
posthog_1.PostHogClient,
License_1.License,
n8n_core_1.InstanceSettings,
workflow_repository_1.WorkflowRepository])
], Telemetry);
//# sourceMappingURL=index.js.map