From 3ef771ea381efe1d254b4c13ee0acf258bdab54f Mon Sep 17 00:00:00 2001 From: Cornelius Suermann Date: Mon, 23 Oct 2023 21:39:29 +0200 Subject: [PATCH] feat: Collect usage metrics on license renewal (no-changelog) (#7486) --- packages/cli/package.json | 2 +- packages/cli/src/License.ts | 14 ++++++++++++++ packages/cli/test/unit/License.test.ts | 2 ++ pnpm-lock.yaml | 25 +++++++++++++++---------- 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index 1246efe7ae..62e52e35af 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -99,7 +99,7 @@ }, "dependencies": { "@n8n/client-oauth2": "workspace:*", - "@n8n_io/license-sdk": "~2.6.1", + "@n8n_io/license-sdk": "~2.7.1", "@oclif/command": "^1.8.16", "@oclif/config": "^1.18.17", "@oclif/core": "^1.16.4", diff --git a/packages/cli/src/License.ts b/packages/cli/src/License.ts index 668df04d20..f42fd0dac4 100644 --- a/packages/cli/src/License.ts +++ b/packages/cli/src/License.ts @@ -12,6 +12,7 @@ import { UNLIMITED_LICENSE_QUOTA, } from './constants'; import Container, { Service } from 'typedi'; +import { WorkflowRepository } from '@/databases/repositories'; import type { BooleanLicenseFeature, N8nInstanceType, NumericLicenseFeature } from './Interfaces'; import type { RedisServicePubSubPublisher } from './services/redis/RedisServicePubSubPublisher'; import { RedisService } from './services/redis.service'; @@ -51,6 +52,9 @@ export class License { const onFeatureChange = isMainInstance ? async (features: TFeatures) => this.onFeatureChange(features) : async () => {}; + const collectUsageMetrics = isMainInstance + ? async () => this.collectUsageMetrics() + : async () => []; try { this.manager = new LicenseManager({ @@ -65,6 +69,7 @@ export class License { loadCertStr: async () => this.loadCertStr(), saveCertStr, deviceFingerprint: () => this.instanceSettings.instanceId, + collectUsageMetrics, onFeatureChange, }); @@ -76,6 +81,15 @@ export class License { } } + async collectUsageMetrics() { + return [ + { + name: 'activeWorkflows', + value: await Container.get(WorkflowRepository).count({ where: { active: true } }), + }, + ]; + } + async loadCertStr(): Promise { // if we have an ephemeral license, we don't want to load it from the database const ephemeralLicense = config.get('license.cert'); diff --git a/packages/cli/test/unit/License.test.ts b/packages/cli/test/unit/License.test.ts index ab3319bb92..2c29a59795 100644 --- a/packages/cli/test/unit/License.test.ts +++ b/packages/cli/test/unit/License.test.ts @@ -42,6 +42,7 @@ describe('License', () => { loadCertStr: expect.any(Function), saveCertStr: expect.any(Function), onFeatureChange: expect.any(Function), + collectUsageMetrics: expect.any(Function), server: MOCK_SERVER_URL, tenantId: 1, }); @@ -61,6 +62,7 @@ describe('License', () => { loadCertStr: expect.any(Function), saveCertStr: expect.any(Function), onFeatureChange: expect.any(Function), + collectUsageMetrics: expect.any(Function), server: MOCK_SERVER_URL, tenantId: 1, }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 11491f8a3f..342f6c71df 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -195,8 +195,8 @@ importers: specifier: workspace:* version: link:../@n8n/client-oauth2 '@n8n_io/license-sdk': - specifier: ~2.6.1 - version: 2.6.1 + specifier: ~2.7.1 + version: 2.7.1 '@oclif/command': specifier: ^1.8.16 version: 1.8.18(@oclif/config@1.18.17)(supports-color@8.1.1) @@ -3956,6 +3956,11 @@ packages: resolution: {integrity: sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ==} dev: true + /@fastify/busboy@2.0.0: + resolution: {integrity: sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==} + engines: {node: '>=14'} + dev: false + /@floating-ui/core@1.3.1: resolution: {integrity: sha512-Bu+AMaXNjrpjh41znzHqaz3r2Nr8hHuHZT6V2LBKMhyMl0FgKA62PNYbqnfgmzOhoWZj70Zecisbo4H1rotP5g==} dev: false @@ -4681,14 +4686,14 @@ packages: acorn-walk: 8.2.0 dev: false - /@n8n_io/license-sdk@2.6.1: - resolution: {integrity: sha512-N4yBzgNIRrQlhy+BWyEC9cbf86asPxryWbJpmrfeaqkFpBR6Z5yIqmWRGnLs7XKVC9se8cdWlF7EWKtaH6oDPA==} - engines: {node: '>=14.0.0', npm: '>=7.10.0'} + /@n8n_io/license-sdk@2.7.1: + resolution: {integrity: sha512-SiPKI/wN2coLPB8Tyb28UlLgAszU2SkSR8PWNioTWAd8PnUhTYg8KN9jfUOZipVF+YMOAHc/hQUq6kJA1PF0xg==} + engines: {node: '>=18.12.1', npm: '>=8.19.2'} dependencies: crypto-js: 4.1.1 node-machine-id: 1.1.12 node-rsa: 1.1.1 - undici: 5.21.0 + undici: 5.26.4 dev: false /@n8n_io/riot-tmpl@4.0.0: @@ -21213,11 +21218,11 @@ packages: undertaker-registry: 1.0.1 dev: true - /undici@5.21.0: - resolution: {integrity: sha512-HOjK8l6a57b2ZGXOcUsI5NLfoTrfmbOl90ixJDl0AEFG4wgHNDQxtZy15/ZQp7HhjkpaGlp/eneMgtsu1dIlUA==} - engines: {node: '>=12.18'} + /undici@5.26.4: + resolution: {integrity: sha512-OG+QOf0fTLtazL9P9X7yqWxQ+Z0395Wk6DSkyTxtaq3wQEjIroVe7Y4asCX/vcCxYpNGMnwz8F0qbRYUoaQVMw==} + engines: {node: '>=14.0'} dependencies: - busboy: 1.6.0 + '@fastify/busboy': 2.0.0 dev: false /unescape@1.0.1: