diff --git a/src/shadowbox/server/shared_metrics.spec.ts b/src/shadowbox/server/shared_metrics.spec.ts index c13460b0..3866eeed 100644 --- a/src/shadowbox/server/shared_metrics.spec.ts +++ b/src/shadowbox/server/shared_metrics.spec.ts @@ -23,7 +23,6 @@ import { CountryUsage, DailyFeatureMetricsReportJson, HourlyServerMetricsReportJson, - KeyUsage, MetricsCollectorClient, OutlineSharedMetricsPublisher, UsageMetrics, @@ -83,11 +82,6 @@ describe('OutlineSharedMetricsPublisher', () => { ); publisher.startSharing(); - usageMetrics.keyUsage = [ - {accessKeyId: 'user-0', inboundBytes: 11}, - {accessKeyId: 'user-1', inboundBytes: 22}, - {accessKeyId: 'user-0', inboundBytes: 33}, - ]; usageMetrics.countryUsage = [ {country: 'AA', inboundBytes: 11}, {country: 'BB', inboundBytes: 11}, @@ -103,9 +97,6 @@ describe('OutlineSharedMetricsPublisher', () => { startUtcMs: startTime, endUtcMs: clock.nowMs, userReports: [ - {userId: 'M(user-0)', bytesTransferred: 11}, - {userId: 'M(user-1)', bytesTransferred: 22}, - {userId: 'M(user-0)', bytesTransferred: 33}, {bytesTransferred: 11, countries: ['AA']}, {bytesTransferred: 11, countries: ['BB']}, {bytesTransferred: 22, countries: ['CC']}, @@ -115,10 +106,6 @@ describe('OutlineSharedMetricsPublisher', () => { }); startTime = clock.nowMs; - usageMetrics.keyUsage = [ - {accessKeyId: 'user-0', inboundBytes: 44}, - {accessKeyId: 'user-2', inboundBytes: 55}, - ]; usageMetrics.countryUsage = [ {country: 'EE', inboundBytes: 44}, {country: 'FF', inboundBytes: 55}, @@ -131,8 +118,6 @@ describe('OutlineSharedMetricsPublisher', () => { startUtcMs: startTime, endUtcMs: clock.nowMs, userReports: [ - {userId: 'M(user-0)', bytesTransferred: 44}, - {userId: 'M(user-2)', bytesTransferred: 55}, {bytesTransferred: 44, countries: ['EE']}, {bytesTransferred: 55, countries: ['FF']}, ], @@ -157,11 +142,6 @@ describe('OutlineSharedMetricsPublisher', () => { ); publisher.startSharing(); - usageMetrics.keyUsage = [ - {accessKeyId: 'user-0', inboundBytes: 11}, - {accessKeyId: 'user-1', inboundBytes: 22}, - {accessKeyId: 'user-0', inboundBytes: 33}, - ]; usageMetrics.countryUsage = [ {country: 'AA', inboundBytes: 11}, {country: 'SY', inboundBytes: 11}, @@ -177,9 +157,6 @@ describe('OutlineSharedMetricsPublisher', () => { startUtcMs: startTime, endUtcMs: clock.nowMs, userReports: [ - {userId: 'M(user-0)', bytesTransferred: 11}, - {userId: 'M(user-1)', bytesTransferred: 22}, - {userId: 'M(user-0)', bytesTransferred: 33}, {bytesTransferred: 11, countries: ['AA']}, {bytesTransferred: 22, countries: ['CC']}, {bytesTransferred: 33, countries: ['AA']}, @@ -289,19 +266,13 @@ class FakeMetricsCollector implements MetricsCollectorClient { } class ManualUsageMetrics implements UsageMetrics { - public keyUsage = [] as KeyUsage[]; public countryUsage = [] as CountryUsage[]; - - getKeyUsage(): Promise { - return Promise.resolve(this.keyUsage); - } getCountryUsage(): Promise { - return Promise.resolve(this.countryUsage) + return Promise.resolve(this.countryUsage); } reset() { - this.keyUsage = [] as KeyUsage[]; this.countryUsage = [] as CountryUsage[]; } } diff --git a/src/shadowbox/server/shared_metrics.ts b/src/shadowbox/server/shared_metrics.ts index 3354902d..76455471 100644 --- a/src/shadowbox/server/shared_metrics.ts +++ b/src/shadowbox/server/shared_metrics.ts @@ -27,12 +27,6 @@ const MS_PER_HOUR = 60 * 60 * 1000; const MS_PER_DAY = 24 * MS_PER_HOUR; const SANCTIONED_COUNTRIES = new Set(['CU', 'KP', 'SY']); -// Used internally to track key usage. -export interface KeyUsage { - accessKeyId: string; - inboundBytes: number; -} - export interface CountryUsage { country: string; inboundBytes: number; @@ -50,8 +44,7 @@ export interface HourlyServerMetricsReportJson { // JSON format for the published report. // Field renames will break backwards-compatibility. export interface HourlyUserMetricsReportJson { - userId?: string; - countries?: string[]; + countries: string[]; bytesTransferred: number; } @@ -78,7 +71,6 @@ export interface SharedMetricsPublisher { } export interface UsageMetrics { - getKeyUsage(): Promise; getCountryUsage(): Promise; reset(); } @@ -89,23 +81,6 @@ export class PrometheusUsageMetrics implements UsageMetrics { constructor(private prometheusClient: PrometheusClient) {} - async getKeyUsage(): Promise { - const timeDeltaSecs = Math.round((Date.now() - this.resetTimeMs) / 1000); - // We measure the traffic to and from the target, since that's what we are protecting. - const result = await this.prometheusClient.query( - `sum(increase(shadowsocks_data_bytes{dir=~"p>t|p 0) { - usage.push({accessKeyId, inboundBytes}); - } - } - return usage; - } - async getCountryUsage(): Promise { const timeDeltaSecs = Math.round((Date.now() - this.resetTimeMs) / 1000); // We measure the traffic to and from the target, since that's what we are protecting. @@ -191,9 +166,7 @@ export class OutlineSharedMetricsPublisher implements SharedMetricsPublisher { return; } try { - const keyUsagePromise = usageMetrics.getKeyUsage() - const countryUsagePromise = usageMetrics.getCountryUsage() - await this.reportServerUsageMetrics(await keyUsagePromise, await countryUsagePromise); + await this.reportServerUsageMetrics(await usageMetrics.getCountryUsage()); usageMetrics.reset(); } catch (err) { logging.error(`Failed to report server usage metrics: ${err}`); @@ -227,26 +200,10 @@ export class OutlineSharedMetricsPublisher implements SharedMetricsPublisher { return this.serverConfig.data().metricsEnabled || false; } - private async reportServerUsageMetrics(keyUsageMetrics: KeyUsage[], countryUsageMetrics: CountryUsage[]): Promise { + private async reportServerUsageMetrics(countryUsageMetrics: CountryUsage[]): Promise { const reportEndTimestampMs = this.clock.now(); const userReports = [] as HourlyUserMetricsReportJson[]; - // HACK! We use the same backend reporting endpoint for key and country usage. - // A row with empty country is for key usage, a row with empty userId is for country usage. - // Note that this reports usage twice. If you want the total, filter to rows with non empty countries. - for (const keyUsage of keyUsageMetrics) { - if (keyUsage.inboundBytes === 0) { - continue; - } - const userId = this.toMetricsId(keyUsage.accessKeyId); - if (!userId) { - continue; - } - userReports.push({ - userId, - bytesTransferred: keyUsage.inboundBytes, - }); - } for (const countryUsage of countryUsageMetrics) { if (countryUsage.inboundBytes === 0) { continue; @@ -254,8 +211,8 @@ export class OutlineSharedMetricsPublisher implements SharedMetricsPublisher { if (isSanctionedCountry(countryUsage.country)) { continue; } - // Make sure to always set the country to differentiate the row - // from key usage rows. + // Make sure to always set a country, which is required by the metrics server validation. + // It's used to differentiate the row from the legacy key usage rows. const country = countryUsage.country || 'ZZ'; userReports.push({ bytesTransferred: countryUsage.inboundBytes,