Skip to content

Commit 7e8578e

Browse files
zirkelcdreamorosi
andauthored
feat(metrics): disable metrics with POWERTOOLS_METRICS_DISABLED (#3351)
Co-authored-by: Andrea Amorosi <[email protected]>
1 parent b692b79 commit 7e8578e

File tree

5 files changed

+158
-2
lines changed

5 files changed

+158
-2
lines changed

Diff for: packages/commons/src/config/EnvironmentVariablesService.ts

+11
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,17 @@ class EnvironmentVariablesService implements ConfigServiceInterface {
9393
return truthyValues.includes(value.toLowerCase());
9494
}
9595

96+
/**
97+
* Helper function to determine if a value is considered falsy.
98+
*
99+
* @param value The value to check for falsiness.
100+
*/
101+
public isValueFalse(value: string): boolean {
102+
const falsyValues: string[] = ['0', 'n', 'no', 'f', 'false', 'off'];
103+
104+
return falsyValues.includes(value.toLowerCase());
105+
}
106+
96107
/**
97108
* Get the AWS X-Ray Trace data from the environment variable.
98109
*

Diff for: packages/commons/tests/unit/EnvironmentVariablesService.test.ts

+31
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,37 @@ describe('Class: EnvironmentVariablesService', () => {
159159
);
160160
});
161161

162+
describe('Method: isValueFalse', () => {
163+
const valuesToTest: Array<Array<string | boolean>> = [
164+
['0', true],
165+
['n', true],
166+
['no', true],
167+
['f', true],
168+
['FALSE', true],
169+
['off', true],
170+
['1', false],
171+
['y', false],
172+
['yes', false],
173+
['t', false],
174+
['TRUE', false],
175+
['on', false],
176+
['', false],
177+
['somethingsilly', false],
178+
];
179+
180+
it.each(valuesToTest)(
181+
'takes string "%s" and returns %s',
182+
(input, output) => {
183+
// Prepare
184+
const service = new EnvironmentVariablesService();
185+
// Act
186+
const value = service.isValueFalse(input as string);
187+
// Assess
188+
expect(value).toBe(output);
189+
}
190+
);
191+
});
192+
162193
describe('Method: isDevMode', () => {
163194
it('returns true if the environment variable POWERTOOLS_DEV is "true"', () => {
164195
// Prepare

Diff for: packages/metrics/src/Metrics.ts

+28-2
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,11 @@ class Metrics extends Utility implements MetricsInterface {
201201
*/
202202
private storedMetrics: StoredMetrics = {};
203203

204+
/**
205+
* Whether to disable metrics
206+
*/
207+
private disabled = false;
208+
204209
/**
205210
* Custom timestamp for the metrics
206211
*/
@@ -472,6 +477,13 @@ class Metrics extends Utility implements MetricsInterface {
472477
return Object.keys(this.storedMetrics).length > 0;
473478
}
474479

480+
/**
481+
* Whether metrics are disabled.
482+
*/
483+
protected isDisabled(): boolean {
484+
return this.disabled;
485+
}
486+
475487
/**
476488
* A class method decorator to automatically log metrics after the method returns or throws an error.
477489
*
@@ -579,8 +591,12 @@ class Metrics extends Utility implements MetricsInterface {
579591
'If application metrics should never be empty, consider using `throwOnEmptyMetrics`'
580592
);
581593
}
582-
const emfOutput = this.serializeMetrics();
583-
hasMetrics && this.console.log(JSON.stringify(emfOutput));
594+
595+
if (!this.disabled) {
596+
const emfOutput = this.serializeMetrics();
597+
hasMetrics && this.console.log(JSON.stringify(emfOutput));
598+
}
599+
584600
this.clearMetrics();
585601
this.clearDimensions();
586602
this.clearMetadata();
@@ -913,6 +929,15 @@ class Metrics extends Utility implements MetricsInterface {
913929
this.getEnvVarsService().getNamespace()) as string;
914930
}
915931

932+
/**
933+
* Set the disbaled flag based on the environment variables `POWERTOOLS_METRICS_DISABLED` and `POWERTOOLS_DEV`.
934+
*
935+
* The `POWERTOOLS_METRICS_DISABLED` environment variable takes precedence over `POWERTOOLS_DEV`.
936+
*/
937+
private setDisabled(): void {
938+
this.disabled = this.getEnvVarsService().getMetricsDisabled();
939+
}
940+
916941
/**
917942
* Set the options to be used by the Metrics instance.
918943
*
@@ -932,6 +957,7 @@ class Metrics extends Utility implements MetricsInterface {
932957
this.setEnvVarsService();
933958
this.setConsole();
934959
this.setCustomConfigService(customConfigService);
960+
this.setDisabled();
935961
this.setNamespace(namespace);
936962
this.setService(serviceName);
937963
this.setDefaultDimensions(defaultDimensions);

Diff for: packages/metrics/src/config/EnvironmentVariablesService.ts

+17
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,29 @@ class EnvironmentVariablesService
1313
{
1414
private namespaceVariable = 'POWERTOOLS_METRICS_NAMESPACE';
1515

16+
private readonly disabledVariable = 'POWERTOOLS_METRICS_DISABLED';
17+
1618
/**
1719
* Get the value of the `POWERTOOLS_METRICS_NAMESPACE` environment variable.
1820
*/
1921
public getNamespace(): string {
2022
return this.get(this.namespaceVariable);
2123
}
24+
25+
/**
26+
* Get the value of the `POWERTOOLS_METRICS_DISABLED` or `POWERTOOLS_DEV` environment variables.
27+
*
28+
* The `POWERTOOLS_METRICS_DISABLED` environment variable takes precedence over `POWERTOOLS_DEV`.
29+
*/
30+
public getMetricsDisabled(): boolean {
31+
const value = this.get(this.disabledVariable);
32+
33+
if (this.isValueFalse(value)) return false;
34+
if (this.isValueTrue(value)) return true;
35+
if (this.isDevMode()) return true;
36+
37+
return false;
38+
}
2239
}
2340

