Skip to content
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

refactor environment configuration #859

Merged
merged 8 commits into from
Nov 9, 2022
Merged

refactor environment configuration #859

merged 8 commits into from
Nov 9, 2022

Conversation

brettmc
Copy link
Collaborator

@brettmc brettmc commented Nov 6, 2022

Refactoring Environment access to allow configuration from multiple sources. Initially, the sources are env and php.ini, but this should allow us to add more sources in future without changing the API.

refacroring Environment access to allow configuration from multiple sources. Initially, the sources are env and php.ini, but this should allow us to
add more sources in future without changing the API.
@brettmc brettmc requested a review from a team as a code owner November 6, 2022 05:40
@codecov
Copy link

codecov bot commented Nov 6, 2022

Codecov Report

Merging #859 (e3c2ee0) into main (0b43fac) will increase coverage by 0.45%.
The diff coverage is 95.55%.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff              @@
##               main     #859      +/-   ##
============================================
+ Coverage     80.80%   81.25%   +0.45%     
- Complexity     1951     1971      +20     
============================================
  Files           248      250       +2     
  Lines          5122     5165      +43     
============================================
+ Hits           4139     4197      +58     
+ Misses          983      968      -15     
Flag Coverage Δ
7.4 80.75% <95.55%> (+0.45%) ⬆️
8.0 81.25% <95.55%> (+0.45%) ⬆️
8.1 81.39% <95.55%> (+0.45%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
src/Contrib/Otlp/Protocols.php 0.00% <ø> (ø)
...K/Common/Configuration/Resolver/PhpIniAccessor.php 0.00% <0.00%> (ø)
.../SDK/Common/Configuration/Parser/BooleanParser.php 88.88% <66.66%> (ø)
src/SDK/Common/Configuration/Parser/MapParser.php 92.85% <75.00%> (ø)
src/SDK/Common/Configuration/Parser/ListParser.php 87.50% <87.50%> (ø)
...ommon/Configuration/Resolver/CompositeResolver.php 91.66% <91.66%> (ø)
src/Contrib/Otlp/SpanExporterFactory.php 97.36% <96.87%> (+97.36%) ⬆️
src/SDK/Common/Configuration/Configuration.php 100.00% <100.00%> (ø)
...rc/SDK/Common/Configuration/Parser/RatioParser.php 100.00% <100.00%> (ø)
...mon/Configuration/Resolver/EnvironmentResolver.php 100.00% <100.00%> (ø)
... and 9 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0b43fac...e3c2ee0. Read the comment docs.

src/SDK/Common/Configuration/IniResolver.php Outdated Show resolved Hide resolved
return DefaultResolver::instance();
}

public static function getInt(string $key, int $default): int
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need the $default parameters or could we return null instead?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could return null, it would mean changing most of our factories to match. Providing a default has the benefit that the default is validated against known types and possible values, so seems safer to me.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I missed that we throw if the key is not set and no default is given - changing the default parameter to nullable / default null to match the other methods is sufficient then.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about OTel specifically, but in the past it's been important on occasion to be able to distinguish between "not set" and "default", when there are multiple things that control something. Usually this comes up because of legacy env vars. For instance, and this is totally made up for example: OTEL_HOST=collector.local but then later we realize that means it can't support https as is, so there's a new one OTEL_COLLECTOR_URI=https://collector.local. For the sake of falling back to an older config, you generally want to be able to distinguish between default and unset.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@morrisonlevi we currently manage that scenario with ::has, although it might start to get gnarly with more variables:

$endpoint = Configuration::has(Variables::OTEL_EXPORTER_OTLP_TRACES_ENDPOINT)
    ? Configuration::getString(Variables::OTEL_EXPORTER_OTLP_TRACES_ENDPOINT)
    : Configuration::getString(Variables::OTEL_EXPORTER_OTLP_ENDPOINT);

src/SDK/Common/Configuration/Configuration.php Outdated Show resolved Hide resolved
src/SDK/Common/Configuration/EnvironmentResolver.php Outdated Show resolved Hide resolved
{
$value = getenv($variableName);
if ($value === false) {
$value = $_ENV[$variableName] ?? $default;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$value retreived from $_ENV can be any type. I think we should allow resolvers to return mixed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's true, but there is a bunch of logic in Accessor to parse and validate string values, and I think it makes sense to leave it there.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should skip parsing if $value is not a string and just validate/coerce the type.
Limiting the type to string will become an actual issue when configuration files with support for more complex types are added to the spec.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolvers can return mixed now. Rather than skip parsing, I updated the parsers to allow their own type (eg bool|string)...

@brettmc brettmc mentioned this pull request Nov 7, 2022
handle get_cfg_var array response
add CompositeResolver and simplify Configuration class
check $_SERVER instead of $_ENV for env vars
src/SDK/Common/Configuration/Resolver.php Outdated Show resolved Hide resolved
src/Contrib/Otlp/SpanExporterFactory.php Outdated Show resolved Hide resolved
{
$value = getenv($variableName);
if ($value === false) {
$value = $_SERVER[$variableName] ?? $default;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should check $_SERVER first. For example vlucas/phpdotenv populates only $_SERVER and $_ENV by default, "Using getenv() and putenv() is strongly discouraged due to the fact that these functions are not thread safe".

Do we have to use local_only: true?

Warning If PHP is running in a SAPI such as Fast CGI, this function will always return the value of an environment variable set by the SAPI, even if putenv() has been used to set a local environment variable of the same name. Use the local_only parameter to return the value of locally-set environment variables.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if we want to remove getenv/putenv support it can be in a separate PR. I was worried about what that would mean for all the tests which rely on putenv, but I think that phpunit's @backupGlobals feature should do (and not having to support both $_ENV and getenv should simplify tests a little)

@brettmc brettmc merged commit f083b10 into open-telemetry:main Nov 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants