opentelemetry-php icon indicating copy to clipboard operation
opentelemetry-php copied to clipboard

prototype: generate registry from composer autoload-dump

Open brettmc opened this issue 1 year ago • 5 comments

To resolve our long-standing race conditions stemming from using composer's autoload->files to register SDK components at runtime, this changes things so that:

  • components can be registered in various composer.json files, under extra.spi
  • the SDK Registry is modified to make manually registering components a no-op (currently behind a flag, OTEL_PHP_EXPERIMENTAL_SPI_REGISTRY), and instead configure itself via SPI's ServiceLoader

If we move ahead with this approach, a follow-up PR could tidy up the Registry and remove our various late-binding providers.

todo:

  • [ ] add config to appropriate composer.json files (currently only in root composer.json)

brettmc avatar Oct 18 '24 06:10 brettmc

Deploy Preview for opentelemetry-php canceled.

Name Link
Latest commit 5ffe83be2c000d079eb1afe1e7381b315dd779f9
Latest deploy log https://app.netlify.com/sites/opentelemetry-php/deploys/671f1d38fe1753000839d348

netlify[bot] avatar Oct 18 '24 07:10 netlify[bot]

Codecov Report

Attention: Patch coverage is 44.97817% with 126 lines in your changes missing coverage. Please review.

Project coverage is 72.07%. Comparing base (a19455c) to head (67891d0). Report is 40 commits behind head on 2.x.

Files with missing lines Patch % Lines
src/Config/SDK/_register.php 0.00% 26 Missing :warning:
src/SDK/_register.php 0.00% 17 Missing :warning:
src/Contrib/Otlp/_register.php 0.00% 6 Missing :warning:
src/SDK/Propagation/B3MultiPropagatorFactory.php 0.00% 6 Missing :warning:
src/SDK/Propagation/B3PropagatorFactory.php 0.00% 6 Missing :warning:
src/SDK/Propagation/BaggagePropagatorFactory.php 0.00% 6 Missing :warning:
.../Propagation/CloudTraceOneWayPropagatorFactory.php 0.00% 6 Missing :warning:
...rc/SDK/Propagation/CloudTracePropagatorFactory.php 0.00% 6 Missing :warning:
...SDK/Propagation/JaegerBaggagePropagatorFactory.php 0.00% 6 Missing :warning:
src/SDK/Propagation/JaegerPropagatorFactory.php 0.00% 6 Missing :warning:
... and 15 more
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff              @@
##                2.x    #1412      +/-   ##
============================================
- Coverage     72.31%   72.07%   -0.24%     
- Complexity     2729     2758      +29     
============================================
  Files           401      405       +4     
  Lines          8148     8200      +52     
============================================
+ Hits           5892     5910      +18     
- Misses         2256     2290      +34     
Flag Coverage Δ
8.2 71.91% <44.97%> (-0.22%) :arrow_down:
8.3 71.87% <44.97%> (-0.26%) :arrow_down:
8.4 71.89% <44.97%> (-0.38%) :arrow_down:
8.5 71.98% <44.97%> (-0.21%) :arrow_down:

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

Files with missing lines Coverage Δ
...entProvider/Propagator/TextMapPropagatorJaeger.php 0.00% <ø> (ø)
src/Contrib/Grpc/GrpcTransportFactory.php 73.17% <100.00%> (+1.37%) :arrow_up:
src/Contrib/Otlp/LogsExporterFactory.php 97.61% <100.00%> (+0.18%) :arrow_up:
src/Contrib/Otlp/MetricExporterFactory.php 98.03% <100.00%> (+0.12%) :arrow_up:
src/Contrib/Otlp/SpanExporterFactory.php 97.50% <100.00%> (+0.20%) :arrow_up:
src/SDK/Common/Export/Http/PsrTransportFactory.php 81.25% <100.00%> (+2.67%) :arrow_up:
src/SDK/Common/Export/Http/PsrUtils.php 92.64% <100.00%> (ø)
...DK/Common/Export/Stream/StreamTransportFactory.php 91.11% <100.00%> (+0.86%) :arrow_up:
src/SDK/Common/Services/Loader.php 100.00% <100.00%> (ø)
src/SDK/Logs/Exporter/ConsoleExporterFactory.php 100.00% <100.00%> (ø)
... and 36 more

