-
Notifications
You must be signed in to change notification settings - Fork 153
Maintenance: undefined
environment variable returning empty string from EnvironmentVariablesService
#165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Would like to pick up again the discussion about this topic to see if we want to change the current behaviour or not. In case we decide to change I'm available to pick up the task. The outcome of this discussion should be an agreement on whether ContextThe example below is from /**
* Class EnvironmentVariablesService
*
* This class is used to return environment variables that are available in the runtime of
* the current Lambda invocation.
* These variables can be a mix of runtime environment variables set by AWS and
* variables that can be set by the developer additionally.
*
* @class
* @extends {ConfigService}
* @see https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-runtime
* @see https://awslabs.github.io/aws-lambda-powertools-typescript/latest/#environment-variables
*/
class EnvironmentVariablesService extends ConfigService {
// Reserved environment variables
private xRayTraceIdVariable = '_X_AMZN_TRACE_ID';
/**
* It returns the value of an environment variable that has given name.
*
* @param {string} name
* @returns {string}
*/
public get(name: string): string {
return process.env[name]?.trim() || '';
}
/**
* It returns the value of the AWS_REGION environment variable.
*
* @returns {string}
*/
public getAwsRegion(): string {
return this.get(this.awsRegionVariable);
}
/**
* It returns the value of the POWERTOOLS_SERVICE_NAME environment variable.
*
* @returns {string}
*/
public getServiceName(): string {
return this.get(this.serviceNameVariable); // <- this.serviceNameVariable is inherited from `ConfigService`
}
}
LoggerFor example (link): /**
* It adds important data to the Logger instance that will affect the content of all logs.
*
* @param {string} serviceName
* @param {Environment} environment
* @param {LogAttributes} persistentLogAttributes
* @private
* @returns {void}
*/
private setPowertoolLogData(
serviceName?: string,
environment?: Environment,
persistentLogAttributes: LogAttributes = {},
): void {
this.addToPowertoolLogData(
{
awsRegion: this.getEnvVarsService().getAwsRegion(),
environment:
environment ||
this.getCustomConfigService()?.getCurrentEnvironment() ||
this.getEnvVarsService().getCurrentEnvironment(),
sampleRateValue: this.getSampleRateValue(),
serviceName:
serviceName || this.getCustomConfigService()?.getServiceName() || this.getEnvVarsService().getServiceName() || Logger.defaultServiceName,
xRayTraceId: this.getEnvVarsService().getXrayTraceId(),
},
persistentLogAttributes,
);
} In the example above some keys might end up having an empty string as value, these keys are then filtered out before emitting the log (here) with the following logic: pickBy(attributes, (value) => value !== undefined && value !== '' && value !== null); Even if MetricsIn private setNamespace(namespace: string | undefined): void {
this.namespace = (namespace ||
this.getCustomConfigService()?.getNamespace() ||
this.getEnvVarsService().getNamespace()) as string;
}
private setService(service: string | undefined): void {
const targetService = (service ||
this.getCustomConfigService()?.getService() ||
this.getEnvVarsService().getService()) as string;
if (targetService.length > 0) {
this.addDimension('service', targetService);
}
} In the case of In the case of return {
_aws: {
Timestamp: new Date().getTime(),
CloudWatchMetrics: [
{
Namespace: this.namespace || DEFAULT_NAMESPACE,
Dimensions: [dimensionNames],
Metrics: metricDefinitions,
},
],
},
...this.defaultDimensions,
...this.dimensions,
...metricValues,
...this.metadata,
}; If TracerIn /**
* Setter for `captureResponse` based on configuration passed and environment variables.
* Used internally during initialization.
*/
private setCaptureResponse(): void {
const customConfigValue = this.getCustomConfigService()?.getTracingCaptureResponse();
if (customConfigValue !== undefined && customConfigValue.toLowerCase() === 'false') {
this.captureResponse = false;
return;
}
const envVarsValue = this.getEnvVarsService()?.getTracingCaptureResponse();
if (envVarsValue.toLowerCase() === 'false') {
this.captureResponse = false;
return;
}
} If To Sum Up
Do we want to leave the implementation as it is or change it and return the actual value? What would be the advantage in doing so? At the moment I can't think of any good reason to not leave it as it is but I'd like to hear other opinions. |
Thanks for the thorough context. Thoughts:
The concern stems from duplications and slightly different implementations. As these classes deviate over time (and we have more utilities), it can introduces bugs. |
Assigning |
I don't see the My preference would be to return We could add a second optional parameter public get(name: string, defaultValue?: string): string {
return process.env[name]?.trim() ?? defaultValue;
} |
Hi @buggy, yes it's an internal API and as such is not represented in the docs. Here's an example of this class being used in the Tracer utility, the other two have a similar implementation. As it was pointed out in one of the comments above, in addition to maybe fixing the return type, a prospect resolver should also tackle the deduplication work. We have a 4th package called Contributions are welcome. If you or any future reader is interested, please leave a comment and we'll be happy to provide more details / guidance if needed, or at least review the PRs. |
Update on the topic:
The resolver of this issue will have to standardize the getter in the shared The changes related to this issue should leave public APIs and default values intact. As usual, if anyone is interested in picking this up, please leave a comment here, then discuss your proposal before opening a PR. |
undefined
environment variable returning empty string from EnvironmentVariablesService
This is an internal API that is now part of the The current implementation of the Given that the logic is no longer duplicated and that this is ultimately an internal API, I'm going to close this issue as resolved for the time being. If in the future we need to extend the behavior of this class we can revisit the choice and consider any refactor. |
|
Description of the feature request
Problem statement
Currently the EnvironmentVariablesService returns an empty string if an env var is not set, rather than undefined.
Ticket to discuss the pros and cons of this approach and consider changing the logic to use undefined
Summary of the feature
Code examples
Benefits for you and the wider AWS community
Describe alternatives you've considered
Additional context
Related issues, RFCs
This issue should be addressed after:
#484
The text was updated successfully, but these errors were encountered: