diff --git a/packages/tracer/src/Tracer.ts b/packages/tracer/src/Tracer.ts index 281241bdbc..b69a657b02 100644 --- a/packages/tracer/src/Tracer.ts +++ b/packages/tracer/src/Tracer.ts @@ -20,9 +20,11 @@ import type { Handler } from 'aws-lambda'; import type { Segment, Subsegment } from 'aws-xray-sdk-core'; import xraySdk from 'aws-xray-sdk-core'; import { - type EnvironmentVariablesService, - environmentVariablesService, -} from './config/EnvironmentVariablesService.js'; + getStringFromEnv, + getServiceName, + getXRayTraceIdFromEnv, + isRequestXRaySampled, +} from '@aws-lambda-powertools/commons/utils/env'; import { ProviderService } from './provider/ProviderService.js'; import type { ConfigServiceInterface } from './types/ConfigServiceInterface.js'; import type { ProviderServiceInterface } from './types/ProviderService.js'; @@ -171,11 +173,6 @@ class Tracer extends Utility implements TracerInterface { */ private customConfigService?: ConfigServiceInterface; - /** - * The environment variables service used by the Tracer, is always initialized in the constructor in setOptions(). - */ - private envVarsService!: EnvironmentVariablesService; - // serviceName is always initialized in the constructor in setOptions() /** * The name of the service, is always initialized in the constructor in setOptions(). @@ -187,9 +184,31 @@ class Tracer extends Utility implements TracerInterface { */ private tracingEnabled = true; + // Cache environment variables once for performance and clarity + readonly #envConfig: { + awsExecutionEnv: string; + samLocal: string; + captureError: string; + captureHTTPsRequests: string; + captureResponse: string; + tracingEnabled: string; + serviceName: string; + xrayTraceId: string; + } = { + awsExecutionEnv: '', + samLocal: '', + captureError: '', + captureHTTPsRequests: '', + captureResponse: '', + tracingEnabled: '', + serviceName: '', + xrayTraceId: '', + }; + public constructor(options: TracerOptions = {}) { super(); + this.#setEnvConfig(); this.setOptions(options); this.provider = new ProviderService(); if (this.isTracingEnabled() && this.captureHTTPsRequests) { @@ -576,10 +595,9 @@ class Tracer extends Utility implements TracerInterface { * }; * } * } - * ``` */ public getRootXrayTraceId(): string | undefined { - return this.envVarsService.getXrayTraceId(); + return this.#envConfig.xrayTraceId; } /** @@ -600,7 +618,6 @@ class Tracer extends Utility implements TracerInterface { * const currentSegment = tracer.getSegment(); * ... // Do something with segment * } - * ``` */ public getSegment(): Segment | Subsegment | undefined { if (!this.isTracingEnabled()) { @@ -626,7 +643,7 @@ class Tracer extends Utility implements TracerInterface { public isTraceSampled(): boolean { if (!this.isTracingEnabled()) return false; - return this.envVarsService.getXrayTraceSampled(); + return isRequestXRaySampled(); } /** @@ -731,23 +748,12 @@ class Tracer extends Utility implements TracerInterface { return this.customConfigService; } - /** - * Get for `envVarsService`. - * Used internally during initialization. - */ - private getEnvVarsService(): EnvironmentVariablesService { - return this.envVarsService; - } - /** * Determine if we are running inside an Amplify CLI process. * Used internally during initialization. */ private isAmplifyCli(): boolean { - return ( - this.getEnvVarsService().getAwsExecutionEnv() === - 'AWS_Lambda_amplify-mock' - ); + return this.#envConfig.awsExecutionEnv === 'AWS_Lambda_amplify-mock'; } /** @@ -755,7 +761,7 @@ class Tracer extends Utility implements TracerInterface { * Used internally during initialization. */ private isLambdaExecutionEnv(): boolean { - return this.getEnvVarsService().getAwsExecutionEnv() !== ''; + return this.#envConfig.awsExecutionEnv !== ''; } /** @@ -763,7 +769,7 @@ class Tracer extends Utility implements TracerInterface { * Used internally during initialization. */ private isLambdaSamCli(): boolean { - return this.getEnvVarsService().getSamLocal() !== ''; + return this.#envConfig.samLocal !== ''; } /** @@ -778,14 +784,11 @@ class Tracer extends Utility implements TracerInterface { customConfigValue.toLowerCase() === 'false' ) { this.captureError = false; - return; } - const envVarsValue = this.getEnvVarsService().getTracingCaptureError(); - if (envVarsValue.toLowerCase() === 'false') { + if (this.#envConfig.captureError.toLowerCase() === 'false') { this.captureError = false; - return; } } @@ -803,7 +806,6 @@ class Tracer extends Utility implements TracerInterface { private setCaptureHTTPsRequests(enabled?: boolean): void { if (enabled !== undefined && !enabled) { this.captureHTTPsRequests = false; - return; } @@ -814,14 +816,11 @@ class Tracer extends Utility implements TracerInterface { customConfigValue.toLowerCase() === 'false' ) { this.captureHTTPsRequests = false; - return; } - const envVarsValue = this.getEnvVarsService().getCaptureHTTPsRequests(); - if (envVarsValue.toLowerCase() === 'false') { + if (this.#envConfig.captureHTTPsRequests.toLowerCase() === 'false') { this.captureHTTPsRequests = false; - return; } } @@ -838,14 +837,11 @@ class Tracer extends Utility implements TracerInterface { customConfigValue.toLowerCase() === 'false' ) { this.captureResponse = false; - return; } - const envVarsValue = this.getEnvVarsService().getTracingCaptureResponse(); - if (envVarsValue.toLowerCase() === 'false') { + if (this.#envConfig.captureResponse.toLowerCase() === 'false') { this.captureResponse = false; - return; } } @@ -874,7 +870,6 @@ class Tracer extends Utility implements TracerInterface { const { enabled, serviceName, captureHTTPsRequests, customConfigService } = options; - this.envVarsService = environmentVariablesService; this.setCustomConfigService(customConfigService); this.setTracingEnabled(enabled); this.setCaptureResponse(); @@ -894,7 +889,6 @@ class Tracer extends Utility implements TracerInterface { private setServiceName(serviceName?: string): void { if (serviceName !== undefined && this.isValidServiceName(serviceName)) { this.serviceName = serviceName; - return; } @@ -904,14 +898,11 @@ class Tracer extends Utility implements TracerInterface { this.isValidServiceName(customConfigValue) ) { this.serviceName = customConfigValue; - return; } - const envVarsValue = this.getEnvVarsService().getServiceName(); - if (envVarsValue !== undefined && this.isValidServiceName(envVarsValue)) { - this.serviceName = envVarsValue; - + if (this.#envConfig.serviceName !== undefined && this.isValidServiceName(this.#envConfig.serviceName)) { + this.serviceName = this.#envConfig.serviceName; return; } this.serviceName = this.defaultServiceName; @@ -926,7 +917,6 @@ class Tracer extends Utility implements TracerInterface { private setTracingEnabled(enabled?: boolean): void { if (enabled !== undefined && !enabled) { this.tracingEnabled = enabled; - return; } @@ -937,17 +927,13 @@ class Tracer extends Utility implements TracerInterface { customConfigValue.toLowerCase() === 'false' ) { this.tracingEnabled = false; - return; } - const envVarsValue = this.getEnvVarsService().getTracingEnabled(); - if (envVarsValue.toLowerCase() === 'false') { + if (this.#envConfig.tracingEnabled.toLowerCase() === 'false') { this.tracingEnabled = false; - return; } - if ( this.isAmplifyCli() || this.isLambdaSamCli() || @@ -956,6 +942,18 @@ class Tracer extends Utility implements TracerInterface { this.tracingEnabled = false; } } + + // Populate #envConfig with all relevant environment variables + #setEnvConfig(): void { + this.#envConfig.awsExecutionEnv = getStringFromEnv({ key: 'AWS_EXECUTION_ENV', defaultValue: '' }); + this.#envConfig.samLocal = getStringFromEnv({ key: 'AWS_SAM_LOCAL', defaultValue: '' }); + this.#envConfig.captureError = getStringFromEnv({ key: 'POWERTOOLS_TRACER_CAPTURE_ERROR', defaultValue: '' }); + this.#envConfig.captureHTTPsRequests = getStringFromEnv({ key: 'POWERTOOLS_TRACER_CAPTURE_HTTPS_REQUESTS', defaultValue: '' }); + this.#envConfig.captureResponse = getStringFromEnv({ key: 'POWERTOOLS_TRACER_CAPTURE_RESPONSE', defaultValue: '' }); + this.#envConfig.tracingEnabled = getStringFromEnv({ key: 'POWERTOOLS_TRACE_ENABLED', defaultValue: '' }); + this.#envConfig.serviceName = getServiceName(); + this.#envConfig.xrayTraceId = getXRayTraceIdFromEnv() || ''; + } } export { Tracer }; diff --git a/packages/tracer/src/config/EnvironmentVariablesService.ts b/packages/tracer/src/config/EnvironmentVariablesService.ts deleted file mode 100644 index 4f48eeef2c..0000000000 --- a/packages/tracer/src/config/EnvironmentVariablesService.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { EnvironmentVariablesService as CommonEnvironmentVariablesService } from '@aws-lambda-powertools/commons'; -import type { ConfigServiceInterface } from '../types/ConfigServiceInterface.js'; - -class EnvironmentVariablesService - extends CommonEnvironmentVariablesService - implements ConfigServiceInterface -{ - // Environment variables - private awsExecutionEnv = 'AWS_EXECUTION_ENV'; - private samLocalVariable = 'AWS_SAM_LOCAL'; - private tracerCaptureErrorVariable = 'POWERTOOLS_TRACER_CAPTURE_ERROR'; - private tracerCaptureHTTPsRequestsVariable = - 'POWERTOOLS_TRACER_CAPTURE_HTTPS_REQUESTS'; - private tracerCaptureResponseVariable = 'POWERTOOLS_TRACER_CAPTURE_RESPONSE'; - private tracingEnabledVariable = 'POWERTOOLS_TRACE_ENABLED'; - - /** - * It returns the value of the AWS_EXECUTION_ENV environment variable. - * - * @returns {string} - */ - public getAwsExecutionEnv(): string { - return this.get(this.awsExecutionEnv); - } - - /** - * It returns the value of the POWERTOOLS_TRACER_CAPTURE_HTTPS_REQUESTS environment variable. - * - * @returns {string} - */ - public getCaptureHTTPsRequests(): string { - return this.get(this.tracerCaptureHTTPsRequestsVariable); - } - - /** - * It returns the value of the AWS_SAM_LOCAL environment variable. - * - * @returns {string} - */ - public getSamLocal(): string { - return this.get(this.samLocalVariable); - } - - /** - * It returns the value of the POWERTOOLS_TRACER_CAPTURE_ERROR environment variable. - * - * @returns {string} - */ - public getTracingCaptureError(): string { - return this.get(this.tracerCaptureErrorVariable); - } - - /** - * It returns the value of the POWERTOOLS_TRACER_CAPTURE_RESPONSE environment variable. - * - * @returns {string} - */ - public getTracingCaptureResponse(): string { - return this.get(this.tracerCaptureResponseVariable); - } - - /** - * It returns the value of the POWERTOOLS_TRACE_ENABLED environment variable. - * - * @returns {string} - */ - public getTracingEnabled(): string { - return this.get(this.tracingEnabledVariable); - } -} - -const environmentVariablesService = new EnvironmentVariablesService(); - -export { EnvironmentVariablesService, environmentVariablesService }; diff --git a/packages/tracer/src/provider/ProviderService.ts b/packages/tracer/src/provider/ProviderService.ts index a080a32278..ea9216887c 100644 --- a/packages/tracer/src/provider/ProviderService.ts +++ b/packages/tracer/src/provider/ProviderService.ts @@ -26,7 +26,7 @@ import http from 'node:http'; import https from 'node:https'; import { addUserAgentMiddleware } from '@aws-lambda-powertools/commons'; import type { DiagnosticsChannel } from 'undici-types'; -import { environmentVariablesService } from '../config/EnvironmentVariablesService.js'; +import { getXRayTraceIdFromEnv } from '@aws-lambda-powertools/commons/utils/env'; import { findHeaderAndDecode, getRequestURL, @@ -132,7 +132,7 @@ class ProviderService implements ProviderServiceInterface { // @ts-expect-error request.addHeader( 'X-Amzn-Trace-Id', - `Root=${environmentVariablesService.getXrayTraceId()};Parent=${subsegment.id};Sampled=${subsegment.notTraced ? '0' : '1'}` + `Root=${getXRayTraceIdFromEnv()};Parent=${subsegment.id};Sampled=${subsegment.notTraced ? '0' : '1'}` ); (subsegment as HttpSubsegment).http = { diff --git a/packages/tracer/tests/unit/EnvironmentVariablesService.test.ts b/packages/tracer/tests/unit/EnvironmentVariablesService.test.ts deleted file mode 100644 index 1a6b137465..0000000000 --- a/packages/tracer/tests/unit/EnvironmentVariablesService.test.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { afterAll, beforeEach, describe, expect, it, vi } from 'vitest'; -import { EnvironmentVariablesService } from '../../src/config/EnvironmentVariablesService.js'; - -describe('Class: EnvironmentVariablesService', () => { - const ENVIRONMENT_VARIABLES = process.env; - - beforeEach(() => { - vi.resetModules(); - process.env = { ...ENVIRONMENT_VARIABLES }; - }); - - afterAll(() => { - process.env = ENVIRONMENT_VARIABLES; - }); - - describe('Method: getTracingEnabled', () => { - it('returns the value of the environment variable POWERTOOLS_TRACE_ENABLED', () => { - // Prepare - process.env.POWERTOOLS_TRACE_ENABLED = 'false'; - const service = new EnvironmentVariablesService(); - - // Act - const value = service.getTracingEnabled(); - - // Assess - expect(value).toEqual('false'); - }); - }); - - describe('Method: getTracingCaptureResponse', () => { - it('returns the value of the environment variable POWERTOOLS_TRACER_CAPTURE_RESPONSE', () => { - // Prepare - process.env.POWERTOOLS_TRACER_CAPTURE_RESPONSE = 'false'; - const service = new EnvironmentVariablesService(); - - // Act - const value = service.getTracingCaptureResponse(); - - // Assess - expect(value).toEqual('false'); - }); - }); - - describe('Method: getTracingCaptureError', () => { - it('returns the value of the environment variable POWERTOOLS_TRACER_CAPTURE_ERROR', () => { - // Prepare - process.env.POWERTOOLS_TRACER_CAPTURE_ERROR = 'false'; - const service = new EnvironmentVariablesService(); - - // Act - const value = service.getTracingCaptureError(); - - // Assess - expect(value).toEqual('false'); - }); - }); - - describe('Method: getCaptureHTTPsRequests', () => { - it('returns the value of the environment variable POWERTOOLS_TRACER_CAPTURE_HTTPS_REQUESTS', () => { - // Prepare - process.env.POWERTOOLS_TRACER_CAPTURE_HTTPS_REQUESTS = 'false'; - const service = new EnvironmentVariablesService(); - - // Act - const value = service.getCaptureHTTPsRequests(); - - // Assess - expect(value).toEqual('false'); - }); - }); - - describe('Method: getSamLocal', () => { - it('returns the value of the environment variable AWS_SAM_LOCAL', () => { - // Prepare - process.env.AWS_SAM_LOCAL = 'true'; - const service = new EnvironmentVariablesService(); - - // Act - const value = service.getSamLocal(); - - // Assess - expect(value).toEqual('true'); - }); - }); - - describe('Method: getAwsExecutionEnv', () => { - it('returns the value of the environment variable AWS_EXECUTION_ENV', () => { - // Prepare - process.env.AWS_EXECUTION_ENV = 'nodejs20.x'; - const service = new EnvironmentVariablesService(); - - // Act - const value = service.getAwsExecutionEnv(); - - // Assess - expect(value).toEqual('nodejs20.x'); - }); - }); -});