... and 14 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

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

:rocket: New features to boost your workflow:
  • :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

codecov[bot] avatar Oct 18 '24 07:10 codecov[bot]

An alternative idea if we want to avoid duplicating the "load implementations from composer.json" approach:

The main difference between the solution in this PR and an SPI-based approach is the addition of a name/key for each implementation within the composer.json configuration. This information could instead be added as additional method in the interfaces[^1] to allow loading them using SPI.

[^1]: See also Java ServiceLoader - Designing Services: > A service should declare as many methods as needed to allow service providers to communicate their domain-specific properties and other quality-of-implementation factors. An application which obtains a service loader for the service may then invoke these methods on each instance of a service provider, in order to choose the best provider for the application.

Registry is currently used for two different types of implementations:

  • factories used to initialize the SDK from environment variables
  • transport factory implementations, which are also used outside of environment variables configuration

Transport factory implementations

We can extend TransportFactoryInterface with the necessary information to populate the transport factories:

$factories = iterator_to_array(ServiceLoader::load(TransportFactoryServiceInterface::class));
array_multisort(
    array_map(static fn($factory) => $factory->priority(), $factories),
    SORT_DESC,
    $factories,
);
$factoriesByProtocol = [];
foreach ($factories as $factory) {
    $factoriesByProtocol[$factory->protocol()] ??= $factory;
}

self::$transportFactories = $factoriesByProtocol;
interface TransportFactoryServiceInterface extends TransportFactoryInterface {

    public function protocol(): string;
    
    public function priority(): int;
}

Factories to initialize the SDK from environment variables

We could align the implementation with the file-based implementation by adding a new, from the current implementation independent interface[^2] similar to Configuration\ComponentProvider and deprecate the current registry methods and factory interfaces. Very basic interface definition:

namespace OpenTelemetry\Config\SDK\Environment;

/**
 * @template T
 */
interface ComponentProvider {

    /**
     * @return T
     */
    public function createPlugin(): mixed;

    public function name(): string;
}

Alternatively we could follow the approach mentioned for transport factory implementations and add a name(/priority) method to the factory interfaces and continue using the Registry.

[^2]: FWIW I've been using the following Env\Loader interface for env-based configuration, its implementations are loaded via SPI: ```php /** * @template T */ interface Loader {

    /**
     * @return T
     */
    public function load(EnvResolver $env, LoaderRegistry $registry, Context $context): mixed;

    public function name(): string;
}
```

Nevay avatar Oct 21 '24 21:10 Nevay

updated to use SPI, and implemented the idea of having factories declare their key & priority.

brettmc avatar Oct 22 '24 10:10 brettmc

  • [ ] The Vneno i

haad avatar Oct 23 '24 10:10 haad

I understand that the Registry stuff will not be used when using extra.spi. Is it correct that third-party libraries (in my case, proprietary code/packages within a company) can also add their instrumentation through the SPI way, as shown in composer.json?

@xvilo That's right. It's still up for debate exactly how registry/SPI should interact, and which one would be the default. The SPI mechanism will definitely allow custom components like we have now.

brettmc avatar Oct 23 '24 23:10 brettmc

@open-telemetry/php-approvers @Nevay I think this is ready for review: NB that it targets 2.x branch and has some BC breakage, which I've started to document in docs/upgrading.md

brettmc avatar Jan 10 '25 02:01 brettmc

@open-telemetry/php-approvers this is ready for another review. I think all feedback from Nevay addressed and OK'd.

brettmc avatar Jan 28 '25 01:01 brettmc