2441
export { EnvironmentVariablesService };

Diff for: packages/metrics/tests/unit/Metrics.test.ts

+71
Original file line numberDiff line numberDiff line change
@@ -1430,6 +1430,29 @@ describe('Class: Metrics', () => {
14301430
expect(consoleLogSpy).toBeCalledWith(JSON.stringify(mockData));
14311431
});
14321432

1433+
test('it should not log anything if metrics are disabled', () => {
1434+
// Prepare
1435+
process.env.POWERTOOLS_METRICS_DISABLED = 'true';
1436+
const customLogger = {
1437+
log: jest.fn(),
1438+
warn: jest.fn(),
1439+
debug: jest.fn(),
1440+
error: jest.fn(),
1441+
info: jest.fn(),
1442+
};
1443+
const metrics: Metrics = new Metrics({
1444+
namespace: TEST_NAMESPACE,
1445+
logger: customLogger,
1446+
});
1447+
const consoleLogSpy = jest.spyOn(customLogger, 'log');
1448+
1449+
// Act
1450+
metrics.publishStoredMetrics();
1451+
1452+
// Assess
1453+
expect(consoleLogSpy).toHaveBeenCalledTimes(0);
1454+
});
1455+
14331456
test('it should call clearMetrics function', () => {
14341457
// Prepare
14351458
const metrics: Metrics = new Metrics({ namespace: TEST_NAMESPACE });
@@ -2355,6 +2378,54 @@ describe('Class: Metrics', () => {
23552378
});
23562379
});
23572380

2381+
describe('Method: isDisabled', () => {
2382+
it('should be enabled by default', () => {
2383+
const metrics: Metrics = new Metrics({ namespace: TEST_NAMESPACE });
2384+
2385+
// Act & Assess
2386+
// biome-ignore lint/complexity/useLiteralKeys: accessing protected method
2387+
expect(metrics['isDisabled']()).toBe(false);
2388+
});
2389+
2390+
it('should be disabled if POWERTOOLS_DEV is set to true', () => {
2391+
process.env.POWERTOOLS_DEV = 'true';
2392+
const metrics: Metrics = new Metrics({ namespace: TEST_NAMESPACE });
2393+
2394+
// Act & Assess
2395+
// biome-ignore lint/complexity/useLiteralKeys: accessing protected method
2396+
expect(metrics['isDisabled']()).toBe(true);
2397+
});
2398+
2399+
it('should be disabled if POWERTOOLS_METRICS_DISABLED is set to true', () => {
2400+
// Prepare
2401+
process.env.POWERTOOLS_METRICS_DISABLED = 'true';
2402+
const metrics: Metrics = new Metrics({ namespace: TEST_NAMESPACE });
2403+
2404+
// Act & Assess
2405+
// biome-ignore lint/complexity/useLiteralKeys: accessing protected method
2406+
expect(metrics['isDisabled']()).toBe(true);
2407+
});
2408+
2409+
it('should be enabled if POWERTOOLS_METRICS_DISABLED is set to false', () => {
2410+
process.env.POWERTOOLS_METRICS_DISABLED = 'false';
2411+
const metrics: Metrics = new Metrics({ namespace: TEST_NAMESPACE });
2412+
2413+
// Act & Assess
2414+
// biome-ignore lint/complexity/useLiteralKeys: accessing protected method
2415+
expect(metrics['isDisabled']()).toBe(false);
2416+
});
2417+
2418+
it('should be enabled if POWERTOOLS_DEV is set to true and POWERTOOLS_METRICS_DISABLED is set to false', () => {
2419+
process.env.POWERTOOLS_DEV = 'true';
2420+
process.env.POWERTOOLS_METRICS_DISABLED = 'false';
2421+
const metrics: Metrics = new Metrics({ namespace: TEST_NAMESPACE });
2422+
2423+
// Act & Assess
2424+
// biome-ignore lint/complexity/useLiteralKeys: accessing protected method
2425+
expect(metrics['isDisabled']()).toBe(false);
2426+
});
2427+
});
2428+
23582429
describe('Method: setTimestamp', () => {
23592430
const testCases = [
23602431
{

0 commit comments

Comments
 (0)