summaryrefslogtreecommitdiff
path: root/vendor/open-telemetry/sdk
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/open-telemetry/sdk')
-rw-r--r--vendor/open-telemetry/sdk/Common/Adapter/HttpDiscovery/DependencyResolver.php83
-rw-r--r--vendor/open-telemetry/sdk/Common/Adapter/HttpDiscovery/HttpPlugClientResolver.php29
-rw-r--r--vendor/open-telemetry/sdk/Common/Adapter/HttpDiscovery/MessageFactoryResolver.php88
-rw-r--r--vendor/open-telemetry/sdk/Common/Adapter/HttpDiscovery/PsrClientResolver.php29
-rw-r--r--vendor/open-telemetry/sdk/Common/Attribute/AttributeValidator.php58
-rw-r--r--vendor/open-telemetry/sdk/Common/Attribute/AttributeValidatorInterface.php11
-rw-r--r--vendor/open-telemetry/sdk/Common/Attribute/Attributes.php67
-rw-r--r--vendor/open-telemetry/sdk/Common/Attribute/AttributesBuilder.php120
-rw-r--r--vendor/open-telemetry/sdk/Common/Attribute/AttributesBuilderInterface.php12
-rw-r--r--vendor/open-telemetry/sdk/Common/Attribute/AttributesFactory.php36
-rw-r--r--vendor/open-telemetry/sdk/Common/Attribute/AttributesFactoryInterface.php10
-rw-r--r--vendor/open-telemetry/sdk/Common/Attribute/AttributesInterface.php19
-rw-r--r--vendor/open-telemetry/sdk/Common/Attribute/FilteredAttributesBuilder.php77
-rw-r--r--vendor/open-telemetry/sdk/Common/Attribute/FilteredAttributesFactory.php33
-rw-r--r--vendor/open-telemetry/sdk/Common/Attribute/LogRecordAttributeValidator.php19
-rw-r--r--vendor/open-telemetry/sdk/Common/Configuration/Configuration.php182
-rw-r--r--vendor/open-telemetry/sdk/Common/Configuration/Defaults.php122
-rw-r--r--vendor/open-telemetry/sdk/Common/Configuration/KnownValues.php208
-rw-r--r--vendor/open-telemetry/sdk/Common/Configuration/Parser/BooleanParser.php34
-rw-r--r--vendor/open-telemetry/sdk/Common/Configuration/Parser/ListParser.php28
-rw-r--r--vendor/open-telemetry/sdk/Common/Configuration/Parser/MapParser.php45
-rw-r--r--vendor/open-telemetry/sdk/Common/Configuration/Parser/RatioParser.php38
-rw-r--r--vendor/open-telemetry/sdk/Common/Configuration/Resolver/CompositeResolver.php68
-rw-r--r--vendor/open-telemetry/sdk/Common/Configuration/Resolver/EnvironmentResolver.php40
-rw-r--r--vendor/open-telemetry/sdk/Common/Configuration/Resolver/PhpIniAccessor.php18
-rw-r--r--vendor/open-telemetry/sdk/Common/Configuration/Resolver/PhpIniResolver.php41
-rw-r--r--vendor/open-telemetry/sdk/Common/Configuration/Resolver/ResolverInterface.php15
-rw-r--r--vendor/open-telemetry/sdk/Common/Configuration/ValueTypes.php133
-rw-r--r--vendor/open-telemetry/sdk/Common/Configuration/VariableTypes.php62
-rw-r--r--vendor/open-telemetry/sdk/Common/Configuration/Variables.php142
-rw-r--r--vendor/open-telemetry/sdk/Common/Dev/Compatibility/README.md14
-rw-r--r--vendor/open-telemetry/sdk/Common/Dev/Compatibility/Util.php93
-rw-r--r--vendor/open-telemetry/sdk/Common/Dev/Compatibility/_load.php7
-rw-r--r--vendor/open-telemetry/sdk/Common/Exception/StackTraceFormatter.php155
-rw-r--r--vendor/open-telemetry/sdk/Common/Export/Http/PsrTransport.php168
-rw-r--r--vendor/open-telemetry/sdk/Common/Export/Http/PsrTransportFactory.php74
-rw-r--r--vendor/open-telemetry/sdk/Common/Export/Http/PsrUtils.php175
-rw-r--r--vendor/open-telemetry/sdk/Common/Export/Stream/StreamTransport.php97
-rw-r--r--vendor/open-telemetry/sdk/Common/Export/Stream/StreamTransportFactory.php118
-rw-r--r--vendor/open-telemetry/sdk/Common/Export/TransportFactoryInterface.php32
-rw-r--r--vendor/open-telemetry/sdk/Common/Export/TransportInterface.php22
-rw-r--r--vendor/open-telemetry/sdk/Common/Future/CancellationInterface.php18
-rw-r--r--vendor/open-telemetry/sdk/Common/Future/CompletedFuture.php48
-rw-r--r--vendor/open-telemetry/sdk/Common/Future/ErrorFuture.php40
-rw-r--r--vendor/open-telemetry/sdk/Common/Future/FutureInterface.php34
-rw-r--r--vendor/open-telemetry/sdk/Common/Future/NullCancellation.php20
-rw-r--r--vendor/open-telemetry/sdk/Common/Http/DependencyResolverInterface.php13
-rw-r--r--vendor/open-telemetry/sdk/Common/Http/HttpPlug/Client/ResolverInterface.php12
-rw-r--r--vendor/open-telemetry/sdk/Common/Http/Psr/Client/ResolverInterface.php12
-rw-r--r--vendor/open-telemetry/sdk/Common/Http/Psr/Message/FactoryResolverInterface.php22
-rw-r--r--vendor/open-telemetry/sdk/Common/Http/Psr/Message/MessageFactory.php52
-rw-r--r--vendor/open-telemetry/sdk/Common/Http/Psr/Message/MessageFactoryInterface.php13
-rw-r--r--vendor/open-telemetry/sdk/Common/Instrumentation/InstrumentationScope.php46
-rw-r--r--vendor/open-telemetry/sdk/Common/Instrumentation/InstrumentationScopeFactory.php31
-rw-r--r--vendor/open-telemetry/sdk/Common/Instrumentation/InstrumentationScopeFactoryInterface.php15
-rw-r--r--vendor/open-telemetry/sdk/Common/Instrumentation/InstrumentationScopeInterface.php18
-rw-r--r--vendor/open-telemetry/sdk/Common/Time/ClockFactory.php30
-rw-r--r--vendor/open-telemetry/sdk/Common/Time/ClockFactoryInterface.php16
-rw-r--r--vendor/open-telemetry/sdk/Common/Time/ClockInterface.php19
-rw-r--r--vendor/open-telemetry/sdk/Common/Time/StopWatch.php119
-rw-r--r--vendor/open-telemetry/sdk/Common/Time/StopWatchFactory.php44
-rw-r--r--vendor/open-telemetry/sdk/Common/Time/StopWatchFactoryInterface.php18
-rw-r--r--vendor/open-telemetry/sdk/Common/Time/StopWatchInterface.php20
-rw-r--r--vendor/open-telemetry/sdk/Common/Time/SystemClock.php49
-rw-r--r--vendor/open-telemetry/sdk/Common/Time/Util.php32
-rw-r--r--vendor/open-telemetry/sdk/Common/Util/ClassConstantAccessor.php35
-rw-r--r--vendor/open-telemetry/sdk/Common/Util/ShutdownHandler.php82
-rw-r--r--vendor/open-telemetry/sdk/Common/Util/WeakMap.php175
-rw-r--r--vendor/open-telemetry/sdk/Common/Util/functions.php52
-rw-r--r--vendor/open-telemetry/sdk/Logs/Exporter/ConsoleExporter.php106
-rw-r--r--vendor/open-telemetry/sdk/Logs/Exporter/ConsoleExporterFactory.php19
-rw-r--r--vendor/open-telemetry/sdk/Logs/Exporter/InMemoryExporter.php48
-rw-r--r--vendor/open-telemetry/sdk/Logs/Exporter/InMemoryExporterFactory.php16
-rw-r--r--vendor/open-telemetry/sdk/Logs/Exporter/NoopExporter.php28
-rw-r--r--vendor/open-telemetry/sdk/Logs/Exporter/_register.php6
-rw-r--r--vendor/open-telemetry/sdk/Logs/ExporterFactory.php29
-rw-r--r--vendor/open-telemetry/sdk/Logs/LogRecordExporterFactoryInterface.php10
-rw-r--r--vendor/open-telemetry/sdk/Logs/LogRecordExporterInterface.php18
-rw-r--r--vendor/open-telemetry/sdk/Logs/LogRecordLimits.php29
-rw-r--r--vendor/open-telemetry/sdk/Logs/LogRecordLimitsBuilder.php58
-rw-r--r--vendor/open-telemetry/sdk/Logs/LogRecordProcessorFactory.php62
-rw-r--r--vendor/open-telemetry/sdk/Logs/LogRecordProcessorInterface.php15
-rw-r--r--vendor/open-telemetry/sdk/Logs/Logger.php37
-rw-r--r--vendor/open-telemetry/sdk/Logs/LoggerProvider.php56
-rw-r--r--vendor/open-telemetry/sdk/Logs/LoggerProviderBuilder.php55
-rw-r--r--vendor/open-telemetry/sdk/Logs/LoggerProviderFactory.php24
-rw-r--r--vendor/open-telemetry/sdk/Logs/LoggerProviderInterface.php13
-rw-r--r--vendor/open-telemetry/sdk/Logs/LoggerSharedState.php60
-rw-r--r--vendor/open-telemetry/sdk/Logs/NoopLoggerProvider.php33
-rw-r--r--vendor/open-telemetry/sdk/Logs/Processor/BatchLogRecordProcessor.php273
-rw-r--r--vendor/open-telemetry/sdk/Logs/Processor/MultiLogRecordProcessor.php62
-rw-r--r--vendor/open-telemetry/sdk/Logs/Processor/NoopLogRecordProcessor.php37
-rw-r--r--vendor/open-telemetry/sdk/Logs/Processor/SimpleLogRecordProcessor.php38
-rw-r--r--vendor/open-telemetry/sdk/Logs/PsrSeverityMapperInterface.php50
-rw-r--r--vendor/open-telemetry/sdk/Logs/ReadWriteLogRecord.php9
-rw-r--r--vendor/open-telemetry/sdk/Logs/ReadableLogRecord.php103
-rw-r--r--vendor/open-telemetry/sdk/Logs/SimplePsrFileLogger.php83
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Aggregation/ExplicitBucketHistogramAggregation.php167
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Aggregation/ExplicitBucketHistogramSummary.php40
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Aggregation/LastValueAggregation.php81
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Aggregation/LastValueSummary.php22
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Aggregation/SumAggregation.php91
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Aggregation/SumSummary.php20
-rw-r--r--vendor/open-telemetry/sdk/Metrics/AggregationInterface.php57
-rw-r--r--vendor/open-telemetry/sdk/Metrics/AggregationTemporalitySelectorInterface.php21
-rw-r--r--vendor/open-telemetry/sdk/Metrics/AttributeProcessor/FilteredAttributeProcessor.php33
-rw-r--r--vendor/open-telemetry/sdk/Metrics/AttributeProcessor/IdentityAttributeProcessor.php20
-rw-r--r--vendor/open-telemetry/sdk/Metrics/AttributeProcessorInterface.php16
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Counter.php37
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Data/DataInterface.php9
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Data/Exemplar.php65
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Data/Gauge.php22
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Data/Histogram.php29
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Data/HistogramDataPoint.php76
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Data/Metric.php46
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Data/NumberDataPoint.php43
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Data/Sum.php34
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Data/Temporality.php20
-rw-r--r--vendor/open-telemetry/sdk/Metrics/DefaultAggregationProviderInterface.php13
-rw-r--r--vendor/open-telemetry/sdk/Metrics/DefaultAggregationProviderTrait.php28
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Exemplar/BucketEntry.php26
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Exemplar/BucketStorage.php92
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilter/AllExemplarFilter.php21
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilter/NoneExemplarFilter.php21
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilter/WithSampledTraceExemplarFilter.php22
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilterInterface.php20
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarReservoirInterface.php24
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Exemplar/FilteredReservoir.php36
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Exemplar/FixedSizeReservoir.php38
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Exemplar/HistogramBucketReservoir.php40
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Exemplar/NoopReservoir.php21
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Histogram.php37
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Instrument.php36
-rw-r--r--vendor/open-telemetry/sdk/Metrics/InstrumentType.php25
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Meter.php314
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MeterInstruments.php29
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MeterProvider.php130
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MeterProviderBuilder.php62
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MeterProviderFactory.php78
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MeterProviderInterface.php12
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricExporter/ConsoleMetricExporter.php105
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricExporter/ConsoleMetricExporterFactory.php16
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricExporter/InMemoryExporter.php78
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricExporter/InMemoryExporterFactory.php16
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricExporter/NoopMetricExporter.php23
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricExporter/NoopMetricExporterFactory.php16
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricExporter/_register.php7
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricExporterFactoryInterface.php10
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricExporterInterface.php17
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricFactory/StreamFactory.php187
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricFactory/StreamMetricSource.php44
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricFactory/StreamMetricSourceProvider.php98
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricFactoryInterface.php41
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricMetadataInterface.php28
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricReader/ExportingReader.php156
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricReaderInterface.php14
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricRegistration/MultiRegistryRegistration.php36
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricRegistration/RegistryRegistration.php31
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricRegistrationInterface.php13
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricCollectorInterface.php13
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricRegistry.php184
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricRegistryInterface.php22
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricWriterInterface.php20
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricRegistry/MultiObserver.php37
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricRegistry/NoopObserver.php18
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricSourceInterface.php24
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricSourceProviderInterface.php15
-rw-r--r--vendor/open-telemetry/sdk/Metrics/MetricSourceRegistryInterface.php10
-rw-r--r--vendor/open-telemetry/sdk/Metrics/NoopMeterProvider.php26
-rw-r--r--vendor/open-telemetry/sdk/Metrics/ObservableCallback.php58
-rw-r--r--vendor/open-telemetry/sdk/Metrics/ObservableCallbackDestructor.php32
-rw-r--r--vendor/open-telemetry/sdk/Metrics/ObservableCounter.php15
-rw-r--r--vendor/open-telemetry/sdk/Metrics/ObservableGauge.php15
-rw-r--r--vendor/open-telemetry/sdk/Metrics/ObservableInstrumentTrait.php61
-rw-r--r--vendor/open-telemetry/sdk/Metrics/ObservableUpDownCounter.php15
-rw-r--r--vendor/open-telemetry/sdk/Metrics/PushMetricExporterInterface.php12
-rw-r--r--vendor/open-telemetry/sdk/Metrics/ReferenceCounterInterface.php15
-rw-r--r--vendor/open-telemetry/sdk/Metrics/StalenessHandler/DelayedStalenessHandler.php71
-rw-r--r--vendor/open-telemetry/sdk/Metrics/StalenessHandler/DelayedStalenessHandlerFactory.php64
-rw-r--r--vendor/open-telemetry/sdk/Metrics/StalenessHandler/ImmediateStalenessHandler.php50
-rw-r--r--vendor/open-telemetry/sdk/Metrics/StalenessHandler/ImmediateStalenessHandlerFactory.php16
-rw-r--r--vendor/open-telemetry/sdk/Metrics/StalenessHandler/NoopStalenessHandler.php30
-rw-r--r--vendor/open-telemetry/sdk/Metrics/StalenessHandler/NoopStalenessHandlerFactory.php18
-rw-r--r--vendor/open-telemetry/sdk/Metrics/StalenessHandlerFactoryInterface.php13
-rw-r--r--vendor/open-telemetry/sdk/Metrics/StalenessHandlerInterface.php12
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Stream/AsynchronousMetricStream.php111
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Stream/Delta.php33
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Stream/DeltaStorage.php110
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Stream/Metric.php44
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregator.php73
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregatorFactory.php28
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregatorFactoryInterface.php13
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregatorInterface.php12
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Stream/MetricCollectorInterface.php13
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Stream/MetricStreamInterface.php58
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Stream/SynchronousMetricStream.php126
-rw-r--r--vendor/open-telemetry/sdk/Metrics/Stream/WritableMetricStreamInterface.php19
-rw-r--r--vendor/open-telemetry/sdk/Metrics/UpDownCounter.php37
-rw-r--r--vendor/open-telemetry/sdk/Metrics/View/CriteriaViewRegistry.php40
-rw-r--r--vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/AllCriteria.php33
-rw-r--r--vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentNameCriteria.php28
-rw-r--r--vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentTypeCriteria.php29
-rw-r--r--vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentationScopeNameCriteria.php24
-rw-r--r--vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentationScopeSchemaUrlCriteria.php24
-rw-r--r--vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentationScopeVersionCriteria.php24
-rw-r--r--vendor/open-telemetry/sdk/Metrics/View/SelectionCriteriaInterface.php13
-rw-r--r--vendor/open-telemetry/sdk/Metrics/View/ViewTemplate.php77
-rw-r--r--vendor/open-telemetry/sdk/Metrics/ViewProjection.php47
-rw-r--r--vendor/open-telemetry/sdk/Metrics/ViewRegistryInterface.php15
-rw-r--r--vendor/open-telemetry/sdk/Propagation/PropagatorFactory.php55
-rw-r--r--vendor/open-telemetry/sdk/Propagation/_register.php16
-rw-r--r--vendor/open-telemetry/sdk/README.md49
-rw-r--r--vendor/open-telemetry/sdk/Registry.php208
-rw-r--r--vendor/open-telemetry/sdk/Resource/Detectors/Composer.php30
-rw-r--r--vendor/open-telemetry/sdk/Resource/Detectors/Composite.php32
-rw-r--r--vendor/open-telemetry/sdk/Resource/Detectors/Constant.php23
-rw-r--r--vendor/open-telemetry/sdk/Resource/Detectors/Environment.php40
-rw-r--r--vendor/open-telemetry/sdk/Resource/Detectors/Host.php27
-rw-r--r--vendor/open-telemetry/sdk/Resource/Detectors/OperatingSystem.php32
-rw-r--r--vendor/open-telemetry/sdk/Resource/Detectors/Process.php43
-rw-r--r--vendor/open-telemetry/sdk/Resource/Detectors/ProcessRuntime.php28
-rw-r--r--vendor/open-telemetry/sdk/Resource/Detectors/Sdk.php53
-rw-r--r--vendor/open-telemetry/sdk/Resource/Detectors/SdkProvided.php25
-rw-r--r--vendor/open-telemetry/sdk/Resource/ResourceDetectorInterface.php10
-rw-r--r--vendor/open-telemetry/sdk/Resource/ResourceInfo.php125
-rw-r--r--vendor/open-telemetry/sdk/Resource/ResourceInfoFactory.php95
-rw-r--r--vendor/open-telemetry/sdk/Sdk.php70
-rw-r--r--vendor/open-telemetry/sdk/SdkAutoloader.php76
-rw-r--r--vendor/open-telemetry/sdk/SdkBuilder.php98
-rw-r--r--vendor/open-telemetry/sdk/Trace/Behavior/LoggerAwareTrait.php48
-rw-r--r--vendor/open-telemetry/sdk/Trace/Behavior/SpanExporterDecoratorTrait.php47
-rw-r--r--vendor/open-telemetry/sdk/Trace/Behavior/SpanExporterTrait.php47
-rw-r--r--vendor/open-telemetry/sdk/Trace/Behavior/UsesSpanConverterTrait.php41
-rw-r--r--vendor/open-telemetry/sdk/Trace/Event.php47
-rw-r--r--vendor/open-telemetry/sdk/Trace/EventInterface.php15
-rw-r--r--vendor/open-telemetry/sdk/Trace/ExporterFactory.php32
-rw-r--r--vendor/open-telemetry/sdk/Trace/IdGeneratorInterface.php12
-rw-r--r--vendor/open-telemetry/sdk/Trace/ImmutableSpan.php153
-rw-r--r--vendor/open-telemetry/sdk/Trace/Link.php30
-rw-r--r--vendor/open-telemetry/sdk/Trace/LinkInterface.php14
-rw-r--r--vendor/open-telemetry/sdk/Trace/NoopTracerProvider.php21
-rw-r--r--vendor/open-telemetry/sdk/Trace/RandomIdGenerator.php49
-rw-r--r--vendor/open-telemetry/sdk/Trace/ReadWriteSpanInterface.php11
-rw-r--r--vendor/open-telemetry/sdk/Trace/ReadableSpanInterface.php48
-rw-r--r--vendor/open-telemetry/sdk/Trace/Sampler/AlwaysOffSampler.php50
-rw-r--r--vendor/open-telemetry/sdk/Trace/Sampler/AlwaysOnSampler.php50
-rw-r--r--vendor/open-telemetry/sdk/Trace/Sampler/ParentBased.php100
-rw-r--r--vendor/open-telemetry/sdk/Trace/Sampler/TraceIdRatioBasedSampler.php70
-rw-r--r--vendor/open-telemetry/sdk/Trace/SamplerFactory.php48
-rw-r--r--vendor/open-telemetry/sdk/Trace/SamplerInterface.php46
-rw-r--r--vendor/open-telemetry/sdk/Trace/SamplingResult.php71
-rw-r--r--vendor/open-telemetry/sdk/Trace/Span.php359
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanBuilder.php191
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanConverterInterface.php10
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanDataInterface.php46
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanExporter/AbstractDecorator.php12
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanExporter/ConsoleSpanExporter.php57
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanExporter/ConsoleSpanExporterFactory.php18
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanExporter/FriendlySpanConverter.php173
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanExporter/InMemoryExporter.php40
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanExporter/InMemorySpanExporterFactory.php15
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanExporter/LoggerDecorator.php58
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanExporter/LoggerExporter.php96
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanExporter/NullSpanConverter.php15
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanExporter/SpanExporterFactoryInterface.php12
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanExporter/_register.php7
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanExporterInterface.php29
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanLimits.php67
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanLimitsBuilder.php148
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanProcessor/BatchSpanProcessor.php290
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanProcessor/BatchSpanProcessorBuilder.php41
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanProcessor/MultiSpanProcessor.php79
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanProcessor/NoopSpanProcessor.php47
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanProcessor/SimpleSpanProcessor.php120
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanProcessorFactory.php48
-rw-r--r--vendor/open-telemetry/sdk/Trace/SpanProcessorInterface.php38
-rw-r--r--vendor/open-telemetry/sdk/Trace/StatusData.php84
-rw-r--r--vendor/open-telemetry/sdk/Trace/StatusDataInterface.php18
-rw-r--r--vendor/open-telemetry/sdk/Trace/Tracer.php52
-rw-r--r--vendor/open-telemetry/sdk/Trace/TracerProvider.php99
-rw-r--r--vendor/open-telemetry/sdk/Trace/TracerProviderBuilder.php45
-rw-r--r--vendor/open-telemetry/sdk/Trace/TracerProviderFactory.php60
-rw-r--r--vendor/open-telemetry/sdk/Trace/TracerProviderInterface.php15
-rw-r--r--vendor/open-telemetry/sdk/Trace/TracerSharedState.php100
-rw-r--r--vendor/open-telemetry/sdk/_autoload.php5
-rw-r--r--vendor/open-telemetry/sdk/composer.json59
286 files changed, 14929 insertions, 0 deletions
diff --git a/vendor/open-telemetry/sdk/Common/Adapter/HttpDiscovery/DependencyResolver.php b/vendor/open-telemetry/sdk/Common/Adapter/HttpDiscovery/DependencyResolver.php
new file mode 100644
index 000000000..8ba992f9a
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Adapter/HttpDiscovery/DependencyResolver.php
@@ -0,0 +1,83 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Adapter\HttpDiscovery;
+
+use Http\Client\HttpAsyncClient;
+use OpenTelemetry\SDK\Common\Http\DependencyResolverInterface;
+use OpenTelemetry\SDK\Common\Http\HttpPlug\Client\ResolverInterface as HttpPlugClientResolverInterface;
+use OpenTelemetry\SDK\Common\Http\Psr\Client\ResolverInterface as PsrClientResolverInterface;
+use OpenTelemetry\SDK\Common\Http\Psr\Message\FactoryResolverInterface as MessageFactoryResolverInterface;
+use Psr\Http\Client\ClientInterface;
+use Psr\Http\Message\RequestFactoryInterface;
+use Psr\Http\Message\ResponseFactoryInterface;
+use Psr\Http\Message\ServerRequestFactoryInterface;
+use Psr\Http\Message\StreamFactoryInterface;
+use Psr\Http\Message\UploadedFileFactoryInterface;
+use Psr\Http\Message\UriFactoryInterface;
+
+final class DependencyResolver implements DependencyResolverInterface
+{
+ private MessageFactoryResolverInterface $messageFactoryResolver;
+ private PsrClientResolverInterface $psrClientResolver;
+ private HttpPlugClientResolverInterface $httpPlugClientResolver;
+
+ public function __construct(
+ ?MessageFactoryResolverInterface $messageFactoryResolver = null,
+ ?PsrClientResolverInterface $psrClientResolver = null,
+ ?HttpPlugClientResolverInterface $httpPlugClientResolver = null
+ ) {
+ $this->messageFactoryResolver = $messageFactoryResolver ?? MessageFactoryResolver::create();
+ $this->psrClientResolver = $psrClientResolver ?? PsrClientResolver::create();
+ $this->httpPlugClientResolver = $httpPlugClientResolver ?? HttpPlugClientResolver::create();
+ }
+
+ public static function create(
+ ?MessageFactoryResolverInterface $messageFactoryResolver = null,
+ ?PsrClientResolverInterface $psrClientResolver = null,
+ ?HttpPlugClientResolverInterface $httpPlugClientResolver = null
+ ): self {
+ return new self($messageFactoryResolver, $psrClientResolver, $httpPlugClientResolver);
+ }
+
+ public function resolveRequestFactory(): RequestFactoryInterface
+ {
+ return $this->messageFactoryResolver->resolveRequestFactory();
+ }
+
+ public function resolveResponseFactory(): ResponseFactoryInterface
+ {
+ return $this->messageFactoryResolver->resolveResponseFactory();
+ }
+
+ public function resolveServerRequestFactory(): ServerRequestFactoryInterface
+ {
+ return $this->messageFactoryResolver->resolveServerRequestFactory();
+ }
+
+ public function resolveStreamFactory(): StreamFactoryInterface
+ {
+ return $this->messageFactoryResolver->resolveStreamFactory();
+ }
+
+ public function resolveUploadedFileFactory(): UploadedFileFactoryInterface
+ {
+ return $this->messageFactoryResolver->resolveUploadedFileFactory();
+ }
+
+ public function resolveUriFactory(): UriFactoryInterface
+ {
+ return $this->messageFactoryResolver->resolveUriFactory();
+ }
+
+ public function resolveHttpPlugAsyncClient(): HttpAsyncClient
+ {
+ return $this->httpPlugClientResolver->resolveHttpPlugAsyncClient();
+ }
+
+ public function resolvePsrClient(): ClientInterface
+ {
+ return $this->psrClientResolver->resolvePsrClient();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Adapter/HttpDiscovery/HttpPlugClientResolver.php b/vendor/open-telemetry/sdk/Common/Adapter/HttpDiscovery/HttpPlugClientResolver.php
new file mode 100644
index 000000000..9751984ee
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Adapter/HttpDiscovery/HttpPlugClientResolver.php
@@ -0,0 +1,29 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Adapter\HttpDiscovery;
+
+use Http\Client\HttpAsyncClient;
+use Http\Discovery\HttpAsyncClientDiscovery;
+use OpenTelemetry\SDK\Common\Http\HttpPlug\Client\ResolverInterface;
+
+final class HttpPlugClientResolver implements ResolverInterface
+{
+ private ?HttpAsyncClient $httpAsyncClient;
+
+ public function __construct(?HttpAsyncClient $httpAsyncClient = null)
+ {
+ $this->httpAsyncClient = $httpAsyncClient;
+ }
+
+ public static function create(?HttpAsyncClient $httpAsyncClient = null): self
+ {
+ return new self($httpAsyncClient);
+ }
+
+ public function resolveHttpPlugAsyncClient(): HttpAsyncClient
+ {
+ return $this->httpAsyncClient ??= HttpAsyncClientDiscovery::find();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Adapter/HttpDiscovery/MessageFactoryResolver.php b/vendor/open-telemetry/sdk/Common/Adapter/HttpDiscovery/MessageFactoryResolver.php
new file mode 100644
index 000000000..6ed0895ff
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Adapter/HttpDiscovery/MessageFactoryResolver.php
@@ -0,0 +1,88 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Adapter\HttpDiscovery;
+
+use Http\Discovery\Psr17FactoryDiscovery;
+use OpenTelemetry\SDK\Common\Http\Psr\Message\FactoryResolverInterface;
+use Psr\Http\Message\RequestFactoryInterface;
+use Psr\Http\Message\ResponseFactoryInterface;
+use Psr\Http\Message\ServerRequestFactoryInterface;
+use Psr\Http\Message\StreamFactoryInterface;
+use Psr\Http\Message\UploadedFileFactoryInterface;
+use Psr\Http\Message\UriFactoryInterface;
+
+final class MessageFactoryResolver implements FactoryResolverInterface
+{
+ private ?RequestFactoryInterface $requestFactory;
+ private ?ResponseFactoryInterface $responseFactory;
+ private ?ServerRequestFactoryInterface $serverRequestFactory;
+ private ?StreamFactoryInterface $streamFactory;
+ private ?UploadedFileFactoryInterface $uploadedFileFactory;
+ private ?UriFactoryInterface $uriFactory;
+
+ public function __construct(
+ ?RequestFactoryInterface $requestFactory = null,
+ ?ResponseFactoryInterface $responseFactory = null,
+ ?ServerRequestFactoryInterface $serverRequestFactory = null,
+ ?StreamFactoryInterface $streamFactory = null,
+ ?UploadedFileFactoryInterface $uploadedFileFactory = null,
+ ?UriFactoryInterface $uriFactory = null
+ ) {
+ $this->requestFactory = $requestFactory;
+ $this->responseFactory = $responseFactory;
+ $this->serverRequestFactory = $serverRequestFactory;
+ $this->streamFactory = $streamFactory;
+ $this->uploadedFileFactory = $uploadedFileFactory;
+ $this->uriFactory = $uriFactory;
+ }
+
+ public static function create(
+ ?RequestFactoryInterface $requestFactory = null,
+ ?ResponseFactoryInterface $responseFactory = null,
+ ?ServerRequestFactoryInterface $serverRequestFactory = null,
+ ?StreamFactoryInterface $streamFactory = null,
+ ?UploadedFileFactoryInterface $uploadedFileFactory = null,
+ ?UriFactoryInterface $uriFactory = null
+ ): self {
+ return new self(
+ $requestFactory,
+ $responseFactory,
+ $serverRequestFactory,
+ $streamFactory,
+ $uploadedFileFactory,
+ $uriFactory
+ );
+ }
+
+ public function resolveRequestFactory(): RequestFactoryInterface
+ {
+ return $this->requestFactory ??= Psr17FactoryDiscovery::findRequestFactory();
+ }
+
+ public function resolveResponseFactory(): ResponseFactoryInterface
+ {
+ return $this->responseFactory ??= Psr17FactoryDiscovery::findResponseFactory();
+ }
+
+ public function resolveServerRequestFactory(): ServerRequestFactoryInterface
+ {
+ return $this->serverRequestFactory ??= Psr17FactoryDiscovery::findServerRequestFactory();
+ }
+
+ public function resolveStreamFactory(): StreamFactoryInterface
+ {
+ return $this->streamFactory ??= Psr17FactoryDiscovery::findStreamFactory();
+ }
+
+ public function resolveUploadedFileFactory(): UploadedFileFactoryInterface
+ {
+ return $this->uploadedFileFactory ??= Psr17FactoryDiscovery::findUploadedFileFactory();
+ }
+
+ public function resolveUriFactory(): UriFactoryInterface
+ {
+ return $this->uriFactory ??= Psr17FactoryDiscovery::findUriFactory();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Adapter/HttpDiscovery/PsrClientResolver.php b/vendor/open-telemetry/sdk/Common/Adapter/HttpDiscovery/PsrClientResolver.php
new file mode 100644
index 000000000..46fb36312
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Adapter/HttpDiscovery/PsrClientResolver.php
@@ -0,0 +1,29 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Adapter\HttpDiscovery;
+
+use Http\Discovery\Psr18ClientDiscovery;
+use OpenTelemetry\SDK\Common\Http\Psr\Client\ResolverInterface;
+use Psr\Http\Client\ClientInterface;
+
+final class PsrClientResolver implements ResolverInterface
+{
+ private ?ClientInterface $client;
+
+ public function __construct(?ClientInterface $client = null)
+ {
+ $this->client = $client;
+ }
+
+ public static function create(?ClientInterface $client = null): self
+ {
+ return new self($client);
+ }
+
+ public function resolvePsrClient(): ClientInterface
+ {
+ return $this->client ??= Psr18ClientDiscovery::find();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Attribute/AttributeValidator.php b/vendor/open-telemetry/sdk/Common/Attribute/AttributeValidator.php
new file mode 100644
index 000000000..e9a1f7334
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Attribute/AttributeValidator.php
@@ -0,0 +1,58 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Attribute;
+
+class AttributeValidator implements AttributeValidatorInterface
+{
+ private const PRIMITIVES = [
+ 'string',
+ 'integer',
+ 'double',
+ 'boolean',
+ ];
+ private const NUMERICS = [
+ 'double',
+ 'integer',
+ ];
+
+ /**
+ * Validate whether a value is a primitive, or a homogeneous array of primitives (treating int/double as equivalent).
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.21.0/specification/common/README.md#attribute
+ */
+ public function validate($value): bool
+ {
+ if (is_array($value)) {
+ return $this->validateArray($value);
+ }
+
+ return in_array(gettype($value), self::PRIMITIVES);
+ }
+
+ private function validateArray(array $value): bool
+ {
+ if ($value === []) {
+ return true;
+ }
+ $type = gettype(reset($value));
+ if (!in_array($type, self::PRIMITIVES)) {
+ return false;
+ }
+ foreach ($value as $v) {
+ if (in_array(gettype($v), self::NUMERICS) && in_array($type, self::NUMERICS)) {
+ continue;
+ }
+ if (gettype($v) !== $type) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public function getInvalidMessage(): string
+ {
+ return 'attribute with non-primitive or non-homogeneous array of primitives dropped';
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Attribute/AttributeValidatorInterface.php b/vendor/open-telemetry/sdk/Common/Attribute/AttributeValidatorInterface.php
new file mode 100644
index 000000000..afbfba6e7
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Attribute/AttributeValidatorInterface.php
@@ -0,0 +1,11 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Attribute;
+
+interface AttributeValidatorInterface
+{
+ public function validate($value): bool;
+ public function getInvalidMessage(): string;
+}
diff --git a/vendor/open-telemetry/sdk/Common/Attribute/Attributes.php b/vendor/open-telemetry/sdk/Common/Attribute/Attributes.php
new file mode 100644
index 000000000..bb131ce94
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Attribute/Attributes.php
@@ -0,0 +1,67 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Attribute;
+
+use function array_key_exists;
+use IteratorAggregate;
+use Traversable;
+
+final class Attributes implements AttributesInterface, IteratorAggregate
+{
+ private array $attributes;
+ private int $droppedAttributesCount;
+
+ /**
+ * @internal
+ */
+ public function __construct(array $attributes, int $droppedAttributesCount)
+ {
+ $this->attributes = $attributes;
+ $this->droppedAttributesCount = $droppedAttributesCount;
+ }
+
+ public static function create(iterable $attributes): AttributesInterface
+ {
+ return self::factory()->builder($attributes)->build();
+ }
+
+ public static function factory(?int $attributeCountLimit = null, ?int $attributeValueLengthLimit = null): AttributesFactoryInterface
+ {
+ return new AttributesFactory($attributeCountLimit, $attributeValueLengthLimit);
+ }
+
+ public function has(string $name): bool
+ {
+ return array_key_exists($name, $this->attributes);
+ }
+
+ public function get(string $name)
+ {
+ return $this->attributes[$name] ?? null;
+ }
+
+ /** @psalm-mutation-free */
+ public function count(): int
+ {
+ return \count($this->attributes);
+ }
+
+ public function getIterator(): Traversable
+ {
+ foreach ($this->attributes as $key => $value) {
+ yield (string) $key => $value;
+ }
+ }
+
+ public function toArray(): array
+ {
+ return $this->attributes;
+ }
+
+ public function getDroppedAttributesCount(): int
+ {
+ return $this->droppedAttributesCount;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Attribute/AttributesBuilder.php b/vendor/open-telemetry/sdk/Common/Attribute/AttributesBuilder.php
new file mode 100644
index 000000000..5c1150638
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Attribute/AttributesBuilder.php
@@ -0,0 +1,120 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Attribute;
+
+use function array_key_exists;
+use function count;
+use function is_array;
+use function is_string;
+use function mb_substr;
+use OpenTelemetry\API\Behavior\LogsMessagesTrait;
+
+/**
+ * @internal
+ */
+final class AttributesBuilder implements AttributesBuilderInterface
+{
+ use LogsMessagesTrait;
+
+ private array $attributes;
+ private ?int $attributeCountLimit;
+ private ?int $attributeValueLengthLimit;
+ private int $droppedAttributesCount;
+ private AttributeValidatorInterface $attributeValidator;
+
+ public function __construct(
+ array $attributes,
+ ?int $attributeCountLimit,
+ ?int $attributeValueLengthLimit,
+ int $droppedAttributesCount,
+ ?AttributeValidatorInterface $attributeValidator
+ ) {
+ $this->attributes = $attributes;
+ $this->attributeCountLimit = $attributeCountLimit;
+ $this->attributeValueLengthLimit = $attributeValueLengthLimit;
+ $this->droppedAttributesCount = $droppedAttributesCount;
+ $this->attributeValidator = $attributeValidator ?? new AttributeValidator();
+ }
+
+ public function build(): AttributesInterface
+ {
+ return new Attributes($this->attributes, $this->droppedAttributesCount);
+ }
+
+ public function offsetExists($offset): bool
+ {
+ return array_key_exists($offset, $this->attributes);
+ }
+
+ /**
+ * @phan-suppress PhanUndeclaredClassAttribute
+ */
+ #[\ReturnTypeWillChange]
+ public function offsetGet($offset)
+ {
+ return $this->attributes[$offset] ?? null;
+ }
+
+ /**
+ * @phan-suppress PhanUndeclaredClassAttribute
+ */
+ #[\ReturnTypeWillChange]
+ public function offsetSet($offset, $value)
+ {
+ if ($offset === null) {
+ return;
+ }
+ if ($value === null) {
+ unset($this->attributes[$offset]);
+
+ return;
+ }
+ if (!$this->attributeValidator->validate($value)) {
+ self::logWarning($this->attributeValidator->getInvalidMessage() . ': ' . $offset);
+ $this->droppedAttributesCount++;
+
+ return;
+ }
+ if (count($this->attributes) === $this->attributeCountLimit && !array_key_exists($offset, $this->attributes)) {
+ $this->droppedAttributesCount++;
+
+ return;
+ }
+
+ $this->attributes[$offset] = $this->normalizeValue($value);
+ //@todo "There SHOULD be a message printed in the SDK's log to indicate to the user that an attribute was
+ // discarded due to such a limit. To prevent excessive logging, the message MUST be printed at most
+ // once per <thing> (i.e., not per discarded attribute)."
+ }
+
+ /**
+ * @phan-suppress PhanUndeclaredClassAttribute
+ */
+ #[\ReturnTypeWillChange]
+ public function offsetUnset($offset)
+ {
+ unset($this->attributes[$offset]);
+ }
+
+ private function normalizeValue($value)
+ {
+ if (is_string($value) && $this->attributeValueLengthLimit !== null) {
+ return mb_substr($value, 0, $this->attributeValueLengthLimit);
+ }
+
+ if (is_array($value)) {
+ foreach ($value as $k => $v) {
+ $processed = $this->normalizeValue($v);
+ if ($processed !== $v) {
+ $value[$k] = $processed;
+ }
+ }
+
+ return $value;
+ }
+
+ return $value;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Attribute/AttributesBuilderInterface.php b/vendor/open-telemetry/sdk/Common/Attribute/AttributesBuilderInterface.php
new file mode 100644
index 000000000..7e3d64062
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Attribute/AttributesBuilderInterface.php
@@ -0,0 +1,12 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Attribute;
+
+use ArrayAccess;
+
+interface AttributesBuilderInterface extends ArrayAccess
+{
+ public function build(): AttributesInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Common/Attribute/AttributesFactory.php b/vendor/open-telemetry/sdk/Common/Attribute/AttributesFactory.php
new file mode 100644
index 000000000..d53ab25aa
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Attribute/AttributesFactory.php
@@ -0,0 +1,36 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Attribute;
+
+/**
+ * @internal
+ */
+final class AttributesFactory implements AttributesFactoryInterface
+{
+ private ?int $attributeCountLimit;
+ private ?int $attributeValueLengthLimit;
+
+ public function __construct(?int $attributeCountLimit = null, ?int $attributeValueLengthLimit = null)
+ {
+ $this->attributeCountLimit = $attributeCountLimit;
+ $this->attributeValueLengthLimit = $attributeValueLengthLimit;
+ }
+
+ public function builder(iterable $attributes = [], ?AttributeValidatorInterface $attributeValidator = null): AttributesBuilderInterface
+ {
+ $builder = new AttributesBuilder(
+ [],
+ $this->attributeCountLimit,
+ $this->attributeValueLengthLimit,
+ 0,
+ $attributeValidator,
+ );
+ foreach ($attributes as $key => $value) {
+ $builder[$key] = $value;
+ }
+
+ return $builder;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Attribute/AttributesFactoryInterface.php b/vendor/open-telemetry/sdk/Common/Attribute/AttributesFactoryInterface.php
new file mode 100644
index 000000000..1b74461d4
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Attribute/AttributesFactoryInterface.php
@@ -0,0 +1,10 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Attribute;
+
+interface AttributesFactoryInterface
+{
+ public function builder(iterable $attributes = [], ?AttributeValidatorInterface $attributeValidator = null): AttributesBuilderInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Common/Attribute/AttributesInterface.php b/vendor/open-telemetry/sdk/Common/Attribute/AttributesInterface.php
new file mode 100644
index 000000000..1af7dc8d9
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Attribute/AttributesInterface.php
@@ -0,0 +1,19 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Attribute;
+
+use Countable;
+use Traversable;
+
+interface AttributesInterface extends Traversable, Countable
+{
+ public function has(string $name): bool;
+
+ public function get(string $name);
+
+ public function getDroppedAttributesCount(): int;
+
+ public function toArray(): array;
+}
diff --git a/vendor/open-telemetry/sdk/Common/Attribute/FilteredAttributesBuilder.php b/vendor/open-telemetry/sdk/Common/Attribute/FilteredAttributesBuilder.php
new file mode 100644
index 000000000..d79cff96a
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Attribute/FilteredAttributesBuilder.php
@@ -0,0 +1,77 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Attribute;
+
+use function in_array;
+
+/**
+ * @internal
+ */
+final class FilteredAttributesBuilder implements AttributesBuilderInterface
+{
+ private AttributesBuilderInterface $builder;
+ private array $rejectedKeys;
+ private int $rejected = 0;
+
+ /**
+ * @param list<string> $rejectedKeys
+ */
+ public function __construct(AttributesBuilderInterface $builder, array $rejectedKeys)
+ {
+ $this->builder = $builder;
+ $this->rejectedKeys = $rejectedKeys;
+ }
+
+ public function __clone()
+ {
+ $this->builder = clone $this->builder;
+ }
+
+ public function build(): AttributesInterface
+ {
+ $attributes = $this->builder->build();
+ $dropped = $attributes->getDroppedAttributesCount() + $this->rejected;
+
+ return new Attributes($attributes->toArray(), $dropped);
+ }
+
+ public function offsetExists($offset): bool
+ {
+ return $this->builder->offsetExists($offset);
+ }
+
+ /**
+ * @phan-suppress PhanUndeclaredClassAttribute
+ */
+ #[\ReturnTypeWillChange]
+ public function offsetGet($offset)
+ {
+ return $this->builder->offsetGet($offset);
+ }
+
+ /**
+ * @phan-suppress PhanUndeclaredClassAttribute
+ */
+ #[\ReturnTypeWillChange]
+ public function offsetSet($offset, $value)
+ {
+ if ($value !== null && in_array($offset, $this->rejectedKeys, true)) {
+ $this->rejected++;
+
+ return;
+ }
+
+ $this->builder->offsetSet($offset, $value);
+ }
+
+ /**
+ * @phan-suppress PhanUndeclaredClassAttribute
+ */
+ #[\ReturnTypeWillChange]
+ public function offsetUnset($offset)
+ {
+ $this->builder->offsetUnset($offset);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Attribute/FilteredAttributesFactory.php b/vendor/open-telemetry/sdk/Common/Attribute/FilteredAttributesFactory.php
new file mode 100644
index 000000000..1d9c4ae1c
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Attribute/FilteredAttributesFactory.php
@@ -0,0 +1,33 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Attribute;
+
+/**
+ * @internal
+ */
+final class FilteredAttributesFactory implements AttributesFactoryInterface
+{
+ private AttributesFactoryInterface $factory;
+ private array $rejectedKeys;
+
+ /**
+ * @param list<string> $rejectedKeys
+ */
+ public function __construct(AttributesFactoryInterface $factory, array $rejectedKeys)
+ {
+ $this->factory = $factory;
+ $this->rejectedKeys = $rejectedKeys;
+ }
+
+ public function builder(iterable $attributes = [], ?AttributeValidatorInterface $attributeValidator = null): AttributesBuilderInterface
+ {
+ $builder = new FilteredAttributesBuilder($this->factory->builder([], $attributeValidator), $this->rejectedKeys);
+ foreach ($attributes as $attribute => $value) {
+ $builder[$attribute] = $value;
+ }
+
+ return $builder;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Attribute/LogRecordAttributeValidator.php b/vendor/open-telemetry/sdk/Common/Attribute/LogRecordAttributeValidator.php
new file mode 100644
index 000000000..a09d26372
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Attribute/LogRecordAttributeValidator.php
@@ -0,0 +1,19 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Attribute;
+
+class LogRecordAttributeValidator implements AttributeValidatorInterface
+{
+ public function validate($value): bool
+ {
+ return true;
+ }
+
+ public function getInvalidMessage(): string
+ {
+ //not required as this validator always returns true
+ return 'unused';
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Configuration/Configuration.php b/vendor/open-telemetry/sdk/Common/Configuration/Configuration.php
new file mode 100644
index 000000000..58673fd98
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Configuration/Configuration.php
@@ -0,0 +1,182 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Configuration;
+
+use InvalidArgumentException;
+use OpenTelemetry\API\Behavior\LogsMessagesTrait;
+use OpenTelemetry\SDK\Common\Configuration\Parser\BooleanParser;
+use OpenTelemetry\SDK\Common\Configuration\Parser\ListParser;
+use OpenTelemetry\SDK\Common\Configuration\Parser\MapParser;
+use OpenTelemetry\SDK\Common\Configuration\Parser\RatioParser;
+use OpenTelemetry\SDK\Common\Configuration\Resolver\CompositeResolver;
+use OpenTelemetry\SDK\Common\Util\ClassConstantAccessor;
+use UnexpectedValueException;
+
+/**
+ * Configuration can come from one or more of the following sources (from highest to lowest priority):
+ * - values defined in php.ini
+ * - environment variable ($_SERVER)
+ * - configuration file (todo)
+ */
+class Configuration
+{
+ use LogsMessagesTrait;
+
+ public static function has(string $name): bool
+ {
+ return CompositeResolver::instance()->hasVariable($name);
+ }
+
+ public static function getInt(string $key, int $default = null): int
+ {
+ return (int) self::validateVariableValue(
+ CompositeResolver::instance()->resolve(
+ self::validateVariableType($key, VariableTypes::INTEGER),
+ $default
+ ),
+ FILTER_VALIDATE_INT
+ );
+ }
+
+ public static function getString(string $key, string $default = null): string
+ {
+ return (string) self::validateVariableValue(
+ CompositeResolver::instance()->resolve(
+ self::validateVariableType($key, VariableTypes::STRING),
+ $default
+ )
+ );
+ }
+
+ public static function getBoolean(string $key, bool $default = null): bool
+ {
+ $resolved = self::validateVariableValue(
+ CompositeResolver::instance()->resolve(
+ self::validateVariableType($key, VariableTypes::BOOL),
+ null === $default ? $default : ($default ? 'true' : 'false')
+ )
+ );
+
+ try {
+ return BooleanParser::parse($resolved);
+ } catch (InvalidArgumentException $e) {
+ self::logWarning(sprintf('Invalid boolean value "%s" interpreted as "false" for %s', $resolved, $key));
+
+ return false;
+ }
+ }
+
+ public static function getMixed(string $key, $default = null)
+ {
+ return self::validateVariableValue(
+ CompositeResolver::instance()->resolve(
+ $key,
+ $default
+ )
+ );
+ }
+
+ public static function getMap(string $key, array $default = null): array
+ {
+ return MapParser::parse(
+ CompositeResolver::instance()->resolve(
+ self::validateVariableType($key, VariableTypes::MAP),
+ $default
+ )
+ );
+ }
+
+ public static function getList(string $key, array $default = null): array
+ {
+ return ListParser::parse(
+ CompositeResolver::instance()->resolve(
+ self::validateVariableType($key, VariableTypes::LIST),
+ $default
+ )
+ );
+ }
+
+ public static function getEnum(string $key, string $default = null): string
+ {
+ return (string) self::validateVariableValue(
+ CompositeResolver::instance()->resolve(
+ self::validateVariableType($key, VariableTypes::ENUM),
+ $default
+ )
+ );
+ }
+
+ public static function getFloat(string $key, float $default = null): float
+ {
+ return (float) self::validateVariableValue(
+ CompositeResolver::instance()->resolve(
+ self::validateVariableType($key, VariableTypes::FLOAT),
+ $default
+ ),
+ FILTER_VALIDATE_FLOAT
+ );
+ }
+
+ public static function getRatio(string $key, float $default = null): float
+ {
+ return RatioParser::parse(
+ self::validateVariableValue(
+ CompositeResolver::instance()->resolve(
+ self::validateVariableType($key, VariableTypes::RATIO),
+ $default
+ )
+ )
+ );
+ }
+
+ public static function getKnownValues(string $variableName): ?array
+ {
+ return ClassConstantAccessor::getValue(KnownValues::class, $variableName);
+ }
+
+ public static function getDefault(string $variableName)
+ {
+ return ClassConstantAccessor::getValue(Defaults::class, $variableName);
+ }
+
+ public static function getType(string $variableName): ?string
+ {
+ return ClassConstantAccessor::getValue(ValueTypes::class, $variableName);
+ }
+
+ public static function isEmpty($value): bool
+ {
+ // don't use 'empty()', since '0' is not considered to be empty
+ return $value === null || $value === '';
+ }
+
+ private static function validateVariableType(string $variableName, string $type): string
+ {
+ $variableType = self::getType($variableName);
+
+ if ($variableType !== null && $variableType !== $type && $variableType !== VariableTypes::MIXED) {
+ throw new UnexpectedValueException(
+ sprintf('Variable "%s" is not supposed to be of type "%s" but type "%s"', $variableName, $type, $variableType)
+ );
+ }
+
+ return $variableName;
+ }
+
+ private static function validateVariableValue($value, ?int $filterType = null)
+ {
+ if ($filterType !== null && filter_var($value, $filterType) === false) {
+ throw new UnexpectedValueException(sprintf('Value has invalid type "%s"', gettype($value)));
+ }
+
+ if ($value === null || $value === '') {
+ throw new UnexpectedValueException(
+ 'Variable must not be null or empty'
+ );
+ }
+
+ return $value;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Configuration/Defaults.php b/vendor/open-telemetry/sdk/Common/Configuration/Defaults.php
new file mode 100644
index 000000000..7228270a6
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Configuration/Defaults.php
@@ -0,0 +1,122 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Configuration;
+
+/**
+ * Default values for environment variables defined by the OpenTelemetry specification and language specific variables for the PHP SDK.
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md
+ */
+interface Defaults
+{
+ /**
+ * General SDK Configuration
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#general-sdk-configuration
+ */
+ public const OTEL_LOG_LEVEL = 'info';
+ public const OTEL_PROPAGATORS = 'tracecontext,baggage';
+ public const OTEL_TRACES_SAMPLER = 'parentbased_always_on';
+ public const OTEL_SDK_DISABLED = 'false';
+ /**
+ * Batch Span Processor
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#batch-span-processor
+ */
+ public const OTEL_BSP_SCHEDULE_DELAY = 5000;
+ public const OTEL_BSP_EXPORT_TIMEOUT = 30000;
+ public const OTEL_BSP_MAX_QUEUE_SIZE = 2048;
+ public const OTEL_BSP_MAX_EXPORT_BATCH_SIZE = 512;
+ /**
+ * Batch LogRecord Processor
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#batch-logrecord-processor
+ */
+ public const OTEL_BLRP_SCHEDULE_DELAY = 1000;
+ public const OTEL_BLRP_EXPORT_TIMEOUT = 30000;
+ public const OTEL_BLRP_MAX_QUEUE_SIZE = 2048;
+ public const OTEL_BLRP_MAX_EXPORT_BATCH_SIZE = 512;
+ /**
+ * Attribute Limits
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#attribute-limits
+ */
+ public const OTEL_ATTRIBUTE_COUNT_LIMIT = 128;
+ public const OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT = PHP_INT_MAX;
+ /**
+ * Span Limits
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#span-limits
+ */
+ public const OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT = 128;
+ public const OTEL_SPAN_EVENT_COUNT_LIMIT = 128;
+ public const OTEL_SPAN_LINK_COUNT_LIMIT = 128;
+ public const OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT = 128;
+ public const OTEL_LINK_ATTRIBUTE_COUNT_LIMIT = 128;
+ /**
+ * LogRecord Limits
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#logrecord-limits
+ */
+ public const OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT = PHP_INT_MAX;
+ public const OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT = 128;
+ /**
+ * OTLP Exporter
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options
+ */
+ // Endpoint
+ public const OTEL_EXPORTER_OTLP_ENDPOINT = 'http://localhost:4318';
+ public const OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = 'http://localhost:4318';
+ public const OTEL_EXPORTER_OTLP_METRICS_ENDPOINT = 'http://localhost:4318';
+ public const OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = 'http://localhost:4318';
+ // Insecure
+ public const OTEL_EXPORTER_OTLP_INSECURE = 'false';
+ public const OTEL_EXPORTER_OTLP_TRACES_INSECURE = 'false';
+ public const OTEL_EXPORTER_OTLP_METRICS_INSECURE = 'false';
+ public const OTEL_EXPORTER_OTLP_LOGS_INSECURE = 'false';
+ // Timeout (seconds)
+ public const OTEL_EXPORTER_OTLP_TIMEOUT = 10;
+ public const OTEL_EXPORTER_OTLP_TRACES_TIMEOUT = 10;
+ public const OTEL_EXPORTER_OTLP_METRICS_TIMEOUT = 10;
+ public const OTEL_EXPORTER_OTLP_LOGS_TIMEOUT = 10;
+ // Protocol
+ public const OTEL_EXPORTER_OTLP_PROTOCOL = 'http/protobuf';
+ public const OTEL_EXPORTER_OTLP_TRACES_PROTOCOL = 'http/protobuf';
+ public const OTEL_EXPORTER_OTLP_METRICS_PROTOCOL = 'http/protobuf';
+ public const OTEL_EXPORTER_OTLP_LOGS_PROTOCOL = 'http/protobuf';
+ /**
+ * Zipkin Exporter
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#zipkin-exporter
+ */
+ public const OTEL_EXPORTER_ZIPKIN_ENDPOINT = 'http://localhost:9411/api/v2/spans';
+ // Timeout (seconds)
+ public const OTEL_EXPORTER_ZIPKIN_TIMEOUT = 10;
+ /**
+ * Prometheus Exporter
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#prometheus-exporter
+ */
+ public const OTEL_EXPORTER_PROMETHEUS_HOST = '0.0.0.0';
+ public const OTEL_EXPORTER_PROMETHEUS_PORT = 9464;
+ /**
+ * Exporter Selection
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#exporter-selection
+ */
+ public const OTEL_TRACES_EXPORTER = 'otlp';
+ public const OTEL_METRICS_EXPORTER = 'otlp';
+ public const OTEL_LOGS_EXPORTER = 'otlp';
+ /**
+ * Metrics SDK Configuration
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#metrics-sdk-configuration
+ */
+ public const OTEL_METRICS_EXEMPLAR_FILTER = 'with_sampled_trace';
+ public const OTEL_METRIC_EXPORT_INTERVAL = 60000;
+ public const OTEL_METRIC_EXPORT_TIMEOUT = 30000;
+ public const OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE = 'cumulative';
+ public const OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION = 'explicit_bucket_histogram';
+ /**
+ * Language Specific Environment Variables
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#language-specific-environment-variables
+ */
+ public const OTEL_PHP_TRACES_PROCESSOR = 'batch';
+ public const OTEL_PHP_DETECTORS = 'all';
+ public const OTEL_PHP_AUTOLOAD_ENABLED = 'false';
+ public const OTEL_PHP_INTERNAL_METRICS_ENABLED = 'false';
+ public const OTEL_PHP_DISABLED_INSTRUMENTATIONS = [];
+ public const OTEL_PHP_LOGS_PROCESSOR = 'batch';
+ public const OTEL_PHP_LOG_DESTINATION = 'default';
+}
diff --git a/vendor/open-telemetry/sdk/Common/Configuration/KnownValues.php b/vendor/open-telemetry/sdk/Common/Configuration/KnownValues.php
new file mode 100644
index 000000000..8975b20f9
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Configuration/KnownValues.php
@@ -0,0 +1,208 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Configuration;
+
+use Psr\Log\LogLevel;
+
+/**
+ * "Known values" for OpenTelemetry configurataion variables.
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md
+ * Notice: Values specific to the PHP SDK have been added
+ */
+interface KnownValues
+{
+ public const VALUE_TRUE = 'true';
+ public const VALUE_FALSE = 'false';
+ public const VALUE_ON = 'on';
+ public const VALUE_OFF = 'off';
+ public const VALUE_1 = '1';
+ public const VALUE_0 = '0';
+ public const VALUE_ALL = 'all';
+ public const VALUE_NONE = 'none';
+ public const VALUE_TRACECONTEXT = 'tracecontext';
+ public const VALUE_BAGGAGE = 'baggage';
+ public const VALUE_B3 = 'b3';
+ public const VALUE_B3_MULTI = 'b3multi';
+ public const VALUE_XRAY = 'xray';
+ public const VALUE_OTTRACE = 'ottrace';
+ public const VALUE_ALWAYS_ON = 'always_on';
+ public const VALUE_ALWAYS_OFF = 'always_off';
+ public const VALUE_TRACE_ID_RATIO = 'traceidratio';
+ public const VALUE_PARENT_BASED_ALWAYS_ON = 'parentbased_always_on';
+ public const VALUE_PARENT_BASED_ALWAYS_OFF = 'parentbased_always_off';
+ public const VALUE_PARENT_BASED_TRACE_ID_RATIO = 'parentbased_traceidratio';
+ public const VALUE_GZIP = 'gzip';
+ public const VALUE_GRPC = 'grpc';
+ public const VALUE_HTTP_PROTOBUF = 'http/protobuf';
+ public const VALUE_HTTP_JSON = 'http/json';
+ public const VALUE_HTTP_NDJSON = 'http/ndjson';
+ public const VALUE_OTLP = 'otlp';
+ public const VALUE_ZIPKIN = 'zipkin';
+ public const VALUE_PROMETHEUS = 'prometheus';
+ public const VALUE_WITH_SAMPLED_TRACE = 'with_sampled_trace';
+ public const VALUE_BATCH = 'batch';
+ public const VALUE_SIMPLE = 'simple';
+ public const VALUE_NOOP = 'noop';
+ public const VALUE_LOG_EMERGENCY = LogLevel::EMERGENCY;
+ public const VALUE_LOG_ALERT = LogLevel::ALERT;
+ public const VALUE_LOG_CRITICAL = LogLevel::CRITICAL;
+ public const VALUE_LOG_ERROR = LogLevel::ERROR;
+ public const VALUE_LOG_WARNING = LogLevel::WARNING;
+ public const VALUE_LOG_NOTICE = LogLevel::NOTICE;
+ public const VALUE_LOG_INFO = LogLevel::INFO;
+ public const VALUE_LOG_DEBUG = LogLevel::DEBUG;
+ public const VALUE_TEMPORALITY_CUMULATIVE = 'cumulative';
+ public const VALUE_TEMPORALITY_DELTA = 'delta';
+ public const VALUE_TEMPORALITY_LOW_MEMORY = 'lowmemory';
+ public const VALUE_HISTOGRAM_AGGREGATION_EXPLICIT = 'explicit_bucket_histogram';
+ public const VALUE_HISTOGRAM_AGGREGATION_BASE2_EXPONENTIAL = 'base2_exponential_bucket_histogram';
+
+ public const VALUES_BOOLEAN = [
+ self::VALUE_TRUE,
+ self::VALUE_FALSE,
+ ];
+
+ public const VALUES_COMPRESSION= [
+ self::VALUE_GZIP,
+ self::VALUE_NONE,
+ ];
+
+ public const VALUES_OTLP_PROTOCOL = [
+ self::VALUE_GRPC,
+ self::VALUE_HTTP_PROTOBUF,
+ self::VALUE_HTTP_JSON,
+ ];
+
+ public const VALUES_TEMPORALITY_PREFERENCE = [
+ self::VALUE_TEMPORALITY_CUMULATIVE,
+ self::VALUE_TEMPORALITY_DELTA,
+ self::VALUE_TEMPORALITY_LOW_MEMORY,
+ ];
+
+ public const VALUES_HISTOGRAM_AGGREGATION = [
+ self::VALUE_HISTOGRAM_AGGREGATION_EXPLICIT,
+ self::VALUE_HISTOGRAM_AGGREGATION_BASE2_EXPONENTIAL,
+ ];
+
+ /**
+ * General SDK Configuration
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#general-sdk-configuration
+ */
+ public const OTEL_LOG_LEVEL = [
+ self::VALUE_LOG_EMERGENCY,
+ self::VALUE_LOG_ALERT,
+ self::VALUE_LOG_CRITICAL,
+ self::VALUE_LOG_ERROR,
+ self::VALUE_LOG_WARNING,
+ self::VALUE_LOG_NOTICE,
+ self::VALUE_LOG_INFO,
+ self::VALUE_LOG_DEBUG,
+ ];
+ public const OTEL_PROPAGATORS = [
+ self::VALUE_TRACECONTEXT, // W3C Trace Context
+ self::VALUE_BAGGAGE, // W3C Baggage
+ self::VALUE_B3, // B3 Single
+ self::VALUE_B3_MULTI, // B3 Multi
+ self::VALUE_XRAY, // AWS X-Ray (third party)
+ self::VALUE_OTTRACE, // OT Trace (third party)
+ self::VALUE_NONE, // No automatically configured propagator.
+ ];
+ public const OTEL_TRACES_SAMPLER = [
+ self::VALUE_ALWAYS_ON,
+ self::VALUE_ALWAYS_OFF,
+ self::VALUE_TRACE_ID_RATIO,
+ self::VALUE_PARENT_BASED_ALWAYS_ON,
+ self::VALUE_PARENT_BASED_ALWAYS_OFF,
+ self::VALUE_PARENT_BASED_TRACE_ID_RATIO,
+ self::VALUE_XRAY,
+ ];
+ /**
+ * OTLP Exporter
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options
+ */
+ // Insecure
+ public const OTEL_EXPORTER_OTLP_INSECURE = self::VALUES_BOOLEAN;
+ public const OTEL_EXPORTER_OTLP_TRACES_INSECURE = self::VALUES_BOOLEAN;
+ public const OTEL_EXPORTER_OTLP_METRICS_INSECURE = self::VALUES_BOOLEAN;
+ // Compression
+ public const OTEL_EXPORTER_OTLP_COMPRESSION = self::VALUES_COMPRESSION;
+ public const OTEL_EXPORTER_OTLP_TRACES_COMPRESSION = self::VALUES_COMPRESSION;
+ public const OTEL_EXPORTER_OTLP_METRICS_COMPRESSION = self::VALUES_COMPRESSION;
+ // Protocol
+ public const OTEL_EXPORTER_OTLP_PROTOCOL = self::VALUES_OTLP_PROTOCOL;
+ public const OTEL_EXPORTER_OTLP_TRACES_PROTOCOL = self::VALUES_OTLP_PROTOCOL;
+ public const OTEL_EXPORTER_OTLP_METRICS_PROTOCOL = self::VALUES_OTLP_PROTOCOL;
+ /**
+ * Exporter Selection
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#exporter-selection
+ */
+ public const OTEL_TRACES_EXPORTER = [
+ self::VALUE_OTLP,
+ self::VALUE_ZIPKIN,
+ self::VALUE_NONE,
+ ];
+ public const OTEL_METRICS_EXPORTER = [
+ self::VALUE_OTLP,
+ self::VALUE_PROMETHEUS,
+ self::VALUE_NONE,
+ ];
+ public const OTEL_LOGS_EXPORTER = [
+ self::VALUE_OTLP,
+ self::VALUE_NONE,
+ ];
+ /**
+ * Metrics SDK Configuration
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#metrics-sdk-configuration
+ */
+ public const OTEL_METRICS_EXEMPLAR_FILTER = [
+ self::VALUE_WITH_SAMPLED_TRACE,
+ self::VALUE_ALL,
+ self::VALUE_NONE,
+ ];
+ /**
+ * Language Specific Environment Variables
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#language-specific-environment-variables
+ */
+ public const OTEL_PHP_TRACES_PROCESSOR = [
+ self::VALUE_BATCH,
+ self::VALUE_SIMPLE,
+ self::VALUE_NOOP,
+ self::VALUE_NONE,
+ ];
+ public const OTEL_PHP_AUTOLOAD_ENABLED = self::VALUES_BOOLEAN;
+ public const VALUE_ERROR_LOG = 'error_log';
+ public const VALUE_STDERR = 'stderr';
+ public const VALUE_STDOUT = 'stdout';
+ public const VALUE_PSR3 = 'psr3';
+ public const VALUE_EMPTY = '';
+ public const VALUE_DETECTORS_ENVIRONMENT = 'env';
+ public const VALUE_DETECTORS_HOST = 'host';
+ public const VALUE_DETECTORS_OS = 'os';
+ public const VALUE_DETECTORS_PROCESS = 'process';
+ public const VALUE_DETECTORS_PROCESS_RUNTIME = 'process_runtime';
+ public const VALUE_DETECTORS_SDK = 'sdk';
+ public const VALUE_DETECTORS_SDK_PROVIDED = 'sdk_provided';
+ public const VALUE_DETECTORS_COMPOSER = 'composer';
+ public const OTEL_PHP_DETECTORS = [
+ self::VALUE_ALL,
+ self::VALUE_DETECTORS_ENVIRONMENT,
+ self::VALUE_DETECTORS_HOST,
+ self::VALUE_DETECTORS_OS,
+ self::VALUE_DETECTORS_PROCESS,
+ self::VALUE_DETECTORS_PROCESS_RUNTIME,
+ self::VALUE_DETECTORS_SDK,
+ self::VALUE_DETECTORS_SDK_PROVIDED,
+ self::VALUE_DETECTORS_COMPOSER,
+ self::VALUE_NONE,
+ ];
+ public const OTEL_PHP_LOG_DESTINATION = [
+ self::VALUE_ERROR_LOG,
+ self::VALUE_STDERR,
+ self::VALUE_STDOUT,
+ self::VALUE_PSR3,
+ self::VALUE_EMPTY,
+ self::VALUE_NONE,
+ ];
+}
diff --git a/vendor/open-telemetry/sdk/Common/Configuration/Parser/BooleanParser.php b/vendor/open-telemetry/sdk/Common/Configuration/Parser/BooleanParser.php
new file mode 100644
index 000000000..4141c61ef
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Configuration/Parser/BooleanParser.php
@@ -0,0 +1,34 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Configuration\Parser;
+
+use InvalidArgumentException;
+
+class BooleanParser
+{
+ private const TRUE_VALUE = 'true';
+ private const FALSE_VALUE = 'false';
+
+ /**
+ * @param string|bool $value
+ */
+ public static function parse($value): bool
+ {
+ if (is_bool($value)) {
+ return $value;
+ }
+ if (strtolower($value) === self::TRUE_VALUE) {
+ return true;
+ }
+
+ if (strtolower($value) === self::FALSE_VALUE) {
+ return false;
+ }
+
+ throw new InvalidArgumentException(
+ sprintf('Value "%s" is a non-boolean value', $value)
+ );
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Configuration/Parser/ListParser.php b/vendor/open-telemetry/sdk/Common/Configuration/Parser/ListParser.php
new file mode 100644
index 000000000..f27b16597
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Configuration/Parser/ListParser.php
@@ -0,0 +1,28 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Configuration\Parser;
+
+class ListParser
+{
+ private const DEFAULT_SEPARATOR = ',';
+
+ /**
+ * @param string|array $value
+ */
+ public static function parse($value): array
+ {
+ if (is_array($value)) {
+ return $value;
+ }
+ if (trim($value) === '') {
+ return [];
+ }
+
+ return array_map(
+ fn ($value) => trim($value),
+ explode(self::DEFAULT_SEPARATOR, $value)
+ );
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Configuration/Parser/MapParser.php b/vendor/open-telemetry/sdk/Common/Configuration/Parser/MapParser.php
new file mode 100644
index 000000000..273d57c87
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Configuration/Parser/MapParser.php
@@ -0,0 +1,45 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Configuration\Parser;
+
+use InvalidArgumentException;
+
+class MapParser
+{
+ private const VARIABLE_SEPARATOR = ',';
+ private const KEY_VALUE_SEPARATOR = '=';
+
+ public static function parse($value): array
+ {
+ if (is_array($value)) {
+ return $value;
+ }
+ $result = [];
+
+ if (null === $value || trim($value) === '') {
+ return $result;
+ }
+
+ foreach (explode(self::VARIABLE_SEPARATOR, $value) as $pair) {
+ self::validateKeyValuePair($pair);
+
+ [$key, $value] = explode(self::KEY_VALUE_SEPARATOR, $pair, 2);
+ $result[trim($key)] = trim($value);
+ }
+
+ return $result;
+ }
+
+ private static function validateKeyValuePair(string $pair)
+ {
+ if (strpos($pair, self::KEY_VALUE_SEPARATOR) === false) {
+ throw new InvalidArgumentException(sprintf(
+ 'Key-Value pair "%s" does not contain separator "%s"',
+ $pair,
+ self::KEY_VALUE_SEPARATOR
+ ));
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Configuration/Parser/RatioParser.php b/vendor/open-telemetry/sdk/Common/Configuration/Parser/RatioParser.php
new file mode 100644
index 000000000..f0fe32100
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Configuration/Parser/RatioParser.php
@@ -0,0 +1,38 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Configuration\Parser;
+
+use InvalidArgumentException;
+use RangeException;
+
+class RatioParser
+{
+ private const MAX_VALUE = 1;
+ private const MIN_VALUE = 0;
+
+ public static function parse($value): float
+ {
+ if (filter_var($value, FILTER_VALIDATE_FLOAT) === false) {
+ throw new InvalidArgumentException(
+ sprintf('Value "%s" contains non-numeric value', $value)
+ );
+ }
+
+ $result = (float) $value;
+
+ if ($result > self::MAX_VALUE || $result < self::MIN_VALUE) {
+ throw new RangeException(
+ sprintf(
+ 'Value must not be lower than %s or higher than %s. Given: %s',
+ self::MIN_VALUE,
+ self::MAX_VALUE,
+ $value
+ )
+ );
+ }
+
+ return $result;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Configuration/Resolver/CompositeResolver.php b/vendor/open-telemetry/sdk/Common/Configuration/Resolver/CompositeResolver.php
new file mode 100644
index 000000000..b72400b01
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Configuration/Resolver/CompositeResolver.php
@@ -0,0 +1,68 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Configuration\Resolver;
+
+use OpenTelemetry\SDK\Common\Configuration\Configuration;
+
+/**
+ * @interal
+ */
+class CompositeResolver
+{
+ // @var array<ResolverInterface>
+ private array $resolvers = [];
+
+ public static function instance(): self
+ {
+ static $instance;
+ $instance ??= new self([
+ new PhpIniResolver(),
+ new EnvironmentResolver(),
+ ]);
+
+ return $instance;
+ }
+
+ public function __construct($resolvers)
+ {
+ foreach ($resolvers as $resolver) {
+ $this->addResolver($resolver);
+ }
+ }
+
+ public function addResolver(ResolverInterface $resolver): void
+ {
+ $this->resolvers[] = $resolver;
+ }
+
+ public function getResolvers(): array
+ {
+ return $this->resolvers;
+ }
+
+ public function resolve(string $variableName, $default = '')
+ {
+ foreach ($this->resolvers as $resolver) {
+ if ($resolver->hasVariable($variableName)) {
+ return $resolver->retrieveValue($variableName);
+ }
+ }
+
+ return Configuration::isEmpty($default)
+ ? Configuration::getDefault($variableName)
+ : $default;
+ }
+
+ public function hasVariable(string $variableName): bool
+ {
+ foreach ($this->resolvers as $resolver) {
+ if ($resolver->hasVariable($variableName)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Configuration/Resolver/EnvironmentResolver.php b/vendor/open-telemetry/sdk/Common/Configuration/Resolver/EnvironmentResolver.php
new file mode 100644
index 000000000..453f98e39
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Configuration/Resolver/EnvironmentResolver.php
@@ -0,0 +1,40 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Configuration\Resolver;
+
+use OpenTelemetry\SDK\Common\Configuration\Configuration;
+
+/**
+ * @internal
+ */
+class EnvironmentResolver implements ResolverInterface
+{
+ public function hasVariable(string $variableName): bool
+ {
+ if (!Configuration::isEmpty($_SERVER[$variableName] ?? null)) {
+ return true;
+ }
+ $env = getenv($variableName);
+ if ($env === false) {
+ return false;
+ }
+
+ return !Configuration::isEmpty($env);
+ }
+
+ /**
+ * @psalm-suppress InvalidReturnStatement
+ * @psalm-suppress InvalidReturnType
+ */
+ public function retrieveValue(string $variableName)
+ {
+ $value = getenv($variableName);
+ if ($value === false) {
+ $value = $_SERVER[$variableName] ?? null;
+ }
+
+ return $value;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Configuration/Resolver/PhpIniAccessor.php b/vendor/open-telemetry/sdk/Common/Configuration/Resolver/PhpIniAccessor.php
new file mode 100644
index 000000000..a12b507e8
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Configuration/Resolver/PhpIniAccessor.php
@@ -0,0 +1,18 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Configuration\Resolver;
+
+class PhpIniAccessor
+{
+ /**
+ * Mockable accessor for php.ini values
+ * @internal
+ * @return array|false|string
+ */
+ public function get(string $variableName)
+ {
+ return get_cfg_var($variableName);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Configuration/Resolver/PhpIniResolver.php b/vendor/open-telemetry/sdk/Common/Configuration/Resolver/PhpIniResolver.php
new file mode 100644
index 000000000..c9a8f3b4e
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Configuration/Resolver/PhpIniResolver.php
@@ -0,0 +1,41 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Configuration\Resolver;
+
+use OpenTelemetry\SDK\Common\Configuration\Configuration;
+
+/**
+ * @interal
+ * @psalm-suppress TypeDoesNotContainType
+ */
+class PhpIniResolver implements ResolverInterface
+{
+ private PhpIniAccessor $accessor;
+
+ public function __construct(?PhpIniAccessor $accessor = null)
+ {
+ $this->accessor = $accessor ?? new PhpIniAccessor();
+ }
+
+ public function retrieveValue(string $variableName)
+ {
+ $value = $this->accessor->get($variableName) ?: '';
+ if (is_array($value)) {
+ return implode(',', $value);
+ }
+
+ return $value;
+ }
+
+ public function hasVariable(string $variableName): bool
+ {
+ $value = $this->accessor->get($variableName);
+ if ($value === []) {
+ return false;
+ }
+
+ return $value !== false && !Configuration::isEmpty($value);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Configuration/Resolver/ResolverInterface.php b/vendor/open-telemetry/sdk/Common/Configuration/Resolver/ResolverInterface.php
new file mode 100644
index 000000000..4e88f3ff6
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Configuration/Resolver/ResolverInterface.php
@@ -0,0 +1,15 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Configuration\Resolver;
+
+interface ResolverInterface
+{
+ /**
+ * @return mixed
+ */
+ public function retrieveValue(string $variableName);
+
+ public function hasVariable(string $variableName): bool;
+}
diff --git a/vendor/open-telemetry/sdk/Common/Configuration/ValueTypes.php b/vendor/open-telemetry/sdk/Common/Configuration/ValueTypes.php
new file mode 100644
index 000000000..64a69f6a7
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Configuration/ValueTypes.php
@@ -0,0 +1,133 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Configuration;
+
+/**
+ * Environment variables defined by the OpenTelemetry specification and language specific variables for the PHP SDK.
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md
+ */
+interface ValueTypes
+{
+ /**
+ * General SDK Configuration
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#general-sdk-configuration
+ */
+ public const OTEL_RESOURCE_ATTRIBUTES = VariableTypes::MAP;
+ public const OTEL_SERVICE_NAME = VariableTypes::STRING;
+ public const OTEL_LOG_LEVEL = VariableTypes::ENUM;
+ public const OTEL_PROPAGATORS = VariableTypes::LIST;
+ public const OTEL_TRACES_SAMPLER = VariableTypes::STRING;
+ public const OTEL_TRACES_SAMPLER_ARG = VariableTypes::MIXED;
+ /**
+ * Batch Span Processor
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#batch-span-processor
+ */
+ public const OTEL_BSP_SCHEDULE_DELAY = VariableTypes::INTEGER;
+ public const OTEL_BSP_EXPORT_TIMEOUT = VariableTypes::INTEGER;
+ public const OTEL_BSP_MAX_QUEUE_SIZE = VariableTypes::INTEGER;
+ public const OTEL_BSP_MAX_EXPORT_BATCH_SIZE = VariableTypes::INTEGER;
+ /**
+ * Batch LogRecord Processor
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#batch-logrecord-processor
+ */
+ public const OTEL_BLRP_SCHEDULE_DELAY = VariableTypes::INTEGER;
+ public const OTEL_BLRP_EXPORT_TIMEOUT = VariableTypes::INTEGER;
+ public const OTEL_BLRP_MAX_QUEUE_SIZE = VariableTypes::INTEGER;
+ public const OTEL_BLRP_MAX_EXPORT_BATCH_SIZE = VariableTypes::INTEGER;
+ /**
+ * Attribute Limits
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#attribute-limits
+ */
+ public const OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT = VariableTypes::INTEGER;
+ public const OTEL_ATTRIBUTE_COUNT_LIMIT = VariableTypes::INTEGER;
+ /**
+ * Span Limits
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#span-limits
+ */
+ public const OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT = VariableTypes::INTEGER;
+ public const OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT = VariableTypes::INTEGER;
+ public const OTEL_SPAN_EVENT_COUNT_LIMIT = VariableTypes::INTEGER;
+ public const OTEL_SPAN_LINK_COUNT_LIMIT = VariableTypes::INTEGER;
+ public const OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT = VariableTypes::INTEGER;
+ public const OTEL_LINK_ATTRIBUTE_COUNT_LIMIT = VariableTypes::INTEGER;
+ /**
+ * LogRecord Limits
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#logrecord-limits
+ */
+ public const OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT = VariableTypes::INTEGER;
+ public const OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT = VariableTypes::INTEGER;
+ /**
+ * OTLP Exporter
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options
+ */
+ // Endpoint
+ public const OTEL_EXPORTER_OTLP_ENDPOINT = VariableTypes::STRING;
+ public const OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = VariableTypes::STRING;
+ public const OTEL_EXPORTER_OTLP_METRICS_ENDPOINT = VariableTypes::STRING;
+ // Insecure
+ public const OTEL_EXPORTER_OTLP_INSECURE = VariableTypes::BOOL;
+ public const OTEL_EXPORTER_OTLP_TRACES_INSECURE = VariableTypes::BOOL;
+ public const OTEL_EXPORTER_OTLP_METRICS_INSECURE = VariableTypes::BOOL;
+ // Certificate File
+ public const OTEL_EXPORTER_OTLP_CERTIFICATE = VariableTypes::STRING;
+ public const OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE = VariableTypes::STRING;
+ public const OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE = VariableTypes::STRING;
+ // Headers
+ public const OTEL_EXPORTER_OTLP_HEADERS = VariableTypes::MAP;
+ public const OTEL_EXPORTER_OTLP_TRACES_HEADERS = VariableTypes::MAP;
+ public const OTEL_EXPORTER_OTLP_METRICS_HEADERS = VariableTypes::MAP;
+ // Compression
+ public const OTEL_EXPORTER_OTLP_COMPRESSION = VariableTypes::ENUM;
+ public const OTEL_EXPORTER_OTLP_TRACES_COMPRESSION = VariableTypes::ENUM;
+ public const OTEL_EXPORTER_OTLP_METRICS_COMPRESSION = VariableTypes::ENUM;
+ // Timeout
+ public const OTEL_EXPORTER_OTLP_TIMEOUT = VariableTypes::INTEGER;
+ public const OTEL_EXPORTER_OTLP_TRACES_TIMEOUT = VariableTypes::INTEGER;
+ public const OTEL_EXPORTER_OTLP_METRICS_TIMEOUT = VariableTypes::INTEGER;
+ // Protocol
+ public const OTEL_EXPORTER_OTLP_PROTOCOL = VariableTypes::ENUM;
+ public const OTEL_EXPORTER_OTLP_TRACES_PROTOCOL = VariableTypes::ENUM;
+ public const OTEL_EXPORTER_OTLP_METRICS_PROTOCOL = VariableTypes::ENUM;
+ /**
+ * Zipkin Exporter
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#zipkin-exporter
+ */
+ public const OTEL_EXPORTER_ZIPKIN_ENDPOINT = VariableTypes::STRING;
+ public const OTEL_EXPORTER_ZIPKIN_TIMEOUT = VariableTypes::INTEGER;
+ public const OTEL_EXPORTER_ZIPKIN_PROTOCOL = VariableTypes::STRING;
+ /**
+ * Prometheus Exporter
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#prometheus-exporter
+ */
+ public const OTEL_EXPORTER_PROMETHEUS_HOST = VariableTypes::STRING;
+ public const OTEL_EXPORTER_PROMETHEUS_PORT = VariableTypes::INTEGER;
+ /**
+ * Exporter Selection
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#exporter-selection
+ */
+ public const OTEL_TRACES_EXPORTER = VariableTypes::LIST;
+ public const OTEL_METRICS_EXPORTER = VariableTypes::LIST;
+ public const OTEL_LOGS_EXPORTER = VariableTypes::LIST;
+ /**
+ * Metrics SDK Configuration
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#metrics-sdk-configuration
+ */
+ public const OTEL_METRICS_EXEMPLAR_FILTER = VariableTypes::ENUM;
+ public const OTEL_METRIC_EXPORT_INTERVAL = VariableTypes::INTEGER;
+ public const OTEL_METRIC_EXPORT_TIMEOUT = VariableTypes::INTEGER;
+ public const OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE = VariableTypes::ENUM;
+ public const OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION = VariableTypes::ENUM;
+ /**
+ * Language Specific Environment Variables
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#language-specific-environment-variables
+ */
+ public const OTEL_PHP_TRACES_PROCESSOR = VariableTypes::ENUM;
+ public const OTEL_PHP_LOGS_PROCESSOR = VariableTypes::LIST;
+ public const OTEL_PHP_DETECTORS = VariableTypes::LIST;
+ public const OTEL_PHP_AUTOLOAD_ENABLED = VariableTypes::BOOL;
+ public const OTEL_PHP_LOG_DESTINATION = VariableTypes::ENUM;
+ public const OTEL_PHP_INTERNAL_METRICS_ENABLED = VariableTypes::BOOL;
+ public const OTEL_PHP_DISABLED_INSTRUMENTATIONS = VariableTypes::LIST;
+}
diff --git a/vendor/open-telemetry/sdk/Common/Configuration/VariableTypes.php b/vendor/open-telemetry/sdk/Common/Configuration/VariableTypes.php
new file mode 100644
index 000000000..471632e16
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Configuration/VariableTypes.php
@@ -0,0 +1,62 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Configuration;
+
+interface VariableTypes
+{
+ /**
+ * A single boolean value represented as a string or integer ('true', 'false', 0, 1)
+ * example: value1
+ */
+ public const BOOL = 'bool';
+
+ /**
+ * A single string value
+ * example: value1
+ */
+ public const STRING = 'string';
+
+ /**
+ * A single integer value
+ * example: 5000
+ */
+ public const INTEGER = 'integer';
+
+ /**
+ * A single float value
+ * example: 10.5
+ */
+ public const FLOAT = 'float';
+
+ /**
+ * A single float value between 0.0 and 1.0
+ * example: 0.5
+ */
+ public const RATIO = 'ratio';
+
+ /**
+ * A single string value from a fixed list of values
+ * example values: value1, value2, value3
+ * example: value1
+ */
+ public const ENUM = 'enum';
+
+ /**
+ * A comma separated list of single string values
+ * example: value1,value2,value3
+ */
+ public const LIST = 'list';
+
+ /**
+ * A comma separated list of key-value pairs
+ * example: key1=value1,key2=value2
+ */
+ public const MAP = 'map';
+
+ /**
+ * Values of mixed type
+ */
+ public const MIXED = 'mixed';
+}
diff --git a/vendor/open-telemetry/sdk/Common/Configuration/Variables.php b/vendor/open-telemetry/sdk/Common/Configuration/Variables.php
new file mode 100644
index 000000000..d0bb3c8ab
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Configuration/Variables.php
@@ -0,0 +1,142 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Configuration;
+
+/**
+ * Environment variables defined by the OpenTelemetry specification and language specific variables for the PHP SDK.
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md
+ */
+interface Variables
+{
+ /**
+ * General SDK Configuration
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#general-sdk-configuration
+ */
+ public const OTEL_RESOURCE_ATTRIBUTES = 'OTEL_RESOURCE_ATTRIBUTES';
+ public const OTEL_SERVICE_NAME = 'OTEL_SERVICE_NAME';
+ public const OTEL_LOG_LEVEL = 'OTEL_LOG_LEVEL';
+ public const OTEL_PROPAGATORS = 'OTEL_PROPAGATORS';
+ public const OTEL_TRACES_SAMPLER = 'OTEL_TRACES_SAMPLER';
+ public const OTEL_TRACES_SAMPLER_ARG = 'OTEL_TRACES_SAMPLER_ARG';
+ public const OTEL_SDK_DISABLED = 'OTEL_SDK_DISABLED';
+ /**
+ * Batch Span Processor
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#batch-span-processor
+ */
+ public const OTEL_BSP_SCHEDULE_DELAY = 'OTEL_BSP_SCHEDULE_DELAY';
+ public const OTEL_BSP_EXPORT_TIMEOUT = 'OTEL_BSP_EXPORT_TIMEOUT';
+ public const OTEL_BSP_MAX_QUEUE_SIZE = 'OTEL_BSP_MAX_QUEUE_SIZE';
+ public const OTEL_BSP_MAX_EXPORT_BATCH_SIZE = 'OTEL_BSP_MAX_EXPORT_BATCH_SIZE';
+ /**
+ * Batch LogRecord Processor
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#batch-logrecord-processor
+ */
+ public const OTEL_BLRP_SCHEDULE_DELAY = 'OTEL_BLRP_SCHEDULE_DELAY';
+ public const OTEL_BLRP_EXPORT_TIMEOUT = 'OTEL_BLRP_EXPORT_TIMEOUT';
+ public const OTEL_BLRP_MAX_QUEUE_SIZE = 'OTEL_BLRP_MAX_QUEUE_SIZE';
+ public const OTEL_BLRP_MAX_EXPORT_BATCH_SIZE = 'OTEL_BLRP_MAX_EXPORT_BATCH_SIZE';
+ /**
+ * Attribute Limits
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#attribute-limits
+ */
+ public const OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT = 'OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT';
+ public const OTEL_ATTRIBUTE_COUNT_LIMIT = 'OTEL_ATTRIBUTE_COUNT_LIMIT';
+ /**
+ * LogRecord limits
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#logrecord-limits
+ */
+ public const OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT = 'OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT';
+ public const OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT = 'OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT';
+ /**
+ * Span Limits
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#span-limits
+ */
+ public const OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT = 'OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT';
+ public const OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT = 'OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT';
+ public const OTEL_SPAN_EVENT_COUNT_LIMIT = 'OTEL_SPAN_EVENT_COUNT_LIMIT';
+ public const OTEL_SPAN_LINK_COUNT_LIMIT = 'OTEL_SPAN_LINK_COUNT_LIMIT';
+ public const OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT = 'OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT';
+ public const OTEL_LINK_ATTRIBUTE_COUNT_LIMIT = 'OTEL_LINK_ATTRIBUTE_COUNT_LIMIT';
+ /**
+ * OTLP Exporter
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options
+ */
+ // Endpoint
+ public const OTEL_EXPORTER_OTLP_ENDPOINT = 'OTEL_EXPORTER_OTLP_ENDPOINT';
+ public const OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = 'OTEL_EXPORTER_OTLP_TRACES_ENDPOINT';
+ public const OTEL_EXPORTER_OTLP_METRICS_ENDPOINT = 'OTEL_EXPORTER_OTLP_METRICS_ENDPOINT';
+ public const OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = 'OTEL_EXPORTER_OTLP_LOGS_ENDPOINT';
+ // Insecure
+ public const OTEL_EXPORTER_OTLP_INSECURE = 'OTEL_EXPORTER_OTLP_INSECURE';
+ public const OTEL_EXPORTER_OTLP_TRACES_INSECURE = 'OTEL_EXPORTER_OTLP_TRACES_INSECURE';
+ public const OTEL_EXPORTER_OTLP_METRICS_INSECURE = 'OTEL_EXPORTER_OTLP_METRICS_INSECURE';
+ public const OTEL_EXPORTER_OTLP_LOGS_INSECURE = 'OTEL_EXPORTER_OTLP_LOGS_INSECURE';
+ // Certificate File
+ public const OTEL_EXPORTER_OTLP_CERTIFICATE = 'OTEL_EXPORTER_OTLP_CERTIFICATE';
+ public const OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE = 'OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE';
+ public const OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE = 'OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE';
+ public const OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE = 'OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE';
+ // Headers
+ public const OTEL_EXPORTER_OTLP_HEADERS = 'OTEL_EXPORTER_OTLP_HEADERS';
+ public const OTEL_EXPORTER_OTLP_TRACES_HEADERS = 'OTEL_EXPORTER_OTLP_TRACES_HEADERS';
+ public const OTEL_EXPORTER_OTLP_METRICS_HEADERS = 'OTEL_EXPORTER_OTLP_METRICS_HEADERS';
+ public const OTEL_EXPORTER_OTLP_LOGS_HEADERS = 'OTEL_EXPORTER_OTLP_LOGS_HEADERS';
+ // Compression
+ public const OTEL_EXPORTER_OTLP_COMPRESSION = 'OTEL_EXPORTER_OTLP_COMPRESSION';
+ public const OTEL_EXPORTER_OTLP_TRACES_COMPRESSION = 'OTEL_EXPORTER_OTLP_TRACES_COMPRESSION';
+ public const OTEL_EXPORTER_OTLP_METRICS_COMPRESSION = 'OTEL_EXPORTER_OTLP_METRICS_COMPRESSION';
+ public const OTEL_EXPORTER_OTLP_LOGS_COMPRESSION = 'OTEL_EXPORTER_OTLP_LOGS_COMPRESSION';
+ // Timeout
+ public const OTEL_EXPORTER_OTLP_TIMEOUT = 'OTEL_EXPORTER_OTLP_TIMEOUT';
+ public const OTEL_EXPORTER_OTLP_TRACES_TIMEOUT = 'OTEL_EXPORTER_OTLP_TRACES_TIMEOUT';
+ public const OTEL_EXPORTER_OTLP_METRICS_TIMEOUT = 'OTEL_EXPORTER_OTLP_METRICS_TIMEOUT';
+ public const OTEL_EXPORTER_OTLP_LOGS_TIMEOUT = 'OTEL_EXPORTER_OTLP_LOGS_TIMEOUT';
+ // Protocol
+ public const OTEL_EXPORTER_OTLP_PROTOCOL = 'OTEL_EXPORTER_OTLP_PROTOCOL';
+ public const OTEL_EXPORTER_OTLP_TRACES_PROTOCOL = 'OTEL_EXPORTER_OTLP_TRACES_PROTOCOL';
+ public const OTEL_EXPORTER_OTLP_METRICS_PROTOCOL = 'OTEL_EXPORTER_OTLP_METRICS_PROTOCOL';
+ public const OTEL_EXPORTER_OTLP_LOGS_PROTOCOL = 'OTEL_EXPORTER_OTLP_LOGS_PROTOCOL';
+ /**
+ * Zipkin Exporter
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#zipkin-exporter
+ */
+ public const OTEL_EXPORTER_ZIPKIN_ENDPOINT = 'OTEL_EXPORTER_ZIPKIN_ENDPOINT';
+ public const OTEL_EXPORTER_ZIPKIN_TIMEOUT = 'OTEL_EXPORTER_ZIPKIN_TIMEOUT';
+ public const OTEL_EXPORTER_ZIPKIN_PROTOCOL = 'OTEL_EXPORTER_ZIPKIN_PROTOCOL';
+ /**
+ * Prometheus Exporter
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#prometheus-exporter
+ */
+ public const OTEL_EXPORTER_PROMETHEUS_HOST = 'OTEL_EXPORTER_PROMETHEUS_HOST';
+ public const OTEL_EXPORTER_PROMETHEUS_PORT = 'OTEL_EXPORTER_PROMETHEUS_PORT';
+ /**
+ * Exporter Selection
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#exporter-selection
+ */
+ public const OTEL_TRACES_EXPORTER = 'OTEL_TRACES_EXPORTER';
+ public const OTEL_METRICS_EXPORTER = 'OTEL_METRICS_EXPORTER';
+ public const OTEL_LOGS_EXPORTER = 'OTEL_LOGS_EXPORTER';
+ /**
+ * Metrics SDK Configuration
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#metrics-sdk-configuration
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#periodic-exporting-metricreader
+ */
+ public const OTEL_METRICS_EXEMPLAR_FILTER = 'OTEL_METRICS_EXEMPLAR_FILTER';
+ public const OTEL_METRIC_EXPORT_INTERVAL = 'OTEL_METRIC_EXPORT_INTERVAL';
+ public const OTEL_METRIC_EXPORT_TIMEOUT = 'OTEL_METRIC_EXPORT_TIMEOUT';
+ public const OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE = 'OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE';
+ public const OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION = 'OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION';
+ /**
+ * Language Specific Environment Variables
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#language-specific-environment-variables
+ */
+ public const OTEL_PHP_TRACES_PROCESSOR = 'OTEL_PHP_TRACES_PROCESSOR';
+ public const OTEL_PHP_LOGS_PROCESSOR = 'OTEL_PHP_LOGS_PROCESSOR';
+ public const OTEL_PHP_LOG_DESTINATION = 'OTEL_PHP_LOG_DESTINATION';
+ public const OTEL_PHP_DETECTORS = 'OTEL_PHP_DETECTORS';
+ public const OTEL_PHP_AUTOLOAD_ENABLED = 'OTEL_PHP_AUTOLOAD_ENABLED';
+ public const OTEL_PHP_INTERNAL_METRICS_ENABLED = 'OTEL_PHP_INTERNAL_METRICS_ENABLED'; //whether the SDK should emit its own metrics
+ public const OTEL_PHP_DISABLED_INSTRUMENTATIONS = 'OTEL_PHP_DISABLED_INSTRUMENTATIONS';
+}
diff --git a/vendor/open-telemetry/sdk/Common/Dev/Compatibility/README.md b/vendor/open-telemetry/sdk/Common/Dev/Compatibility/README.md
new file mode 100644
index 000000000..661eed3b8
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Dev/Compatibility/README.md
@@ -0,0 +1,14 @@
+# Backwards Compatibility
+
+We aim to provide backward compatibility (without any guarantee) even for alpha releases, however the library will raise notices indicating breaking changes and what to do about them. \
+If you don't want these notices to appear or change the error message level, you can do so by calling:
+```php
+OpenTelemetry\SDK\Common\Dev\Compatibility\Util::setErrorLevel(0)
+```
+to turn messages off completely, or (for example)
+```php
+OpenTelemetry\SDK\Common\Dev\Compatibility\Util::setErrorLevel(E_USER_DEPRECATED)
+```
+to trigger only deprecation notices. Valid error levels are `0` (none), `E_USER_DEPRECATED`, `E_USER_NOTICE`, `E_USER_WARNING` and `E_USER_ERROR` \
+However (as long as in alpha) it is safer to pin a dependency on the library to a specific version and/or make the adjustments
+mentioned in the provided messages, since doing otherwise may break things completely for you in the future!
diff --git a/vendor/open-telemetry/sdk/Common/Dev/Compatibility/Util.php b/vendor/open-telemetry/sdk/Common/Dev/Compatibility/Util.php
new file mode 100644
index 000000000..1a3debfdd
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Dev/Compatibility/Util.php
@@ -0,0 +1,93 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Dev\Compatibility;
+
+class Util
+{
+ public const E_NONE = 0;
+ public const DEFAULT_ERROR_LEVEL = E_USER_NOTICE;
+ public const ERROR_LEVELS = [
+ self::E_NONE,
+ E_USER_DEPRECATED,
+ E_USER_NOTICE,
+ E_USER_WARNING,
+ E_USER_ERROR,
+ ];
+
+ private static int $errorLevel = E_USER_NOTICE;
+
+ public static function setErrorLevel(int $errorLevel = E_USER_NOTICE): void
+ {
+ self::validateErrorLevel($errorLevel);
+
+ self::$errorLevel = $errorLevel;
+ }
+
+ public static function getErrorLevel(): int
+ {
+ return self::$errorLevel;
+ }
+
+ /**
+ * @psalm-suppress ArgumentTypeCoercion
+ */
+ public static function triggerClassDeprecationNotice(string $className, string $alternativeClassName = null): void
+ {
+ if (self::getErrorLevel() === self::E_NONE) {
+ return;
+ }
+
+ $notice = sprintf(
+ 'Class "%s" is deprecated and will be removed in a future release. ',
+ $className
+ );
+
+ if ($alternativeClassName !== null) {
+ $notice .= sprintf('Please, use "%s" instead.', $alternativeClassName);
+ }
+
+ trigger_error($notice, self::$errorLevel);
+ }
+
+ /**
+ * @psalm-suppress ArgumentTypeCoercion
+ */
+ public static function triggerMethodDeprecationNotice(
+ string $methodName,
+ string $alternativeMethodName = null,
+ string $alternativeClassName = null
+ ): void {
+ if (self::getErrorLevel() === self::E_NONE) {
+ return;
+ }
+
+ $notice = sprintf(
+ 'Method "%s " is deprecated and will be removed in a future release. ',
+ $methodName
+ );
+
+ if ($alternativeMethodName !== null) {
+ $method = $alternativeClassName === null
+ ? $alternativeMethodName
+ : sprintf('%s::%s', $alternativeClassName, $alternativeMethodName);
+
+ $notice .= sprintf('Please, use "%s" instead.', $method);
+ }
+
+ trigger_error($notice, self::$errorLevel);
+ }
+
+ private static function validateErrorLevel(int $errorLevel): void
+ {
+ if (!in_array($errorLevel, self::ERROR_LEVELS, true)) {
+ throw new \InvalidArgumentException(
+ sprintf(
+ 'Error level must be one of "%s"',
+ implode('", "', self::ERROR_LEVELS)
+ ),
+ );
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Dev/Compatibility/_load.php b/vendor/open-telemetry/sdk/Common/Dev/Compatibility/_load.php
new file mode 100644
index 000000000..99f86c574
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Dev/Compatibility/_load.php
@@ -0,0 +1,7 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * To add a BC compatibility:
+ * require_once __DIR__ . '/BC/SomeFile.php';
+ */
diff --git a/vendor/open-telemetry/sdk/Common/Exception/StackTraceFormatter.php b/vendor/open-telemetry/sdk/Common/Exception/StackTraceFormatter.php
new file mode 100644
index 000000000..675fc7626
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Exception/StackTraceFormatter.php
@@ -0,0 +1,155 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Exception;
+
+use function basename;
+use function count;
+use function get_class;
+use function sprintf;
+use function str_repeat;
+
+use Throwable;
+
+/**
+ * @psalm-type Frame = array{
+ * function: string,
+ * class: ?class-string,
+ * file: ?string,
+ * line: ?int,
+ * }
+ * @psalm-type Frames = non-empty-list<Frame>
+ */
+final class StackTraceFormatter
+{
+ private function __construct()
+ {
+ }
+
+ /**
+ * Formats an exception in a java-like format.
+ *
+ * @param Throwable $e exception to format
+ * @return string formatted exception
+ *
+ * @see https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Throwable.html#printStackTrace()
+ */
+ public static function format(Throwable $e): string
+ {
+ $s = '';
+ $seen = [];
+
+ /** @var Frames|null $enclosing */
+ $enclosing = null;
+ do {
+ if ($enclosing) {
+ self::writeNewline($s);
+ $s .= 'Caused by: ';
+ }
+ if (isset($seen[spl_object_id($e)])) {
+ $s .= '[CIRCULAR REFERENCE: ';
+ self::writeInlineHeader($s, $e);
+ $s .= ']';
+
+ break;
+ }
+ $seen[spl_object_id($e)] = $e;
+
+ $frames = self::frames($e);
+ self::writeInlineHeader($s, $e);
+ self::writeFrames($s, $frames, $enclosing);
+
+ $enclosing = $frames;
+ } while ($e = $e->getPrevious());
+
+ return $s;
+ }
+
+ /**
+ * @phan-suppress-next-line PhanTypeMismatchDeclaredParam
+ * @param Frames $frames
+ * @phan-suppress-next-line PhanTypeMismatchDeclaredParam
+ * @param Frames|null $enclosing
+ */
+ private static function writeFrames(string &$s, array $frames, ?array $enclosing): void
+ {
+ $n = count($frames);
+ if ($enclosing) {
+ for ($m = count($enclosing);
+ $n && $m && $frames[$n - 1] === $enclosing[$m - 1];
+ $n--, $m--) {
+ }
+ }
+ for ($i = 0; $i < $n; $i++) {
+ $frame = $frames[$i];
+ self::writeNewline($s, 1);
+ $s .= 'at ';
+ if ($frame['class'] !== null) {
+ $s .= self::formatName($frame['class']);
+ $s .= '.';
+ }
+ $s .= self::formatName($frame['function']);
+ $s .= '(';
+ if ($frame['file'] !== null) {
+ $s .= basename($frame['file']);
+ if ($frame['line']) {
+ $s .= ':';
+ $s .= $frame['line'];
+ }
+ } else {
+ $s .= 'Unknown Source';
+ }
+ $s .= ')';
+ }
+ if ($n !== count($frames)) {
+ self::writeNewline($s, 1);
+ $s .= sprintf('... %d more', count($frames) - $n);
+ }
+ }
+
+ private static function writeInlineHeader(string &$s, Throwable $e): void
+ {
+ $s .= self::formatName(get_class($e));
+ if ($e->getMessage() !== '') {
+ $s .= ': ';
+ $s .= $e->getMessage();
+ }
+ }
+
+ private static function writeNewline(string &$s, int $indent = 0): void
+ {
+ $s .= "\n";
+ $s .= str_repeat("\t", $indent);
+ }
+
+ /**
+ * @return Frames
+ *
+ * @psalm-suppress PossiblyUndefinedArrayOffset
+ */
+ private static function frames(Throwable $e): array
+ {
+ $frames = [];
+ $trace = $e->getTrace();
+ $traceCount = count($trace);
+ for ($i = 0; $i < $traceCount + 1; $i++) {
+ $frames[] = [
+ 'function' => $trace[$i]['function'] ?? '{main}',
+ 'class' => $trace[$i]['class'] ?? null,
+ 'file' => $trace[$i - 1]['file'] ?? null,
+ 'line' => $trace[$i - 1]['line'] ?? null,
+ ];
+ }
+ $frames[0]['file'] = $e->getFile();
+ $frames[0]['line'] = $e->getLine();
+
+ /** @var Frames $frames */
+ return $frames;
+ }
+
+ private static function formatName(string $name): string
+ {
+ return strtr($name, ['\\' => '.']);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Export/Http/PsrTransport.php b/vendor/open-telemetry/sdk/Common/Export/Http/PsrTransport.php
new file mode 100644
index 000000000..a53e5b80a
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Export/Http/PsrTransport.php
@@ -0,0 +1,168 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Export\Http;
+
+use function assert;
+use BadMethodCallException;
+use function explode;
+use function in_array;
+use OpenTelemetry\SDK\Common\Export\TransportInterface;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Common\Future\CompletedFuture;
+use OpenTelemetry\SDK\Common\Future\ErrorFuture;
+use OpenTelemetry\SDK\Common\Future\FutureInterface;
+use Psr\Http\Client\ClientInterface;
+use Psr\Http\Client\NetworkExceptionInterface;
+use Psr\Http\Message\RequestFactoryInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\StreamFactoryInterface;
+use RuntimeException;
+use function strtolower;
+use Throwable;
+use function time_nanosleep;
+use function trim;
+
+/**
+ * @psalm-template CONTENT_TYPE of string
+ * @template-implements TransportInterface<CONTENT_TYPE>
+ */
+final class PsrTransport implements TransportInterface
+{
+ private ClientInterface $client;
+ private RequestFactoryInterface $requestFactory;
+ private StreamFactoryInterface $streamFactory;
+
+ private string $endpoint;
+ private string $contentType;
+ private array $headers;
+ private array $compression;
+ private int $retryDelay;
+ private int $maxRetries;
+
+ private bool $closed = false;
+
+ /**
+ * @psalm-param CONTENT_TYPE $contentType
+ */
+ public function __construct(
+ ClientInterface $client,
+ RequestFactoryInterface $requestFactory,
+ StreamFactoryInterface $streamFactory,
+ string $endpoint,
+ string $contentType,
+ array $headers,
+ array $compression,
+ int $retryDelay,
+ int $maxRetries
+ ) {
+ $this->client = $client;
+ $this->requestFactory = $requestFactory;
+ $this->streamFactory = $streamFactory;
+ $this->endpoint = $endpoint;
+ $this->contentType = $contentType;
+ $this->headers = $headers;
+ $this->compression = $compression;
+ $this->retryDelay = $retryDelay;
+ $this->maxRetries = $maxRetries;
+ }
+
+ public function contentType(): string
+ {
+ return $this->contentType;
+ }
+
+ public function send(string $payload, ?CancellationInterface $cancellation = null): FutureInterface
+ {
+ if ($this->closed) {
+ return new ErrorFuture(new BadMethodCallException('Transport closed'));
+ }
+
+ $body = PsrUtils::encode($payload, $this->compression, $appliedEncodings);
+ $request = $this->requestFactory
+ ->createRequest('POST', $this->endpoint)
+ ->withBody($this->streamFactory->createStream($body))
+ ->withHeader('Content-Type', $this->contentType)
+ ;
+ if ($appliedEncodings) {
+ $request = $request->withHeader('Content-Encoding', $appliedEncodings);
+ }
+ foreach ($this->headers as $header => $value) {
+ $request = $request->withAddedHeader($header, $value);
+ }
+
+ for ($retries = 0;; $retries++) {
+ $response = null;
+ $e = null;
+
+ try {
+ $response = $this->client->sendRequest($request);
+ if ($response->getStatusCode() >= 200 && $response->getStatusCode() < 300) {
+ break;
+ }
+
+ if ($response->getStatusCode() >= 400 && $response->getStatusCode() < 500 && !in_array($response->getStatusCode(), [408, 429], true)) {
+ throw new RuntimeException($response->getReasonPhrase(), $response->getStatusCode());
+ }
+ } catch (NetworkExceptionInterface $e) {
+ } catch (Throwable $e) {
+ return new ErrorFuture($e);
+ }
+
+ if ($retries >= $this->maxRetries) {
+ return new ErrorFuture(new RuntimeException('Export retry limit exceeded', 0, $e));
+ }
+
+ $delay = PsrUtils::retryDelay($retries, $this->retryDelay, $response);
+ $sec = (int) $delay;
+ $nsec = (int) (($delay - $sec) * 1e9);
+
+ /** @psalm-suppress ArgumentTypeCoercion */
+ if (time_nanosleep($sec, $nsec) !== true) {
+ return new ErrorFuture(new RuntimeException('Export cancelled', 0, $e));
+ }
+ }
+
+ assert(isset($response));
+
+ try {
+ $body = PsrUtils::decode(
+ $response->getBody()->__toString(),
+ self::parseContentEncoding($response),
+ );
+ } catch (Throwable $e) {
+ return new ErrorFuture($e);
+ }
+
+ return new CompletedFuture($body);
+ }
+
+ private static function parseContentEncoding(ResponseInterface $response): array
+ {
+ $encodings = [];
+ foreach (explode(',', $response->getHeaderLine('Content-Encoding')) as $encoding) {
+ if (($encoding = trim($encoding, " \t")) !== '') {
+ $encodings[] = strtolower($encoding);
+ }
+ }
+
+ return $encodings;
+ }
+
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ if ($this->closed) {
+ return false;
+ }
+
+ $this->closed = true;
+
+ return true;
+ }
+
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ return !$this->closed;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Export/Http/PsrTransportFactory.php b/vendor/open-telemetry/sdk/Common/Export/Http/PsrTransportFactory.php
new file mode 100644
index 000000000..5ef78d82c
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Export/Http/PsrTransportFactory.php
@@ -0,0 +1,74 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Export\Http;
+
+use const FILTER_VALIDATE_URL;
+use function filter_var;
+use Http\Discovery\Psr17FactoryDiscovery;
+use Http\Discovery\Psr18ClientDiscovery;
+use InvalidArgumentException;
+use OpenTelemetry\SDK\Common\Export\TransportFactoryInterface;
+use Psr\Http\Client\ClientInterface;
+use Psr\Http\Message\RequestFactoryInterface;
+use Psr\Http\Message\StreamFactoryInterface;
+
+final class PsrTransportFactory implements TransportFactoryInterface
+{
+ private ClientInterface $client;
+ private RequestFactoryInterface $requestFactory;
+ private StreamFactoryInterface $streamFactory;
+
+ public function __construct(
+ ClientInterface $client,
+ RequestFactoryInterface $requestFactory,
+ StreamFactoryInterface $streamFactory
+ ) {
+ $this->client = $client;
+ $this->requestFactory = $requestFactory;
+ $this->streamFactory = $streamFactory;
+ }
+
+ /**
+ * @phan-suppress PhanTypeMismatchArgumentNullable
+ */
+ public function create(
+ string $endpoint,
+ string $contentType,
+ array $headers = [],
+ $compression = null,
+ float $timeout = 10.,
+ int $retryDelay = 100,
+ int $maxRetries = 3,
+ ?string $cacert = null,
+ ?string $cert = null,
+ ?string $key = null
+ ): PsrTransport {
+ if (!filter_var($endpoint, FILTER_VALIDATE_URL)) {
+ throw new InvalidArgumentException(sprintf('Invalid endpoint url "%s"', $endpoint));
+ }
+ assert(!empty($endpoint));
+
+ return new PsrTransport(
+ $this->client,
+ $this->requestFactory,
+ $this->streamFactory,
+ $endpoint,
+ $contentType,
+ $headers,
+ PsrUtils::compression($compression),
+ $retryDelay,
+ $maxRetries,
+ );
+ }
+
+ public static function discover(): self
+ {
+ return new self(
+ Psr18ClientDiscovery::find(),
+ Psr17FactoryDiscovery::findRequestFactory(),
+ Psr17FactoryDiscovery::findStreamFactory(),
+ );
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Export/Http/PsrUtils.php b/vendor/open-telemetry/sdk/Common/Export/Http/PsrUtils.php
new file mode 100644
index 000000000..eaf2f3b47
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Export/Http/PsrUtils.php
@@ -0,0 +1,175 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Export\Http;
+
+use function array_filter;
+use function array_map;
+use function count;
+use ErrorException;
+use LogicException;
+use function max;
+use OpenTelemetry\SDK\Common\Export\TransportFactoryInterface;
+use Psr\Http\Message\ResponseInterface;
+use function rand;
+use function restore_error_handler;
+use function set_error_handler;
+use function sprintf;
+use function strcasecmp;
+use function strtotime;
+use Throwable;
+use function time;
+use function trim;
+use UnexpectedValueException;
+
+/**
+ * @internal
+ */
+final class PsrUtils
+{
+ /**
+ * @param int $retry zero-indexed attempt number
+ * @param int $retryDelay initial delay in milliseconds
+ * @param ResponseInterface|null $response response of failed request
+ * @return float delay in seconds
+ */
+ public static function retryDelay(int $retry, int $retryDelay, ?ResponseInterface $response = null): float
+ {
+ $delay = $retryDelay << $retry;
+ $delay = rand($delay >> 1, $delay) / 1000;
+
+ return max($delay, self::parseRetryAfter($response));
+ }
+
+ private static function parseRetryAfter(?ResponseInterface $response): int
+ {
+ if (!$response || !$retryAfter = $response->getHeaderLine('Retry-After')) {
+ return 0;
+ }
+
+ $retryAfter = trim($retryAfter, " \t");
+ if ($retryAfter === (string) (int) $retryAfter) {
+ return (int) $retryAfter;
+ }
+
+ if (($time = strtotime($retryAfter)) !== false) {
+ return $time - time();
+ }
+
+ return 0;
+ }
+
+ /**
+ * @param list<string> $encodings
+ * @param array<int, string>|null $appliedEncodings
+ */
+ public static function encode(string $value, array $encodings, ?array &$appliedEncodings = null): string
+ {
+ for ($i = 0, $n = count($encodings); $i < $n; $i++) {
+ if (!$encoder = self::encoder($encodings[$i])) {
+ unset($encodings[$i]);
+
+ continue;
+ }
+
+ try {
+ $value = $encoder($value);
+ } catch (Throwable $e) {
+ unset($encodings[$i]);
+ }
+ }
+
+ $appliedEncodings = $encodings;
+
+ return $value;
+ }
+
+ /**
+ * @param list<string> $encodings
+ */
+ public static function decode(string $value, array $encodings): string
+ {
+ for ($i = count($encodings); --$i >= 0;) {
+ if (strcasecmp($encodings[$i], 'identity') === 0) {
+ continue;
+ }
+ if (!$decoder = self::decoder($encodings[$i])) {
+ throw new UnexpectedValueException(sprintf('Not supported decompression encoding "%s"', $encodings[$i]));
+ }
+
+ $value = $decoder($value);
+ }
+
+ return $value;
+ }
+
+ /**
+ * Resolve an array or CSV of compression types to a list
+ */
+ public static function compression($compression): array
+ {
+ if (is_array($compression)) {
+ return $compression;
+ }
+ if (!$compression) {
+ return [];
+ }
+ if (strpos($compression, ',') === false) {
+ return [$compression];
+ }
+
+ return array_map('trim', explode(',', $compression));
+ }
+
+ private static function encoder(string $encoding): ?callable
+ {
+ static $encoders;
+
+ /** @noinspection SpellCheckingInspection */
+ $encoders ??= array_map(fn (callable $callable): callable => self::throwOnErrorOrFalse($callable), array_filter([
+ TransportFactoryInterface::COMPRESSION_GZIP => 'gzencode',
+ TransportFactoryInterface::COMPRESSION_DEFLATE => 'gzcompress',
+ TransportFactoryInterface::COMPRESSION_BROTLI => 'brotli_compress',
+ ], 'function_exists'));
+
+ return $encoders[$encoding] ?? null;
+ }
+
+ private static function decoder(string $encoding): ?callable
+ {
+ static $decoders;
+
+ /** @noinspection SpellCheckingInspection */
+ $decoders ??= array_map(fn (callable $callable): callable => self::throwOnErrorOrFalse($callable), array_filter([
+ TransportFactoryInterface::COMPRESSION_GZIP => 'gzdecode',
+ TransportFactoryInterface::COMPRESSION_DEFLATE => 'gzuncompress',
+ TransportFactoryInterface::COMPRESSION_BROTLI => 'brotli_uncompress',
+ ], 'function_exists'));
+
+ return $decoders[$encoding] ?? null;
+ }
+
+ private static function throwOnErrorOrFalse(callable $callable): callable
+ {
+ return static function (...$args) use ($callable) {
+ set_error_handler(static function (int $errno, string $errstr, string $errfile, int $errline): bool {
+ throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
+ });
+
+ try {
+ $result = $callable(...$args);
+ } finally {
+ restore_error_handler();
+ }
+
+ /** @phan-suppress-next-line PhanPossiblyUndeclaredVariable */
+ if ($result === false) {
+ throw new LogicException();
+ }
+
+ /** @phan-suppress-next-line PhanPossiblyUndeclaredVariable */
+ return $result;
+ };
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Export/Stream/StreamTransport.php b/vendor/open-telemetry/sdk/Common/Export/Stream/StreamTransport.php
new file mode 100644
index 000000000..4b99cf756
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Export/Stream/StreamTransport.php
@@ -0,0 +1,97 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Export\Stream;
+
+use BadMethodCallException;
+use ErrorException;
+use function fflush;
+use function fwrite;
+use OpenTelemetry\SDK\Common\Export\TransportInterface;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Common\Future\CompletedFuture;
+use OpenTelemetry\SDK\Common\Future\ErrorFuture;
+use OpenTelemetry\SDK\Common\Future\FutureInterface;
+use function restore_error_handler;
+use RuntimeException;
+use function set_error_handler;
+use function strlen;
+use Throwable;
+
+/**
+ * @internal
+ *
+ * @psalm-template CONTENT_TYPE of string
+ * @template-implements TransportInterface<CONTENT_TYPE>
+ */
+final class StreamTransport implements TransportInterface
+{
+ /**
+ * @var resource|null
+ */
+ private $stream;
+ private string $contentType;
+
+ /**
+ * @param resource $stream
+ *
+ * @psalm-param CONTENT_TYPE $contentType
+ */
+ public function __construct($stream, string $contentType)
+ {
+ $this->stream = $stream;
+ $this->contentType = $contentType;
+ }
+
+ public function contentType(): string
+ {
+ return $this->contentType;
+ }
+
+ public function send(string $payload, ?CancellationInterface $cancellation = null): FutureInterface
+ {
+ if (!$this->stream) {
+ return new ErrorFuture(new BadMethodCallException('Transport closed'));
+ }
+
+ set_error_handler(static function (int $errno, string $errstr, string $errfile, int $errline): bool {
+ throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
+ });
+
+ try {
+ $bytesWritten = fwrite($this->stream, $payload);
+ } catch (Throwable $e) {
+ return new ErrorFuture($e);
+ } finally {
+ restore_error_handler();
+ }
+
+ if ($bytesWritten !== strlen($payload)) {
+ return new ErrorFuture(new RuntimeException(sprintf('Write failure, wrote %d of %d bytes', $bytesWritten, strlen($payload))));
+ }
+
+ return new CompletedFuture(null);
+ }
+
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ if (!$this->stream) {
+ return false;
+ }
+
+ $flush = @fflush($this->stream);
+ $this->stream = null;
+
+ return $flush;
+ }
+
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ if (!$this->stream) {
+ return false;
+ }
+
+ return @fflush($this->stream);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Export/Stream/StreamTransportFactory.php b/vendor/open-telemetry/sdk/Common/Export/Stream/StreamTransportFactory.php
new file mode 100644
index 000000000..59e411318
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Export/Stream/StreamTransportFactory.php
@@ -0,0 +1,118 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Export\Stream;
+
+use ErrorException;
+use function fopen;
+use function implode;
+use function is_resource;
+use LogicException;
+use OpenTelemetry\SDK\Common\Export\TransportFactoryInterface;
+use OpenTelemetry\SDK\Common\Export\TransportInterface;
+use function restore_error_handler;
+use function set_error_handler;
+use function sprintf;
+use function stream_context_create;
+
+/**
+ * @psalm-internal \OpenTelemetry
+ */
+final class StreamTransportFactory implements TransportFactoryInterface
+{
+ /**
+ * @param string|resource $endpoint
+ * @param array<string, string|string[]> $headers
+ * @param string|string[]|null $compression
+ *
+ * @psalm-template CONTENT_TYPE of string
+ * @psalm-param CONTENT_TYPE $contentType
+ * @psalm-return TransportInterface<CONTENT_TYPE>
+ */
+ public function create(
+ $endpoint,
+ string $contentType,
+ array $headers = [],
+ $compression = null,
+ float $timeout = 10.,
+ int $retryDelay = 100,
+ int $maxRetries = 3,
+ ?string $cacert = null,
+ ?string $cert = null,
+ ?string $key = null
+ ): TransportInterface {
+ assert(!empty($endpoint));
+ $stream = is_resource($endpoint)
+ ? $endpoint
+ : self::createStream(
+ $endpoint,
+ $contentType,
+ $headers,
+ $timeout,
+ $cacert,
+ $cert,
+ $key,
+ );
+
+ return new StreamTransport($stream, $contentType);
+ }
+
+ /**
+ * @throws ErrorException
+ * @return resource
+ */
+ private static function createStream(
+ string $endpoint,
+ string $contentType,
+ array $headers = [],
+ float $timeout = 10.,
+ ?string $cacert = null,
+ ?string $cert = null,
+ ?string $key = null
+ ) {
+ $context = stream_context_create([
+ 'http' => [
+ 'method' => 'POST',
+ 'header' => self::createHeaderArray($contentType, $headers),
+ 'timeout' => $timeout,
+ ],
+ 'ssl' => [
+ 'cafile' => $cacert,
+ 'local_cert' => $cert,
+ 'local_pk' => $key,
+ ],
+ ]);
+
+ set_error_handler(static function (int $errno, string $errstr, string $errfile, int $errline): bool {
+ throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
+ });
+
+ /**
+ * @psalm-suppress PossiblyNullArgument
+ */
+ try {
+ $stream = fopen($endpoint, 'ab', false, $context);
+ } finally {
+ restore_error_handler();
+ }
+
+ /** @phan-suppress-next-line PhanPossiblyUndeclaredVariable */
+ if (!$stream) {
+ throw new LogicException(sprintf('Failed opening stream "%s"', $endpoint));
+ }
+
+ return $stream;
+ }
+
+ private static function createHeaderArray(string $contentType, array $headers): array
+ {
+ $header = [];
+ $header[] = sprintf('Content-Type: %s', $contentType);
+ foreach ($headers as $name => $value) {
+ $header[] = sprintf('%s: %s', $name, implode(', ', (array) $value));
+ }
+
+ return $header;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Export/TransportFactoryInterface.php b/vendor/open-telemetry/sdk/Common/Export/TransportFactoryInterface.php
new file mode 100644
index 000000000..48e538443
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Export/TransportFactoryInterface.php
@@ -0,0 +1,32 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Export;
+
+interface TransportFactoryInterface
+{
+ public const COMPRESSION_GZIP = 'gzip';
+ public const COMPRESSION_DEFLATE = 'deflate';
+ public const COMPRESSION_BROTLI = 'br';
+
+ /**
+ * @psalm-template CONTENT_TYPE of string
+ * @psalm-param CONTENT_TYPE $contentType
+ * @psalm-param array<string, string|string[]> $headers
+ * @psalm-param string|string[]|null $compression
+ * @psalm-return TransportInterface<CONTENT_TYPE>
+ */
+ public function create(
+ string $endpoint,
+ string $contentType,
+ array $headers = [],
+ $compression = null,
+ float $timeout = 10.,
+ int $retryDelay = 100,
+ int $maxRetries = 3,
+ ?string $cacert = null,
+ ?string $cert = null,
+ ?string $key = null
+ ): TransportInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Common/Export/TransportInterface.php b/vendor/open-telemetry/sdk/Common/Export/TransportInterface.php
new file mode 100644
index 000000000..5fb26eff8
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Export/TransportInterface.php
@@ -0,0 +1,22 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Export;
+
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Common\Future\FutureInterface;
+
+/**
+ * @psalm-template-covariant CONTENT_TYPE of string
+ */
+interface TransportInterface
+{
+ public function contentType(): string;
+
+ public function send(string $payload, ?CancellationInterface $cancellation = null): FutureInterface;
+
+ public function shutdown(?CancellationInterface $cancellation = null): bool;
+
+ public function forceFlush(?CancellationInterface $cancellation = null): bool;
+}
diff --git a/vendor/open-telemetry/sdk/Common/Future/CancellationInterface.php b/vendor/open-telemetry/sdk/Common/Future/CancellationInterface.php
new file mode 100644
index 000000000..16909ec6d
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Future/CancellationInterface.php
@@ -0,0 +1,18 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Future;
+
+use Closure;
+use Throwable;
+
+interface CancellationInterface
+{
+ /**
+ * @param Closure(Throwable): void $callback
+ */
+ public function subscribe(Closure $callback): string;
+
+ public function unsubscribe(string $id): void;
+}
diff --git a/vendor/open-telemetry/sdk/Common/Future/CompletedFuture.php b/vendor/open-telemetry/sdk/Common/Future/CompletedFuture.php
new file mode 100644
index 000000000..7f0cd6536
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Future/CompletedFuture.php
@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Future;
+
+use Closure;
+use Throwable;
+
+/**
+ * @template T
+ * @template-implements FutureInterface<T>
+ */
+final class CompletedFuture implements FutureInterface
+{
+ /** @var T */
+ private $value;
+
+ /**
+ * @param T $value
+ */
+ public function __construct($value)
+ {
+ $this->value = $value;
+ }
+
+ public function await()
+ {
+ return $this->value;
+ }
+
+ public function map(Closure $closure): FutureInterface
+ {
+ $c = $closure;
+ unset($closure);
+
+ try {
+ return new CompletedFuture($c($this->value));
+ } catch (Throwable $e) {
+ return new ErrorFuture($e);
+ }
+ }
+
+ public function catch(Closure $closure): FutureInterface
+ {
+ return $this;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Future/ErrorFuture.php b/vendor/open-telemetry/sdk/Common/Future/ErrorFuture.php
new file mode 100644
index 000000000..32cf3d995
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Future/ErrorFuture.php
@@ -0,0 +1,40 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Future;
+
+use Closure;
+use Throwable;
+
+final class ErrorFuture implements FutureInterface
+{
+ private Throwable $throwable;
+
+ public function __construct(Throwable $throwable)
+ {
+ $this->throwable = $throwable;
+ }
+
+ public function await()
+ {
+ throw $this->throwable;
+ }
+
+ public function map(Closure $closure): FutureInterface
+ {
+ return $this;
+ }
+
+ public function catch(Closure $closure): FutureInterface
+ {
+ $c = $closure;
+ unset($closure);
+
+ try {
+ return new CompletedFuture($c($this->throwable));
+ } catch (Throwable $e) {
+ return new ErrorFuture($e);
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Future/FutureInterface.php b/vendor/open-telemetry/sdk/Common/Future/FutureInterface.php
new file mode 100644
index 000000000..850699bf6
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Future/FutureInterface.php
@@ -0,0 +1,34 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Future;
+
+use Closure;
+
+/**
+ * @template-covariant T
+ */
+interface FutureInterface
+{
+ /**
+ * @psalm-return T
+ */
+ public function await();
+
+ /**
+ * @psalm-template U
+ * @psalm-param Closure(T): U $closure
+ * @psalm-return FutureInterface<U>
+ *
+ * @psalm-suppress InvalidTemplateParam
+ */
+ public function map(Closure $closure): FutureInterface;
+
+ /**
+ * @psalm-template U
+ * @psalm-param Closure(\Throwable): U $closure
+ * @psalm-return FutureInterface<T|U>
+ */
+ public function catch(Closure $closure): FutureInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Common/Future/NullCancellation.php b/vendor/open-telemetry/sdk/Common/Future/NullCancellation.php
new file mode 100644
index 000000000..5e5b642f9
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Future/NullCancellation.php
@@ -0,0 +1,20 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Future;
+
+use Closure;
+
+final class NullCancellation implements CancellationInterface
+{
+ public function subscribe(Closure $callback): string
+ {
+ return self::class;
+ }
+
+ public function unsubscribe(string $id): void
+ {
+ // no-op
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Http/DependencyResolverInterface.php b/vendor/open-telemetry/sdk/Common/Http/DependencyResolverInterface.php
new file mode 100644
index 000000000..824335213
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Http/DependencyResolverInterface.php
@@ -0,0 +1,13 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Http;
+
+use OpenTelemetry\SDK\Common\Http\HttpPlug\Client\ResolverInterface as HttpPlugClientResolverInterface;
+use OpenTelemetry\SDK\Common\Http\Psr\Client\ResolverInterface as PsrClientResolverInterface;
+use OpenTelemetry\SDK\Common\Http\Psr\Message\FactoryResolverInterface;
+
+interface DependencyResolverInterface extends FactoryResolverInterface, PsrClientResolverInterface, HttpPlugClientResolverInterface
+{
+}
diff --git a/vendor/open-telemetry/sdk/Common/Http/HttpPlug/Client/ResolverInterface.php b/vendor/open-telemetry/sdk/Common/Http/HttpPlug/Client/ResolverInterface.php
new file mode 100644
index 000000000..3b2f4d53e
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Http/HttpPlug/Client/ResolverInterface.php
@@ -0,0 +1,12 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Http\HttpPlug\Client;
+
+use Http\Client\HttpAsyncClient;
+
+interface ResolverInterface
+{
+ public function resolveHttpPlugAsyncClient(): HttpAsyncClient;
+}
diff --git a/vendor/open-telemetry/sdk/Common/Http/Psr/Client/ResolverInterface.php b/vendor/open-telemetry/sdk/Common/Http/Psr/Client/ResolverInterface.php
new file mode 100644
index 000000000..ba028e38a
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Http/Psr/Client/ResolverInterface.php
@@ -0,0 +1,12 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Http\Psr\Client;
+
+use Psr\Http\Client\ClientInterface;
+
+interface ResolverInterface
+{
+ public function resolvePsrClient(): ClientInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Common/Http/Psr/Message/FactoryResolverInterface.php b/vendor/open-telemetry/sdk/Common/Http/Psr/Message/FactoryResolverInterface.php
new file mode 100644
index 000000000..4582e19ce
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Http/Psr/Message/FactoryResolverInterface.php
@@ -0,0 +1,22 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Http\Psr\Message;
+
+use Psr\Http\Message\RequestFactoryInterface;
+use Psr\Http\Message\ResponseFactoryInterface;
+use Psr\Http\Message\ServerRequestFactoryInterface;
+use Psr\Http\Message\StreamFactoryInterface;
+use Psr\Http\Message\UploadedFileFactoryInterface;
+use Psr\Http\Message\UriFactoryInterface;
+
+interface FactoryResolverInterface
+{
+ public function resolveRequestFactory(): RequestFactoryInterface;
+ public function resolveResponseFactory(): ResponseFactoryInterface;
+ public function resolveServerRequestFactory(): ServerRequestFactoryInterface;
+ public function resolveStreamFactory(): StreamFactoryInterface;
+ public function resolveUploadedFileFactory(): UploadedFileFactoryInterface;
+ public function resolveUriFactory(): UriFactoryInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Common/Http/Psr/Message/MessageFactory.php b/vendor/open-telemetry/sdk/Common/Http/Psr/Message/MessageFactory.php
new file mode 100644
index 000000000..8e99d64c0
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Http/Psr/Message/MessageFactory.php
@@ -0,0 +1,52 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Http\Psr\Message;
+
+use Psr\Http\Message\RequestFactoryInterface;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseFactoryInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestFactoryInterface;
+use Psr\Http\Message\ServerRequestInterface;
+
+final class MessageFactory implements MessageFactoryInterface
+{
+ private RequestFactoryInterface $requestFactory;
+ private ResponseFactoryInterface $responseFactory;
+ private ServerRequestFactoryInterface $serverRequestFactory;
+
+ public function __construct(
+ RequestFactoryInterface $requestFactory,
+ ResponseFactoryInterface $responseFactory,
+ ServerRequestFactoryInterface $serverRequestFactory
+ ) {
+ $this->requestFactory = $requestFactory;
+ $this->responseFactory = $responseFactory;
+ $this->serverRequestFactory = $serverRequestFactory;
+ }
+
+ public static function create(
+ RequestFactoryInterface $requestFactory,
+ ResponseFactoryInterface $responseFactory,
+ ServerRequestFactoryInterface $serverRequestFactory
+ ): self {
+ return new self($requestFactory, $responseFactory, $serverRequestFactory);
+ }
+
+ public function createRequest(string $method, $uri): RequestInterface
+ {
+ return $this->requestFactory->createRequest($method, $uri);
+ }
+
+ public function createResponse(int $code = 200, string $reasonPhrase = ''): ResponseInterface
+ {
+ return $this->responseFactory->createResponse($code, $reasonPhrase);
+ }
+
+ public function createServerRequest(string $method, $uri, array $serverParams = []): ServerRequestInterface
+ {
+ return $this->serverRequestFactory->createServerRequest($method, $uri, $serverParams);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Http/Psr/Message/MessageFactoryInterface.php b/vendor/open-telemetry/sdk/Common/Http/Psr/Message/MessageFactoryInterface.php
new file mode 100644
index 000000000..97258491f
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Http/Psr/Message/MessageFactoryInterface.php
@@ -0,0 +1,13 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Http\Psr\Message;
+
+use Psr\Http\Message\RequestFactoryInterface;
+use Psr\Http\Message\ResponseFactoryInterface;
+use Psr\Http\Message\ServerRequestFactoryInterface;
+
+interface MessageFactoryInterface extends RequestFactoryInterface, ServerRequestFactoryInterface, ResponseFactoryInterface
+{
+}
diff --git a/vendor/open-telemetry/sdk/Common/Instrumentation/InstrumentationScope.php b/vendor/open-telemetry/sdk/Common/Instrumentation/InstrumentationScope.php
new file mode 100644
index 000000000..ec9b52fb0
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Instrumentation/InstrumentationScope.php
@@ -0,0 +1,46 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Instrumentation;
+
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+/**
+ * Represents the instrumentation scope information associated with the Tracer or Meter
+ */
+final class InstrumentationScope implements InstrumentationScopeInterface
+{
+ private string $name;
+ private ?string $version;
+ private ?string $schemaUrl;
+ private AttributesInterface $attributes;
+
+ public function __construct(string $name, ?string $version, ?string $schemaUrl, AttributesInterface $attributes)
+ {
+ $this->name = $name;
+ $this->version = $version;
+ $this->schemaUrl = $schemaUrl;
+ $this->attributes = $attributes;
+ }
+
+ public function getName(): string
+ {
+ return $this->name;
+ }
+
+ public function getVersion(): ?string
+ {
+ return $this->version;
+ }
+
+ public function getSchemaUrl(): ?string
+ {
+ return $this->schemaUrl;
+ }
+
+ public function getAttributes(): AttributesInterface
+ {
+ return $this->attributes;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Instrumentation/InstrumentationScopeFactory.php b/vendor/open-telemetry/sdk/Common/Instrumentation/InstrumentationScopeFactory.php
new file mode 100644
index 000000000..f1ae7c072
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Instrumentation/InstrumentationScopeFactory.php
@@ -0,0 +1,31 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Instrumentation;
+
+use OpenTelemetry\SDK\Common\Attribute\AttributesFactoryInterface;
+
+final class InstrumentationScopeFactory implements InstrumentationScopeFactoryInterface
+{
+ private AttributesFactoryInterface $attributesFactory;
+
+ public function __construct(AttributesFactoryInterface $attributesFactory)
+ {
+ $this->attributesFactory = $attributesFactory;
+ }
+
+ public function create(
+ string $name,
+ ?string $version = null,
+ ?string $schemaUrl = null,
+ iterable $attributes = []
+ ): InstrumentationScopeInterface {
+ return new InstrumentationScope(
+ $name,
+ $version,
+ $schemaUrl,
+ $this->attributesFactory->builder($attributes)->build(),
+ );
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Instrumentation/InstrumentationScopeFactoryInterface.php b/vendor/open-telemetry/sdk/Common/Instrumentation/InstrumentationScopeFactoryInterface.php
new file mode 100644
index 000000000..78292de58
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Instrumentation/InstrumentationScopeFactoryInterface.php
@@ -0,0 +1,15 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Instrumentation;
+
+interface InstrumentationScopeFactoryInterface
+{
+ public function create(
+ string $name,
+ ?string $version = null,
+ ?string $schemaUrl = null,
+ iterable $attributes = []
+ ): InstrumentationScopeInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Common/Instrumentation/InstrumentationScopeInterface.php b/vendor/open-telemetry/sdk/Common/Instrumentation/InstrumentationScopeInterface.php
new file mode 100644
index 000000000..43ba71d89
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Instrumentation/InstrumentationScopeInterface.php
@@ -0,0 +1,18 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Instrumentation;
+
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+interface InstrumentationScopeInterface
+{
+ public function getName(): string;
+
+ public function getVersion(): ?string;
+
+ public function getSchemaUrl(): ?string;
+
+ public function getAttributes(): AttributesInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Common/Time/ClockFactory.php b/vendor/open-telemetry/sdk/Common/Time/ClockFactory.php
new file mode 100644
index 000000000..33f4364f6
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Time/ClockFactory.php
@@ -0,0 +1,30 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Time;
+
+final class ClockFactory implements ClockFactoryInterface
+{
+ private static ?ClockInterface $default = null;
+
+ public static function create(): self
+ {
+ return new self();
+ }
+
+ public function build(): ClockInterface
+ {
+ return new SystemClock();
+ }
+
+ public static function getDefault(): ClockInterface
+ {
+ return self::$default ?? self::$default = self::create()->build();
+ }
+
+ public static function setDefault(?ClockInterface $clock): void
+ {
+ self::$default = $clock;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Time/ClockFactoryInterface.php b/vendor/open-telemetry/sdk/Common/Time/ClockFactoryInterface.php
new file mode 100644
index 000000000..6d9afde91
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Time/ClockFactoryInterface.php
@@ -0,0 +1,16 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Time;
+
+interface ClockFactoryInterface
+{
+ public static function create(): self;
+
+ public function build(): ClockInterface;
+
+ public static function getDefault(): ClockInterface;
+
+ public static function setDefault(?ClockInterface $clock): void;
+}
diff --git a/vendor/open-telemetry/sdk/Common/Time/ClockInterface.php b/vendor/open-telemetry/sdk/Common/Time/ClockInterface.php
new file mode 100644
index 000000000..8f3170185
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Time/ClockInterface.php
@@ -0,0 +1,19 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Time;
+
+interface ClockInterface
+{
+ public const MILLIS_PER_SECOND = 1_000;
+ public const MICROS_PER_SECOND = 1_000_000;
+ public const NANOS_PER_SECOND = 1_000_000_000;
+ public const NANOS_PER_MILLISECOND = 1_000_000;
+ public const NANOS_PER_MICROSECOND = 1_000;
+
+ /**
+ * Returns the current epoch wall-clock timestamp in nanoseconds
+ */
+ public function now(): int;
+}
diff --git a/vendor/open-telemetry/sdk/Common/Time/StopWatch.php b/vendor/open-telemetry/sdk/Common/Time/StopWatch.php
new file mode 100644
index 000000000..b2abdabae
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Time/StopWatch.php
@@ -0,0 +1,119 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Time;
+
+final class StopWatch implements StopWatchInterface
+{
+ private const INITIAL_ELAPSED_TIME = 0;
+
+ private ClockInterface $clock;
+ private bool $running = false;
+ private ?int $initialStartTime;
+ private ?int $startTime = null;
+ private ?int $stopTime = null;
+
+ public function __construct(ClockInterface $clock, ?int $initialStartTime = null)
+ {
+ $this->clock = $clock;
+ $this->initialStartTime = $initialStartTime;
+ }
+
+ public function isRunning(): bool
+ {
+ return $this->running;
+ }
+
+ public function start(): void
+ {
+ // resolve start time as early as possible
+ $startTime = $this->time();
+
+ if ($this->isRunning()) {
+ return;
+ }
+
+ $this->startTime = $startTime;
+ if (!$this->hasBeenStarted()) {
+ $this->initialStartTime = $startTime;
+ }
+ $this->running = true;
+ }
+
+ public function stop(): void
+ {
+ if (!$this->isRunning()) {
+ return;
+ }
+
+ $this->stopTime = $this->time();
+ $this->running = false;
+ }
+
+ public function reset(): void
+ {
+ $this->startTime = $this->initialStartTime = $this->isRunning() ? $this->time() : null;
+ }
+
+ public function getElapsedTime(): int
+ {
+ if (!$this->hasBeenStarted()) {
+ return self::INITIAL_ELAPSED_TIME;
+ }
+
+ return $this->calculateElapsedTime();
+ }
+
+ public function getLastElapsedTime(): int
+ {
+ if (!$this->hasBeenStarted()) {
+ return self::INITIAL_ELAPSED_TIME;
+ }
+
+ return $this->calculateLastElapsedTime();
+ }
+
+ private function time(): int
+ {
+ return $this->clock->now();
+ }
+
+ private function hasBeenStarted(): bool
+ {
+ return $this->initialStartTime !== null;
+ }
+
+ private function calculateElapsedTime(): int
+ {
+ $referenceTime = $this->isRunning()
+ ? $this->time()
+ : $this->getStopTime();
+
+ return $referenceTime - $this->getInitialStartTime();
+ }
+
+ private function calculateLastElapsedTime(): int
+ {
+ $referenceTime = $this->isRunning()
+ ? $this->time()
+ : $this->getStopTime();
+
+ return $referenceTime - $this->getStartTime();
+ }
+
+ private function getInitialStartTime(): ?int
+ {
+ return $this->initialStartTime;
+ }
+
+ private function getStartTime(): ?int
+ {
+ return $this->startTime;
+ }
+
+ private function getStopTime(): ?int
+ {
+ return $this->stopTime;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Time/StopWatchFactory.php b/vendor/open-telemetry/sdk/Common/Time/StopWatchFactory.php
new file mode 100644
index 000000000..f60c377fc
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Time/StopWatchFactory.php
@@ -0,0 +1,44 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Time;
+
+final class StopWatchFactory implements StopWatchFactoryInterface
+{
+ private static ?StopWatchInterface $default = null;
+
+ private ClockInterface $clock;
+ private ?int $initialStartTime;
+
+ public function __construct(?ClockInterface $clock = null, ?int $initialStartTime = null)
+ {
+ $this->clock = $clock ?? ClockFactory::getDefault();
+ $this->initialStartTime = $initialStartTime;
+ }
+
+ public static function create(?ClockInterface $clock = null, ?int $initialStartTime = null): self
+ {
+ return new self($clock, $initialStartTime);
+ }
+
+ public static function fromClockFactory(ClockFactoryInterface $factory, ?int $initialStartTime = null): self
+ {
+ return self::create($factory->build(), $initialStartTime);
+ }
+
+ public function build(): StopWatch
+ {
+ return new StopWatch($this->clock, $this->initialStartTime);
+ }
+
+ public static function getDefault(): StopWatchInterface
+ {
+ return self::$default ?? self::$default = self::create()->build();
+ }
+
+ public static function setDefault(?StopWatchInterface $default): void
+ {
+ self::$default = $default;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Time/StopWatchFactoryInterface.php b/vendor/open-telemetry/sdk/Common/Time/StopWatchFactoryInterface.php
new file mode 100644
index 000000000..9750f5769
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Time/StopWatchFactoryInterface.php
@@ -0,0 +1,18 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Time;
+
+interface StopWatchFactoryInterface
+{
+ public static function create(?ClockInterface $clock = null, ?int $initialStartTime = null): self;
+
+ public static function fromClockFactory(ClockFactoryInterface $factory, ?int $initialStartTime = null): self;
+
+ public function build(): StopWatchInterface;
+
+ public static function getDefault(): StopWatchInterface;
+
+ public static function setDefault(?StopWatchInterface $default): void;
+}
diff --git a/vendor/open-telemetry/sdk/Common/Time/StopWatchInterface.php b/vendor/open-telemetry/sdk/Common/Time/StopWatchInterface.php
new file mode 100644
index 000000000..69a03b75e
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Time/StopWatchInterface.php
@@ -0,0 +1,20 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Time;
+
+interface StopWatchInterface
+{
+ public function isRunning(): bool;
+
+ public function start(): void;
+
+ public function stop(): void;
+
+ public function reset(): void;
+
+ public function getElapsedTime(): int;
+
+ public function getLastElapsedTime(): int;
+}
diff --git a/vendor/open-telemetry/sdk/Common/Time/SystemClock.php b/vendor/open-telemetry/sdk/Common/Time/SystemClock.php
new file mode 100644
index 000000000..f57e98490
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Time/SystemClock.php
@@ -0,0 +1,49 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Time;
+
+use function hrtime;
+use function microtime;
+
+final class SystemClock implements ClockInterface
+{
+ private static int $referenceTime = 0;
+
+ public function __construct()
+ {
+ self::init();
+ }
+
+ public static function create(): self
+ {
+ return new self();
+ }
+
+ /** @inheritDoc */
+ public function now(): int
+ {
+ return self::$referenceTime + hrtime(true);
+ }
+
+ private static function init(): void
+ {
+ if (self::$referenceTime > 0) {
+ return;
+ }
+
+ self::$referenceTime = self::calculateReferenceTime(
+ microtime(true),
+ hrtime(true)
+ );
+ }
+
+ /**
+ * Calculates the reference time which is later used to calculate the current wall clock time in nanoseconds by adding the current uptime.
+ */
+ private static function calculateReferenceTime(float $wallClockMicroTime, int $upTime): int
+ {
+ return ((int) ($wallClockMicroTime * ClockInterface::NANOS_PER_SECOND)) - $upTime;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Time/Util.php b/vendor/open-telemetry/sdk/Common/Time/Util.php
new file mode 100644
index 000000000..e1be1f750
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Time/Util.php
@@ -0,0 +1,32 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Time;
+
+class Util
+{
+ /** @psalm-pure */
+ public static function nanosToMicros(int $nanoseconds): int
+ {
+ return intdiv($nanoseconds, ClockInterface::NANOS_PER_MICROSECOND);
+ }
+
+ /** @psalm-pure */
+ public static function nanosToMillis(int $nanoseconds): int
+ {
+ return intdiv($nanoseconds, ClockInterface::NANOS_PER_MILLISECOND);
+ }
+
+ /** @psalm-pure */
+ public static function secondsToNanos(int $seconds): int
+ {
+ return $seconds * ClockInterface::NANOS_PER_SECOND;
+ }
+
+ /** @psalm-pure */
+ public static function millisToNanos(int $milliSeconds): int
+ {
+ return $milliSeconds * ClockInterface::NANOS_PER_MILLISECOND;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Util/ClassConstantAccessor.php b/vendor/open-telemetry/sdk/Common/Util/ClassConstantAccessor.php
new file mode 100644
index 000000000..237e70ba5
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Util/ClassConstantAccessor.php
@@ -0,0 +1,35 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Util;
+
+use LogicException;
+
+class ClassConstantAccessor
+{
+ public static function requireValue(string $className, string $constantName)
+ {
+ $constant = self::getFullName($className, $constantName);
+
+ if (!defined($constant)) {
+ throw new LogicException(
+ sprintf('The class "%s" does not have a constant "%s"', $className, $constantName)
+ );
+ }
+
+ return constant($constant);
+ }
+
+ public static function getValue(string $className, string $constantName)
+ {
+ $constant = self::getFullName($className, $constantName);
+
+ return defined($constant) ? constant($constant) : null;
+ }
+
+ private static function getFullName(string $className, string $constantName): string
+ {
+ return sprintf('%s::%s', $className, $constantName);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Util/ShutdownHandler.php b/vendor/open-telemetry/sdk/Common/Util/ShutdownHandler.php
new file mode 100644
index 000000000..2de6d47df
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Util/ShutdownHandler.php
@@ -0,0 +1,82 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Util;
+
+use function array_key_last;
+use ArrayAccess;
+use Closure;
+use function register_shutdown_function;
+
+final class ShutdownHandler
+{
+ /** @var array<int, Closure>|null */
+ private static ?array $handlers = null;
+ /** @var ArrayAccess<object, self>|null */
+ private static ?ArrayAccess $weakMap = null;
+
+ private array $ids = [];
+
+ private function __construct()
+ {
+ }
+
+ public function __destruct()
+ {
+ if (!self::$handlers) {
+ return;
+ }
+ foreach ($this->ids as $id) {
+ unset(self::$handlers[$id]);
+ }
+ }
+
+ /**
+ * Registers a function that will be executed on shutdown.
+ *
+ * If the given function is bound to an object, then the function will only
+ * be executed if the bound object is still referenced on shutdown handler
+ * invocation.
+ *
+ * ```php
+ * ShutdownHandler::register([$tracerProvider, 'shutdown']);
+ * ```
+ *
+ * @param callable $shutdownFunction function to register
+ *
+ * @see register_shutdown_function
+ */
+ public static function register(callable $shutdownFunction): void
+ {
+ self::registerShutdownFunction();
+ self::$handlers[] = weaken(closure($shutdownFunction), $target);
+
+ if (!$object = $target) {
+ return;
+ }
+
+ self::$weakMap ??= WeakMap::create();
+ $handler = self::$weakMap[$object] ??= new self();
+ $handler->ids[] = array_key_last(self::$handlers);
+ }
+
+ private static function registerShutdownFunction(): void
+ {
+ if (self::$handlers === null) {
+ register_shutdown_function(static function (): void {
+ $handlers = self::$handlers;
+ self::$handlers = null;
+ self::$weakMap = null;
+
+ // Push shutdown to end of queue
+ // @phan-suppress-next-line PhanTypeMismatchArgumentInternal
+ register_shutdown_function(static function (array $handlers): void {
+ foreach ($handlers as $handler) {
+ $handler();
+ }
+ }, $handlers);
+ });
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Util/WeakMap.php b/vendor/open-telemetry/sdk/Common/Util/WeakMap.php
new file mode 100644
index 000000000..3b62d6d64
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Util/WeakMap.php
@@ -0,0 +1,175 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Util;
+
+use ArrayAccess;
+use function assert;
+use function class_exists;
+use function count;
+use Countable;
+use Error;
+use function get_class;
+use function is_object;
+use IteratorAggregate;
+use const PHP_VERSION_ID;
+use function spl_object_id;
+use function sprintf;
+use Traversable;
+use TypeError;
+use WeakReference;
+
+/**
+ * @internal
+ */
+final class WeakMap implements ArrayAccess, Countable, IteratorAggregate
+{
+ private const KEY = '__otel_weak_map';
+
+ /**
+ * @var array<int, WeakReference>
+ */
+ private array $objects = [];
+
+ private function __construct()
+ {
+ }
+
+ /**
+ * @return ArrayAccess&Countable&IteratorAggregate
+ */
+ public static function create(): ArrayAccess
+ {
+ if (PHP_VERSION_ID >= 80000) {
+ /** @phan-suppress-next-line PhanUndeclaredClassReference */
+ assert(class_exists(\WeakMap::class, false));
+ /** @phan-suppress-next-line PhanUndeclaredClassMethod */
+ $map = new \WeakMap();
+ assert($map instanceof ArrayAccess);
+ assert($map instanceof Countable);
+ assert($map instanceof IteratorAggregate);
+
+ return $map;
+ }
+
+ return new self();
+ }
+
+ public function offsetExists($offset): bool
+ {
+ if (!is_object($offset)) {
+ throw new TypeError('WeakMap key must be an object');
+ }
+
+ return isset($offset->{self::KEY}[spl_object_id($this)]);
+ }
+
+ /**
+ * @phan-suppress PhanUndeclaredClassAttribute
+ */
+ #[\ReturnTypeWillChange]
+ public function offsetGet($offset)
+ {
+ if (!is_object($offset)) {
+ throw new TypeError('WeakMap key must be an object');
+ }
+ if (!$this->contains($offset)) {
+ throw new Error(sprintf('Object %s#%d not contained in WeakMap', get_class($offset), spl_object_id($offset)));
+ }
+
+ return $offset->{self::KEY}[spl_object_id($this)];
+ }
+
+ public function offsetSet($offset, $value): void
+ {
+ if ($offset === null) {
+ throw new Error('Cannot append to WeakMap');
+ }
+ if (!is_object($offset)) {
+ throw new TypeError('WeakMap key must be an object');
+ }
+ if (!$this->contains($offset)) {
+ $this->expunge();
+ }
+
+ $offset->{self::KEY}[spl_object_id($this)] = $value;
+ $this->objects[spl_object_id($offset)] = WeakReference::create($offset);
+ }
+
+ public function offsetUnset($offset): void
+ {
+ if (!is_object($offset)) {
+ throw new TypeError('WeakMap key must be an object');
+ }
+ if (!$this->contains($offset)) {
+ return;
+ }
+
+ unset(
+ $offset->{self::KEY}[spl_object_id($this)],
+ $this->objects[spl_object_id($offset)],
+ );
+ if (!$offset->{self::KEY}) {
+ unset($offset->{self::KEY});
+ }
+ }
+
+ public function count(): int
+ {
+ $this->expunge();
+
+ return count($this->objects);
+ }
+
+ public function getIterator(): Traversable
+ {
+ $this->expunge();
+
+ foreach ($this->objects as $reference) {
+ if (($object = $reference->get()) && $this->contains($object)) {
+ yield $object => $this[$object];
+ }
+ }
+ }
+
+ public function __debugInfo(): array
+ {
+ $debugInfo = [];
+ foreach ($this as $key => $value) {
+ $debugInfo[] = ['key' => $key, 'value' => $value];
+ }
+
+ return $debugInfo;
+ }
+
+ public function __destruct()
+ {
+ foreach ($this->objects as $reference) {
+ if ($object = $reference->get()) {
+ unset($this[$object]);
+ }
+ }
+ }
+
+ private function contains(object $offset): bool
+ {
+ $reference = $this->objects[spl_object_id($offset)] ?? null;
+ if ($reference && $reference->get() === $offset) {
+ return true;
+ }
+
+ unset($this->objects[spl_object_id($offset)]);
+
+ return false;
+ }
+
+ private function expunge(): void
+ {
+ foreach ($this->objects as $id => $reference) {
+ if (!$reference->get()) {
+ unset($this->objects[$id]);
+ }
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Common/Util/functions.php b/vendor/open-telemetry/sdk/Common/Util/functions.php
new file mode 100644
index 000000000..f4fb13b80
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Common/Util/functions.php
@@ -0,0 +1,52 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Common\Util;
+
+use Closure;
+use function get_class;
+use ReflectionFunction;
+use stdClass;
+use WeakReference;
+
+/**
+ * @internal
+ */
+function closure(callable $callable): Closure
+{
+ return Closure::fromCallable($callable);
+}
+
+/**
+ * @internal
+ * @see https://github.com/amphp/amp/blob/f682341c856b1f688026f787bef4f77eaa5c7970/src/functions.php#L140-L191
+ */
+function weaken(Closure $closure, ?object &$target = null): Closure
+{
+ $reflection = new ReflectionFunction($closure);
+ if (!$target = $reflection->getClosureThis()) {
+ return $closure;
+ }
+
+ $scope = $reflection->getClosureScopeClass();
+ $name = $reflection->getShortName();
+ if ($name !== '{closure}') {
+ /** @psalm-suppress InvalidScope @phpstan-ignore-next-line @phan-suppress-next-line PhanUndeclaredThis */
+ $closure = fn (...$args) => $this->$name(...$args);
+ if ($scope !== null) {
+ $closure = $closure->bindTo(null, $scope->name);
+ }
+ }
+
+ static $placeholder;
+ $placeholder ??= new stdClass();
+ $closure = $closure->bindTo($placeholder);
+
+ $ref = WeakReference::create($target);
+
+ /** @psalm-suppress PossiblyInvalidFunctionCall */
+ return $scope && get_class($target) === $scope->name && !$scope->isInternal()
+ ? static fn (...$args) => ($obj = $ref->get()) ? $closure->call($obj, ...$args) : null
+ : static fn (...$args) => ($obj = $ref->get()) ? $closure->bindTo($obj)(...$args) : null;
+}
diff --git a/vendor/open-telemetry/sdk/Logs/Exporter/ConsoleExporter.php b/vendor/open-telemetry/sdk/Logs/Exporter/ConsoleExporter.php
new file mode 100644
index 000000000..e34fa308c
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/Exporter/ConsoleExporter.php
@@ -0,0 +1,106 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs\Exporter;
+
+use OpenTelemetry\SDK\Common\Export\TransportInterface;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Common\Future\CompletedFuture;
+use OpenTelemetry\SDK\Common\Future\FutureInterface;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Logs\LogRecordExporterInterface;
+use OpenTelemetry\SDK\Logs\ReadableLogRecord;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+
+/**
+ * A JSON console exporter for LogRecords. This is only useful for testing; the
+ * output is human-readable, and is not compatible with the OTLP format.
+ */
+class ConsoleExporter implements LogRecordExporterInterface
+{
+ private TransportInterface $transport;
+
+ public function __construct(TransportInterface $transport)
+ {
+ $this->transport = $transport;
+ }
+
+ /**
+ * @param iterable<mixed, ReadableLogRecord> $batch
+ */
+ public function export(iterable $batch, ?CancellationInterface $cancellation = null): FutureInterface
+ {
+ $resource = null;
+ $scopes = [];
+ foreach ($batch as $record) {
+ if (!$resource) {
+ $resource = $this->convertResource($record->getResource());
+ }
+ $key = $this->scopeKey($record->getInstrumentationScope());
+ if (!array_key_exists($key, $scopes)) {
+ $scopes[$key] = $this->convertInstrumentationScope($record->getInstrumentationScope());
+ }
+ $scopes[$key]['logs'][] = $this->convertLogRecord($record);
+ }
+ $output = [
+ 'resource' => $resource,
+ 'scopes' => array_values($scopes),
+ ];
+ $this->transport->send(json_encode($output, JSON_PRETTY_PRINT));
+
+ return new CompletedFuture(true);
+ }
+
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ return true;
+ }
+
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ return true;
+ }
+ private function convertLogRecord(ReadableLogRecord $record): array
+ {
+ $spanContext = $record->getSpanContext();
+
+ return [
+ 'timestamp' => $record->getTimestamp(),
+ 'observed_timestamp' => $record->getObservedTimestamp(),
+ 'severity_number' => $record->getSeverityNumber(),
+ 'severity_text' => $record->getSeverityText(),
+ 'body' => $record->getBody(),
+ 'trace_id' => $spanContext !== null ? $spanContext->getTraceId() : '',
+ 'span_id' => $spanContext !== null ? $spanContext->getSpanId() : '',
+ 'trace_flags' => $spanContext !== null ? $spanContext->getTraceFlags() : null,
+ 'attributes' => $record->getAttributes()->toArray(),
+ 'dropped_attributes_count' => $record->getAttributes()->getDroppedAttributesCount(),
+ ];
+ }
+
+ private function convertResource(ResourceInfo $resource): array
+ {
+ return [
+ 'attributes' => $resource->getAttributes()->toArray(),
+ 'dropped_attributes_count' => $resource->getAttributes()->getDroppedAttributesCount(),
+ ];
+ }
+
+ private function scopeKey(InstrumentationScopeInterface $scope): string
+ {
+ return serialize([$scope->getName(), $scope->getVersion(), $scope->getSchemaUrl(), $scope->getAttributes()]);
+ }
+
+ private function convertInstrumentationScope(InstrumentationScopeInterface $scope): array
+ {
+ return [
+ 'name' => $scope->getName(),
+ 'version' => $scope->getVersion(),
+ 'attributes' => $scope->getAttributes()->toArray(),
+ 'dropped_attributes_count' => $scope->getAttributes()->getDroppedAttributesCount(),
+ 'schema_url' => $scope->getSchemaUrl(),
+ 'logs' => [],
+ ];
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Logs/Exporter/ConsoleExporterFactory.php b/vendor/open-telemetry/sdk/Logs/Exporter/ConsoleExporterFactory.php
new file mode 100644
index 000000000..a959540a0
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/Exporter/ConsoleExporterFactory.php
@@ -0,0 +1,19 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs\Exporter;
+
+use OpenTelemetry\SDK\Logs\LogRecordExporterFactoryInterface;
+use OpenTelemetry\SDK\Logs\LogRecordExporterInterface;
+use OpenTelemetry\SDK\Registry;
+
+class ConsoleExporterFactory implements LogRecordExporterFactoryInterface
+{
+ public function create(): LogRecordExporterInterface
+ {
+ $transport = Registry::transportFactory('stream')->create('php://stdout', 'application/json');
+
+ return new ConsoleExporter($transport);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Logs/Exporter/InMemoryExporter.php b/vendor/open-telemetry/sdk/Logs/Exporter/InMemoryExporter.php
new file mode 100644
index 000000000..dca0531f3
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/Exporter/InMemoryExporter.php
@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs\Exporter;
+
+use ArrayObject;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Common\Future\CompletedFuture;
+use OpenTelemetry\SDK\Common\Future\FutureInterface;
+use OpenTelemetry\SDK\Logs\LogRecordExporterInterface;
+
+class InMemoryExporter implements LogRecordExporterInterface
+{
+ private ArrayObject $storage;
+
+ public function __construct(?ArrayObject $storage = null)
+ {
+ $this->storage = $storage ?? new ArrayObject();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function export(iterable $batch, ?CancellationInterface $cancellation = null): FutureInterface
+ {
+ foreach ($batch as $record) {
+ $this->storage[] = $record;
+ }
+
+ return new CompletedFuture(true);
+ }
+
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ return true;
+ }
+
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ return true;
+ }
+
+ public function getStorage(): ArrayObject
+ {
+ return $this->storage;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Logs/Exporter/InMemoryExporterFactory.php b/vendor/open-telemetry/sdk/Logs/Exporter/InMemoryExporterFactory.php
new file mode 100644
index 000000000..6f24defe0
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/Exporter/InMemoryExporterFactory.php
@@ -0,0 +1,16 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs\Exporter;
+
+use OpenTelemetry\SDK\Logs\LogRecordExporterFactoryInterface;
+use OpenTelemetry\SDK\Logs\LogRecordExporterInterface;
+
+class InMemoryExporterFactory implements LogRecordExporterFactoryInterface
+{
+ public function create(): LogRecordExporterInterface
+ {
+ return new InMemoryExporter();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Logs/Exporter/NoopExporter.php b/vendor/open-telemetry/sdk/Logs/Exporter/NoopExporter.php
new file mode 100644
index 000000000..8eeff62bd
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/Exporter/NoopExporter.php
@@ -0,0 +1,28 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs\Exporter;
+
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Common\Future\CompletedFuture;
+use OpenTelemetry\SDK\Common\Future\FutureInterface;
+use OpenTelemetry\SDK\Logs\LogRecordExporterInterface;
+
+class NoopExporter implements LogRecordExporterInterface
+{
+ public function export(iterable $batch, ?CancellationInterface $cancellation = null): FutureInterface
+ {
+ return new CompletedFuture(true);
+ }
+
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ return true;
+ }
+
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ return true;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Logs/Exporter/_register.php b/vendor/open-telemetry/sdk/Logs/Exporter/_register.php
new file mode 100644
index 000000000..96958baa8
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/Exporter/_register.php
@@ -0,0 +1,6 @@
+<?php
+
+declare(strict_types=1);
+
+\OpenTelemetry\SDK\Registry::registerLogRecordExporterFactory('console', \OpenTelemetry\SDK\Logs\Exporter\ConsoleExporterFactory::class);
+\OpenTelemetry\SDK\Registry::registerLogRecordExporterFactory('memory', \OpenTelemetry\SDK\Logs\Exporter\InMemoryExporterFactory::class);
diff --git a/vendor/open-telemetry/sdk/Logs/ExporterFactory.php b/vendor/open-telemetry/sdk/Logs/ExporterFactory.php
new file mode 100644
index 000000000..2a560ae95
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/ExporterFactory.php
@@ -0,0 +1,29 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs;
+
+use InvalidArgumentException;
+use OpenTelemetry\SDK\Common\Configuration\Configuration;
+use OpenTelemetry\SDK\Common\Configuration\Variables;
+use OpenTelemetry\SDK\Logs\Exporter\NoopExporter;
+use OpenTelemetry\SDK\Registry;
+
+class ExporterFactory
+{
+ public function create(): LogRecordExporterInterface
+ {
+ $exporters = Configuration::getList(Variables::OTEL_LOGS_EXPORTER);
+ if (1 !== count($exporters)) {
+ throw new InvalidArgumentException(sprintf('Configuration %s requires exactly 1 exporter', Variables::OTEL_TRACES_EXPORTER));
+ }
+ $exporter = $exporters[0];
+ if ($exporter === 'none') {
+ return new NoopExporter();
+ }
+ $factory = Registry::logRecordExporterFactory($exporter);
+
+ return $factory->create();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Logs/LogRecordExporterFactoryInterface.php b/vendor/open-telemetry/sdk/Logs/LogRecordExporterFactoryInterface.php
new file mode 100644
index 000000000..523bec1ba
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/LogRecordExporterFactoryInterface.php
@@ -0,0 +1,10 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs;
+
+interface LogRecordExporterFactoryInterface
+{
+ public function create(): LogRecordExporterInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Logs/LogRecordExporterInterface.php b/vendor/open-telemetry/sdk/Logs/LogRecordExporterInterface.php
new file mode 100644
index 000000000..cf9e1aca8
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/LogRecordExporterInterface.php
@@ -0,0 +1,18 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs;
+
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Common\Future\FutureInterface;
+
+interface LogRecordExporterInterface
+{
+ /**
+ * @param iterable<ReadableLogRecord> $batch
+ */
+ public function export(iterable $batch, ?CancellationInterface $cancellation = null): FutureInterface;
+ public function forceFlush(?CancellationInterface $cancellation = null): bool;
+ public function shutdown(?CancellationInterface $cancellation = null): bool;
+}
diff --git a/vendor/open-telemetry/sdk/Logs/LogRecordLimits.php b/vendor/open-telemetry/sdk/Logs/LogRecordLimits.php
new file mode 100644
index 000000000..9f71e62ee
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/LogRecordLimits.php
@@ -0,0 +1,29 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs;
+
+use OpenTelemetry\SDK\Common\Attribute\AttributesFactoryInterface;
+
+/**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/sdk.md#logrecord-limits
+ */
+class LogRecordLimits
+{
+ private AttributesFactoryInterface $attributesFactory;
+
+ /**
+ * @internal Use {@see SpanLimitsBuilder} to create {@see SpanLimits} instance.
+ */
+ public function __construct(
+ AttributesFactoryInterface $attributesFactory
+ ) {
+ $this->attributesFactory = $attributesFactory;
+ }
+
+ public function getAttributeFactory(): AttributesFactoryInterface
+ {
+ return $this->attributesFactory;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Logs/LogRecordLimitsBuilder.php b/vendor/open-telemetry/sdk/Logs/LogRecordLimitsBuilder.php
new file mode 100644
index 000000000..3aa5217ef
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/LogRecordLimitsBuilder.php
@@ -0,0 +1,58 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs;
+
+use OpenTelemetry\SDK\Common\Attribute\Attributes;
+use OpenTelemetry\SDK\Common\Configuration\Configuration;
+use OpenTelemetry\SDK\Common\Configuration\Variables;
+use const PHP_INT_MAX;
+
+class LogRecordLimitsBuilder
+{
+ /** @var ?int Maximum allowed attribute count per record */
+ private ?int $attributeCountLimit = null;
+
+ /** @var ?int Maximum allowed attribute value length */
+ private ?int $attributeValueLengthLimit = null;
+
+ /**
+ * @param int $attributeCountLimit Maximum allowed attribute count per record
+ */
+ public function setAttributeCountLimit(int $attributeCountLimit): LogRecordLimitsBuilder
+ {
+ $this->attributeCountLimit = $attributeCountLimit;
+
+ return $this;
+ }
+
+ /**
+ * @param int $attributeValueLengthLimit Maximum allowed attribute value length
+ */
+ public function setAttributeValueLengthLimit(int $attributeValueLengthLimit): LogRecordLimitsBuilder
+ {
+ $this->attributeValueLengthLimit = $attributeValueLengthLimit;
+
+ return $this;
+ }
+
+ /**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#attribute-limits
+ */
+ public function build(): LogRecordLimits
+ {
+ $attributeCountLimit = $this->attributeCountLimit
+ ?: Configuration::getInt(Variables::OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT);
+ $attributeValueLengthLimit = $this->attributeValueLengthLimit
+ ?: Configuration::getInt(Variables::OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT);
+
+ if ($attributeValueLengthLimit === PHP_INT_MAX) {
+ $attributeValueLengthLimit = null;
+ }
+
+ $attributesFactory = Attributes::factory($attributeCountLimit, $attributeValueLengthLimit);
+
+ return new LogRecordLimits($attributesFactory);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Logs/LogRecordProcessorFactory.php b/vendor/open-telemetry/sdk/Logs/LogRecordProcessorFactory.php
new file mode 100644
index 000000000..dec463735
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/LogRecordProcessorFactory.php
@@ -0,0 +1,62 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs;
+
+use InvalidArgumentException;
+use OpenTelemetry\API\Metrics\MeterProviderInterface;
+use OpenTelemetry\SDK\Common\Configuration\Configuration;
+use OpenTelemetry\SDK\Common\Configuration\KnownValues;
+use OpenTelemetry\SDK\Common\Configuration\KnownValues as Values;
+use OpenTelemetry\SDK\Common\Configuration\Variables;
+use OpenTelemetry\SDK\Common\Time\ClockFactory;
+use OpenTelemetry\SDK\Logs\Processor\BatchLogRecordProcessor;
+use OpenTelemetry\SDK\Logs\Processor\MultiLogRecordProcessor;
+use OpenTelemetry\SDK\Logs\Processor\NoopLogRecordProcessor;
+use OpenTelemetry\SDK\Logs\Processor\SimpleLogRecordProcessor;
+
+class LogRecordProcessorFactory
+{
+ public function create(LogRecordExporterInterface $exporter, ?MeterProviderInterface $meterProvider = null): LogRecordProcessorInterface
+ {
+ $processors = [];
+ $list = Configuration::getList(Variables::OTEL_PHP_LOGS_PROCESSOR);
+ foreach ($list as $name) {
+ $processors[] = $this->createProcessor($name, $exporter, $meterProvider);
+ }
+
+ switch (count($processors)) {
+ case 0:
+ return NoopLogRecordProcessor::getInstance();
+ case 1:
+ return $processors[0];
+ default:
+ return new MultiLogRecordProcessor($processors);
+ }
+ }
+
+ private function createProcessor(string $name, LogRecordExporterInterface $exporter, ?MeterProviderInterface $meterProvider = null): LogRecordProcessorInterface
+ {
+ switch ($name) {
+ case KnownValues::VALUE_BATCH:
+ return new BatchLogRecordProcessor(
+ $exporter,
+ ClockFactory::getDefault(),
+ Configuration::getInt(Variables::OTEL_BLRP_MAX_QUEUE_SIZE),
+ Configuration::getInt(Variables::OTEL_BLRP_SCHEDULE_DELAY),
+ Configuration::getInt(Variables::OTEL_BLRP_EXPORT_TIMEOUT),
+ Configuration::getInt(Variables::OTEL_BLRP_MAX_EXPORT_BATCH_SIZE),
+ true,
+ $meterProvider,
+ );
+ case KnownValues::VALUE_SIMPLE:
+ return new SimpleLogRecordProcessor($exporter);
+ case Values::VALUE_NOOP:
+ case Values::VALUE_NONE:
+ return NoopLogRecordProcessor::getInstance();
+ default:
+ throw new InvalidArgumentException('Unknown processor: ' . $name);
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Logs/LogRecordProcessorInterface.php b/vendor/open-telemetry/sdk/Logs/LogRecordProcessorInterface.php
new file mode 100644
index 000000000..1977d48fd
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/LogRecordProcessorInterface.php
@@ -0,0 +1,15 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+
+interface LogRecordProcessorInterface
+{
+ public function onEmit(ReadWriteLogRecord $record, ?ContextInterface $context = null): void;
+ public function shutdown(?CancellationInterface $cancellation = null): bool;
+ public function forceFlush(?CancellationInterface $cancellation = null): bool;
+}
diff --git a/vendor/open-telemetry/sdk/Logs/Logger.php b/vendor/open-telemetry/sdk/Logs/Logger.php
new file mode 100644
index 000000000..0b8db152d
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/Logger.php
@@ -0,0 +1,37 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs;
+
+use OpenTelemetry\API\Logs\LoggerInterface;
+use OpenTelemetry\API\Logs\LogRecord;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+
+/**
+ * Note that this logger class is deliberately NOT psr-3 compatible, per spec: "Note: this document defines a log
+ * backend API. The API is not intended to be called by application developers directly."
+ *
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/bridge-api.md
+ */
+class Logger implements LoggerInterface
+{
+ private InstrumentationScopeInterface $scope;
+ private LoggerSharedState $loggerSharedState;
+
+ public function __construct(LoggerSharedState $loggerSharedState, InstrumentationScopeInterface $scope)
+ {
+ $this->loggerSharedState = $loggerSharedState;
+ $this->scope = $scope;
+ }
+
+ public function emit(LogRecord $logRecord): void
+ {
+ $readWriteLogRecord = new ReadWriteLogRecord($this->scope, $this->loggerSharedState, $logRecord);
+ // @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/sdk.md#onemit
+ $this->loggerSharedState->getProcessor()->onEmit(
+ $readWriteLogRecord,
+ $readWriteLogRecord->getContext(),
+ );
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Logs/LoggerProvider.php b/vendor/open-telemetry/sdk/Logs/LoggerProvider.php
new file mode 100644
index 000000000..f0a8266c1
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/LoggerProvider.php
@@ -0,0 +1,56 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs;
+
+use OpenTelemetry\API\Logs\LoggerInterface;
+use OpenTelemetry\API\Logs\NoopLogger;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeFactoryInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
+
+class LoggerProvider implements LoggerProviderInterface
+{
+ private LoggerSharedState $loggerSharedState;
+ private InstrumentationScopeFactoryInterface $instrumentationScopeFactory;
+
+ public function __construct(LogRecordProcessorInterface $processor, InstrumentationScopeFactoryInterface $instrumentationScopeFactory, ?ResourceInfo $resource = null)
+ {
+ $this->loggerSharedState = new LoggerSharedState(
+ $resource ?? ResourceInfoFactory::defaultResource(),
+ (new LogRecordLimitsBuilder())->build(),
+ $processor
+ );
+ $this->instrumentationScopeFactory = $instrumentationScopeFactory;
+ }
+
+ /**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/sdk.md#logger-creation
+ */
+ public function getLogger(string $name, ?string $version = null, ?string $schemaUrl = null, iterable $attributes = []): LoggerInterface
+ {
+ if ($this->loggerSharedState->hasShutdown()) {
+ return NoopLogger::getInstance();
+ }
+ $scope = $this->instrumentationScopeFactory->create($name, $version, $schemaUrl, $attributes);
+
+ return new Logger($this->loggerSharedState, $scope);
+ }
+
+ public function shutdown(CancellationInterface $cancellation = null): bool
+ {
+ return $this->loggerSharedState->shutdown($cancellation);
+ }
+
+ public function forceFlush(CancellationInterface $cancellation = null): bool
+ {
+ return $this->loggerSharedState->forceFlush($cancellation);
+ }
+
+ public static function builder(): LoggerProviderBuilder
+ {
+ return new LoggerProviderBuilder();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Logs/LoggerProviderBuilder.php b/vendor/open-telemetry/sdk/Logs/LoggerProviderBuilder.php
new file mode 100644
index 000000000..37c56245c
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/LoggerProviderBuilder.php
@@ -0,0 +1,55 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs;
+
+use OpenTelemetry\SDK\Common\Attribute\Attributes;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeFactory;
+use OpenTelemetry\SDK\Logs\Processor\MultiLogRecordProcessor;
+use OpenTelemetry\SDK\Logs\Processor\NoopLogRecordProcessor;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+
+class LoggerProviderBuilder
+{
+ /**
+ * @var array<LogRecordProcessorInterface>
+ */
+ private array $processors = [];
+ private ?ResourceInfo $resource = null;
+
+ public function addLogRecordProcessor(LogRecordProcessorInterface $processor): self
+ {
+ $this->processors[] = $processor;
+
+ return $this;
+ }
+
+ public function setResource(ResourceInfo $resource): self
+ {
+ $this->resource = $resource;
+
+ return $this;
+ }
+
+ public function build(): LoggerProviderInterface
+ {
+ return new LoggerProvider(
+ $this->buildProcessor(),
+ new InstrumentationScopeFactory(Attributes::factory()),
+ $this->resource
+ );
+ }
+
+ private function buildProcessor(): LogRecordProcessorInterface
+ {
+ switch (count($this->processors)) {
+ case 0:
+ return NoopLogRecordProcessor::getInstance();
+ case 1:
+ return $this->processors[0];
+ default:
+ return new MultiLogRecordProcessor($this->processors);
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Logs/LoggerProviderFactory.php b/vendor/open-telemetry/sdk/Logs/LoggerProviderFactory.php
new file mode 100644
index 000000000..3d0e965fd
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/LoggerProviderFactory.php
@@ -0,0 +1,24 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs;
+
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeFactory;
+use OpenTelemetry\SDK\Metrics\MeterProviderInterface;
+use OpenTelemetry\SDK\Sdk;
+
+class LoggerProviderFactory
+{
+ public function create(?MeterProviderInterface $meterProvider = null): LoggerProviderInterface
+ {
+ if (Sdk::isDisabled()) {
+ return NoopLoggerProvider::getInstance();
+ }
+ $exporter = (new ExporterFactory())->create();
+ $processor = (new LogRecordProcessorFactory())->create($exporter, $meterProvider);
+ $instrumentationScopeFactory = new InstrumentationScopeFactory((new LogRecordLimitsBuilder())->build()->getAttributeFactory());
+
+ return new LoggerProvider($processor, $instrumentationScopeFactory);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Logs/LoggerProviderInterface.php b/vendor/open-telemetry/sdk/Logs/LoggerProviderInterface.php
new file mode 100644
index 000000000..5debb13cc
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/LoggerProviderInterface.php
@@ -0,0 +1,13 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs;
+
+use OpenTelemetry\API\Logs as API;
+
+interface LoggerProviderInterface extends API\LoggerProviderInterface
+{
+ public function shutdown(): bool;
+ public function forceFlush(): bool;
+}
diff --git a/vendor/open-telemetry/sdk/Logs/LoggerSharedState.php b/vendor/open-telemetry/sdk/Logs/LoggerSharedState.php
new file mode 100644
index 000000000..aeeb45518
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/LoggerSharedState.php
@@ -0,0 +1,60 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs;
+
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+
+class LoggerSharedState
+{
+ private ResourceInfo $resource;
+ private LogRecordProcessorInterface $processor;
+ private LogRecordLimits $limits;
+ private ?bool $shutdownResult = null;
+
+ public function __construct(
+ ResourceInfo $resource,
+ LogRecordLimits $limits,
+ LogRecordProcessorInterface $processor
+ ) {
+ $this->resource = $resource;
+ $this->limits = $limits;
+ $this->processor = $processor;
+ }
+ public function hasShutdown(): bool
+ {
+ return null !== $this->shutdownResult;
+ }
+
+ public function getResource(): ResourceInfo
+ {
+ return $this->resource;
+ }
+
+ public function getProcessor(): LogRecordProcessorInterface
+ {
+ return $this->processor;
+ }
+
+ public function getLogRecordLimits(): LogRecordLimits
+ {
+ return $this->limits;
+ }
+
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ if ($this->shutdownResult !== null) {
+ return $this->shutdownResult;
+ }
+ $this->shutdownResult = $this->processor->shutdown($cancellation);
+
+ return $this->shutdownResult;
+ }
+
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ return $this->processor->forceFlush($cancellation);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Logs/NoopLoggerProvider.php b/vendor/open-telemetry/sdk/Logs/NoopLoggerProvider.php
new file mode 100644
index 000000000..819e02ee5
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/NoopLoggerProvider.php
@@ -0,0 +1,33 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs;
+
+use OpenTelemetry\API\Logs\LoggerInterface;
+use OpenTelemetry\API\Logs\NoopLogger;
+
+class NoopLoggerProvider implements LoggerProviderInterface
+{
+ public static function getInstance(): self
+ {
+ static $instance;
+
+ return $instance ??= new self();
+ }
+
+ public function getLogger(string $name, ?string $version = null, ?string $schemaUrl = null, iterable $attributes = []): LoggerInterface
+ {
+ return NoopLogger::getInstance();
+ }
+
+ public function shutdown(): bool
+ {
+ return true;
+ }
+
+ public function forceFlush(): bool
+ {
+ return true;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Logs/Processor/BatchLogRecordProcessor.php b/vendor/open-telemetry/sdk/Logs/Processor/BatchLogRecordProcessor.php
new file mode 100644
index 000000000..fc6faca54
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/Processor/BatchLogRecordProcessor.php
@@ -0,0 +1,273 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs\Processor;
+
+use InvalidArgumentException;
+use OpenTelemetry\API\Behavior\LogsMessagesTrait;
+use OpenTelemetry\API\Metrics\MeterProviderInterface;
+use OpenTelemetry\API\Metrics\ObserverInterface;
+use OpenTelemetry\Context\Context;
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Common\Time\ClockInterface;
+use OpenTelemetry\SDK\Logs\LogRecordExporterInterface;
+use OpenTelemetry\SDK\Logs\LogRecordProcessorInterface;
+use OpenTelemetry\SDK\Logs\ReadWriteLogRecord;
+use SplQueue;
+use Throwable;
+
+class BatchLogRecordProcessor implements LogRecordProcessorInterface
+{
+ use LogsMessagesTrait;
+
+ public const DEFAULT_SCHEDULE_DELAY = 1000;
+ public const DEFAULT_EXPORT_TIMEOUT = 30000;
+ public const DEFAULT_MAX_QUEUE_SIZE = 2048;
+ public const DEFAULT_MAX_EXPORT_BATCH_SIZE = 512;
+
+ private const ATTRIBUTES_PROCESSOR = ['processor' => 'batching'];
+ private const ATTRIBUTES_QUEUED = self::ATTRIBUTES_PROCESSOR + ['state' => 'queued'];
+ private const ATTRIBUTES_PENDING = self::ATTRIBUTES_PROCESSOR + ['state' => 'pending'];
+ private const ATTRIBUTES_PROCESSED = self::ATTRIBUTES_PROCESSOR + ['state' => 'processed'];
+ private const ATTRIBUTES_DROPPED = self::ATTRIBUTES_PROCESSOR + ['state' => 'dropped'];
+ private const ATTRIBUTES_FREE = self::ATTRIBUTES_PROCESSOR + ['state' => 'free'];
+
+ private LogRecordExporterInterface $exporter;
+ private ClockInterface $clock;
+ private int $maxQueueSize;
+ private int $scheduledDelayNanos;
+ private int $maxExportBatchSize;
+ private bool $autoFlush;
+ private ContextInterface $exportContext;
+
+ private ?int $nextScheduledRun = null;
+ private bool $running = false;
+ private int $dropped = 0;
+ private int $processed = 0;
+ private int $batchId = 0;
+ private int $queueSize = 0;
+ /** @var list<ReadWriteLogRecord> */
+ private array $batch = [];
+ /** @var SplQueue<list<ReadWriteLogRecord>> */
+ private SplQueue $queue;
+ /** @var SplQueue<array{int, string, ?CancellationInterface, bool, ContextInterface}> */
+ private SplQueue $flush;
+
+ private bool $closed = false;
+
+ public function __construct(
+ LogRecordExporterInterface $exporter,
+ ClockInterface $clock,
+ int $maxQueueSize = self::DEFAULT_MAX_QUEUE_SIZE,
+ int $scheduledDelayMillis = self::DEFAULT_SCHEDULE_DELAY,
+ int $exportTimeoutMillis = self::DEFAULT_EXPORT_TIMEOUT,
+ int $maxExportBatchSize = self::DEFAULT_MAX_EXPORT_BATCH_SIZE,
+ bool $autoFlush = true,
+ ?MeterProviderInterface $meterProvider = null
+ ) {
+ if ($maxQueueSize <= 0) {
+ throw new InvalidArgumentException(sprintf('Maximum queue size (%d) must be greater than zero', $maxQueueSize));
+ }
+ if ($scheduledDelayMillis <= 0) {
+ throw new InvalidArgumentException(sprintf('Scheduled delay (%d) must be greater than zero', $scheduledDelayMillis));
+ }
+ if ($exportTimeoutMillis <= 0) {
+ throw new InvalidArgumentException(sprintf('Export timeout (%d) must be greater than zero', $exportTimeoutMillis));
+ }
+ if ($maxExportBatchSize <= 0) {
+ throw new InvalidArgumentException(sprintf('Maximum export batch size (%d) must be greater than zero', $maxExportBatchSize));
+ }
+ if ($maxExportBatchSize > $maxQueueSize) {
+ throw new InvalidArgumentException(sprintf('Maximum export batch size (%d) must be less than or equal to maximum queue size (%d)', $maxExportBatchSize, $maxQueueSize));
+ }
+
+ $this->exporter = $exporter;
+ $this->clock = $clock;
+ $this->maxQueueSize = $maxQueueSize;
+ $this->scheduledDelayNanos = $scheduledDelayMillis * 1_000_000;
+ $this->maxExportBatchSize = $maxExportBatchSize;
+ $this->autoFlush = $autoFlush;
+
+ $this->exportContext = Context::getCurrent();
+ $this->queue = new SplQueue();
+ $this->flush = new SplQueue();
+
+ if ($meterProvider === null) {
+ return;
+ }
+
+ $meter = $meterProvider->getMeter('io.opentelemetry.sdk');
+ $meter
+ ->createObservableUpDownCounter(
+ 'otel.logs.log_processor.logs',
+ '{logs}',
+ 'The number of log records received by the processor',
+ )
+ ->observe(function (ObserverInterface $observer): void {
+ $queued = $this->queue->count() * $this->maxExportBatchSize + count($this->batch);
+ $pending = $this->queueSize - $queued;
+ $processed = $this->processed;
+ $dropped = $this->dropped;
+
+ $observer->observe($queued, self::ATTRIBUTES_QUEUED);
+ $observer->observe($pending, self::ATTRIBUTES_PENDING);
+ $observer->observe($processed, self::ATTRIBUTES_PROCESSED);
+ $observer->observe($dropped, self::ATTRIBUTES_DROPPED);
+ });
+ $meter
+ ->createObservableUpDownCounter(
+ 'otel.logs.log_processor.queue.limit',
+ '{logs}',
+ 'The queue size limit',
+ )
+ ->observe(function (ObserverInterface $observer): void {
+ $observer->observe($this->maxQueueSize, self::ATTRIBUTES_PROCESSOR);
+ });
+ $meter
+ ->createObservableUpDownCounter(
+ 'otel.logs.log_processor.queue.usage',
+ '{logs}',
+ 'The current queue usage',
+ )
+ ->observe(function (ObserverInterface $observer): void {
+ $queued = $this->queue->count() * $this->maxExportBatchSize + count($this->batch);
+ $pending = $this->queueSize - $queued;
+ $free = $this->maxQueueSize - $this->queueSize;
+
+ $observer->observe($queued, self::ATTRIBUTES_QUEUED);
+ $observer->observe($pending, self::ATTRIBUTES_PENDING);
+ $observer->observe($free, self::ATTRIBUTES_FREE);
+ });
+ }
+
+ public function onEmit(ReadWriteLogRecord $record, ?ContextInterface $context = null): void
+ {
+ if ($this->closed) {
+ return;
+ }
+
+ if ($this->queueSize === $this->maxQueueSize) {
+ $this->dropped++;
+
+ return;
+ }
+
+ $this->queueSize++;
+ $this->batch[] = $record;
+ $this->nextScheduledRun ??= $this->clock->now() + $this->scheduledDelayNanos;
+
+ if (count($this->batch) === $this->maxExportBatchSize) {
+ $this->enqueueBatch();
+ }
+ if ($this->autoFlush) {
+ $this->flush();
+ }
+ }
+
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ if ($this->closed) {
+ return false;
+ }
+
+ return $this->flush(__FUNCTION__, $cancellation);
+ }
+
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ if ($this->closed) {
+ return false;
+ }
+
+ $this->closed = true;
+
+ return $this->flush(__FUNCTION__, $cancellation);
+ }
+
+ private function flush(?string $flushMethod = null, ?CancellationInterface $cancellation = null): bool
+ {
+ if ($flushMethod !== null) {
+ $flushId = $this->batchId + $this->queue->count() + (int) (bool) $this->batch;
+ $this->flush->enqueue([$flushId, $flushMethod, $cancellation, !$this->running, Context::getCurrent()]);
+ }
+
+ if ($this->running) {
+ return false;
+ }
+
+ $success = true;
+ $exception = null;
+ $this->running = true;
+
+ try {
+ for (;;) {
+ while (!$this->flush->isEmpty() && $this->flush->bottom()[0] <= $this->batchId) {
+ [, $flushMethod, $cancellation, $propagateResult, $context] = $this->flush->dequeue();
+ $scope = $context->activate();
+
+ try {
+ $result = $this->exporter->$flushMethod($cancellation);
+ if ($propagateResult) {
+ $success = $result;
+ }
+ } catch (Throwable $e) {
+ if ($propagateResult) {
+ $exception = $e;
+ } else {
+ self::logError(sprintf('Unhandled %s error', $flushMethod), ['exception' => $e]);
+ }
+ } finally {
+ $scope->detach();
+ }
+ }
+
+ if (!$this->shouldFlush()) {
+ break;
+ }
+
+ if ($this->queue->isEmpty()) {
+ $this->enqueueBatch();
+ }
+ $batchSize = count($this->queue->bottom());
+ $this->batchId++;
+ $scope = $this->exportContext->activate();
+
+ try {
+ $this->exporter->export($this->queue->dequeue())->await();
+ } catch (Throwable $e) {
+ self::logError('Unhandled export error', ['exception' => $e]);
+ } finally {
+ $this->processed += $batchSize;
+ $this->queueSize -= $batchSize;
+ $scope->detach();
+ }
+ }
+ } finally {
+ $this->running = false;
+ }
+
+ if ($exception !== null) {
+ throw $exception;
+ }
+
+ return $success;
+ }
+
+ private function shouldFlush(): bool
+ {
+ return !$this->flush->isEmpty()
+ || $this->autoFlush && !$this->queue->isEmpty()
+ || $this->autoFlush && $this->nextScheduledRun !== null && $this->clock->now() > $this->nextScheduledRun;
+ }
+
+ private function enqueueBatch(): void
+ {
+ assert($this->batch !== []);
+
+ $this->queue->enqueue($this->batch);
+ $this->batch = [];
+ $this->nextScheduledRun = null;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Logs/Processor/MultiLogRecordProcessor.php b/vendor/open-telemetry/sdk/Logs/Processor/MultiLogRecordProcessor.php
new file mode 100644
index 000000000..753a75df8
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/Processor/MultiLogRecordProcessor.php
@@ -0,0 +1,62 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs\Processor;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Logs\LogRecordProcessorInterface;
+use OpenTelemetry\SDK\Logs\ReadWriteLogRecord;
+
+class MultiLogRecordProcessor implements LogRecordProcessorInterface
+{
+ // @var LogRecordProcessorInterface[]
+ private array $processors = [];
+
+ public function __construct(array $processors)
+ {
+ foreach ($processors as $processor) {
+ assert($processor instanceof LogRecordProcessorInterface);
+ $this->processors[] = $processor;
+ }
+ }
+
+ public function onEmit(ReadWriteLogRecord $record, ?ContextInterface $context = null): void
+ {
+ foreach ($this->processors as $processor) {
+ $processor->onEmit($record, $context);
+ }
+ }
+
+ /**
+ * Returns `true` if all processors shut down successfully, else `false`
+ * Subsequent calls to `shutdown` are a no-op.
+ */
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ $result = true;
+ foreach ($this->processors as $processor) {
+ if (!$processor->shutdown($cancellation)) {
+ $result = false;
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * Returns `true` if all processors flush successfully, else `false`.
+ */
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ $result = true;
+ foreach ($this->processors as $processor) {
+ if (!$processor->forceFlush($cancellation)) {
+ $result = false;
+ }
+ }
+
+ return $result;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Logs/Processor/NoopLogRecordProcessor.php b/vendor/open-telemetry/sdk/Logs/Processor/NoopLogRecordProcessor.php
new file mode 100644
index 000000000..7028052e1
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/Processor/NoopLogRecordProcessor.php
@@ -0,0 +1,37 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs\Processor;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Logs\LogRecordProcessorInterface;
+use OpenTelemetry\SDK\Logs\ReadWriteLogRecord;
+
+class NoopLogRecordProcessor implements LogRecordProcessorInterface
+{
+ public static function getInstance(): self
+ {
+ static $instance;
+
+ return $instance ??= new self();
+ }
+
+ /**
+ * @codeCoverageIgnore
+ */
+ public function onEmit(ReadWriteLogRecord $record, ?ContextInterface $context = null): void
+ {
+ }
+
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ return true;
+ }
+
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ return true;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Logs/Processor/SimpleLogRecordProcessor.php b/vendor/open-telemetry/sdk/Logs/Processor/SimpleLogRecordProcessor.php
new file mode 100644
index 000000000..f26f6607c
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/Processor/SimpleLogRecordProcessor.php
@@ -0,0 +1,38 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs\Processor;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Logs\LogRecordExporterInterface;
+use OpenTelemetry\SDK\Logs\LogRecordProcessorInterface;
+use OpenTelemetry\SDK\Logs\ReadWriteLogRecord;
+
+class SimpleLogRecordProcessor implements LogRecordProcessorInterface
+{
+ private LogRecordExporterInterface $exporter;
+ public function __construct(LogRecordExporterInterface $exporter)
+ {
+ $this->exporter = $exporter;
+ }
+
+ /**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/sdk.md#onemit
+ */
+ public function onEmit(ReadWriteLogRecord $record, ?ContextInterface $context = null): void
+ {
+ $this->exporter->export([$record]);
+ }
+
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ return $this->exporter->shutdown($cancellation);
+ }
+
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ return $this->exporter->forceFlush($cancellation);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Logs/PsrSeverityMapperInterface.php b/vendor/open-telemetry/sdk/Logs/PsrSeverityMapperInterface.php
new file mode 100644
index 000000000..3bb288c56
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/PsrSeverityMapperInterface.php
@@ -0,0 +1,50 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs;
+
+use Psr\Log\LogLevel as PsrLogLevel;
+
+interface PsrSeverityMapperInterface
+{
+ /**
+ * Severity code according to rfc5424 (Syslog Protocol)
+ * @see : https://datatracker.ietf.org/doc/html/rfc5424#page-10
+ */
+ public const RFC_CODE = [
+ // Detailed debug information.
+ PsrLogLevel::DEBUG => 7,
+ // Interesting events. Examples: User logs in, SQL logs.
+ PsrLogLevel::INFO => 6,
+ // Normal but significant events.
+ PsrLogLevel::NOTICE => 5,
+ // Exceptional occurrences that are not errors. Examples: Use of deprecated APIs, poor use of an API,
+ // undesirable things that are not necessarily wrong.
+ PsrLogLevel::WARNING => 4,
+ // Runtime errors that do not require immediate action but should typically be logged and monitored.
+ PsrLogLevel::ERROR => 3,
+ // Critical conditions. Example: Application component unavailable, unexpected exception.
+ PsrLogLevel::CRITICAL => 2,
+ // Action must be taken immediately. Example: Entire website down, database unavailable, etc.
+ // This should trigger the alerts and wake you up.
+ PsrLogLevel::ALERT => 1,
+ // Emergency: system is unusable.
+ PsrLogLevel::EMERGENCY => 0,
+ ];
+
+ /**
+ * Mappig of OpenTelemetry SeverityNumber to PsrLogLevel.
+ * @see: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/specification/logs/data-model.md#field-severitynumber
+ */
+ public const SEVERITY_NUMBER = [
+ PsrLogLevel::DEBUG => 5,
+ PsrLogLevel::INFO => 9,
+ PsrLogLevel::NOTICE => 10,
+ PsrLogLevel::WARNING => 13,
+ PsrLogLevel::ERROR => 17,
+ PsrLogLevel::CRITICAL => 18,
+ PsrLogLevel::ALERT => 21,
+ PsrLogLevel::EMERGENCY => 22,
+ ];
+}
diff --git a/vendor/open-telemetry/sdk/Logs/ReadWriteLogRecord.php b/vendor/open-telemetry/sdk/Logs/ReadWriteLogRecord.php
new file mode 100644
index 000000000..9bb4b1564
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/ReadWriteLogRecord.php
@@ -0,0 +1,9 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs;
+
+class ReadWriteLogRecord extends ReadableLogRecord
+{
+}
diff --git a/vendor/open-telemetry/sdk/Logs/ReadableLogRecord.php b/vendor/open-telemetry/sdk/Logs/ReadableLogRecord.php
new file mode 100644
index 000000000..5c6531477
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/ReadableLogRecord.php
@@ -0,0 +1,103 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs;
+
+use OpenTelemetry\API\Logs\LogRecord;
+use OpenTelemetry\API\Trace\Span;
+use OpenTelemetry\API\Trace\SpanContextInterface;
+use OpenTelemetry\Context\Context;
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Common\Attribute\LogRecordAttributeValidator;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+
+/**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#log-and-event-record-definition
+ * "Note: Typically this will be implemented with a new interface or (immutable) value type."
+ */
+class ReadableLogRecord extends LogRecord
+{
+ private InstrumentationScopeInterface $scope;
+ private LoggerSharedState $loggerSharedState;
+ protected AttributesInterface $convertedAttributes;
+ protected SpanContextInterface $spanContext;
+
+ public function __construct(InstrumentationScopeInterface $scope, LoggerSharedState $loggerSharedState, LogRecord $logRecord)
+ {
+ $this->scope = $scope;
+ $this->loggerSharedState = $loggerSharedState;
+
+ parent::__construct($logRecord->body);
+ $this->timestamp = $logRecord->timestamp;
+ $this->observedTimestamp = $logRecord->observedTimestamp
+ ?? (int) (microtime(true) * LogRecord::NANOS_PER_SECOND);
+ $this->context = $logRecord->context;
+ $context = $this->context ?? Context::getCurrent();
+ $this->spanContext = Span::fromContext($context)->getContext();
+ $this->severityNumber = $logRecord->severityNumber;
+ $this->severityText = $logRecord->severityText;
+
+ //convert attributes now so that excess data is not sent to processors
+ $this->convertedAttributes = $this->loggerSharedState
+ ->getLogRecordLimits()
+ ->getAttributeFactory()
+ ->builder($logRecord->attributes, new LogRecordAttributeValidator())
+ ->build();
+ }
+
+ public function getInstrumentationScope(): InstrumentationScopeInterface
+ {
+ return $this->scope;
+ }
+
+ public function getResource(): ResourceInfo
+ {
+ return $this->loggerSharedState->getResource();
+ }
+
+ public function getTimestamp(): ?int
+ {
+ return $this->timestamp;
+ }
+
+ public function getObservedTimestamp(): ?int
+ {
+ return $this->observedTimestamp;
+ }
+
+ public function getContext(): ?ContextInterface
+ {
+ return $this->context;
+ }
+
+ public function getSpanContext(): ?SpanContextInterface
+ {
+ return $this->spanContext;
+ }
+
+ public function getSeverityNumber(): ?int
+ {
+ return $this->severityNumber;
+ }
+
+ public function getSeverityText(): ?string
+ {
+ return $this->severityText;
+ }
+
+ /**
+ * @return mixed|null
+ */
+ public function getBody()
+ {
+ return $this->body;
+ }
+
+ public function getAttributes(): AttributesInterface
+ {
+ return $this->convertedAttributes;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Logs/SimplePsrFileLogger.php b/vendor/open-telemetry/sdk/Logs/SimplePsrFileLogger.php
new file mode 100644
index 000000000..9d9d55de6
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Logs/SimplePsrFileLogger.php
@@ -0,0 +1,83 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Logs;
+
+use Psr\Log\InvalidArgumentException;
+use Psr\Log\LoggerInterface;
+use Psr\Log\LoggerTrait;
+use Psr\Log\LogLevel;
+use ReflectionClass;
+use Throwable;
+
+class SimplePsrFileLogger implements LoggerInterface
+{
+ use LoggerTrait;
+
+ private const DEFAULT_LOGGER_NAME = 'otel';
+
+ private static ?array $logLevels = null;
+
+ private string $filename;
+
+ private string $loggerName ;
+
+ /**
+ * @param string $filename
+ */
+ public function __construct(string $filename, string $loggerName = self::DEFAULT_LOGGER_NAME)
+ {
+ $this->filename = $filename;
+ $this->loggerName = $loggerName;
+ }
+
+ /**
+ * @psalm-suppress MoreSpecificImplementedParamType
+ */
+ public function log($level, $message, array $context = []): void
+ {
+ $level = strtolower($level);
+
+ if (!in_array($level, self::getLogLevels(), true)) {
+ throw new InvalidArgumentException(
+ sprintf('Invalid Log level: "%s"', $level)
+ );
+ }
+
+ file_put_contents($this->filename, $this->formatLog((string) $level, (string) $message, $context), FILE_APPEND);
+ }
+
+ /**
+ * @param string $level
+ * @param string $message
+ * @param array $context
+ * @return string
+ */
+ private function formatLog(string $level, string $message, array $context = []): string
+ {
+ try {
+ $encodedContext = json_encode($context, JSON_THROW_ON_ERROR);
+ } catch (Throwable $t) {
+ $encodedContext = sprintf('(Could not encode context: %s)', $t->getMessage());
+ }
+
+ return sprintf(
+ '[%s] %s %s: %s %s%s',
+ date(DATE_RFC3339_EXTENDED),
+ $this->loggerName,
+ $level,
+ $message,
+ $encodedContext,
+ PHP_EOL
+ );
+ }
+
+ /**
+ * @return array
+ */
+ private static function getLogLevels(): array
+ {
+ return self::$logLevels ?? self::$logLevels = (new ReflectionClass(LogLevel::class))->getConstants();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Aggregation/ExplicitBucketHistogramAggregation.php b/vendor/open-telemetry/sdk/Metrics/Aggregation/ExplicitBucketHistogramAggregation.php
new file mode 100644
index 000000000..d68ecd830
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Aggregation/ExplicitBucketHistogramAggregation.php
@@ -0,0 +1,167 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Aggregation;
+
+use function array_fill;
+use function count;
+use const INF;
+use const NAN;
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Metrics\AggregationInterface;
+use OpenTelemetry\SDK\Metrics\Data;
+
+/**
+ * @implements AggregationInterface<ExplicitBucketHistogramSummary>
+ */
+final class ExplicitBucketHistogramAggregation implements AggregationInterface
+{
+ /**
+ * @var list<float|int>
+ * @readonly
+ */
+ public array $boundaries;
+
+ /**
+ * @param list<float|int> $boundaries strictly ascending histogram bucket boundaries
+ */
+ public function __construct(array $boundaries)
+ {
+ $this->boundaries = $boundaries;
+ }
+
+ public function initialize(): ExplicitBucketHistogramSummary
+ {
+ return new ExplicitBucketHistogramSummary(
+ 0,
+ 0,
+ +INF,
+ -INF,
+ array_fill(0, count($this->boundaries) + 1, 0),
+ );
+ }
+
+ /**
+ * @param ExplicitBucketHistogramSummary $summary
+ */
+ public function record($summary, $value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): void
+ {
+ $boundariesCount = count($this->boundaries);
+ for ($i = 0; $i < $boundariesCount && $this->boundaries[$i] < $value; $i++) {
+ }
+ $summary->count++;
+ $summary->sum += $value;
+ $summary->min = self::min($value, $summary->min);
+ $summary->max = self::max($value, $summary->max);
+ $summary->buckets[$i]++;
+ }
+
+ /**
+ * @param ExplicitBucketHistogramSummary $left
+ * @param ExplicitBucketHistogramSummary $right
+ */
+ public function merge($left, $right): ExplicitBucketHistogramSummary
+ {
+ $count = $left->count + $right->count;
+ $sum = $left->sum + $right->sum;
+ $min = self::min($left->min, $right->min);
+ $max = self::max($left->max, $right->max);
+ $buckets = $right->buckets;
+ foreach ($left->buckets as $i => $bucketCount) {
+ $buckets[$i] += $bucketCount;
+ }
+
+ return new ExplicitBucketHistogramSummary(
+ $count,
+ $sum,
+ $min,
+ $max,
+ $buckets,
+ );
+ }
+
+ /**
+ * @param ExplicitBucketHistogramSummary $left
+ * @param ExplicitBucketHistogramSummary $right
+ */
+ public function diff($left, $right): ExplicitBucketHistogramSummary
+ {
+ $count = -$left->count + $right->count;
+ $sum = -$left->sum + $right->sum;
+ $min = $left->min > $right->min ? $right->min : NAN;
+ $max = $left->max < $right->max ? $right->max : NAN;
+ $buckets = $right->buckets;
+ foreach ($left->buckets as $i => $bucketCount) {
+ $buckets[$i] -= $bucketCount;
+ }
+
+ return new ExplicitBucketHistogramSummary(
+ $count,
+ $sum,
+ $min,
+ $max,
+ $buckets,
+ );
+ }
+
+ /**
+ * @param array<ExplicitBucketHistogramSummary> $summaries
+ */
+ public function toData(
+ array $attributes,
+ array $summaries,
+ array $exemplars,
+ int $startTimestamp,
+ int $timestamp,
+ $temporality
+ ): Data\Histogram {
+ $dataPoints = [];
+ foreach ($attributes as $key => $dataPointAttributes) {
+ if ($summaries[$key]->count === 0) {
+ continue;
+ }
+
+ $dataPoints[] = new Data\HistogramDataPoint(
+ $summaries[$key]->count,
+ $summaries[$key]->sum,
+ $summaries[$key]->min,
+ $summaries[$key]->max,
+ $summaries[$key]->buckets,
+ $this->boundaries,
+ $dataPointAttributes,
+ $startTimestamp,
+ $timestamp,
+ $exemplars[$key] ?? [],
+ );
+ }
+
+ return new Data\Histogram(
+ $dataPoints,
+ $temporality,
+ );
+ }
+
+ /**
+ * @param float|int $left
+ * @param float|int $right
+ * @return float|int
+ */
+ private static function min($left, $right)
+ {
+ /** @noinspection PhpConditionAlreadyCheckedInspection */
+ return $left <= $right ? $left : ($right <= $left ? $right : NAN);
+ }
+
+ /**
+ * @param float|int $left
+ * @param float|int $right
+ * @return float|int
+ */
+ private static function max($left, $right)
+ {
+ /** @noinspection PhpConditionAlreadyCheckedInspection */
+ return $left >= $right ? $left : ($right >= $left ? $right : NAN);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Aggregation/ExplicitBucketHistogramSummary.php b/vendor/open-telemetry/sdk/Metrics/Aggregation/ExplicitBucketHistogramSummary.php
new file mode 100644
index 000000000..1878a34a0
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Aggregation/ExplicitBucketHistogramSummary.php
@@ -0,0 +1,40 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Aggregation;
+
+final class ExplicitBucketHistogramSummary
+{
+ public int $count;
+ /**
+ * @var float|int
+ */
+ public $sum;
+ /**
+ * @var float|int
+ */
+ public $min;
+ /**
+ * @var float|int
+ */
+ public $max;
+ /**
+ * @var int[]
+ */
+ public array $buckets;
+ /**
+ * @param float|int $sum
+ * @param float|int $min
+ * @param float|int $max
+ * @param int[] $buckets
+ */
+ public function __construct(int $count, $sum, $min, $max, array $buckets)
+ {
+ $this->count = $count;
+ $this->sum = $sum;
+ $this->min = $min;
+ $this->max = $max;
+ $this->buckets = $buckets;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Aggregation/LastValueAggregation.php b/vendor/open-telemetry/sdk/Metrics/Aggregation/LastValueAggregation.php
new file mode 100644
index 000000000..aff04e315
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Aggregation/LastValueAggregation.php
@@ -0,0 +1,81 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Aggregation;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Metrics\AggregationInterface;
+use OpenTelemetry\SDK\Metrics\Data;
+
+/**
+ * @implements AggregationInterface<LastValueSummary>
+ */
+final class LastValueAggregation implements AggregationInterface
+{
+ public function initialize(): LastValueSummary
+ {
+ return new LastValueSummary(null, 0);
+ }
+
+ /**
+ * @param LastValueSummary $summary
+ */
+ public function record($summary, $value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): void
+ {
+ if ($summary->value === null || $timestamp >= $summary->timestamp) {
+ $summary->value = $value;
+ $summary->timestamp = $timestamp;
+ }
+ }
+
+ /**
+ * @param LastValueSummary $left
+ * @param LastValueSummary $right
+ */
+ public function merge($left, $right): LastValueSummary
+ {
+ return $right->timestamp >= $left->timestamp ? $right : $left;
+ }
+
+ /**
+ * @param LastValueSummary $left
+ * @param LastValueSummary $right
+ */
+ public function diff($left, $right): LastValueSummary
+ {
+ return $right->timestamp >= $left->timestamp ? $right : $left;
+ }
+
+ /**
+ * @param array<LastValueSummary> $summaries
+ */
+ public function toData(
+ array $attributes,
+ array $summaries,
+ array $exemplars,
+ int $startTimestamp,
+ int $timestamp,
+ $temporality
+ ): Data\Gauge {
+ $dataPoints = [];
+ foreach ($attributes as $key => $dataPointAttributes) {
+ if ($summaries[$key]->value === null) {
+ continue;
+ }
+
+ $dataPoints[] = new Data\NumberDataPoint(
+ $summaries[$key]->value,
+ $dataPointAttributes,
+ $startTimestamp,
+ $timestamp,
+ $exemplars[$key] ?? [],
+ );
+ }
+
+ return new Data\Gauge(
+ $dataPoints,
+ );
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Aggregation/LastValueSummary.php b/vendor/open-telemetry/sdk/Metrics/Aggregation/LastValueSummary.php
new file mode 100644
index 000000000..6cdb5ac9f
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Aggregation/LastValueSummary.php
@@ -0,0 +1,22 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Aggregation;
+
+final class LastValueSummary
+{
+ /**
+ * @var float|int|null
+ */
+ public $value;
+ public int $timestamp;
+ /**
+ * @param float|int|null $value
+ */
+ public function __construct($value, int $timestamp)
+ {
+ $this->value = $value;
+ $this->timestamp = $timestamp;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Aggregation/SumAggregation.php b/vendor/open-telemetry/sdk/Metrics/Aggregation/SumAggregation.php
new file mode 100644
index 000000000..dc317ce73
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Aggregation/SumAggregation.php
@@ -0,0 +1,91 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Aggregation;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Metrics\AggregationInterface;
+use OpenTelemetry\SDK\Metrics\Data;
+
+/**
+ * @implements AggregationInterface<SumSummary>
+ */
+final class SumAggregation implements AggregationInterface
+{
+ private bool $monotonic;
+
+ public function __construct(bool $monotonic = false)
+ {
+ $this->monotonic = $monotonic;
+ }
+
+ public function initialize(): SumSummary
+ {
+ return new SumSummary(0);
+ }
+
+ /**
+ * @param SumSummary $summary
+ */
+ public function record($summary, $value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): void
+ {
+ $summary->value += $value;
+ }
+
+ /**
+ * @param SumSummary $left
+ * @param SumSummary $right
+ */
+ public function merge($left, $right): SumSummary
+ {
+ $sum = $left->value + $right->value;
+
+ return new SumSummary(
+ $sum,
+ );
+ }
+
+ /**
+ * @param SumSummary $left
+ * @param SumSummary $right
+ */
+ public function diff($left, $right): SumSummary
+ {
+ $sum = -$left->value + $right->value;
+
+ return new SumSummary(
+ $sum,
+ );
+ }
+
+ /**
+ * @param array<SumSummary> $summaries
+ */
+ public function toData(
+ array $attributes,
+ array $summaries,
+ array $exemplars,
+ int $startTimestamp,
+ int $timestamp,
+ $temporality
+ ): Data\Sum {
+ $dataPoints = [];
+ foreach ($attributes as $key => $dataPointAttributes) {
+ $dataPoints[] = new Data\NumberDataPoint(
+ $summaries[$key]->value,
+ $dataPointAttributes,
+ $startTimestamp,
+ $timestamp,
+ $exemplars[$key] ?? [],
+ );
+ }
+
+ return new Data\Sum(
+ $dataPoints,
+ $temporality,
+ $this->monotonic,
+ );
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Aggregation/SumSummary.php b/vendor/open-telemetry/sdk/Metrics/Aggregation/SumSummary.php
new file mode 100644
index 000000000..9b257193c
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Aggregation/SumSummary.php
@@ -0,0 +1,20 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Aggregation;
+
+final class SumSummary
+{
+ /**
+ * @var float|int
+ */
+ public $value;
+ /**
+ * @param float|int $value
+ */
+ public function __construct($value)
+ {
+ $this->value = $value;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/AggregationInterface.php b/vendor/open-telemetry/sdk/Metrics/AggregationInterface.php
new file mode 100644
index 000000000..0a85207e0
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/AggregationInterface.php
@@ -0,0 +1,57 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Metrics\Data\DataInterface;
+use OpenTelemetry\SDK\Metrics\Data\Exemplar;
+use OpenTelemetry\SDK\Metrics\Data\Temporality;
+
+/**
+ * @psalm-template T
+ */
+interface AggregationInterface
+{
+ /**
+ * @psalm-return T
+ */
+ public function initialize();
+
+ /**
+ * @psalm-param T $summary
+ * @psalm-param float|int $value
+ */
+ public function record($summary, $value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): void;
+
+ /**
+ * @psalm-param T $left
+ * @psalm-param T $right
+ * @psalm-return T
+ */
+ public function merge($left, $right);
+
+ /**
+ * @psalm-param T $left
+ * @psalm-param T $right
+ * @psalm-return T
+ */
+ public function diff($left, $right);
+
+ /**
+ * @param array<AttributesInterface> $attributes
+ * @psalm-param array<T> $summaries
+ * @param array<list<Exemplar>> $exemplars
+ * @param string|Temporality $temporality
+ */
+ public function toData(
+ array $attributes,
+ array $summaries,
+ array $exemplars,
+ int $startTimestamp,
+ int $timestamp,
+ $temporality
+ ): DataInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/AggregationTemporalitySelectorInterface.php b/vendor/open-telemetry/sdk/Metrics/AggregationTemporalitySelectorInterface.php
new file mode 100644
index 000000000..f046d033d
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/AggregationTemporalitySelectorInterface.php
@@ -0,0 +1,21 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\SDK\Metrics\Data\Temporality;
+
+interface AggregationTemporalitySelectorInterface
+{
+ /**
+ * Returns the temporality to use for the given metric.
+ *
+ * It is recommended to return {@see MetricMetadataInterface::temporality()}
+ * if the exporter does not require a specific temporality.
+ *
+ * @return string|Temporality|null temporality to use, or null to signal
+ * that the given metric should not be exported by this exporter
+ */
+ public function temporality(MetricMetadataInterface $metric);
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/AttributeProcessor/FilteredAttributeProcessor.php b/vendor/open-telemetry/sdk/Metrics/AttributeProcessor/FilteredAttributeProcessor.php
new file mode 100644
index 000000000..c4df8e878
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/AttributeProcessor/FilteredAttributeProcessor.php
@@ -0,0 +1,33 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\AttributeProcessor;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\Attributes;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Metrics\AttributeProcessorInterface;
+
+/**
+ * @internal
+ */
+final class FilteredAttributeProcessor implements AttributeProcessorInterface
+{
+ private array $attributeKeys;
+
+ public function __construct(array $attributeKeys)
+ {
+ $this->attributeKeys = $attributeKeys;
+ }
+
+ public function process(AttributesInterface $attributes, ContextInterface $context): AttributesInterface
+ {
+ $filtered = [];
+ foreach ($this->attributeKeys as $key) {
+ $filtered[$key] = $attributes->get($key);
+ }
+
+ return new Attributes($filtered, 0);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/AttributeProcessor/IdentityAttributeProcessor.php b/vendor/open-telemetry/sdk/Metrics/AttributeProcessor/IdentityAttributeProcessor.php
new file mode 100644
index 000000000..f261563ea
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/AttributeProcessor/IdentityAttributeProcessor.php
@@ -0,0 +1,20 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\AttributeProcessor;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Metrics\AttributeProcessorInterface;
+
+/**
+ * @internal
+ */
+final class IdentityAttributeProcessor implements AttributeProcessorInterface
+{
+ public function process(AttributesInterface $attributes, ContextInterface $context): AttributesInterface
+ {
+ return $attributes;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/AttributeProcessorInterface.php b/vendor/open-telemetry/sdk/Metrics/AttributeProcessorInterface.php
new file mode 100644
index 000000000..d2077aa39
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/AttributeProcessorInterface.php
@@ -0,0 +1,16 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+/**
+ * @internal
+ */
+interface AttributeProcessorInterface
+{
+ public function process(AttributesInterface $attributes, ContextInterface $context): AttributesInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Counter.php b/vendor/open-telemetry/sdk/Metrics/Counter.php
new file mode 100644
index 000000000..9cc6b75f9
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Counter.php
@@ -0,0 +1,37 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\API\Metrics\CounterInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricWriterInterface;
+
+/**
+ * @internal
+ */
+final class Counter implements CounterInterface
+{
+ private MetricWriterInterface $writer;
+ private Instrument $instrument;
+ private ReferenceCounterInterface $referenceCounter;
+
+ public function __construct(MetricWriterInterface $writer, Instrument $instrument, ReferenceCounterInterface $referenceCounter)
+ {
+ $this->writer = $writer;
+ $this->instrument = $instrument;
+ $this->referenceCounter = $referenceCounter;
+
+ $this->referenceCounter->acquire();
+ }
+
+ public function __destruct()
+ {
+ $this->referenceCounter->release();
+ }
+
+ public function add($amount, iterable $attributes = [], $context = null): void
+ {
+ $this->writer->record($this->instrument, $amount, $attributes, $context);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Data/DataInterface.php b/vendor/open-telemetry/sdk/Metrics/Data/DataInterface.php
new file mode 100644
index 000000000..7aa0c0e20
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Data/DataInterface.php
@@ -0,0 +1,9 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Data;
+
+interface DataInterface
+{
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Data/Exemplar.php b/vendor/open-telemetry/sdk/Metrics/Data/Exemplar.php
new file mode 100644
index 000000000..bd2034f75
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Data/Exemplar.php
@@ -0,0 +1,65 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Data;
+
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+final class Exemplar
+{
+
+ /**
+ * @var int|string
+ */
+ private $index;
+ /**
+ * @var float|int
+ * @readonly
+ */
+ public $value;
+ /**
+ * @readonly
+ */
+ public int $timestamp;
+ /**
+ * @readonly
+ */
+ public AttributesInterface $attributes;
+ /**
+ * @readonly
+ */
+ public ?string $traceId;
+ /**
+ * @readonly
+ */
+ public ?string $spanId;
+
+ /**
+ * @param int|string $index
+ * @param float|int $value
+ */
+ public function __construct($index, $value, int $timestamp, AttributesInterface $attributes, ?string $traceId, ?string $spanId)
+ {
+ $this->index = $index;
+ $this->value = $value;
+ $this->timestamp = $timestamp;
+ $this->attributes = $attributes;
+ $this->traceId = $traceId;
+ $this->spanId = $spanId;
+ }
+
+ /**
+ * @param iterable<Exemplar> $exemplars
+ * @return array<list<Exemplar>>
+ */
+ public static function groupByIndex(iterable $exemplars): array
+ {
+ $grouped = [];
+ foreach ($exemplars as $exemplar) {
+ $grouped[$exemplar->index][] = $exemplar;
+ }
+
+ return $grouped;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Data/Gauge.php b/vendor/open-telemetry/sdk/Metrics/Data/Gauge.php
new file mode 100644
index 000000000..00eb50939
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Data/Gauge.php
@@ -0,0 +1,22 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Data;
+
+final class Gauge implements DataInterface
+{
+
+ /**
+ * @var iterable<NumberDataPoint>
+ * @readonly
+ */
+ public iterable $dataPoints;
+ /**
+ * @param iterable<NumberDataPoint> $dataPoints
+ */
+ public function __construct(iterable $dataPoints)
+ {
+ $this->dataPoints = $dataPoints;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Data/Histogram.php b/vendor/open-telemetry/sdk/Metrics/Data/Histogram.php
new file mode 100644
index 000000000..782698026
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Data/Histogram.php
@@ -0,0 +1,29 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Data;
+
+final class Histogram implements DataInterface
+{
+
+ /**
+ * @var iterable<HistogramDataPoint>
+ * @readonly
+ */
+ public iterable $dataPoints;
+ /**
+ * @var string|Temporality
+ * @readonly
+ */
+ public $temporality;
+ /**
+ * @param iterable<HistogramDataPoint> $dataPoints
+ * @param string|Temporality $temporality
+ */
+ public function __construct(iterable $dataPoints, $temporality)
+ {
+ $this->dataPoints = $dataPoints;
+ $this->temporality = $temporality;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Data/HistogramDataPoint.php b/vendor/open-telemetry/sdk/Metrics/Data/HistogramDataPoint.php
new file mode 100644
index 000000000..4c9df07b4
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Data/HistogramDataPoint.php
@@ -0,0 +1,76 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Data;
+
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+final class HistogramDataPoint
+{
+ /**
+ * @readonly
+ */
+ public int $count;
+ /**
+ * @var float|int
+ * @readonly
+ */
+ public $sum;
+ /**
+ * @var float|int
+ * @readonly
+ */
+ public $min;
+ /**
+ * @var float|int
+ * @readonly
+ */
+ public $max;
+ /**
+ * @var int[]
+ * @readonly
+ */
+ public array $bucketCounts;
+ /**
+ * @var list<float|int>
+ * @readonly
+ */
+ public array $explicitBounds;
+ /**
+ * @readonly
+ */
+ public AttributesInterface $attributes;
+ /**
+ * @readonly
+ */
+ public int $startTimestamp;
+ /**
+ * @readonly
+ */
+ public int $timestamp;
+ /**
+ * @readonly
+ */
+ public iterable $exemplars = [];
+ /**
+ * @param float|int $sum
+ * @param float|int $min
+ * @param float|int $max
+ * @param int[] $bucketCounts
+ * @param list<float|int> $explicitBounds
+ */
+ public function __construct(int $count, $sum, $min, $max, array $bucketCounts, array $explicitBounds, AttributesInterface $attributes, int $startTimestamp, int $timestamp, iterable $exemplars = [])
+ {
+ $this->count = $count;
+ $this->sum = $sum;
+ $this->min = $min;
+ $this->max = $max;
+ $this->bucketCounts = $bucketCounts;
+ $this->explicitBounds = $explicitBounds;
+ $this->attributes = $attributes;
+ $this->startTimestamp = $startTimestamp;
+ $this->timestamp = $timestamp;
+ $this->exemplars = $exemplars;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Data/Metric.php b/vendor/open-telemetry/sdk/Metrics/Data/Metric.php
new file mode 100644
index 000000000..41fcb52dd
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Data/Metric.php
@@ -0,0 +1,46 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Data;
+
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+
+final class Metric
+{
+ /**
+ * @readonly
+ */
+ public InstrumentationScopeInterface $instrumentationScope;
+ /**
+ * @readonly
+ */
+ public ResourceInfo $resource;
+ /**
+ * @readonly
+ */
+ public string $name;
+ /**
+ * @readonly
+ */
+ public ?string $description;
+ /**
+ * @readonly
+ */
+ public ?string $unit;
+ /**
+ * @readonly
+ */
+ public DataInterface $data;
+
+ public function __construct(InstrumentationScopeInterface $instrumentationScope, ResourceInfo $resource, string $name, ?string $unit, ?string $description, DataInterface $data)
+ {
+ $this->instrumentationScope = $instrumentationScope;
+ $this->resource = $resource;
+ $this->name = $name;
+ $this->description = $description;
+ $this->unit = $unit;
+ $this->data = $data;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Data/NumberDataPoint.php b/vendor/open-telemetry/sdk/Metrics/Data/NumberDataPoint.php
new file mode 100644
index 000000000..1d00e783a
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Data/NumberDataPoint.php
@@ -0,0 +1,43 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Data;
+
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+final class NumberDataPoint
+{
+ /**
+ * @var float|int
+ * @readonly
+ */
+ public $value;
+ /**
+ * @readonly
+ */
+ public AttributesInterface $attributes;
+ /**
+ * @readonly
+ */
+ public int $startTimestamp;
+ /**
+ * @readonly
+ */
+ public int $timestamp;
+ /**
+ * @readonly
+ */
+ public iterable $exemplars = [];
+ /**
+ * @param float|int $value
+ */
+ public function __construct($value, AttributesInterface $attributes, int $startTimestamp, int $timestamp, iterable $exemplars = [])
+ {
+ $this->value = $value;
+ $this->attributes = $attributes;
+ $this->startTimestamp = $startTimestamp;
+ $this->timestamp = $timestamp;
+ $this->exemplars = $exemplars;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Data/Sum.php b/vendor/open-telemetry/sdk/Metrics/Data/Sum.php
new file mode 100644
index 000000000..77c4c1021
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Data/Sum.php
@@ -0,0 +1,34 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Data;
+
+final class Sum implements DataInterface
+{
+
+ /**
+ * @var iterable<NumberDataPoint>
+ * @readonly
+ */
+ public iterable $dataPoints;
+ /**
+ * @var string|Temporality
+ * @readonly
+ */
+ public $temporality;
+ /**
+ * @readonly
+ */
+ public bool $monotonic;
+ /**
+ * @param iterable<NumberDataPoint> $dataPoints
+ * @param string|Temporality $temporality
+ */
+ public function __construct(iterable $dataPoints, $temporality, bool $monotonic)
+ {
+ $this->dataPoints = $dataPoints;
+ $this->temporality = $temporality;
+ $this->monotonic = $monotonic;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Data/Temporality.php b/vendor/open-telemetry/sdk/Metrics/Data/Temporality.php
new file mode 100644
index 000000000..b6642ebd0
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Data/Temporality.php
@@ -0,0 +1,20 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Data;
+
+/**
+ * Metric aggregation temporality.
+ *
+ * Has to be type-hinted as `string|Temporality` to be forward compatible.
+ */
+final class Temporality
+{
+ public const DELTA = 'Delta';
+ public const CUMULATIVE = 'Cumulative';
+
+ private function __construct()
+ {
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/DefaultAggregationProviderInterface.php b/vendor/open-telemetry/sdk/Metrics/DefaultAggregationProviderInterface.php
new file mode 100644
index 000000000..e5c2fcc0c
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/DefaultAggregationProviderInterface.php
@@ -0,0 +1,13 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+interface DefaultAggregationProviderInterface
+{
+ /**
+ * @param string|InstrumentType $instrumentType
+ */
+ public function defaultAggregation($instrumentType): ?AggregationInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/DefaultAggregationProviderTrait.php b/vendor/open-telemetry/sdk/Metrics/DefaultAggregationProviderTrait.php
new file mode 100644
index 000000000..37c5cb110
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/DefaultAggregationProviderTrait.php
@@ -0,0 +1,28 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+trait DefaultAggregationProviderTrait
+{
+ public function defaultAggregation($instrumentType): ?AggregationInterface
+ {
+ switch ($instrumentType) {
+ case InstrumentType::COUNTER:
+ case InstrumentType::ASYNCHRONOUS_COUNTER:
+ return new Aggregation\SumAggregation(true);
+ case InstrumentType::UP_DOWN_COUNTER:
+ case InstrumentType::ASYNCHRONOUS_UP_DOWN_COUNTER:
+ return new Aggregation\SumAggregation();
+ case InstrumentType::HISTOGRAM:
+ return new Aggregation\ExplicitBucketHistogramAggregation([0, 5, 10, 25, 50, 75, 100, 250, 500, 1000]);
+ case InstrumentType::ASYNCHRONOUS_GAUGE:
+ return new Aggregation\LastValueAggregation();
+ }
+
+ // @codeCoverageIgnoreStart
+ return null;
+ // @codeCoverageIgnoreEnd
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Exemplar/BucketEntry.php b/vendor/open-telemetry/sdk/Metrics/Exemplar/BucketEntry.php
new file mode 100644
index 000000000..3a50430ed
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Exemplar/BucketEntry.php
@@ -0,0 +1,26 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Exemplar;
+
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+/**
+ * @internal
+ */
+final class BucketEntry
+{
+ /**
+ * @var int|string
+ */
+ public $index;
+ /**
+ * @var float|int
+ */
+ public $value;
+ public int $timestamp;
+ public AttributesInterface $attributes;
+ public ?string $traceId = null;
+ public ?string $spanId = null;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Exemplar/BucketStorage.php b/vendor/open-telemetry/sdk/Metrics/Exemplar/BucketStorage.php
new file mode 100644
index 000000000..574ce92af
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Exemplar/BucketStorage.php
@@ -0,0 +1,92 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Exemplar;
+
+use function array_fill;
+use function assert;
+use function count;
+use OpenTelemetry\API\Trace\Span;
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\Attributes;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Metrics\Data\Exemplar;
+
+/**
+ * @internal
+ */
+final class BucketStorage
+{
+ /** @var array<int, BucketEntry|null> */
+ private array $buckets;
+
+ public function __construct(int $size = 0)
+ {
+ $this->buckets = array_fill(0, $size, null);
+ }
+
+ /**
+ * @param int|string $index
+ * @param float|int $value
+ */
+ public function store(int $bucket, $index, $value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): void
+ {
+ assert($bucket <= count($this->buckets));
+
+ $exemplar = $this->buckets[$bucket] ??= new BucketEntry();
+ $exemplar->index = $index;
+ $exemplar->value = $value;
+ $exemplar->timestamp = $timestamp;
+ $exemplar->attributes = $attributes;
+
+ if (($spanContext = Span::fromContext($context)->getContext())->isValid()) {
+ $exemplar->traceId = $spanContext->getTraceId();
+ $exemplar->spanId = $spanContext->getSpanId();
+ } else {
+ $exemplar->traceId = null;
+ $exemplar->spanId = null;
+ }
+ }
+
+ /**
+ * @param array<AttributesInterface> $dataPointAttributes
+ * @return array<Exemplar>
+ */
+ public function collect(array $dataPointAttributes): array
+ {
+ $exemplars = [];
+ foreach ($this->buckets as $index => &$exemplar) {
+ if (!$exemplar) {
+ continue;
+ }
+
+ $exemplars[$index] = new Exemplar(
+ $exemplar->index,
+ $exemplar->value,
+ $exemplar->timestamp,
+ $this->filterExemplarAttributes(
+ $dataPointAttributes[$exemplar->index],
+ $exemplar->attributes,
+ ),
+ $exemplar->traceId,
+ $exemplar->spanId,
+ );
+ $exemplar = null;
+ }
+
+ return $exemplars;
+ }
+
+ private function filterExemplarAttributes(AttributesInterface $dataPointAttributes, AttributesInterface $exemplarAttributes): AttributesInterface
+ {
+ $attributes = [];
+ foreach ($exemplarAttributes as $key => $value) {
+ if ($dataPointAttributes->get($key) === null) {
+ $attributes[$key] = $value;
+ }
+ }
+
+ return new Attributes($attributes, $exemplarAttributes->getDroppedAttributesCount());
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilter/AllExemplarFilter.php b/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilter/AllExemplarFilter.php
new file mode 100644
index 000000000..b74e738aa
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilter/AllExemplarFilter.php
@@ -0,0 +1,21 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilter;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilterInterface;
+
+/**
+ * The exemplar spec is not yet stable, and can change at any time.
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exemplar
+ */
+final class AllExemplarFilter implements ExemplarFilterInterface
+{
+ public function accepts($value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): bool
+ {
+ return true;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilter/NoneExemplarFilter.php b/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilter/NoneExemplarFilter.php
new file mode 100644
index 000000000..91fdf3b55
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilter/NoneExemplarFilter.php
@@ -0,0 +1,21 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilter;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilterInterface;
+
+/**
+ * The exemplar spec is not yet stable, and can change at any time.
+ * see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exemplar
+ */
+final class NoneExemplarFilter implements ExemplarFilterInterface
+{
+ public function accepts($value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): bool
+ {
+ return false;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilter/WithSampledTraceExemplarFilter.php b/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilter/WithSampledTraceExemplarFilter.php
new file mode 100644
index 000000000..3e800b416
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilter/WithSampledTraceExemplarFilter.php
@@ -0,0 +1,22 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilter;
+
+use OpenTelemetry\API\Trace\Span;
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilterInterface;
+
+/**
+ * The exemplar spec is not yet stable, and can change at any time.
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exemplar
+ */
+final class WithSampledTraceExemplarFilter implements ExemplarFilterInterface
+{
+ public function accepts($value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): bool
+ {
+ return Span::fromContext($context)->getContext()->isSampled();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilterInterface.php b/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilterInterface.php
new file mode 100644
index 000000000..1d5dec7b8
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarFilterInterface.php
@@ -0,0 +1,20 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Exemplar;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+/**
+ * The exemplar spec is not yet stable, and can change at any time.
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exemplar
+ */
+interface ExemplarFilterInterface
+{
+ /**
+ * @param float|int $value
+ */
+ public function accepts($value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): bool;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarReservoirInterface.php b/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarReservoirInterface.php
new file mode 100644
index 000000000..70648b919
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Exemplar/ExemplarReservoirInterface.php
@@ -0,0 +1,24 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Exemplar;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Metrics\Data\Exemplar;
+
+interface ExemplarReservoirInterface
+{
+ /**
+ * @param int|string $index
+ * @param float|int $value
+ */
+ public function offer($index, $value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): void;
+
+ /**
+ * @param array<AttributesInterface> $dataPointAttributes
+ * @return array<Exemplar>
+ */
+ public function collect(array $dataPointAttributes): array;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Exemplar/FilteredReservoir.php b/vendor/open-telemetry/sdk/Metrics/Exemplar/FilteredReservoir.php
new file mode 100644
index 000000000..0e4f24357
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Exemplar/FilteredReservoir.php
@@ -0,0 +1,36 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Exemplar;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+/**
+ * The exemplar spec is not yet stable, and can change at any time.
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exemplar
+ */
+final class FilteredReservoir implements ExemplarReservoirInterface
+{
+ private ExemplarReservoirInterface $reservoir;
+ private ExemplarFilterInterface $filter;
+
+ public function __construct(ExemplarReservoirInterface $reservoir, ExemplarFilterInterface $filter)
+ {
+ $this->reservoir = $reservoir;
+ $this->filter = $filter;
+ }
+
+ public function offer($index, $value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): void
+ {
+ if ($this->filter->accepts($value, $attributes, $context, $timestamp)) {
+ $this->reservoir->offer($index, $value, $attributes, $context, $timestamp);
+ }
+ }
+
+ public function collect(array $dataPointAttributes): array
+ {
+ return $this->reservoir->collect($dataPointAttributes);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Exemplar/FixedSizeReservoir.php b/vendor/open-telemetry/sdk/Metrics/Exemplar/FixedSizeReservoir.php
new file mode 100644
index 000000000..479292a4c
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Exemplar/FixedSizeReservoir.php
@@ -0,0 +1,38 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Exemplar;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use function random_int;
+
+final class FixedSizeReservoir implements ExemplarReservoirInterface
+{
+ private BucketStorage $storage;
+ private int $size;
+ private int $measurements = 0;
+
+ public function __construct(int $size = 4)
+ {
+ $this->storage = new BucketStorage($size);
+ $this->size = $size;
+ }
+
+ public function offer($index, $value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): void
+ {
+ $bucket = random_int(0, $this->measurements);
+ $this->measurements++;
+ if ($bucket < $this->size) {
+ $this->storage->store($bucket, $index, $value, $attributes, $context, $timestamp);
+ }
+ }
+
+ public function collect(array $dataPointAttributes): array
+ {
+ $this->measurements = 0;
+
+ return $this->storage->collect($dataPointAttributes);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Exemplar/HistogramBucketReservoir.php b/vendor/open-telemetry/sdk/Metrics/Exemplar/HistogramBucketReservoir.php
new file mode 100644
index 000000000..b56a1b2be
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Exemplar/HistogramBucketReservoir.php
@@ -0,0 +1,40 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Exemplar;
+
+use function count;
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+final class HistogramBucketReservoir implements ExemplarReservoirInterface
+{
+ private BucketStorage $storage;
+ /**
+ * @var list<float|int>
+ */
+ private array $boundaries;
+
+ /**
+ * @param list<float|int> $boundaries
+ */
+ public function __construct(array $boundaries)
+ {
+ $this->storage = new BucketStorage(count($boundaries) + 1);
+ $this->boundaries = $boundaries;
+ }
+
+ public function offer($index, $value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): void
+ {
+ $boundariesCount = count($this->boundaries);
+ for ($i = 0; $i < $boundariesCount && $this->boundaries[$i] < $value; $i++) {
+ }
+ $this->storage->store($i, $index, $value, $attributes, $context, $timestamp);
+ }
+
+ public function collect(array $dataPointAttributes): array
+ {
+ return $this->storage->collect($dataPointAttributes);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Exemplar/NoopReservoir.php b/vendor/open-telemetry/sdk/Metrics/Exemplar/NoopReservoir.php
new file mode 100644
index 000000000..010aeff20
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Exemplar/NoopReservoir.php
@@ -0,0 +1,21 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Exemplar;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+final class NoopReservoir implements ExemplarReservoirInterface
+{
+ public function offer($index, $value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): void
+ {
+ // no-op
+ }
+
+ public function collect(array $dataPointAttributes): array
+ {
+ return [];
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Histogram.php b/vendor/open-telemetry/sdk/Metrics/Histogram.php
new file mode 100644
index 000000000..532b1b4bf
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Histogram.php
@@ -0,0 +1,37 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\API\Metrics\HistogramInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricWriterInterface;
+
+/**
+ * @internal
+ */
+final class Histogram implements HistogramInterface
+{
+ private MetricWriterInterface $writer;
+ private Instrument $instrument;
+ private ReferenceCounterInterface $referenceCounter;
+
+ public function __construct(MetricWriterInterface $writer, Instrument $instrument, ReferenceCounterInterface $referenceCounter)
+ {
+ $this->writer = $writer;
+ $this->instrument = $instrument;
+ $this->referenceCounter = $referenceCounter;
+
+ $this->referenceCounter->acquire();
+ }
+
+ public function __destruct()
+ {
+ $this->referenceCounter->release();
+ }
+
+ public function record($amount, iterable $attributes = [], $context = null): void
+ {
+ $this->writer->record($this->instrument, $amount, $attributes, $context);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Instrument.php b/vendor/open-telemetry/sdk/Metrics/Instrument.php
new file mode 100644
index 000000000..3543604c0
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Instrument.php
@@ -0,0 +1,36 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+final class Instrument
+{
+ /**
+ * @var string|InstrumentType
+ * @readonly
+ */
+ public $type;
+ /**
+ * @readonly
+ */
+ public string $name;
+ /**
+ * @readonly
+ */
+ public ?string $unit;
+ /**
+ * @readonly
+ */
+ public ?string $description;
+ /**
+ * @param string|InstrumentType $type
+ */
+ public function __construct($type, string $name, ?string $unit, ?string $description)
+ {
+ $this->type = $type;
+ $this->name = $name;
+ $this->unit = $unit;
+ $this->description = $description;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/InstrumentType.php b/vendor/open-telemetry/sdk/Metrics/InstrumentType.php
new file mode 100644
index 000000000..ae603b2fe
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/InstrumentType.php
@@ -0,0 +1,25 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+/**
+ * Instrument type.
+ *
+ * Has to be type-hinted as `string|InstrumentType` to be forward compatible.
+ */
+final class InstrumentType
+{
+ public const COUNTER = 'Counter';
+ public const UP_DOWN_COUNTER = 'UpDownCounter';
+ public const HISTOGRAM = 'Histogram';
+
+ public const ASYNCHRONOUS_COUNTER = 'AsynchronousCounter';
+ public const ASYNCHRONOUS_UP_DOWN_COUNTER = 'AsynchronousUpDownCounter';
+ public const ASYNCHRONOUS_GAUGE = 'AsynchronousGauge';
+
+ private function __construct()
+ {
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Meter.php b/vendor/open-telemetry/sdk/Metrics/Meter.php
new file mode 100644
index 000000000..902284839
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Meter.php
@@ -0,0 +1,314 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use ArrayAccess;
+use OpenTelemetry\API\Metrics\CounterInterface;
+use OpenTelemetry\API\Metrics\HistogramInterface;
+use OpenTelemetry\API\Metrics\MeterInterface;
+use OpenTelemetry\API\Metrics\ObservableCounterInterface;
+use OpenTelemetry\API\Metrics\ObservableGaugeInterface;
+use OpenTelemetry\API\Metrics\ObservableUpDownCounterInterface;
+use OpenTelemetry\API\Metrics\UpDownCounterInterface;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Common\Time\ClockInterface;
+use function OpenTelemetry\SDK\Common\Util\closure;
+use OpenTelemetry\SDK\Common\Util\WeakMap;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilterInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistration\MultiRegistryRegistration;
+use OpenTelemetry\SDK\Metrics\MetricRegistration\RegistryRegistration;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricRegistryInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricWriterInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use const PHP_VERSION_ID;
+use function serialize;
+
+/**
+ * @internal
+ */
+final class Meter implements MeterInterface
+{
+ private MetricFactoryInterface $metricFactory;
+ private ResourceInfo $resource;
+ private ClockInterface $clock;
+ private StalenessHandlerFactoryInterface $stalenessHandlerFactory;
+ /** @var iterable<MetricSourceRegistryInterface&DefaultAggregationProviderInterface> */
+ private iterable $metricRegistries;
+ private ViewRegistryInterface $viewRegistry;
+ private ?ExemplarFilterInterface $exemplarFilter;
+ private MeterInstruments $instruments;
+ private InstrumentationScopeInterface $instrumentationScope;
+
+ private MetricRegistryInterface $registry;
+ private MetricWriterInterface $writer;
+
+ private ?string $instrumentationScopeId = null;
+
+ /**
+ * @param iterable<MetricSourceRegistryInterface&DefaultAggregationProviderInterface> $metricRegistries
+ */
+ public function __construct(
+ MetricFactoryInterface $metricFactory,
+ ResourceInfo $resource,
+ ClockInterface $clock,
+ StalenessHandlerFactoryInterface $stalenessHandlerFactory,
+ iterable $metricRegistries,
+ ViewRegistryInterface $viewRegistry,
+ ?ExemplarFilterInterface $exemplarFilter,
+ MeterInstruments $instruments,
+ InstrumentationScopeInterface $instrumentationScope,
+ MetricRegistryInterface $registry,
+ MetricWriterInterface $writer
+ ) {
+ $this->metricFactory = $metricFactory;
+ $this->resource = $resource;
+ $this->clock = $clock;
+ $this->stalenessHandlerFactory = $stalenessHandlerFactory;
+ $this->metricRegistries = $metricRegistries;
+ $this->viewRegistry = $viewRegistry;
+ $this->exemplarFilter = $exemplarFilter;
+ $this->instruments = $instruments;
+ $this->instrumentationScope = $instrumentationScope;
+ $this->registry = $registry;
+ $this->writer = $writer;
+ }
+
+ public function createCounter(string $name, ?string $unit = null, ?string $description = null): CounterInterface
+ {
+ [$instrument, $referenceCounter] = $this->createSynchronousWriter(
+ InstrumentType::COUNTER,
+ $name,
+ $unit,
+ $description,
+ );
+
+ return new Counter($this->writer, $instrument, $referenceCounter);
+ }
+
+ public function createObservableCounter(string $name, ?string $unit = null, ?string $description = null, callable ...$callbacks): ObservableCounterInterface
+ {
+ [$instrument, $referenceCounter, $destructors] = $this->createAsynchronousObserver(
+ InstrumentType::ASYNCHRONOUS_COUNTER,
+ $name,
+ $unit,
+ $description,
+ );
+
+ foreach ($callbacks as $callback) {
+ $this->writer->registerCallback(closure($callback), $instrument);
+ $referenceCounter->acquire(true);
+ }
+
+ return new ObservableCounter($this->writer, $instrument, $referenceCounter, $destructors);
+ }
+
+ public function createHistogram(string $name, ?string $unit = null, ?string $description = null): HistogramInterface
+ {
+ [$instrument, $referenceCounter] = $this->createSynchronousWriter(
+ InstrumentType::HISTOGRAM,
+ $name,
+ $unit,
+ $description,
+ );
+
+ return new Histogram($this->writer, $instrument, $referenceCounter);
+ }
+
+ public function createObservableGauge(string $name, ?string $unit = null, ?string $description = null, callable ...$callbacks): ObservableGaugeInterface
+ {
+ [$instrument, $referenceCounter, $destructors] = $this->createAsynchronousObserver(
+ InstrumentType::ASYNCHRONOUS_GAUGE,
+ $name,
+ $unit,
+ $description,
+ );
+
+ foreach ($callbacks as $callback) {
+ $this->writer->registerCallback(closure($callback), $instrument);
+ $referenceCounter->acquire(true);
+ }
+
+ return new ObservableGauge($this->writer, $instrument, $referenceCounter, $destructors);
+ }
+
+ public function createUpDownCounter(string $name, ?string $unit = null, ?string $description = null): UpDownCounterInterface
+ {
+ [$instrument, $referenceCounter] = $this->createSynchronousWriter(
+ InstrumentType::UP_DOWN_COUNTER,
+ $name,
+ $unit,
+ $description,
+ );
+
+ return new UpDownCounter($this->writer, $instrument, $referenceCounter);
+ }
+
+ public function createObservableUpDownCounter(string $name, ?string $unit = null, ?string $description = null, callable ...$callbacks): ObservableUpDownCounterInterface
+ {
+ [$instrument, $referenceCounter, $destructors] = $this->createAsynchronousObserver(
+ InstrumentType::ASYNCHRONOUS_UP_DOWN_COUNTER,
+ $name,
+ $unit,
+ $description,
+ );
+
+ foreach ($callbacks as $callback) {
+ $this->writer->registerCallback(closure($callback), $instrument);
+ $referenceCounter->acquire(true);
+ }
+
+ return new ObservableUpDownCounter($this->writer, $instrument, $referenceCounter, $destructors);
+ }
+
+ /**
+ * @param string|InstrumentType $instrumentType
+ * @return array{Instrument, ReferenceCounterInterface}
+ */
+ private function createSynchronousWriter($instrumentType, string $name, ?string $unit, ?string $description): array
+ {
+ $instrument = new Instrument($instrumentType, $name, $unit, $description);
+
+ $instrumentationScopeId = $this->instrumentationScopeId($this->instrumentationScope);
+ $instrumentId = $this->instrumentId($instrument);
+
+ $instruments = $this->instruments;
+ if ($writer = $instruments->writers[$instrumentationScopeId][$instrumentId] ?? null) {
+ return $writer;
+ }
+
+ $stalenessHandler = $this->stalenessHandlerFactory->create();
+ $instruments->startTimestamp ??= $this->clock->now();
+ $streamIds = $this->metricFactory->createSynchronousWriter(
+ $this->registry,
+ $this->resource,
+ $this->instrumentationScope,
+ $instrument,
+ $instruments->startTimestamp,
+ $this->viewRegistrationRequests($instrument, $stalenessHandler),
+ $this->exemplarFilter,
+ );
+
+ $registry = $this->registry;
+ $stalenessHandler->onStale(static function () use ($instruments, $instrumentationScopeId, $instrumentId, $registry, $streamIds): void {
+ unset($instruments->writers[$instrumentationScopeId][$instrumentId]);
+ if (!$instruments->writers[$instrumentationScopeId]) {
+ unset($instruments->writers[$instrumentationScopeId]);
+ }
+ foreach ($streamIds as $streamId) {
+ $registry->unregisterStream($streamId);
+ }
+
+ $instruments->startTimestamp = null;
+ });
+
+ return $instruments->writers[$instrumentationScopeId][$instrumentId] = [
+ $instrument,
+ $stalenessHandler,
+ ];
+ }
+
+ /**
+ * @param string|InstrumentType $instrumentType
+ * @return array{Instrument, ReferenceCounterInterface, ArrayAccess<object, ObservableCallbackDestructor>}
+ */
+ private function createAsynchronousObserver($instrumentType, string $name, ?string $unit, ?string $description): array
+ {
+ $instrument = new Instrument($instrumentType, $name, $unit, $description);
+
+ $instrumentationScopeId = $this->instrumentationScopeId($this->instrumentationScope);
+ $instrumentId = $this->instrumentId($instrument);
+
+ $instruments = $this->instruments;
+ /** @phan-suppress-next-line PhanDeprecatedProperty */
+ $instruments->staleObservers = [];
+ if ($observer = $instruments->observers[$instrumentationScopeId][$instrumentId] ?? null) {
+ return $observer;
+ }
+
+ $stalenessHandler = $this->stalenessHandlerFactory->create();
+ $instruments->startTimestamp ??= $this->clock->now();
+ $streamIds = $this->metricFactory->createAsynchronousObserver(
+ $this->registry,
+ $this->resource,
+ $this->instrumentationScope,
+ $instrument,
+ $instruments->startTimestamp,
+ $this->viewRegistrationRequests($instrument, $stalenessHandler),
+ );
+
+ $registry = $this->registry;
+ $stalenessHandler->onStale(static function () use ($instruments, $instrumentationScopeId, $instrumentId, $registry, $streamIds): void {
+ if (PHP_VERSION_ID < 80000) {
+ /** @phan-suppress-next-line PhanDeprecatedProperty */
+ $instruments->staleObservers[] = $instruments->observers[$instrumentationScopeId][$instrumentId][2];
+ }
+
+ unset($instruments->observers[$instrumentationScopeId][$instrumentId]);
+ if (!$instruments->observers[$instrumentationScopeId]) {
+ unset($instruments->observers[$instrumentationScopeId]);
+ }
+ foreach ($streamIds as $streamId) {
+ $registry->unregisterStream($streamId);
+ }
+
+ $instruments->startTimestamp = null;
+ });
+
+ /** @var ArrayAccess<object, ObservableCallbackDestructor> $destructors */
+ $destructors = WeakMap::create();
+
+ return $instruments->observers[$instrumentationScopeId][$instrumentId] = [
+ $instrument,
+ $stalenessHandler,
+ $destructors,
+ ];
+ }
+
+ /**
+ * @return iterable<array{ViewProjection, MetricRegistrationInterface}>
+ */
+ private function viewRegistrationRequests(Instrument $instrument, StalenessHandlerInterface $stalenessHandler): iterable
+ {
+ $views = $this->viewRegistry->find($instrument, $this->instrumentationScope) ?? [
+ new ViewProjection(
+ $instrument->name,
+ $instrument->unit,
+ $instrument->description,
+ null,
+ null,
+ ),
+ ];
+
+ $compositeRegistration = new MultiRegistryRegistration($this->metricRegistries, $stalenessHandler);
+ foreach ($views as $view) {
+ if ($view->aggregation !== null) {
+ yield [$view, $compositeRegistration];
+ } else {
+ foreach ($this->metricRegistries as $metricRegistry) {
+ yield [
+ new ViewProjection(
+ $view->name,
+ $view->unit,
+ $view->description,
+ $view->attributeKeys,
+ $metricRegistry->defaultAggregation($instrument->type),
+ ),
+ new RegistryRegistration($metricRegistry, $stalenessHandler),
+ ];
+ }
+ }
+ }
+ }
+
+ private function instrumentationScopeId(InstrumentationScopeInterface $instrumentationScope): string
+ {
+ return $this->instrumentationScopeId ??= serialize($instrumentationScope);
+ }
+
+ private function instrumentId(Instrument $instrument): string
+ {
+ return serialize($instrument);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MeterInstruments.php b/vendor/open-telemetry/sdk/Metrics/MeterInstruments.php
new file mode 100644
index 000000000..c331cb608
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MeterInstruments.php
@@ -0,0 +1,29 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use ArrayAccess;
+
+/**
+ * @internal
+ */
+final class MeterInstruments
+{
+ public ?int $startTimestamp = null;
+ /**
+ * @var array<string, array<string, array{Instrument, ReferenceCounterInterface, ArrayAccess<object, ObservableCallbackDestructor>}>>
+ */
+ public array $observers = [];
+ /**
+ * @var array<string, array<string, array{Instrument, ReferenceCounterInterface}>>
+ */
+ public array $writers = [];
+
+ /**
+ * @var list<ArrayAccess<object, ObservableCallbackDestructor>>
+ * @deprecated
+ */
+ public array $staleObservers = [];
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MeterProvider.php b/vendor/open-telemetry/sdk/Metrics/MeterProvider.php
new file mode 100644
index 000000000..36c17cf81
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MeterProvider.php
@@ -0,0 +1,130 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\API\Metrics\MeterInterface;
+use OpenTelemetry\API\Metrics\Noop\NoopMeter;
+use OpenTelemetry\Context\ContextStorageInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesFactoryInterface;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeFactoryInterface;
+use OpenTelemetry\SDK\Common\Time\ClockInterface;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilterInterface;
+use OpenTelemetry\SDK\Metrics\MetricFactory\StreamFactory;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricRegistry;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricRegistryInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricWriterInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use OpenTelemetry\SDK\Sdk;
+
+final class MeterProvider implements MeterProviderInterface
+{
+ private MetricFactoryInterface $metricFactory;
+ private ResourceInfo $resource;
+ private ClockInterface $clock;
+ private InstrumentationScopeFactoryInterface $instrumentationScopeFactory;
+ private iterable $metricReaders;
+ private ViewRegistryInterface $viewRegistry;
+ private ?ExemplarFilterInterface $exemplarFilter;
+ private StalenessHandlerFactoryInterface $stalenessHandlerFactory;
+ private MeterInstruments $instruments;
+ private MetricRegistryInterface $registry;
+ private MetricWriterInterface $writer;
+
+ private bool $closed = false;
+
+ /**
+ * @param iterable<MetricReaderInterface&MetricSourceRegistryInterface&DefaultAggregationProviderInterface> $metricReaders
+ */
+ public function __construct(
+ ?ContextStorageInterface $contextStorage,
+ ResourceInfo $resource,
+ ClockInterface $clock,
+ AttributesFactoryInterface $attributesFactory,
+ InstrumentationScopeFactoryInterface $instrumentationScopeFactory,
+ iterable $metricReaders,
+ ViewRegistryInterface $viewRegistry,
+ ?ExemplarFilterInterface $exemplarFilter,
+ StalenessHandlerFactoryInterface $stalenessHandlerFactory,
+ MetricFactoryInterface $metricFactory = null
+ ) {
+ $this->metricFactory = $metricFactory ?? new StreamFactory();
+ $this->resource = $resource;
+ $this->clock = $clock;
+ $this->instrumentationScopeFactory = $instrumentationScopeFactory;
+ $this->metricReaders = $metricReaders;
+ $this->viewRegistry = $viewRegistry;
+ $this->exemplarFilter = $exemplarFilter;
+ $this->stalenessHandlerFactory = $stalenessHandlerFactory;
+ $this->instruments = new MeterInstruments();
+
+ $registry = new MetricRegistry($contextStorage, $attributesFactory, $clock);
+ $this->registry = $registry;
+ $this->writer = $registry;
+ }
+
+ public function getMeter(
+ string $name,
+ ?string $version = null,
+ ?string $schemaUrl = null,
+ iterable $attributes = []
+ ): MeterInterface {
+ if ($this->closed || Sdk::isDisabled()) { //@todo create meter provider from factory, and move Sdk::isDisabled() there
+ return new NoopMeter();
+ }
+
+ return new Meter(
+ $this->metricFactory,
+ $this->resource,
+ $this->clock,
+ $this->stalenessHandlerFactory,
+ $this->metricReaders,
+ $this->viewRegistry,
+ $this->exemplarFilter,
+ $this->instruments,
+ $this->instrumentationScopeFactory->create($name, $version, $schemaUrl, $attributes),
+ $this->registry,
+ $this->writer,
+ );
+ }
+
+ public function shutdown(): bool
+ {
+ if ($this->closed) {
+ return false;
+ }
+
+ $this->closed = true;
+
+ $success = true;
+ foreach ($this->metricReaders as $metricReader) {
+ if (!$metricReader->shutdown()) {
+ $success = false;
+ }
+ }
+
+ return $success;
+ }
+
+ public function forceFlush(): bool
+ {
+ if ($this->closed) {
+ return false;
+ }
+
+ $success = true;
+ foreach ($this->metricReaders as $metricReader) {
+ if (!$metricReader->forceFlush()) {
+ $success = false;
+ }
+ }
+
+ return $success;
+ }
+
+ public static function builder(): MeterProviderBuilder
+ {
+ return new MeterProviderBuilder();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MeterProviderBuilder.php b/vendor/open-telemetry/sdk/Metrics/MeterProviderBuilder.php
new file mode 100644
index 000000000..17f0be895
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MeterProviderBuilder.php
@@ -0,0 +1,62 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\SDK\Common\Attribute\Attributes;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeFactory;
+use OpenTelemetry\SDK\Common\Time\ClockFactory;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilter\WithSampledTraceExemplarFilter;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilterInterface;
+use OpenTelemetry\SDK\Metrics\StalenessHandler\NoopStalenessHandlerFactory;
+use OpenTelemetry\SDK\Metrics\View\CriteriaViewRegistry;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
+
+class MeterProviderBuilder
+{
+ // @var array<MetricReaderInterface>
+ private array $metricReaders = [];
+ private ?ResourceInfo $resource = null;
+ private ?ExemplarFilterInterface $exemplarFilter = null;
+
+ public function setResource(ResourceInfo $resource): self
+ {
+ $this->resource = $resource;
+
+ return $this;
+ }
+
+ public function setExemplarFilter(ExemplarFilterInterface $exemplarFilter): self
+ {
+ $this->exemplarFilter = $exemplarFilter;
+
+ return $this;
+ }
+
+ public function addReader(MetricReaderInterface $reader): self
+ {
+ $this->metricReaders[] = $reader;
+
+ return $this;
+ }
+
+ /**
+ * @psalm-suppress PossiblyInvalidArgument
+ */
+ public function build(): MeterProviderInterface
+ {
+ return new MeterProvider(
+ null,
+ $this->resource ?? ResourceInfoFactory::emptyResource(),
+ ClockFactory::getDefault(),
+ Attributes::factory(),
+ new InstrumentationScopeFactory(Attributes::factory()),
+ $this->metricReaders,
+ new CriteriaViewRegistry(),
+ $this->exemplarFilter ?? new WithSampledTraceExemplarFilter(),
+ new NoopStalenessHandlerFactory(),
+ );
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MeterProviderFactory.php b/vendor/open-telemetry/sdk/Metrics/MeterProviderFactory.php
new file mode 100644
index 000000000..5f7f9988d
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MeterProviderFactory.php
@@ -0,0 +1,78 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use InvalidArgumentException;
+use OpenTelemetry\API\Behavior\LogsMessagesTrait;
+use OpenTelemetry\SDK\Common\Configuration\Configuration;
+use OpenTelemetry\SDK\Common\Configuration\KnownValues;
+use OpenTelemetry\SDK\Common\Configuration\Variables;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilter\AllExemplarFilter;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilter\NoneExemplarFilter;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilter\WithSampledTraceExemplarFilter;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilterInterface;
+use OpenTelemetry\SDK\Metrics\MetricExporter\NoopMetricExporter;
+use OpenTelemetry\SDK\Metrics\MetricReader\ExportingReader;
+use OpenTelemetry\SDK\Registry;
+use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
+use OpenTelemetry\SDK\Sdk;
+
+class MeterProviderFactory
+{
+ use LogsMessagesTrait;
+
+ /**
+ * @todo https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk_exporters/otlp.md#general
+ * - "The exporter MUST configure the default aggregation on the basis of instrument kind using the
+ * OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION variable as described below if it is implemented."
+ */
+ public function create(): MeterProviderInterface
+ {
+ if (Sdk::isDisabled()) {
+ return new NoopMeterProvider();
+ }
+ $exporters = Configuration::getList(Variables::OTEL_METRICS_EXPORTER);
+ //TODO "The SDK MAY accept a comma-separated list to enable setting multiple exporters"
+ if (count($exporters) !== 1) {
+ throw new InvalidArgumentException(sprintf('Configuration %s requires exactly 1 exporter', Variables::OTEL_METRICS_EXPORTER));
+ }
+ $exporterName = $exporters[0];
+
+ try {
+ $factory = Registry::metricExporterFactory($exporterName);
+ $exporter = $factory->create();
+ } catch (\Throwable $t) {
+ self::logWarning(sprintf('Unable to create %s meter provider: %s', $exporterName, $t->getMessage()));
+ $exporter = new NoopMetricExporter();
+ }
+
+ // @todo "The exporter MUST be paired with a periodic exporting MetricReader"
+ $reader = new ExportingReader($exporter);
+ $resource = ResourceInfoFactory::defaultResource();
+ $exemplarFilter = $this->createExemplarFilter(Configuration::getEnum(Variables::OTEL_METRICS_EXEMPLAR_FILTER));
+
+ return MeterProvider::builder()
+ ->setResource($resource)
+ ->addReader($reader)
+ ->setExemplarFilter($exemplarFilter)
+ ->build();
+ }
+
+ private function createExemplarFilter(string $name): ExemplarFilterInterface
+ {
+ switch ($name) {
+ case KnownValues::VALUE_WITH_SAMPLED_TRACE:
+ return new WithSampledTraceExemplarFilter();
+ case KnownValues::VALUE_ALL:
+ return new AllExemplarFilter();
+ case KnownValues::VALUE_NONE:
+ return new NoneExemplarFilter();
+ default:
+ self::logWarning('Unknown exemplar filter: ' . $name);
+
+ return new NoneExemplarFilter();
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MeterProviderInterface.php b/vendor/open-telemetry/sdk/Metrics/MeterProviderInterface.php
new file mode 100644
index 000000000..fcb951106
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MeterProviderInterface.php
@@ -0,0 +1,12 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+interface MeterProviderInterface extends \OpenTelemetry\API\Metrics\MeterProviderInterface
+{
+ public function shutdown(): bool;
+
+ public function forceFlush(): bool;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricExporter/ConsoleMetricExporter.php b/vendor/open-telemetry/sdk/Metrics/MetricExporter/ConsoleMetricExporter.php
new file mode 100644
index 000000000..62ea7b535
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricExporter/ConsoleMetricExporter.php
@@ -0,0 +1,105 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricExporter;
+
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Metrics\AggregationTemporalitySelectorInterface;
+use OpenTelemetry\SDK\Metrics\Data\Metric;
+use OpenTelemetry\SDK\Metrics\Data\Temporality;
+use OpenTelemetry\SDK\Metrics\MetricMetadataInterface;
+use OpenTelemetry\SDK\Metrics\PushMetricExporterInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+
+/**
+ * Console metrics exporter.
+ * Note that the output is human-readable JSON, not compatible with OTLP.
+ */
+class ConsoleMetricExporter implements PushMetricExporterInterface, AggregationTemporalitySelectorInterface
+{
+ /**
+ * @var string|Temporality|null
+ */
+ private $temporality;
+
+ /**
+ * @param string|Temporality|null $temporality
+ */
+ public function __construct($temporality = null)
+ {
+ $this->temporality = $temporality;
+ }
+ /**
+ * @inheritDoc
+ */
+ public function temporality(MetricMetadataInterface $metric)
+ {
+ return $this->temporality ?? $metric->temporality();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function export(iterable $batch): bool
+ {
+ $resource = null;
+ $scope = null;
+ foreach ($batch as $metric) {
+ /** @var Metric $metric */
+ if (!$resource) {
+ $resource = $this->convertResource($metric->resource);
+ }
+ if (!$scope) {
+ $scope = $this->convertInstrumentationScope($metric->instrumentationScope);
+ $scope['metrics'] = [];
+ }
+ $scope['metrics'][] = $this->convertMetric($metric);
+ }
+ $output = [
+ 'resource' => $resource,
+ 'scope' => $scope,
+ ];
+ echo json_encode($output, JSON_PRETTY_PRINT) . PHP_EOL;
+
+ return true;
+ }
+
+ public function shutdown(): bool
+ {
+ return true;
+ }
+
+ public function forceFlush(): bool
+ {
+ return true;
+ }
+
+ private function convertMetric(Metric $metric): array
+ {
+ return [
+ 'name' => $metric->name,
+ 'description' => $metric->description,
+ 'unit' => $metric->unit,
+ 'data' => $metric->data,
+ ];
+ }
+
+ private function convertResource(ResourceInfo $resource): array
+ {
+ return [
+ 'attributes' => $resource->getAttributes()->toArray(),
+ 'dropped_attributes_count' => $resource->getAttributes()->getDroppedAttributesCount(),
+ ];
+ }
+ private function convertInstrumentationScope(InstrumentationScopeInterface $scope): array
+ {
+ return [
+ 'name' => $scope->getName(),
+ 'version' => $scope->getVersion(),
+ 'attributes' => $scope->getAttributes()->toArray(),
+ 'dropped_attributes_count' => $scope->getAttributes()->getDroppedAttributesCount(),
+ 'schema_url' => $scope->getSchemaUrl(),
+ ];
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricExporter/ConsoleMetricExporterFactory.php b/vendor/open-telemetry/sdk/Metrics/MetricExporter/ConsoleMetricExporterFactory.php
new file mode 100644
index 000000000..19088738d
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricExporter/ConsoleMetricExporterFactory.php
@@ -0,0 +1,16 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricExporter;
+
+use OpenTelemetry\SDK\Metrics\MetricExporterFactoryInterface;
+use OpenTelemetry\SDK\Metrics\MetricExporterInterface;
+
+class ConsoleMetricExporterFactory implements MetricExporterFactoryInterface
+{
+ public function create(): MetricExporterInterface
+ {
+ return new ConsoleMetricExporter();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricExporter/InMemoryExporter.php b/vendor/open-telemetry/sdk/Metrics/MetricExporter/InMemoryExporter.php
new file mode 100644
index 000000000..6bbab8b79
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricExporter/InMemoryExporter.php
@@ -0,0 +1,78 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricExporter;
+
+use function array_push;
+use OpenTelemetry\SDK\Metrics\AggregationTemporalitySelectorInterface;
+use OpenTelemetry\SDK\Metrics\Data\Metric;
+use OpenTelemetry\SDK\Metrics\Data\Temporality;
+use OpenTelemetry\SDK\Metrics\MetricExporterInterface;
+use OpenTelemetry\SDK\Metrics\MetricMetadataInterface;
+
+/**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk_exporters/in-memory.md
+ */
+final class InMemoryExporter implements MetricExporterInterface, AggregationTemporalitySelectorInterface
+{
+ /**
+ * @var list<Metric>
+ */
+ private array $metrics = [];
+ /**
+ * @var string|Temporality|null
+ */
+ private $temporality;
+
+ private bool $closed = false;
+
+ /**
+ * @param string|Temporality|null $temporality
+ */
+ public function __construct($temporality = null)
+ {
+ $this->temporality = $temporality;
+ }
+
+ public function temporality(MetricMetadataInterface $metric)
+ {
+ return $this->temporality ?? $metric->temporality();
+ }
+
+ /**
+ * @return list<Metric>
+ */
+ public function collect(bool $reset = false): array
+ {
+ $metrics = $this->metrics;
+ if ($reset) {
+ $this->metrics = [];
+ }
+
+ return $metrics;
+ }
+
+ public function export(iterable $batch): bool
+ {
+ if ($this->closed) {
+ return false;
+ }
+
+ /** @psalm-suppress InvalidPropertyAssignmentValue */
+ array_push($this->metrics, ...$batch);
+
+ return true;
+ }
+
+ public function shutdown(): bool
+ {
+ if ($this->closed) {
+ return false;
+ }
+
+ $this->closed = true;
+
+ return true;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricExporter/InMemoryExporterFactory.php b/vendor/open-telemetry/sdk/Metrics/MetricExporter/InMemoryExporterFactory.php
new file mode 100644
index 000000000..c72c7b169
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricExporter/InMemoryExporterFactory.php
@@ -0,0 +1,16 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricExporter;
+
+use OpenTelemetry\SDK\Metrics\MetricExporterFactoryInterface;
+use OpenTelemetry\SDK\Metrics\MetricExporterInterface;
+
+class InMemoryExporterFactory implements MetricExporterFactoryInterface
+{
+ public function create(): MetricExporterInterface
+ {
+ return new InMemoryExporter();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricExporter/NoopMetricExporter.php b/vendor/open-telemetry/sdk/Metrics/MetricExporter/NoopMetricExporter.php
new file mode 100644
index 000000000..0cac12fae
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricExporter/NoopMetricExporter.php
@@ -0,0 +1,23 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricExporter;
+
+use OpenTelemetry\SDK\Metrics\MetricExporterInterface;
+
+class NoopMetricExporter implements MetricExporterInterface
+{
+ /**
+ * @inheritDoc
+ */
+ public function export(iterable $batch): bool
+ {
+ return true;
+ }
+
+ public function shutdown(): bool
+ {
+ return true;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricExporter/NoopMetricExporterFactory.php b/vendor/open-telemetry/sdk/Metrics/MetricExporter/NoopMetricExporterFactory.php
new file mode 100644
index 000000000..ab2ab2af3
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricExporter/NoopMetricExporterFactory.php
@@ -0,0 +1,16 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricExporter;
+
+use OpenTelemetry\SDK\Metrics\MetricExporterFactoryInterface;
+use OpenTelemetry\SDK\Metrics\MetricExporterInterface;
+
+class NoopMetricExporterFactory implements MetricExporterFactoryInterface
+{
+ public function create(): MetricExporterInterface
+ {
+ return new NoopMetricExporter();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricExporter/_register.php b/vendor/open-telemetry/sdk/Metrics/MetricExporter/_register.php
new file mode 100644
index 000000000..fba543d02
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricExporter/_register.php
@@ -0,0 +1,7 @@
+<?php
+
+declare(strict_types=1);
+
+\OpenTelemetry\SDK\Registry::registerMetricExporterFactory('memory', \OpenTelemetry\SDK\Metrics\MetricExporter\InMemoryExporterFactory::class);
+\OpenTelemetry\SDK\Registry::registerMetricExporterFactory('console', \OpenTelemetry\SDK\Metrics\MetricExporter\ConsoleMetricExporterFactory::class);
+\OpenTelemetry\SDK\Registry::registerMetricExporterFactory('none', \OpenTelemetry\SDK\Metrics\MetricExporter\NoopMetricExporterFactory::class);
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricExporterFactoryInterface.php b/vendor/open-telemetry/sdk/Metrics/MetricExporterFactoryInterface.php
new file mode 100644
index 000000000..0d2541821
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricExporterFactoryInterface.php
@@ -0,0 +1,10 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+interface MetricExporterFactoryInterface
+{
+ public function create(): MetricExporterInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricExporterInterface.php b/vendor/open-telemetry/sdk/Metrics/MetricExporterInterface.php
new file mode 100644
index 000000000..fa47fbf9e
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricExporterInterface.php
@@ -0,0 +1,17 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\SDK\Metrics\Data\Metric;
+
+interface MetricExporterInterface
+{
+ /**
+ * @param iterable<int, Metric> $batch
+ */
+ public function export(iterable $batch): bool;
+
+ public function shutdown(): bool;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricFactory/StreamFactory.php b/vendor/open-telemetry/sdk/Metrics/MetricFactory/StreamFactory.php
new file mode 100644
index 000000000..2c3af4c06
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricFactory/StreamFactory.php
@@ -0,0 +1,187 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricFactory;
+
+use function array_keys;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Metrics\Aggregation\ExplicitBucketHistogramAggregation;
+use OpenTelemetry\SDK\Metrics\AggregationInterface;
+use OpenTelemetry\SDK\Metrics\AttributeProcessor\FilteredAttributeProcessor;
+use OpenTelemetry\SDK\Metrics\AttributeProcessorInterface;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilterInterface;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarReservoirInterface;
+use OpenTelemetry\SDK\Metrics\Exemplar\FilteredReservoir;
+use OpenTelemetry\SDK\Metrics\Exemplar\FixedSizeReservoir;
+use OpenTelemetry\SDK\Metrics\Exemplar\HistogramBucketReservoir;
+use OpenTelemetry\SDK\Metrics\Instrument;
+use OpenTelemetry\SDK\Metrics\MetricFactoryInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistrationInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricCollectorInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricRegistryInterface;
+use OpenTelemetry\SDK\Metrics\Stream\AsynchronousMetricStream;
+use OpenTelemetry\SDK\Metrics\Stream\MetricAggregator;
+use OpenTelemetry\SDK\Metrics\Stream\MetricAggregatorFactory;
+use OpenTelemetry\SDK\Metrics\Stream\MetricStreamInterface;
+use OpenTelemetry\SDK\Metrics\Stream\SynchronousMetricStream;
+use OpenTelemetry\SDK\Metrics\ViewProjection;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use function serialize;
+use function spl_object_id;
+use Throwable;
+
+/**
+ * @internal
+ */
+final class StreamFactory implements MetricFactoryInterface
+{
+ public function createAsynchronousObserver(
+ MetricRegistryInterface $registry,
+ ResourceInfo $resource,
+ InstrumentationScopeInterface $instrumentationScope,
+ Instrument $instrument,
+ int $timestamp,
+ iterable $views
+ ): array {
+ $streams = [];
+ $dedup = [];
+ foreach ($views as [$view, $registration]) {
+ if ($view->aggregation === null) {
+ continue;
+ }
+
+ $dedupId = $this->streamId($view->aggregation, $view->attributeKeys);
+ if (($streamId = $dedup[$dedupId] ?? null) === null) {
+ $stream = new AsynchronousMetricStream($view->aggregation, $timestamp);
+ $streamId = $registry->registerAsynchronousStream($instrument, $stream, new MetricAggregatorFactory(
+ $this->attributeProcessor($view->attributeKeys),
+ $view->aggregation,
+ ));
+
+ $streams[$streamId] = $stream;
+ $dedup[$dedupId] = $streamId;
+ }
+
+ $this->registerSource(
+ $view,
+ $instrument,
+ $instrumentationScope,
+ $resource,
+ $streams[$streamId],
+ $registry,
+ $registration,
+ $streamId,
+ );
+ }
+
+ return array_keys($streams);
+ }
+
+ public function createSynchronousWriter(
+ MetricRegistryInterface $registry,
+ ResourceInfo $resource,
+ InstrumentationScopeInterface $instrumentationScope,
+ Instrument $instrument,
+ int $timestamp,
+ iterable $views,
+ ?ExemplarFilterInterface $exemplarFilter = null
+ ): array {
+ $streams = [];
+ $dedup = [];
+ foreach ($views as [$view, $registration]) {
+ if ($view->aggregation === null) {
+ continue;
+ }
+
+ $dedupId = $this->streamId($view->aggregation, $view->attributeKeys);
+ if (($streamId = $dedup[$dedupId] ?? null) === null) {
+ $stream = new SynchronousMetricStream($view->aggregation, $timestamp);
+ $streamId = $registry->registerSynchronousStream($instrument, $stream, new MetricAggregator(
+ $this->attributeProcessor($view->attributeKeys),
+ $view->aggregation,
+ $this->createExemplarReservoir($view->aggregation, $exemplarFilter),
+ ));
+
+ $streams[$streamId] = $stream;
+ $dedup[$dedupId] = $streamId;
+ }
+
+ $this->registerSource(
+ $view,
+ $instrument,
+ $instrumentationScope,
+ $resource,
+ $streams[$streamId],
+ $registry,
+ $registration,
+ $streamId,
+ );
+ }
+
+ return array_keys($streams);
+ }
+
+ private function attributeProcessor(
+ ?array $attributeKeys
+ ): ?AttributeProcessorInterface {
+ return $attributeKeys !== null
+ ? new FilteredAttributeProcessor($attributeKeys)
+ : null;
+ }
+
+ private function createExemplarReservoir(
+ AggregationInterface $aggregation,
+ ?ExemplarFilterInterface $exemplarFilter
+ ): ?ExemplarReservoirInterface {
+ if (!$exemplarFilter) {
+ return null;
+ }
+
+ if ($aggregation instanceof ExplicitBucketHistogramAggregation && $aggregation->boundaries) {
+ $exemplarReservoir = new HistogramBucketReservoir($aggregation->boundaries);
+ } else {
+ $exemplarReservoir = new FixedSizeReservoir();
+ }
+
+ return new FilteredReservoir($exemplarReservoir, $exemplarFilter);
+ }
+
+ private function registerSource(
+ ViewProjection $view,
+ Instrument $instrument,
+ InstrumentationScopeInterface $instrumentationScope,
+ ResourceInfo $resource,
+ MetricStreamInterface $stream,
+ MetricCollectorInterface $metricCollector,
+ MetricRegistrationInterface $metricRegistration,
+ int $streamId
+ ): void {
+ $provider = new StreamMetricSourceProvider(
+ $view,
+ $instrument,
+ $instrumentationScope,
+ $resource,
+ $stream,
+ $metricCollector,
+ $streamId,
+ );
+
+ $metricRegistration->register($provider, $provider);
+ }
+
+ private function streamId(AggregationInterface $aggregation, ?array $attributeKeys): string
+ {
+ return $this->trySerialize($aggregation) . serialize($attributeKeys);
+ }
+
+ private function trySerialize(object $object)
+ {
+ try {
+ return serialize($object);
+ } catch (Throwable $e) {
+ }
+
+ return spl_object_id($object);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricFactory/StreamMetricSource.php b/vendor/open-telemetry/sdk/Metrics/MetricFactory/StreamMetricSource.php
new file mode 100644
index 000000000..4939a5341
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricFactory/StreamMetricSource.php
@@ -0,0 +1,44 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricFactory;
+
+use OpenTelemetry\SDK\Metrics\Data\Metric;
+use OpenTelemetry\SDK\Metrics\MetricSourceInterface;
+
+/**
+ * @internal
+ */
+final class StreamMetricSource implements MetricSourceInterface
+{
+ private StreamMetricSourceProvider $provider;
+ private int $reader;
+ public function __construct(StreamMetricSourceProvider $provider, int $reader)
+ {
+ $this->provider = $provider;
+ $this->reader = $reader;
+ }
+
+ public function collectionTimestamp(): int
+ {
+ return $this->provider->stream->timestamp();
+ }
+
+ public function collect(): Metric
+ {
+ return new Metric(
+ $this->provider->instrumentationLibrary,
+ $this->provider->resource,
+ $this->provider->view->name,
+ $this->provider->view->unit,
+ $this->provider->view->description,
+ $this->provider->stream->collect($this->reader),
+ );
+ }
+
+ public function __destruct()
+ {
+ $this->provider->stream->unregister($this->reader);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricFactory/StreamMetricSourceProvider.php b/vendor/open-telemetry/sdk/Metrics/MetricFactory/StreamMetricSourceProvider.php
new file mode 100644
index 000000000..657c3ce62
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricFactory/StreamMetricSourceProvider.php
@@ -0,0 +1,98 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricFactory;
+
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Metrics\Instrument;
+use OpenTelemetry\SDK\Metrics\MetricMetadataInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricCollectorInterface;
+use OpenTelemetry\SDK\Metrics\MetricSourceInterface;
+use OpenTelemetry\SDK\Metrics\MetricSourceProviderInterface;
+use OpenTelemetry\SDK\Metrics\Stream\MetricStreamInterface;
+use OpenTelemetry\SDK\Metrics\ViewProjection;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+
+/**
+ * @internal
+ */
+final class StreamMetricSourceProvider implements MetricSourceProviderInterface, MetricMetadataInterface
+{
+ /**
+ * @readonly
+ */
+ public ViewProjection $view;
+ /**
+ * @readonly
+ */
+ public Instrument $instrument;
+ /**
+ * @readonly
+ */
+ public InstrumentationScopeInterface $instrumentationLibrary;
+ /**
+ * @readonly
+ */
+ public ResourceInfo $resource;
+ /**
+ * @readonly
+ */
+ public MetricStreamInterface $stream;
+ /**
+ * @readonly
+ */
+ public MetricCollectorInterface $metricCollector;
+ /**
+ * @readonly
+ */
+ public int $streamId;
+
+ public function __construct(
+ ViewProjection $view,
+ Instrument $instrument,
+ InstrumentationScopeInterface $instrumentationLibrary,
+ ResourceInfo $resource,
+ MetricStreamInterface $stream,
+ MetricCollectorInterface $metricCollector,
+ int $streamId
+ ) {
+ $this->view = $view;
+ $this->instrument = $instrument;
+ $this->instrumentationLibrary = $instrumentationLibrary;
+ $this->resource = $resource;
+ $this->stream = $stream;
+ $this->metricCollector = $metricCollector;
+ $this->streamId = $streamId;
+ }
+
+ public function create($temporality): MetricSourceInterface
+ {
+ return new StreamMetricSource($this, $this->stream->register($temporality));
+ }
+
+ public function instrumentType()
+ {
+ return $this->instrument->type;
+ }
+
+ public function name(): string
+ {
+ return $this->view->name;
+ }
+
+ public function unit(): ?string
+ {
+ return $this->view->unit;
+ }
+
+ public function description(): ?string
+ {
+ return $this->view->description;
+ }
+
+ public function temporality()
+ {
+ return $this->stream->temporality();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricFactoryInterface.php b/vendor/open-telemetry/sdk/Metrics/MetricFactoryInterface.php
new file mode 100644
index 000000000..a1e228eef
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricFactoryInterface.php
@@ -0,0 +1,41 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilterInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricRegistryInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+
+/**
+ * @internal
+ */
+interface MetricFactoryInterface
+{
+ /**
+ * @param iterable<array{ViewProjection, MetricRegistrationInterface}> $views
+ */
+ public function createAsynchronousObserver(
+ MetricRegistryInterface $registry,
+ ResourceInfo $resource,
+ InstrumentationScopeInterface $instrumentationScope,
+ Instrument $instrument,
+ int $timestamp,
+ iterable $views
+ ): array;
+
+ /**
+ * @param iterable<array{ViewProjection, MetricRegistrationInterface}> $views
+ */
+ public function createSynchronousWriter(
+ MetricRegistryInterface $registry,
+ ResourceInfo $resource,
+ InstrumentationScopeInterface $instrumentationScope,
+ Instrument $instrument,
+ int $timestamp,
+ iterable $views,
+ ?ExemplarFilterInterface $exemplarFilter = null
+ ): array;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricMetadataInterface.php b/vendor/open-telemetry/sdk/Metrics/MetricMetadataInterface.php
new file mode 100644
index 000000000..aa1a02d60
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricMetadataInterface.php
@@ -0,0 +1,28 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\SDK\Metrics\Data\Temporality;
+
+interface MetricMetadataInterface
+{
+ /**
+ * @return string|InstrumentType
+ */
+ public function instrumentType();
+
+ public function name(): string;
+
+ public function unit(): ?string;
+
+ public function description(): ?string;
+
+ /**
+ * Returns the underlying temporality of this metric.
+ *
+ * @return string|Temporality internal temporality
+ */
+ public function temporality();
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricReader/ExportingReader.php b/vendor/open-telemetry/sdk/Metrics/MetricReader/ExportingReader.php
new file mode 100644
index 000000000..3c2eff9f1
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricReader/ExportingReader.php
@@ -0,0 +1,156 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricReader;
+
+use function array_keys;
+use OpenTelemetry\SDK\Metrics\AggregationInterface;
+use OpenTelemetry\SDK\Metrics\AggregationTemporalitySelectorInterface;
+use OpenTelemetry\SDK\Metrics\DefaultAggregationProviderInterface;
+use OpenTelemetry\SDK\Metrics\DefaultAggregationProviderTrait;
+use OpenTelemetry\SDK\Metrics\MetricExporterInterface;
+use OpenTelemetry\SDK\Metrics\MetricFactory\StreamMetricSourceProvider;
+use OpenTelemetry\SDK\Metrics\MetricMetadataInterface;
+use OpenTelemetry\SDK\Metrics\MetricReaderInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricCollectorInterface;
+use OpenTelemetry\SDK\Metrics\MetricSourceInterface;
+use OpenTelemetry\SDK\Metrics\MetricSourceProviderInterface;
+use OpenTelemetry\SDK\Metrics\MetricSourceRegistryInterface;
+use OpenTelemetry\SDK\Metrics\PushMetricExporterInterface;
+use OpenTelemetry\SDK\Metrics\StalenessHandlerInterface;
+use function spl_object_id;
+
+final class ExportingReader implements MetricReaderInterface, MetricSourceRegistryInterface, DefaultAggregationProviderInterface
+{
+ use DefaultAggregationProviderTrait { defaultAggregation as private _defaultAggregation; }
+
+ private MetricExporterInterface $exporter;
+ /** @var array<int, MetricSourceInterface> */
+ private array $sources = [];
+
+ /** @var array<int, MetricCollectorInterface> */
+ private array $registries = [];
+ /** @var array<int, array<int, int>> */
+ private array $streamIds = [];
+
+ private bool $closed = false;
+
+ public function __construct(MetricExporterInterface $exporter)
+ {
+ $this->exporter = $exporter;
+ }
+
+ public function defaultAggregation($instrumentType): ?AggregationInterface
+ {
+ if ($this->exporter instanceof DefaultAggregationProviderInterface) {
+ return $this->exporter->defaultAggregation($instrumentType);
+ }
+
+ return $this->_defaultAggregation($instrumentType);
+ }
+
+ public function add(MetricSourceProviderInterface $provider, MetricMetadataInterface $metadata, StalenessHandlerInterface $stalenessHandler): void
+ {
+ if ($this->closed) {
+ return;
+ }
+ if (!$this->exporter instanceof AggregationTemporalitySelectorInterface) {
+ return;
+ }
+ if (!$temporality = $this->exporter->temporality($metadata)) {
+ return;
+ }
+
+ $source = $provider->create($temporality);
+ $sourceId = spl_object_id($source);
+
+ $this->sources[$sourceId] = $source;
+ $stalenessHandler->onStale(function () use ($sourceId): void {
+ unset($this->sources[$sourceId]);
+ });
+
+ if (!$provider instanceof StreamMetricSourceProvider) {
+ return;
+ }
+
+ $streamId = $provider->streamId;
+ $registry = $provider->metricCollector;
+ $registryId = spl_object_id($registry);
+
+ $this->registries[$registryId] = $registry;
+ $this->streamIds[$registryId][$streamId] ??= 0;
+ $this->streamIds[$registryId][$streamId]++;
+
+ $stalenessHandler->onStale(function () use ($streamId, $registryId): void {
+ if (!--$this->streamIds[$registryId][$streamId]) {
+ unset($this->streamIds[$registryId][$streamId]);
+ if (!$this->streamIds[$registryId]) {
+ unset(
+ $this->registries[$registryId],
+ $this->streamIds[$registryId],
+ );
+ }
+ }
+ });
+ }
+
+ private function doCollect(): bool
+ {
+ foreach ($this->registries as $registryId => $registry) {
+ $streamIds = $this->streamIds[$registryId] ?? [];
+ $registry->collectAndPush(array_keys($streamIds));
+ }
+
+ $metrics = [];
+ foreach ($this->sources as $source) {
+ $metrics[] = $source->collect();
+ }
+
+ if ($metrics === []) {
+ return true;
+ }
+
+ return $this->exporter->export($metrics);
+ }
+
+ public function collect(): bool
+ {
+ if ($this->closed) {
+ return false;
+ }
+
+ return $this->doCollect();
+ }
+
+ public function shutdown(): bool
+ {
+ if ($this->closed) {
+ return false;
+ }
+
+ $this->closed = true;
+
+ $collect = $this->doCollect();
+ $shutdown = $this->exporter->shutdown();
+
+ $this->sources = [];
+
+ return $collect && $shutdown;
+ }
+
+ public function forceFlush(): bool
+ {
+ if ($this->closed) {
+ return false;
+ }
+ if ($this->exporter instanceof PushMetricExporterInterface) {
+ $collect = $this->doCollect();
+ $forceFlush = $this->exporter->forceFlush();
+
+ return $collect && $forceFlush;
+ }
+
+ return true;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricReaderInterface.php b/vendor/open-telemetry/sdk/Metrics/MetricReaderInterface.php
new file mode 100644
index 000000000..f5900eef5
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricReaderInterface.php
@@ -0,0 +1,14 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+interface MetricReaderInterface
+{
+ public function collect(): bool;
+
+ public function shutdown(): bool;
+
+ public function forceFlush(): bool;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricRegistration/MultiRegistryRegistration.php b/vendor/open-telemetry/sdk/Metrics/MetricRegistration/MultiRegistryRegistration.php
new file mode 100644
index 000000000..2472c096f
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricRegistration/MultiRegistryRegistration.php
@@ -0,0 +1,36 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricRegistration;
+
+use OpenTelemetry\SDK\Metrics\MetricMetadataInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistrationInterface;
+use OpenTelemetry\SDK\Metrics\MetricSourceProviderInterface;
+use OpenTelemetry\SDK\Metrics\MetricSourceRegistryInterface;
+use OpenTelemetry\SDK\Metrics\StalenessHandlerInterface;
+
+/**
+ * @internal
+ */
+final class MultiRegistryRegistration implements MetricRegistrationInterface
+{
+ private iterable $registries;
+ private StalenessHandlerInterface $stalenessHandler;
+
+ /**
+ * @param iterable<MetricSourceRegistryInterface> $registries
+ */
+ public function __construct(iterable $registries, StalenessHandlerInterface $stalenessHandler)
+ {
+ $this->registries = $registries;
+ $this->stalenessHandler = $stalenessHandler;
+ }
+
+ public function register(MetricSourceProviderInterface $provider, MetricMetadataInterface $metadata): void
+ {
+ foreach ($this->registries as $registry) {
+ $registry->add($provider, $metadata, $this->stalenessHandler);
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricRegistration/RegistryRegistration.php b/vendor/open-telemetry/sdk/Metrics/MetricRegistration/RegistryRegistration.php
new file mode 100644
index 000000000..3c1108902
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricRegistration/RegistryRegistration.php
@@ -0,0 +1,31 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricRegistration;
+
+use OpenTelemetry\SDK\Metrics\MetricMetadataInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistrationInterface;
+use OpenTelemetry\SDK\Metrics\MetricSourceProviderInterface;
+use OpenTelemetry\SDK\Metrics\MetricSourceRegistryInterface;
+use OpenTelemetry\SDK\Metrics\StalenessHandlerInterface;
+
+/**
+ * @internal
+ */
+final class RegistryRegistration implements MetricRegistrationInterface
+{
+ private MetricSourceRegistryInterface $registry;
+ private StalenessHandlerInterface $stalenessHandler;
+
+ public function __construct(MetricSourceRegistryInterface $registry, StalenessHandlerInterface $stalenessHandler)
+ {
+ $this->registry = $registry;
+ $this->stalenessHandler = $stalenessHandler;
+ }
+
+ public function register(MetricSourceProviderInterface $provider, MetricMetadataInterface $metadata): void
+ {
+ $this->registry->add($provider, $metadata, $this->stalenessHandler);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricRegistrationInterface.php b/vendor/open-telemetry/sdk/Metrics/MetricRegistrationInterface.php
new file mode 100644
index 000000000..b0cc2484e
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricRegistrationInterface.php
@@ -0,0 +1,13 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+/**
+ * @internal
+ */
+interface MetricRegistrationInterface
+{
+ public function register(MetricSourceProviderInterface $provider, MetricMetadataInterface $metadata): void;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricCollectorInterface.php b/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricCollectorInterface.php
new file mode 100644
index 000000000..4e8e91ced
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricCollectorInterface.php
@@ -0,0 +1,13 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricRegistry;
+
+/**
+ * @internal
+ */
+interface MetricCollectorInterface
+{
+ public function collectAndPush(iterable $streamIds): void;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricRegistry.php b/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricRegistry.php
new file mode 100644
index 000000000..9a18d2a84
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricRegistry.php
@@ -0,0 +1,184 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricRegistry;
+
+use function array_key_last;
+use Closure;
+use OpenTelemetry\Context\Context;
+use OpenTelemetry\Context\ContextStorageInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesFactoryInterface;
+use OpenTelemetry\SDK\Common\Time\ClockInterface;
+use OpenTelemetry\SDK\Metrics\Instrument;
+use OpenTelemetry\SDK\Metrics\Stream\MetricAggregatorFactoryInterface;
+use OpenTelemetry\SDK\Metrics\Stream\MetricAggregatorInterface;
+use OpenTelemetry\SDK\Metrics\Stream\MetricStreamInterface;
+use function spl_object_id;
+
+/**
+ * @internal
+ */
+final class MetricRegistry implements MetricRegistryInterface, MetricWriterInterface
+{
+ private ?ContextStorageInterface $contextStorage;
+ private AttributesFactoryInterface $attributesFactory;
+ private ClockInterface $clock;
+
+ /** @var array<int, MetricStreamInterface> */
+ private array $streams = [];
+ /** @var array<int, MetricAggregatorInterface> */
+ private array $synchronousAggregators = [];
+ /** @var array<int, MetricAggregatorFactoryInterface> */
+ private array $asynchronousAggregatorFactories = [];
+
+ /** @var array<int, array<int, int>> */
+ private array $instrumentToStreams = [];
+ /** @var array<int, int> */
+ private array $streamToInstrument = [];
+ /** @var array<int, array<int, int>> */
+ private array $instrumentToCallbacks = [];
+ /** @var array<int, Closure> */
+ private array $asynchronousCallbacks = [];
+ /** @var array<int, list<int>> */
+ private array $asynchronousCallbackArguments = [];
+
+ public function __construct(
+ ?ContextStorageInterface $contextStorage,
+ AttributesFactoryInterface $attributesFactory,
+ ClockInterface $clock
+ ) {
+ $this->contextStorage = $contextStorage;
+ $this->attributesFactory = $attributesFactory;
+ $this->clock = $clock;
+ }
+
+ public function registerSynchronousStream(Instrument $instrument, MetricStreamInterface $stream, MetricAggregatorInterface $aggregator): int
+ {
+ $this->streams[] = $stream;
+ $streamId = array_key_last($this->streams);
+ $instrumentId = spl_object_id($instrument);
+
+ $this->synchronousAggregators[$streamId] = $aggregator;
+ $this->instrumentToStreams[$instrumentId][$streamId] = $streamId;
+ $this->streamToInstrument[$streamId] = $instrumentId;
+
+ return $streamId;
+ }
+
+ public function registerAsynchronousStream(Instrument $instrument, MetricStreamInterface $stream, MetricAggregatorFactoryInterface $aggregatorFactory): int
+ {
+ $this->streams[] = $stream;
+ $streamId = array_key_last($this->streams);
+ $instrumentId = spl_object_id($instrument);
+
+ $this->asynchronousAggregatorFactories[$streamId] = $aggregatorFactory;
+ $this->instrumentToStreams[$instrumentId][$streamId] = $streamId;
+ $this->streamToInstrument[$streamId] = $instrumentId;
+
+ return $streamId;
+ }
+
+ public function unregisterStream(int $streamId): void
+ {
+ $instrumentId = $this->streamToInstrument[$streamId];
+ unset(
+ $this->streams[$streamId],
+ $this->synchronousAggregators[$streamId],
+ $this->asynchronousAggregatorFactories[$streamId],
+ $this->instrumentToStreams[$instrumentId][$streamId],
+ $this->streamToInstrument[$streamId],
+ );
+ if (!$this->instrumentToStreams[$instrumentId]) {
+ unset($this->instrumentToStreams[$instrumentId]);
+ }
+ }
+
+ public function record(Instrument $instrument, $value, iterable $attributes = [], $context = null): void
+ {
+ $context = Context::resolve($context, $this->contextStorage);
+ $attributes = $this->attributesFactory->builder($attributes)->build();
+ $timestamp = $this->clock->now();
+ $instrumentId = spl_object_id($instrument);
+ foreach ($this->instrumentToStreams[$instrumentId] ?? [] as $streamId) {
+ if ($aggregator = $this->synchronousAggregators[$streamId] ?? null) {
+ $aggregator->record($value, $attributes, $context, $timestamp);
+ }
+ }
+ }
+
+ public function registerCallback(Closure $callback, Instrument $instrument, Instrument ...$instruments): int
+ {
+ $callbackId = array_key_last($this->asynchronousCallbacks) + 1;
+ $this->asynchronousCallbacks[$callbackId] = $callback;
+
+ $instrumentId = spl_object_id($instrument);
+ $this->asynchronousCallbackArguments[$callbackId] = [$instrumentId];
+ $this->instrumentToCallbacks[$instrumentId][$callbackId] = $callbackId;
+ foreach ($instruments as $instrument) {
+ $instrumentId = spl_object_id($instrument);
+ $this->asynchronousCallbackArguments[$callbackId][] = $instrumentId;
+ $this->instrumentToCallbacks[$instrumentId][$callbackId] = $callbackId;
+ }
+
+ return $callbackId;
+ }
+
+ public function unregisterCallback(int $callbackId): void
+ {
+ $instrumentIds = $this->asynchronousCallbackArguments[$callbackId];
+ unset(
+ $this->asynchronousCallbacks[$callbackId],
+ $this->asynchronousCallbackArguments[$callbackId],
+ );
+ foreach ($instrumentIds as $instrumentId) {
+ unset($this->instrumentToCallbacks[$instrumentId][$callbackId]);
+ if (!$this->instrumentToCallbacks[$instrumentId]) {
+ unset($this->instrumentToCallbacks[$instrumentId]);
+ }
+ }
+ }
+
+ public function collectAndPush(iterable $streamIds): void
+ {
+ $timestamp = $this->clock->now();
+ $aggregators = [];
+ $observers = [];
+ $callbackIds = [];
+ foreach ($streamIds as $streamId) {
+ if (!$aggregator = $this->synchronousAggregators[$streamId] ?? null) {
+ $aggregator = $this->asynchronousAggregatorFactories[$streamId]->create();
+
+ $instrumentId = $this->streamToInstrument[$streamId];
+ $observers[$instrumentId] ??= new MultiObserver($this->attributesFactory, $timestamp);
+ $observers[$instrumentId]->writers[] = $aggregator;
+ foreach ($this->instrumentToCallbacks[$instrumentId] ?? [] as $callbackId) {
+ $callbackIds[$callbackId] = $callbackId;
+ }
+ }
+
+ $aggregators[$streamId] = $aggregator;
+ }
+
+ $noopObserver = new NoopObserver();
+ $callbacks = [];
+ foreach ($callbackIds as $callbackId) {
+ $args = [];
+ foreach ($this->asynchronousCallbackArguments[$callbackId] as $instrumentId) {
+ $args[] = $observers[$instrumentId] ?? $noopObserver;
+ }
+ $callback = $this->asynchronousCallbacks[$callbackId];
+ $callbacks[] = static fn () => $callback(...$args);
+ }
+ foreach ($callbacks as $callback) {
+ $callback();
+ }
+
+ $timestamp = $this->clock->now();
+ foreach ($aggregators as $streamId => $aggregator) {
+ if ($stream = $this->streams[$streamId] ?? null) {
+ $stream->push($aggregator->collect($timestamp));
+ }
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricRegistryInterface.php b/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricRegistryInterface.php
new file mode 100644
index 000000000..e86731138
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricRegistryInterface.php
@@ -0,0 +1,22 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricRegistry;
+
+use OpenTelemetry\SDK\Metrics\Instrument;
+use OpenTelemetry\SDK\Metrics\Stream\MetricAggregatorFactoryInterface;
+use OpenTelemetry\SDK\Metrics\Stream\MetricAggregatorInterface;
+use OpenTelemetry\SDK\Metrics\Stream\MetricStreamInterface;
+
+/**
+ * @internal
+ */
+interface MetricRegistryInterface extends MetricCollectorInterface
+{
+ public function registerSynchronousStream(Instrument $instrument, MetricStreamInterface $stream, MetricAggregatorInterface $aggregator): int;
+
+ public function registerAsynchronousStream(Instrument $instrument, MetricStreamInterface $stream, MetricAggregatorFactoryInterface $aggregatorFactory): int;
+
+ public function unregisterStream(int $streamId): void;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricWriterInterface.php b/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricWriterInterface.php
new file mode 100644
index 000000000..e5ff7eb5c
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MetricWriterInterface.php
@@ -0,0 +1,20 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricRegistry;
+
+use Closure;
+use OpenTelemetry\SDK\Metrics\Instrument;
+
+/**
+ * @internal
+ */
+interface MetricWriterInterface
+{
+ public function record(Instrument $instrument, $value, iterable $attributes = [], $context = null): void;
+
+ public function registerCallback(Closure $callback, Instrument $instrument, Instrument ...$instruments): int;
+
+ public function unregisterCallback(int $callbackId): void;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MultiObserver.php b/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MultiObserver.php
new file mode 100644
index 000000000..f36f74a2a
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricRegistry/MultiObserver.php
@@ -0,0 +1,37 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricRegistry;
+
+use OpenTelemetry\API\Metrics\ObserverInterface;
+use OpenTelemetry\Context\Context;
+use OpenTelemetry\SDK\Common\Attribute\AttributesFactoryInterface;
+use OpenTelemetry\SDK\Metrics\Stream\WritableMetricStreamInterface;
+
+/**
+ * @internal
+ */
+final class MultiObserver implements ObserverInterface
+{
+ private AttributesFactoryInterface $attributesFactory;
+ private int $timestamp;
+
+ /** @var list<WritableMetricStreamInterface> */
+ public array $writers = [];
+
+ public function __construct(AttributesFactoryInterface $attributesFactory, int $timestamp)
+ {
+ $this->attributesFactory = $attributesFactory;
+ $this->timestamp = $timestamp;
+ }
+
+ public function observe($amount, iterable $attributes = []): void
+ {
+ $context = Context::getRoot();
+ $attributes = $this->attributesFactory->builder($attributes)->build();
+ foreach ($this->writers as $writer) {
+ $writer->record($amount, $attributes, $context, $this->timestamp);
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricRegistry/NoopObserver.php b/vendor/open-telemetry/sdk/Metrics/MetricRegistry/NoopObserver.php
new file mode 100644
index 000000000..efbd94dac
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricRegistry/NoopObserver.php
@@ -0,0 +1,18 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\MetricRegistry;
+
+use OpenTelemetry\API\Metrics\ObserverInterface;
+
+/**
+ * @internal
+ */
+final class NoopObserver implements ObserverInterface
+{
+ public function observe($amount, iterable $attributes = []): void
+ {
+ // no-op
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricSourceInterface.php b/vendor/open-telemetry/sdk/Metrics/MetricSourceInterface.php
new file mode 100644
index 000000000..5f00a0717
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricSourceInterface.php
@@ -0,0 +1,24 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\SDK\Metrics\Data\Metric;
+
+interface MetricSourceInterface
+{
+ /**
+ * Returns the last metric collection timestamp.
+ *
+ * @return int last collection timestamp
+ */
+ public function collectionTimestamp(): int;
+
+ /**
+ * Collects metric data from the underlying provider.
+ *
+ * @return Metric collected metric
+ */
+ public function collect(): Metric;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricSourceProviderInterface.php b/vendor/open-telemetry/sdk/Metrics/MetricSourceProviderInterface.php
new file mode 100644
index 000000000..f8b6ea438
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricSourceProviderInterface.php
@@ -0,0 +1,15 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\SDK\Metrics\Data\Temporality;
+
+interface MetricSourceProviderInterface
+{
+ /**
+ * @param string|Temporality $temporality
+ */
+ public function create($temporality): MetricSourceInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/MetricSourceRegistryInterface.php b/vendor/open-telemetry/sdk/Metrics/MetricSourceRegistryInterface.php
new file mode 100644
index 000000000..dd7ff53ac
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/MetricSourceRegistryInterface.php
@@ -0,0 +1,10 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+interface MetricSourceRegistryInterface
+{
+ public function add(MetricSourceProviderInterface $provider, MetricMetadataInterface $metadata, StalenessHandlerInterface $stalenessHandler): void;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/NoopMeterProvider.php b/vendor/open-telemetry/sdk/Metrics/NoopMeterProvider.php
new file mode 100644
index 000000000..2efb484d3
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/NoopMeterProvider.php
@@ -0,0 +1,26 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\API\Metrics\MeterInterface;
+use OpenTelemetry\API\Metrics\Noop\NoopMeter;
+
+class NoopMeterProvider implements MeterProviderInterface
+{
+ public function shutdown(): bool
+ {
+ return true;
+ }
+
+ public function forceFlush(): bool
+ {
+ return true;
+ }
+
+ public function getMeter(string $name, ?string $version = null, ?string $schemaUrl = null, iterable $attributes = []): MeterInterface
+ {
+ return new NoopMeter();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/ObservableCallback.php b/vendor/open-telemetry/sdk/Metrics/ObservableCallback.php
new file mode 100644
index 000000000..ffe5ead87
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/ObservableCallback.php
@@ -0,0 +1,58 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\API\Metrics\ObservableCallbackInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricWriterInterface;
+
+/**
+ * @internal
+ */
+final class ObservableCallback implements ObservableCallbackInterface
+{
+ private MetricWriterInterface $writer;
+ private ReferenceCounterInterface $referenceCounter;
+ private ?int $callbackId;
+ private ?ObservableCallbackDestructor $callbackDestructor;
+ /** @phpstan-ignore-next-line */
+ private ?object $target;
+
+ public function __construct(MetricWriterInterface $writer, ReferenceCounterInterface $referenceCounter, int $callbackId, ?ObservableCallbackDestructor $callbackDestructor, ?object $target)
+ {
+ $this->writer = $writer;
+ $this->referenceCounter = $referenceCounter;
+ $this->callbackId = $callbackId;
+ $this->callbackDestructor = $callbackDestructor;
+ $this->target = $target;
+ }
+
+ public function detach(): void
+ {
+ if ($this->callbackId === null) {
+ return;
+ }
+
+ $this->writer->unregisterCallback($this->callbackId);
+ $this->referenceCounter->release();
+ if ($this->callbackDestructor !== null) {
+ unset($this->callbackDestructor->callbackIds[$this->callbackId]);
+ }
+
+ $this->callbackId = null;
+ }
+
+ public function __destruct()
+ {
+ if ($this->callbackDestructor !== null) {
+ return;
+ }
+ if ($this->callbackId === null) {
+ return;
+ }
+
+ $this->referenceCounter->acquire(true);
+ $this->referenceCounter->release();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/ObservableCallbackDestructor.php b/vendor/open-telemetry/sdk/Metrics/ObservableCallbackDestructor.php
new file mode 100644
index 000000000..0dfea3907
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/ObservableCallbackDestructor.php
@@ -0,0 +1,32 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricWriterInterface;
+
+/**
+ * @internal
+ */
+final class ObservableCallbackDestructor
+{
+ /** @var array<int, int> */
+ public array $callbackIds = [];
+ private MetricWriterInterface $writer;
+ private ReferenceCounterInterface $referenceCounter;
+
+ public function __construct(MetricWriterInterface $writer, ReferenceCounterInterface $referenceCounter)
+ {
+ $this->writer = $writer;
+ $this->referenceCounter = $referenceCounter;
+ }
+
+ public function __destruct()
+ {
+ foreach ($this->callbackIds as $callbackId) {
+ $this->writer->unregisterCallback($callbackId);
+ $this->referenceCounter->release();
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/ObservableCounter.php b/vendor/open-telemetry/sdk/Metrics/ObservableCounter.php
new file mode 100644
index 000000000..99ae43eee
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/ObservableCounter.php
@@ -0,0 +1,15 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\API\Metrics\ObservableCounterInterface;
+
+/**
+ * @internal
+ */
+final class ObservableCounter implements ObservableCounterInterface
+{
+ use ObservableInstrumentTrait;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/ObservableGauge.php b/vendor/open-telemetry/sdk/Metrics/ObservableGauge.php
new file mode 100644
index 000000000..88c1a546c
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/ObservableGauge.php
@@ -0,0 +1,15 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\API\Metrics\ObservableGaugeInterface;
+
+/**
+ * @internal
+ */
+final class ObservableGauge implements ObservableGaugeInterface
+{
+ use ObservableInstrumentTrait;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/ObservableInstrumentTrait.php b/vendor/open-telemetry/sdk/Metrics/ObservableInstrumentTrait.php
new file mode 100644
index 000000000..b7fdcf5f8
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/ObservableInstrumentTrait.php
@@ -0,0 +1,61 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use ArrayAccess;
+use OpenTelemetry\API\Metrics\ObservableCallbackInterface;
+use OpenTelemetry\API\Metrics\ObserverInterface;
+use function OpenTelemetry\SDK\Common\Util\closure;
+use function OpenTelemetry\SDK\Common\Util\weaken;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricWriterInterface;
+
+/**
+ * @internal
+ */
+trait ObservableInstrumentTrait
+{
+ private MetricWriterInterface $writer;
+ private Instrument $instrument;
+ private ReferenceCounterInterface $referenceCounter;
+ private ArrayAccess $destructors;
+
+ public function __construct(
+ MetricWriterInterface $writer,
+ Instrument $instrument,
+ ReferenceCounterInterface $referenceCounter,
+ ArrayAccess $destructors
+ ) {
+ $this->writer = $writer;
+ $this->instrument = $instrument;
+ $this->referenceCounter = $referenceCounter;
+ $this->destructors = $destructors;
+
+ $this->referenceCounter->acquire();
+ }
+
+ public function __destruct()
+ {
+ $this->referenceCounter->release();
+ }
+
+ /**
+ * @param callable(ObserverInterface): void $callback
+ */
+ public function observe(callable $callback): ObservableCallbackInterface
+ {
+ $callback = weaken(closure($callback), $target);
+
+ $callbackId = $this->writer->registerCallback($callback, $this->instrument);
+ $this->referenceCounter->acquire();
+
+ $destructor = null;
+ if ($target) {
+ $destructor = $this->destructors[$target] ??= new ObservableCallbackDestructor($this->writer, $this->referenceCounter);
+ $destructor->callbackIds[$callbackId] = $callbackId;
+ }
+
+ return new ObservableCallback($this->writer, $this->referenceCounter, $callbackId, $destructor, $target);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/ObservableUpDownCounter.php b/vendor/open-telemetry/sdk/Metrics/ObservableUpDownCounter.php
new file mode 100644
index 000000000..8d21be734
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/ObservableUpDownCounter.php
@@ -0,0 +1,15 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\API\Metrics\ObservableUpDownCounterInterface;
+
+/**
+ * @internal
+ */
+final class ObservableUpDownCounter implements ObservableUpDownCounterInterface
+{
+ use ObservableInstrumentTrait;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/PushMetricExporterInterface.php b/vendor/open-telemetry/sdk/Metrics/PushMetricExporterInterface.php
new file mode 100644
index 000000000..d24b0e396
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/PushMetricExporterInterface.php
@@ -0,0 +1,12 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\SDK\Metrics;
+
+interface PushMetricExporterInterface extends Metrics\MetricExporterInterface
+{
+ public function forceFlush(): bool;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/ReferenceCounterInterface.php b/vendor/open-telemetry/sdk/Metrics/ReferenceCounterInterface.php
new file mode 100644
index 000000000..f7e70b644
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/ReferenceCounterInterface.php
@@ -0,0 +1,15 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+/**
+ * @internal
+ */
+interface ReferenceCounterInterface
+{
+ public function acquire(bool $persistent = false): void;
+
+ public function release(): void;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/StalenessHandler/DelayedStalenessHandler.php b/vendor/open-telemetry/sdk/Metrics/StalenessHandler/DelayedStalenessHandler.php
new file mode 100644
index 000000000..66b271018
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/StalenessHandler/DelayedStalenessHandler.php
@@ -0,0 +1,71 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\StalenessHandler;
+
+use function assert;
+use Closure;
+use OpenTelemetry\SDK\Metrics\ReferenceCounterInterface;
+use OpenTelemetry\SDK\Metrics\StalenessHandlerInterface;
+
+/**
+ * @internal
+ */
+final class DelayedStalenessHandler implements StalenessHandlerInterface, ReferenceCounterInterface
+{
+ private Closure $stale;
+ private Closure $freshen;
+
+ /** @var Closure[]|null */
+ private ?array $onStale = [];
+ private int $count = 0;
+
+ public function __construct(Closure $stale, Closure $freshen)
+ {
+ $this->stale = $stale;
+ $this->freshen = $freshen;
+ }
+
+ public function acquire(bool $persistent = false): void
+ {
+ if ($this->count === 0) {
+ ($this->freshen)($this);
+ }
+
+ $this->count++;
+
+ if ($persistent) {
+ $this->onStale = null;
+ }
+ }
+
+ public function release(): void
+ {
+ if (--$this->count || $this->onStale === null) {
+ return;
+ }
+
+ ($this->stale)($this);
+ }
+
+ public function onStale(Closure $callback): void
+ {
+ if ($this->onStale === null) {
+ return;
+ }
+
+ $this->onStale[] = $callback;
+ }
+
+ public function triggerStale(): void
+ {
+ assert($this->onStale !== null);
+
+ $callbacks = $this->onStale;
+ $this->onStale = [];
+ foreach ($callbacks as $callback) {
+ $callback();
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/StalenessHandler/DelayedStalenessHandlerFactory.php b/vendor/open-telemetry/sdk/Metrics/StalenessHandler/DelayedStalenessHandlerFactory.php
new file mode 100644
index 000000000..0d719c74f
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/StalenessHandler/DelayedStalenessHandlerFactory.php
@@ -0,0 +1,64 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\StalenessHandler;
+
+use ArrayAccess;
+use Closure;
+use OpenTelemetry\SDK\Common\Time\ClockInterface;
+use OpenTelemetry\SDK\Common\Util\WeakMap;
+use OpenTelemetry\SDK\Metrics\StalenessHandlerFactoryInterface;
+use OpenTelemetry\SDK\Metrics\StalenessHandlerInterface;
+use Traversable;
+
+final class DelayedStalenessHandlerFactory implements StalenessHandlerFactoryInterface
+{
+ private ClockInterface $clock;
+ private int $nanoDelay;
+
+ private Closure $stale;
+ private Closure $freshen;
+
+ /** @var ArrayAccess<DelayedStalenessHandler, int>&Traversable<DelayedStalenessHandler, int> */
+ private $staleHandlers;
+
+ /**
+ * @param float $delay delay in seconds
+ */
+ public function __construct(ClockInterface $clock, float $delay)
+ {
+ $this->clock = $clock;
+ $this->nanoDelay = (int) ($delay * 1e9);
+
+ $this->stale = function (DelayedStalenessHandler $handler): void {
+ $this->staleHandlers[$handler] = $this->clock->now();
+ };
+ $this->freshen = function (DelayedStalenessHandler $handler): void {
+ unset($this->staleHandlers[$handler]);
+ };
+
+ $this->staleHandlers = WeakMap::create();
+ }
+
+ public function create(): StalenessHandlerInterface
+ {
+ $this->triggerStaleHandlers();
+
+ return new DelayedStalenessHandler($this->stale, $this->freshen);
+ }
+
+ private function triggerStaleHandlers(): void
+ {
+ $expired = $this->clock->now() - $this->nanoDelay;
+ foreach ($this->staleHandlers as $handler => $timestamp) {
+ if ($timestamp > $expired) {
+ break;
+ }
+
+ /** @var DelayedStalenessHandler $handler */
+ unset($this->staleHandlers[$handler]);
+ $handler->triggerStale();
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/StalenessHandler/ImmediateStalenessHandler.php b/vendor/open-telemetry/sdk/Metrics/StalenessHandler/ImmediateStalenessHandler.php
new file mode 100644
index 000000000..a5b32d5c4
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/StalenessHandler/ImmediateStalenessHandler.php
@@ -0,0 +1,50 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\StalenessHandler;
+
+use Closure;
+use OpenTelemetry\SDK\Metrics\ReferenceCounterInterface;
+use OpenTelemetry\SDK\Metrics\StalenessHandlerInterface;
+
+/**
+ * @internal
+ */
+final class ImmediateStalenessHandler implements StalenessHandlerInterface, ReferenceCounterInterface
+{
+ /** @var Closure[]|null */
+ private ?array $onStale = [];
+ private int $count = 0;
+
+ public function acquire(bool $persistent = false): void
+ {
+ $this->count++;
+
+ if ($persistent) {
+ $this->onStale = null;
+ }
+ }
+
+ public function release(): void
+ {
+ if (--$this->count !== 0 || !$this->onStale) {
+ return;
+ }
+
+ $callbacks = $this->onStale;
+ $this->onStale = [];
+ foreach ($callbacks as $callback) {
+ $callback();
+ }
+ }
+
+ public function onStale(Closure $callback): void
+ {
+ if ($this->onStale === null) {
+ return;
+ }
+
+ $this->onStale[] = $callback;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/StalenessHandler/ImmediateStalenessHandlerFactory.php b/vendor/open-telemetry/sdk/Metrics/StalenessHandler/ImmediateStalenessHandlerFactory.php
new file mode 100644
index 000000000..899615dea
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/StalenessHandler/ImmediateStalenessHandlerFactory.php
@@ -0,0 +1,16 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\StalenessHandler;
+
+use OpenTelemetry\SDK\Metrics\StalenessHandlerFactoryInterface;
+use OpenTelemetry\SDK\Metrics\StalenessHandlerInterface;
+
+final class ImmediateStalenessHandlerFactory implements StalenessHandlerFactoryInterface
+{
+ public function create(): StalenessHandlerInterface
+ {
+ return new ImmediateStalenessHandler();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/StalenessHandler/NoopStalenessHandler.php b/vendor/open-telemetry/sdk/Metrics/StalenessHandler/NoopStalenessHandler.php
new file mode 100644
index 000000000..00d432b6b
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/StalenessHandler/NoopStalenessHandler.php
@@ -0,0 +1,30 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\StalenessHandler;
+
+use Closure;
+use OpenTelemetry\SDK\Metrics\ReferenceCounterInterface;
+use OpenTelemetry\SDK\Metrics\StalenessHandlerInterface;
+
+/**
+ * @internal
+ */
+final class NoopStalenessHandler implements StalenessHandlerInterface, ReferenceCounterInterface
+{
+ public function acquire(bool $persistent = false): void
+ {
+ // no-op
+ }
+
+ public function release(): void
+ {
+ // no-op
+ }
+
+ public function onStale(Closure $callback): void
+ {
+ // no-op
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/StalenessHandler/NoopStalenessHandlerFactory.php b/vendor/open-telemetry/sdk/Metrics/StalenessHandler/NoopStalenessHandlerFactory.php
new file mode 100644
index 000000000..07f34e3b0
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/StalenessHandler/NoopStalenessHandlerFactory.php
@@ -0,0 +1,18 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\StalenessHandler;
+
+use OpenTelemetry\SDK\Metrics\StalenessHandlerFactoryInterface;
+use OpenTelemetry\SDK\Metrics\StalenessHandlerInterface;
+
+final class NoopStalenessHandlerFactory implements StalenessHandlerFactoryInterface
+{
+ public function create(): StalenessHandlerInterface
+ {
+ static $instance;
+
+ return $instance ??= new NoopStalenessHandler();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/StalenessHandlerFactoryInterface.php b/vendor/open-telemetry/sdk/Metrics/StalenessHandlerFactoryInterface.php
new file mode 100644
index 000000000..e22385420
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/StalenessHandlerFactoryInterface.php
@@ -0,0 +1,13 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+interface StalenessHandlerFactoryInterface
+{
+ /**
+ * @return StalenessHandlerInterface&ReferenceCounterInterface
+ */
+ public function create(): StalenessHandlerInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/StalenessHandlerInterface.php b/vendor/open-telemetry/sdk/Metrics/StalenessHandlerInterface.php
new file mode 100644
index 000000000..c85d86f8e
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/StalenessHandlerInterface.php
@@ -0,0 +1,12 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use Closure;
+
+interface StalenessHandlerInterface
+{
+ public function onStale(Closure $callback): void;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Stream/AsynchronousMetricStream.php b/vendor/open-telemetry/sdk/Metrics/Stream/AsynchronousMetricStream.php
new file mode 100644
index 000000000..cb32f94df
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Stream/AsynchronousMetricStream.php
@@ -0,0 +1,111 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Stream;
+
+use function array_search;
+use function count;
+use OpenTelemetry\SDK\Metrics\AggregationInterface;
+use OpenTelemetry\SDK\Metrics\Data\DataInterface;
+use OpenTelemetry\SDK\Metrics\Data\Exemplar;
+use OpenTelemetry\SDK\Metrics\Data\Temporality;
+
+/**
+ * @internal
+ */
+final class AsynchronousMetricStream implements MetricStreamInterface
+{
+ private AggregationInterface $aggregation;
+
+ private int $startTimestamp;
+ private Metric $metric;
+
+ /** @var array<int, Metric|null> */
+ private array $lastReads = [];
+
+ public function __construct(AggregationInterface $aggregation, int $startTimestamp)
+ {
+ $this->aggregation = $aggregation;
+ $this->startTimestamp = $startTimestamp;
+ $this->metric = new Metric([], [], $startTimestamp);
+ }
+
+ public function temporality()
+ {
+ return Temporality::CUMULATIVE;
+ }
+
+ public function timestamp(): int
+ {
+ return $this->metric->timestamp;
+ }
+
+ public function push(Metric $metric): void
+ {
+ $this->metric = $metric;
+ }
+
+ public function register($temporality): int
+ {
+ if ($temporality === Temporality::CUMULATIVE) {
+ return -1;
+ }
+
+ if (($reader = array_search(null, $this->lastReads, true)) === false) {
+ $reader = count($this->lastReads);
+ }
+
+ $this->lastReads[$reader] = $this->metric;
+
+ return $reader;
+ }
+
+ public function unregister(int $reader): void
+ {
+ if (!isset($this->lastReads[$reader])) {
+ return;
+ }
+
+ $this->lastReads[$reader] = null;
+ }
+
+ public function collect(int $reader): DataInterface
+ {
+ $metric = $this->metric;
+
+ if (($lastRead = $this->lastReads[$reader] ?? null) === null) {
+ $temporality = Temporality::CUMULATIVE;
+ $startTimestamp = $this->startTimestamp;
+ } else {
+ $temporality = Temporality::DELTA;
+ $startTimestamp = $lastRead->timestamp;
+
+ $this->lastReads[$reader] = $metric;
+ $metric = $this->diff($lastRead, $metric);
+ }
+
+ return $this->aggregation->toData(
+ $metric->attributes,
+ $metric->summaries,
+ Exemplar::groupByIndex($metric->exemplars),
+ $startTimestamp,
+ $metric->timestamp,
+ $temporality,
+ );
+ }
+
+ private function diff(Metric $lastRead, Metric $metric): Metric
+ {
+ $diff = clone $metric;
+ foreach ($metric->summaries as $k => $summary) {
+ if (!isset($lastRead->summaries[$k])) {
+ continue;
+ }
+
+ $diff->summaries[$k] = $this->aggregation->diff($lastRead->summaries[$k], $summary);
+ }
+
+ return $diff;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Stream/Delta.php b/vendor/open-telemetry/sdk/Metrics/Stream/Delta.php
new file mode 100644
index 000000000..a4ff56d71
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Stream/Delta.php
@@ -0,0 +1,33 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Stream;
+
+use GMP;
+
+/**
+ * @internal
+ */
+final class Delta
+{
+ public Metric $metric;
+ /**
+ * @psalm-suppress UndefinedDocblockClass
+ * @phan-suppress PhanUndeclaredTypeProperty
+ * @var int|GMP
+ */
+ public $readers;
+ public ?self $prev;
+ /**
+ * @psalm-suppress UndefinedDocblockClass
+ * @phan-suppress PhanUndeclaredTypeParameter
+ * @param int|GMP $readers
+ */
+ public function __construct(Metric $metric, $readers, ?self $prev = null)
+ {
+ $this->metric = $metric;
+ $this->readers = $readers;
+ $this->prev = $prev;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Stream/DeltaStorage.php b/vendor/open-telemetry/sdk/Metrics/Stream/DeltaStorage.php
new file mode 100644
index 000000000..b46a28d65
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Stream/DeltaStorage.php
@@ -0,0 +1,110 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Stream;
+
+use function assert;
+use GMP;
+use OpenTelemetry\SDK\Metrics\AggregationInterface;
+
+/**
+ * @internal
+ */
+final class DeltaStorage
+{
+ private AggregationInterface $aggregation;
+ private Delta $head;
+
+ public function __construct(AggregationInterface $aggregation)
+ {
+ $this->aggregation = $aggregation;
+ $this->head = new Delta(new Metric([], [], 0), 0);
+
+ /** @phan-suppress-next-line PhanTypeObjectUnsetDeclaredProperty */
+ unset($this->head->metric);
+ }
+
+ /**
+ * @psalm-suppress UndefinedDocblockClass
+ * @phan-suppress PhanUndeclaredTypeParameter
+ * @param int|GMP $readers
+ */
+ public function add(Metric $metric, $readers): void
+ {
+ /** @phpstan-ignore-next-line */
+ if ($readers == 0) {
+ return;
+ }
+
+ if (($this->head->prev->readers ?? null) != $readers) {
+ $this->head->prev = new Delta($metric, $readers, $this->head->prev);
+ } else {
+ assert($this->head->prev !== null);
+ $this->mergeInto($this->head->prev->metric, $metric);
+ }
+ }
+
+ public function collect(int $reader, bool $retain = false): ?Metric
+ {
+ $n = null;
+ for ($d = $this->head; $d->prev; $d = $d->prev) {
+ if (($d->prev->readers >> $reader & 1) != 0) {
+ if ($n !== null) {
+ assert($n->prev !== null);
+ $n->prev->readers ^= $d->prev->readers;
+ $this->mergeInto($d->prev->metric, $n->prev->metric);
+ $this->tryUnlink($n);
+
+ if ($n->prev === $d->prev) {
+ continue;
+ }
+ }
+
+ $n = $d;
+ }
+ }
+
+ $metric = $n->prev->metric ?? null;
+
+ if (!$retain && $n) {
+ assert($n->prev !== null);
+ $n->prev->readers ^= ($n->prev->readers & 1 | 1) << $reader;
+ $this->tryUnlink($n);
+ }
+
+ return $metric;
+ }
+
+ private function tryUnlink(Delta $n): void
+ {
+ assert($n->prev !== null);
+ /** @phpstan-ignore-next-line */
+ if ($n->prev->readers == 0) {
+ $n->prev = $n->prev->prev;
+
+ return;
+ }
+
+ for ($c = $n->prev->prev;
+ $c && ($n->prev->readers & $c->readers) == 0;
+ $c = $c->prev) {
+ }
+
+ if ($c && $n->prev->readers === $c->readers) {
+ $this->mergeInto($c->metric, $n->prev->metric);
+ $n->prev = $n->prev->prev;
+ }
+ }
+
+ private function mergeInto(Metric $into, Metric $metric): void
+ {
+ foreach ($metric->summaries as $k => $summary) {
+ $into->attributes[$k] ??= $metric->attributes[$k];
+ $into->summaries[$k] = isset($into->summaries[$k])
+ ? $this->aggregation->merge($into->summaries[$k], $summary)
+ : $summary;
+ }
+ $into->exemplars += $metric->exemplars;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Stream/Metric.php b/vendor/open-telemetry/sdk/Metrics/Stream/Metric.php
new file mode 100644
index 000000000..6b1db9eef
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Stream/Metric.php
@@ -0,0 +1,44 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Stream;
+
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Metrics\Data\Exemplar;
+
+/**
+ * @internal
+ *
+ * @template T
+ */
+final class Metric
+{
+
+ /**
+ * @var array<AttributesInterface>
+ */
+ public array $attributes;
+ /**
+ * @var array<T>
+ */
+ public array $summaries;
+ public int $timestamp;
+ /**
+ * @var array<Exemplar>
+ */
+ public array $exemplars;
+
+ /**
+ * @param array<AttributesInterface> $attributes
+ * @param array<T> $summaries
+ * @param array<Exemplar> $exemplars
+ */
+ public function __construct(array $attributes, array $summaries, int $timestamp, array $exemplars = [])
+ {
+ $this->attributes = $attributes;
+ $this->summaries = $summaries;
+ $this->timestamp = $timestamp;
+ $this->exemplars = $exemplars;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregator.php b/vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregator.php
new file mode 100644
index 000000000..b1328eb07
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregator.php
@@ -0,0 +1,73 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Stream;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Metrics\AggregationInterface;
+use OpenTelemetry\SDK\Metrics\AttributeProcessorInterface;
+use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarReservoirInterface;
+use function serialize;
+
+/**
+ * @internal
+ */
+final class MetricAggregator implements MetricAggregatorInterface
+{
+ private ?AttributeProcessorInterface $attributeProcessor;
+ private AggregationInterface $aggregation;
+ private ?ExemplarReservoirInterface $exemplarReservoir;
+
+ /** @var array<AttributesInterface> */
+ private array $attributes = [];
+ private array $summaries = [];
+
+ public function __construct(
+ ?AttributeProcessorInterface $attributeProcessor,
+ AggregationInterface $aggregation,
+ ?ExemplarReservoirInterface $exemplarReservoir = null
+ ) {
+ $this->attributeProcessor = $attributeProcessor;
+ $this->aggregation = $aggregation;
+ $this->exemplarReservoir = $exemplarReservoir;
+ }
+
+ /**
+ * @param float|int $value
+ */
+ public function record($value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): void
+ {
+ $filteredAttributes = $this->attributeProcessor !== null
+ ? $this->attributeProcessor->process($attributes, $context)
+ : $attributes;
+ $raw = $filteredAttributes->toArray();
+ $index = $raw !== [] ? serialize($raw) : 0;
+ $this->attributes[$index] ??= $filteredAttributes;
+ $this->aggregation->record(
+ $this->summaries[$index] ??= $this->aggregation->initialize(),
+ $value,
+ $attributes,
+ $context,
+ $timestamp,
+ );
+
+ if ($this->exemplarReservoir !== null) {
+ $this->exemplarReservoir->offer($index, $value, $attributes, $context, $timestamp);
+ }
+ }
+
+ public function collect(int $timestamp): Metric
+ {
+ $exemplars = $this->exemplarReservoir
+ ? $this->exemplarReservoir->collect($this->attributes)
+ : [];
+ $metric = new Metric($this->attributes, $this->summaries, $timestamp, $exemplars);
+
+ $this->attributes = [];
+ $this->summaries = [];
+
+ return $metric;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregatorFactory.php b/vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregatorFactory.php
new file mode 100644
index 000000000..5866a72b7
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregatorFactory.php
@@ -0,0 +1,28 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Stream;
+
+use OpenTelemetry\SDK\Metrics\AggregationInterface;
+use OpenTelemetry\SDK\Metrics\AttributeProcessorInterface;
+
+/**
+ * @internal
+ */
+final class MetricAggregatorFactory implements MetricAggregatorFactoryInterface
+{
+ private ?AttributeProcessorInterface $attributeProcessor;
+ private AggregationInterface $aggregation;
+
+ public function __construct(?AttributeProcessorInterface $attributeProcessor, AggregationInterface $aggregation)
+ {
+ $this->attributeProcessor = $attributeProcessor;
+ $this->aggregation = $aggregation;
+ }
+
+ public function create(): MetricAggregatorInterface
+ {
+ return new MetricAggregator($this->attributeProcessor, $this->aggregation);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregatorFactoryInterface.php b/vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregatorFactoryInterface.php
new file mode 100644
index 000000000..356f682f2
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregatorFactoryInterface.php
@@ -0,0 +1,13 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Stream;
+
+/**
+ * @internal
+ */
+interface MetricAggregatorFactoryInterface
+{
+ public function create(): MetricAggregatorInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregatorInterface.php b/vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregatorInterface.php
new file mode 100644
index 000000000..2f5cfbf15
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Stream/MetricAggregatorInterface.php
@@ -0,0 +1,12 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Stream;
+
+/**
+ * @internal
+ */
+interface MetricAggregatorInterface extends WritableMetricStreamInterface, MetricCollectorInterface
+{
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Stream/MetricCollectorInterface.php b/vendor/open-telemetry/sdk/Metrics/Stream/MetricCollectorInterface.php
new file mode 100644
index 000000000..51a728df7
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Stream/MetricCollectorInterface.php
@@ -0,0 +1,13 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Stream;
+
+/**
+ * @internal
+ */
+interface MetricCollectorInterface
+{
+ public function collect(int $timestamp): Metric;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Stream/MetricStreamInterface.php b/vendor/open-telemetry/sdk/Metrics/Stream/MetricStreamInterface.php
new file mode 100644
index 000000000..1373a1c93
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Stream/MetricStreamInterface.php
@@ -0,0 +1,58 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Stream;
+
+use OpenTelemetry\SDK\Metrics\Data\DataInterface;
+use OpenTelemetry\SDK\Metrics\Data\Temporality;
+
+/**
+ * @internal
+ */
+interface MetricStreamInterface
+{
+ /**
+ * Returns the internal temporality of this stream.
+ *
+ * @return string|Temporality internal temporality
+ */
+ public function temporality();
+
+ /**
+ * Returns the last metric timestamp.
+ *
+ * @return int metric timestamp
+ */
+ public function timestamp(): int;
+
+ /**
+ * Pushes metric data to the stream.
+ *
+ * @param Metric $metric metric data to push
+ */
+ public function push(Metric $metric): void;
+
+ /**
+ * Registers a new reader with the given temporality.
+ *
+ * @param string|Temporality $temporality temporality to use
+ * @return int reader id
+ */
+ public function register($temporality): int;
+
+ /**
+ * Unregisters the given reader.
+ *
+ * @param int $reader reader id
+ */
+ public function unregister(int $reader): void;
+
+ /**
+ * Collects metric data for the given reader.
+ *
+ * @param int $reader reader id
+ * @return DataInterface metric data
+ */
+ public function collect(int $reader): DataInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Stream/SynchronousMetricStream.php b/vendor/open-telemetry/sdk/Metrics/Stream/SynchronousMetricStream.php
new file mode 100644
index 000000000..52645504c
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Stream/SynchronousMetricStream.php
@@ -0,0 +1,126 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Stream;
+
+use function assert;
+use const E_USER_WARNING;
+use function extension_loaded;
+use GMP;
+use function gmp_init;
+use function is_int;
+use OpenTelemetry\SDK\Metrics\AggregationInterface;
+use OpenTelemetry\SDK\Metrics\Data\DataInterface;
+use OpenTelemetry\SDK\Metrics\Data\Exemplar;
+use OpenTelemetry\SDK\Metrics\Data\Temporality;
+use const PHP_INT_SIZE;
+use function sprintf;
+use function trigger_error;
+
+/**
+ * @internal
+ */
+final class SynchronousMetricStream implements MetricStreamInterface
+{
+ private AggregationInterface $aggregation;
+
+ private int $timestamp;
+
+ private DeltaStorage $delta;
+ /**
+ * @psalm-suppress UndefinedDocblockClass
+ * @phan-suppress PhanUndeclaredTypeProperty
+ * @var int|GMP
+ */
+ private $readers = 0;
+ /**
+ * @psalm-suppress UndefinedDocblockClass
+ * @phan-suppress PhanUndeclaredTypeProperty
+ * @var int|GMP
+ */
+ private $cumulative = 0;
+
+ public function __construct(AggregationInterface $aggregation, int $startTimestamp)
+ {
+ $this->aggregation = $aggregation;
+ $this->timestamp = $startTimestamp;
+ $this->delta = new DeltaStorage($aggregation);
+ }
+
+ public function temporality()
+ {
+ return Temporality::DELTA;
+ }
+
+ public function timestamp(): int
+ {
+ return $this->timestamp;
+ }
+
+ public function push(Metric $metric): void
+ {
+ [$this->timestamp, $metric->timestamp] = [$metric->timestamp, $this->timestamp];
+ $this->delta->add($metric, $this->readers);
+ }
+
+ public function register($temporality): int
+ {
+ $reader = 0;
+ for ($r = $this->readers; ($r & 1) != 0; $r >>= 1, $reader++) {
+ }
+
+ if ($reader === (PHP_INT_SIZE << 3) - 1 && is_int($this->readers)) {
+ if (!extension_loaded('gmp')) {
+ trigger_error(sprintf('GMP extension required to register over %d readers', (PHP_INT_SIZE << 3) - 1), E_USER_WARNING);
+ $reader = PHP_INT_SIZE << 3;
+ } else {
+ assert(is_int($this->cumulative));
+ $this->readers = gmp_init($this->readers);
+ $this->cumulative = gmp_init($this->cumulative);
+ }
+ }
+
+ $readerMask = ($this->readers & 1 | 1) << $reader;
+ $this->readers ^= $readerMask;
+ if ($temporality === Temporality::CUMULATIVE) {
+ $this->cumulative ^= $readerMask;
+ }
+
+ return $reader;
+ }
+
+ public function unregister(int $reader): void
+ {
+ $readerMask = ($this->readers & 1 | 1) << $reader;
+ if (($this->readers & $readerMask) == 0) {
+ return;
+ }
+
+ $this->delta->collect($reader);
+
+ $this->readers ^= $readerMask;
+ if (($this->cumulative & $readerMask) != 0) {
+ $this->cumulative ^= $readerMask;
+ }
+ }
+
+ public function collect(int $reader): DataInterface
+ {
+ $cumulative = ($this->cumulative >> $reader & 1) != 0;
+ $metric = $this->delta->collect($reader, $cumulative) ?? new Metric([], [], $this->timestamp);
+
+ $temporality = $cumulative
+ ? Temporality::CUMULATIVE
+ : Temporality::DELTA;
+
+ return $this->aggregation->toData(
+ $metric->attributes,
+ $metric->summaries,
+ Exemplar::groupByIndex($metric->exemplars),
+ $metric->timestamp,
+ $this->timestamp,
+ $temporality,
+ );
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/Stream/WritableMetricStreamInterface.php b/vendor/open-telemetry/sdk/Metrics/Stream/WritableMetricStreamInterface.php
new file mode 100644
index 000000000..9fd425a44
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/Stream/WritableMetricStreamInterface.php
@@ -0,0 +1,19 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\Stream;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+/**
+ * @internal
+ */
+interface WritableMetricStreamInterface
+{
+ /**
+ * @param float|int $value
+ */
+ public function record($value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): void;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/UpDownCounter.php b/vendor/open-telemetry/sdk/Metrics/UpDownCounter.php
new file mode 100644
index 000000000..1adf67f8a
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/UpDownCounter.php
@@ -0,0 +1,37 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\API\Metrics\UpDownCounterInterface;
+use OpenTelemetry\SDK\Metrics\MetricRegistry\MetricWriterInterface;
+
+/**
+ * @internal
+ */
+final class UpDownCounter implements UpDownCounterInterface
+{
+ private MetricWriterInterface $writer;
+ private Instrument $instrument;
+ private ReferenceCounterInterface $referenceCounter;
+
+ public function __construct(MetricWriterInterface $writer, Instrument $instrument, ReferenceCounterInterface $referenceCounter)
+ {
+ $this->writer = $writer;
+ $this->instrument = $instrument;
+ $this->referenceCounter = $referenceCounter;
+
+ $this->referenceCounter->acquire();
+ }
+
+ public function __destruct()
+ {
+ $this->referenceCounter->release();
+ }
+
+ public function add($amount, iterable $attributes = [], $context = null): void
+ {
+ $this->writer->record($this->instrument, $amount, $attributes, $context);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/View/CriteriaViewRegistry.php b/vendor/open-telemetry/sdk/Metrics/View/CriteriaViewRegistry.php
new file mode 100644
index 000000000..f387abf9c
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/View/CriteriaViewRegistry.php
@@ -0,0 +1,40 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\View;
+
+use Generator;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Metrics\Instrument;
+use OpenTelemetry\SDK\Metrics\ViewRegistryInterface;
+
+final class CriteriaViewRegistry implements ViewRegistryInterface
+{
+ /** @var list<SelectionCriteriaInterface> */
+ private array $criteria = [];
+ /** @var list<ViewTemplate> */
+ private array $views = [];
+
+ public function register(SelectionCriteriaInterface $criteria, ViewTemplate $view): void
+ {
+ $this->criteria[] = $criteria;
+ $this->views[] = $view;
+ }
+
+ public function find(Instrument $instrument, InstrumentationScopeInterface $instrumentationScope): ?iterable
+ {
+ $views = $this->generateViews($instrument, $instrumentationScope);
+
+ return $views->valid() ? $views : null;
+ }
+
+ private function generateViews(Instrument $instrument, InstrumentationScopeInterface $instrumentationScope): Generator
+ {
+ foreach ($this->criteria as $i => $criteria) {
+ if ($criteria->accepts($instrument, $instrumentationScope)) {
+ yield $this->views[$i]->project($instrument);
+ }
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/AllCriteria.php b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/AllCriteria.php
new file mode 100644
index 000000000..438297324
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/AllCriteria.php
@@ -0,0 +1,33 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\View\SelectionCriteria;
+
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Metrics\Instrument;
+use OpenTelemetry\SDK\Metrics\View\SelectionCriteriaInterface;
+
+final class AllCriteria implements SelectionCriteriaInterface
+{
+ private iterable $criteria;
+
+ /**
+ * @param iterable<SelectionCriteriaInterface> $criteria
+ */
+ public function __construct(iterable $criteria)
+ {
+ $this->criteria = $criteria;
+ }
+
+ public function accepts(Instrument $instrument, InstrumentationScopeInterface $instrumentationScope): bool
+ {
+ foreach ($this->criteria as $criterion) {
+ if (!$criterion->accepts($instrument, $instrumentationScope)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentNameCriteria.php b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentNameCriteria.php
new file mode 100644
index 000000000..ed6034755
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentNameCriteria.php
@@ -0,0 +1,28 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\View\SelectionCriteria;
+
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Metrics\Instrument;
+use OpenTelemetry\SDK\Metrics\View\SelectionCriteriaInterface;
+use function preg_match;
+use function preg_quote;
+use function sprintf;
+use function strtr;
+
+final class InstrumentNameCriteria implements SelectionCriteriaInterface
+{
+ private string $pattern;
+
+ public function __construct(string $name)
+ {
+ $this->pattern = sprintf('/^%s$/', strtr(preg_quote($name, '/'), ['\\?' => '.', '\\*' => '.*']));
+ }
+
+ public function accepts(Instrument $instrument, InstrumentationScopeInterface $instrumentationScope): bool
+ {
+ return (bool) preg_match($this->pattern, $instrument->name);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentTypeCriteria.php b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentTypeCriteria.php
new file mode 100644
index 000000000..46a88def0
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentTypeCriteria.php
@@ -0,0 +1,29 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\View\SelectionCriteria;
+
+use function in_array;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Metrics\Instrument;
+use OpenTelemetry\SDK\Metrics\InstrumentType;
+use OpenTelemetry\SDK\Metrics\View\SelectionCriteriaInterface;
+
+final class InstrumentTypeCriteria implements SelectionCriteriaInterface
+{
+ private array $instrumentTypes;
+
+ /**
+ * @param string|InstrumentType|string[]|InstrumentType[] $instrumentType
+ */
+ public function __construct($instrumentType)
+ {
+ $this->instrumentTypes = (array) $instrumentType;
+ }
+
+ public function accepts(Instrument $instrument, InstrumentationScopeInterface $instrumentationScope): bool
+ {
+ return in_array($instrument->type, $this->instrumentTypes, true);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentationScopeNameCriteria.php b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentationScopeNameCriteria.php
new file mode 100644
index 000000000..201d1a7b2
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentationScopeNameCriteria.php
@@ -0,0 +1,24 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\View\SelectionCriteria;
+
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Metrics\Instrument;
+use OpenTelemetry\SDK\Metrics\View\SelectionCriteriaInterface;
+
+final class InstrumentationScopeNameCriteria implements SelectionCriteriaInterface
+{
+ private string $name;
+
+ public function __construct(string $name)
+ {
+ $this->name = $name;
+ }
+
+ public function accepts(Instrument $instrument, InstrumentationScopeInterface $instrumentationScope): bool
+ {
+ return $this->name === $instrumentationScope->getName();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentationScopeSchemaUrlCriteria.php b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentationScopeSchemaUrlCriteria.php
new file mode 100644
index 000000000..a11a1d589
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentationScopeSchemaUrlCriteria.php
@@ -0,0 +1,24 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\View\SelectionCriteria;
+
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Metrics\Instrument;
+use OpenTelemetry\SDK\Metrics\View\SelectionCriteriaInterface;
+
+final class InstrumentationScopeSchemaUrlCriteria implements SelectionCriteriaInterface
+{
+ private ?string $schemaUrl;
+
+ public function __construct(?string $schemaUrl)
+ {
+ $this->schemaUrl = $schemaUrl;
+ }
+
+ public function accepts(Instrument $instrument, InstrumentationScopeInterface $instrumentationScope): bool
+ {
+ return $this->schemaUrl === $instrumentationScope->getSchemaUrl();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentationScopeVersionCriteria.php b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentationScopeVersionCriteria.php
new file mode 100644
index 000000000..37d180f99
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteria/InstrumentationScopeVersionCriteria.php
@@ -0,0 +1,24 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\View\SelectionCriteria;
+
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Metrics\Instrument;
+use OpenTelemetry\SDK\Metrics\View\SelectionCriteriaInterface;
+
+final class InstrumentationScopeVersionCriteria implements SelectionCriteriaInterface
+{
+ private ?string $version;
+
+ public function __construct(?string $version)
+ {
+ $this->version = $version;
+ }
+
+ public function accepts(Instrument $instrument, InstrumentationScopeInterface $instrumentationScope): bool
+ {
+ return $this->version === $instrumentationScope->getVersion();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteriaInterface.php b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteriaInterface.php
new file mode 100644
index 000000000..8abd6fa69
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/View/SelectionCriteriaInterface.php
@@ -0,0 +1,13 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\View;
+
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Metrics\Instrument;
+
+interface SelectionCriteriaInterface
+{
+ public function accepts(Instrument $instrument, InstrumentationScopeInterface $instrumentationScope): bool;
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/View/ViewTemplate.php b/vendor/open-telemetry/sdk/Metrics/View/ViewTemplate.php
new file mode 100644
index 000000000..302ed83ae
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/View/ViewTemplate.php
@@ -0,0 +1,77 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics\View;
+
+use OpenTelemetry\SDK\Metrics\AggregationInterface;
+use OpenTelemetry\SDK\Metrics\Instrument;
+use OpenTelemetry\SDK\Metrics\ViewProjection;
+
+final class ViewTemplate
+{
+ private ?string $name = null;
+ private ?string $description = null;
+ /**
+ * @var list<string>
+ */
+ private ?array $attributeKeys = null;
+ private ?AggregationInterface $aggregation = null;
+
+ private function __construct()
+ {
+ }
+
+ public static function create(): self
+ {
+ static $instance;
+
+ return $instance ??= new self();
+ }
+
+ public function withName(string $name): self
+ {
+ $self = clone $this;
+ $self->name = $name;
+
+ return $self;
+ }
+
+ public function withDescription(string $description): self
+ {
+ $self = clone $this;
+ $self->description = $description;
+
+ return $self;
+ }
+
+ /**
+ * @param list<string> $attributeKeys
+ */
+ public function withAttributeKeys(array $attributeKeys): self
+ {
+ $self = clone $this;
+ $self->attributeKeys = $attributeKeys;
+
+ return $self;
+ }
+
+ public function withAggregation(?AggregationInterface $aggregation): self
+ {
+ $self = clone $this;
+ $self->aggregation = $aggregation;
+
+ return $self;
+ }
+
+ public function project(Instrument $instrument): ViewProjection
+ {
+ return new ViewProjection(
+ $this->name ?? $instrument->name,
+ $instrument->unit,
+ $this->description ?? $instrument->description,
+ $this->attributeKeys,
+ $this->aggregation,
+ );
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/ViewProjection.php b/vendor/open-telemetry/sdk/Metrics/ViewProjection.php
new file mode 100644
index 000000000..046bd6bb1
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/ViewProjection.php
@@ -0,0 +1,47 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+final class ViewProjection
+{
+ /**
+ * @readonly
+ */
+ public string $name;
+ /**
+ * @readonly
+ */
+ public ?string $unit;
+ /**
+ * @readonly
+ */
+ public ?string $description;
+ /**
+ * @readonly
+ * @var list<string>|null
+ */
+ public ?array $attributeKeys;
+ /**
+ * @readonly
+ */
+ public ?AggregationInterface $aggregation;
+
+ /**
+ * @param list<string>|null $attributeKeys
+ */
+ public function __construct(
+ string $name,
+ ?string $unit,
+ ?string $description,
+ ?array $attributeKeys,
+ ?AggregationInterface $aggregation
+ ) {
+ $this->name = $name;
+ $this->unit = $unit;
+ $this->description = $description;
+ $this->attributeKeys = $attributeKeys;
+ $this->aggregation = $aggregation;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Metrics/ViewRegistryInterface.php b/vendor/open-telemetry/sdk/Metrics/ViewRegistryInterface.php
new file mode 100644
index 000000000..19d8f9ffd
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Metrics/ViewRegistryInterface.php
@@ -0,0 +1,15 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Metrics;
+
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+
+interface ViewRegistryInterface
+{
+ /**
+ * @return iterable<ViewProjection>|null
+ */
+ public function find(Instrument $instrument, InstrumentationScopeInterface $instrumentationScope): ?iterable;
+}
diff --git a/vendor/open-telemetry/sdk/Propagation/PropagatorFactory.php b/vendor/open-telemetry/sdk/Propagation/PropagatorFactory.php
new file mode 100644
index 000000000..2dc349dfb
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Propagation/PropagatorFactory.php
@@ -0,0 +1,55 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Propagation;
+
+use OpenTelemetry\API\Behavior\LogsMessagesTrait;
+use OpenTelemetry\Context\Propagation\MultiTextMapPropagator;
+use OpenTelemetry\Context\Propagation\NoopTextMapPropagator;
+use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface;
+use OpenTelemetry\SDK\Common\Configuration\Configuration;
+use OpenTelemetry\SDK\Common\Configuration\Variables;
+use OpenTelemetry\SDK\Registry;
+
+class PropagatorFactory
+{
+ use LogsMessagesTrait;
+
+ public function create(): TextMapPropagatorInterface
+ {
+ $propagators = Configuration::getList(Variables::OTEL_PROPAGATORS);
+ switch (count($propagators)) {
+ case 0:
+ return new NoopTextMapPropagator();
+ case 1:
+ return $this->buildPropagator($propagators[0]);
+ default:
+ return new MultiTextMapPropagator($this->buildPropagators($propagators));
+ }
+ }
+
+ /**
+ * @return array<TextMapPropagatorInterface>
+ */
+ private function buildPropagators(array $names): array
+ {
+ $propagators = [];
+ foreach ($names as $name) {
+ $propagators[] = $this->buildPropagator($name);
+ }
+
+ return $propagators;
+ }
+
+ private function buildPropagator(string $name): TextMapPropagatorInterface
+ {
+ try {
+ return Registry::textMapPropagator($name);
+ } catch (\RuntimeException $e) {
+ self::logWarning($e->getMessage());
+ }
+
+ return NoopTextMapPropagator::getInstance();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Propagation/_register.php b/vendor/open-telemetry/sdk/Propagation/_register.php
new file mode 100644
index 000000000..fd90da184
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Propagation/_register.php
@@ -0,0 +1,16 @@
+<?php
+
+declare(strict_types=1);
+
+\OpenTelemetry\SDK\Registry::registerTextMapPropagator(
+ \OpenTelemetry\SDK\Common\Configuration\KnownValues::VALUE_BAGGAGE,
+ \OpenTelemetry\API\Baggage\Propagation\BaggagePropagator::getInstance()
+);
+\OpenTelemetry\SDK\Registry::registerTextMapPropagator(
+ \OpenTelemetry\SDK\Common\Configuration\KnownValues::VALUE_TRACECONTEXT,
+ \OpenTelemetry\API\Trace\Propagation\TraceContextPropagator::getInstance()
+);
+\OpenTelemetry\SDK\Registry::registerTextMapPropagator(
+ \OpenTelemetry\SDK\Common\Configuration\KnownValues::VALUE_NONE,
+ \OpenTelemetry\Context\Propagation\NoopTextMapPropagator::getInstance()
+);
diff --git a/vendor/open-telemetry/sdk/README.md b/vendor/open-telemetry/sdk/README.md
new file mode 100644
index 000000000..6346dc0f3
--- /dev/null
+++ b/vendor/open-telemetry/sdk/README.md
@@ -0,0 +1,49 @@
+[![Releases](https://img.shields.io/badge/releases-purple)](https://github.com/opentelemetry-php/sdk/releases)
+[![Source](https://img.shields.io/badge/source-sdk-green)](https://github.com/open-telemetry/opentelemetry-php/tree/main/src/SDK)
+[![Mirror](https://img.shields.io/badge/mirror-opentelemetry--php:sdk-blue)](https://github.com/opentelemetry-php/sdk)
+[![Latest Version](http://poser.pugx.org/open-telemetry/sdk/v/unstable)](https://packagist.org/packages/open-telemetry/sdk/)
+[![Stable](http://poser.pugx.org/open-telemetry/sdk/v/stable)](https://packagist.org/packages/open-telemetry/sdk/)
+
+# OpenTelemetry SDK
+
+The OpenTelemetry PHP SDK implements the API, and should be used in conjunction with contributed exporter(s) to generate and export telemetry.
+
+## Documentation
+
+https://opentelemetry.io/docs/instrumentation/php/sdk/
+
+## Getting started
+
+### Manual setup
+
+See https://github.com/open-telemetry/opentelemetry-php/tree/main/examples
+
+### SDK Builder
+
+See https://github.com/open-telemetry/opentelemetry-php/blob/main/examples/sdk_builder.php
+
+### Autoloading
+
+SDK autoloading works with configuration values provided via the environment (or php.ini).
+
+The SDK can be automatically created and registered, if the following conditions are met:
+- `OTEL_PHP_AUTOLOAD_ENABLED=true`
+- all required [SDK configuration](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#general-sdk-configuration) is provided
+
+SDK autoloading will be attempted as part of composer's autoloader:
+
+```php
+require 'vendor/autoload.php';
+
+$tracer = \OpenTelemetry\API\Globals::tracerProvider()->getTracer('example');
+$meter = \OpenTelemetry\API\Globals::meterProvider()->getMeter('example');
+```
+
+If autoloading was not successful (or partially successful), no-op implementations of the above may be returned.
+
+See https://github.com/open-telemetry/opentelemetry-php/blob/main/examples/autoload_sdk.php for a more detailed example.
+
+## Contributing
+
+This repository is a read-only git subtree split.
+To contribute, please see the main [OpenTelemetry PHP monorepo](https://github.com/open-telemetry/opentelemetry-php).
diff --git a/vendor/open-telemetry/sdk/Registry.php b/vendor/open-telemetry/sdk/Registry.php
new file mode 100644
index 000000000..2f0a20263
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Registry.php
@@ -0,0 +1,208 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK;
+
+use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface;
+use OpenTelemetry\SDK\Common\Export\TransportFactoryInterface;
+use OpenTelemetry\SDK\Logs\LogRecordExporterFactoryInterface;
+use OpenTelemetry\SDK\Metrics\MetricExporterFactoryInterface;
+use OpenTelemetry\SDK\Resource\ResourceDetectorInterface;
+use OpenTelemetry\SDK\Trace\SpanExporter\SpanExporterFactoryInterface;
+use RuntimeException;
+
+/**
+ * A registry to enable central registration of components that the SDK requires but which may be provided
+ * by non-SDK modules, such as contrib and extension.
+ */
+class Registry
+{
+ private static array $spanExporterFactories = [];
+ private static array $transportFactories = [];
+ private static array $metricExporterFactories = [];
+ private static array $textMapPropagators = [];
+ private static array $logRecordExporterFactories = [];
+ private static array $resourceDetectors = [];
+
+ /**
+ * @param TransportFactoryInterface|class-string<TransportFactoryInterface> $factory
+ */
+ public static function registerTransportFactory(string $protocol, $factory, bool $clobber = false): void
+ {
+ if (!$clobber && array_key_exists($protocol, self::$transportFactories)) {
+ return;
+ }
+ if (!is_subclass_of($factory, TransportFactoryInterface::class)) {
+ trigger_error(
+ sprintf(
+ 'Cannot register transport factory: %s must exist and implement %s',
+ is_string($factory) ? $factory : get_class($factory),
+ TransportFactoryInterface::class
+ ),
+ E_USER_WARNING
+ );
+
+ return;
+ }
+ self::$transportFactories[$protocol] = $factory;
+ }
+
+ /**
+ * @param SpanExporterFactoryInterface|class-string<SpanExporterFactoryInterface> $factory
+ */
+ public static function registerSpanExporterFactory(string $exporter, $factory, bool $clobber = false): void
+ {
+ if (!$clobber && array_key_exists($exporter, self::$spanExporterFactories)) {
+ return;
+ }
+ if (!is_subclass_of($factory, SpanExporterFactoryInterface::class)) {
+ trigger_error(
+ sprintf(
+ 'Cannot register span exporter factory: %s must exist and implement %s',
+ is_string($factory) ? $factory : get_class($factory),
+ SpanExporterFactoryInterface::class
+ ),
+ E_USER_WARNING
+ );
+
+ return;
+ }
+ self::$spanExporterFactories[$exporter] = $factory;
+ }
+
+ /**
+ * @param MetricExporterFactoryInterface|class-string<MetricExporterFactoryInterface> $factory
+ */
+ public static function registerMetricExporterFactory(string $exporter, $factory, bool $clobber = false): void
+ {
+ if (!$clobber && array_key_exists($exporter, self::$metricExporterFactories)) {
+ return;
+ }
+ if (!is_subclass_of($factory, MetricExporterFactoryInterface::class)) {
+ trigger_error(
+ sprintf(
+ 'Cannot register metric factory: %s must exist and implement %s',
+ is_string($factory) ? $factory : get_class($factory),
+ MetricExporterFactoryInterface::class
+ ),
+ E_USER_WARNING
+ );
+
+ return;
+ }
+ self::$metricExporterFactories[$exporter] = $factory;
+ }
+
+ public static function registerLogRecordExporterFactory(string $exporter, $factory, bool $clobber = false): void
+ {
+ if (!$clobber && array_key_exists($exporter, self::$logRecordExporterFactories)) {
+ return;
+ }
+ if (!is_subclass_of($factory, LogRecordExporterFactoryInterface::class)) {
+ trigger_error(
+ sprintf(
+ 'Cannot register LogRecord exporter factory: %s must exist and implement %s',
+ is_string($factory) ? $factory : get_class($factory),
+ LogRecordExporterFactoryInterface::class
+ ),
+ E_USER_WARNING
+ );
+
+ return;
+ }
+ self::$logRecordExporterFactories[$exporter] = $factory;
+ }
+
+ public static function registerTextMapPropagator(string $name, TextMapPropagatorInterface $propagator, bool $clobber = false): void
+ {
+ if (!$clobber && array_key_exists($name, self::$textMapPropagators)) {
+ return;
+ }
+ self::$textMapPropagators[$name] = $propagator;
+ }
+
+ public static function registerResourceDetector(string $name, ResourceDetectorInterface $detector): void
+ {
+ self::$resourceDetectors[$name] = $detector;
+ }
+
+ public static function spanExporterFactory(string $exporter): SpanExporterFactoryInterface
+ {
+ if (!array_key_exists($exporter, self::$spanExporterFactories)) {
+ throw new RuntimeException('Span exporter factory not defined for: ' . $exporter);
+ }
+ $class = self::$spanExporterFactories[$exporter];
+ $factory = (is_callable($class)) ? $class : new $class();
+ assert($factory instanceof SpanExporterFactoryInterface);
+
+ return $factory;
+ }
+
+ public static function logRecordExporterFactory(string $exporter): LogRecordExporterFactoryInterface
+ {
+ if (!array_key_exists($exporter, self::$logRecordExporterFactories)) {
+ throw new RuntimeException('LogRecord exporter factory not defined for: ' . $exporter);
+ }
+ $class = self::$logRecordExporterFactories[$exporter];
+ $factory = (is_callable($class)) ? $class : new $class();
+ assert($factory instanceof LogRecordExporterFactoryInterface);
+
+ return $factory;
+ }
+
+ /**
+ * Get transport factory registered for protocol. If $protocol contains a content-type eg `http/xyz` then
+ * only the first part, `http`, is used.
+ */
+ public static function transportFactory(string $protocol): TransportFactoryInterface
+ {
+ $protocol = explode('/', $protocol)[0];
+ if (!array_key_exists($protocol, self::$transportFactories)) {
+ throw new RuntimeException('Transport factory not defined for protocol: ' . $protocol);
+ }
+ $class = self::$transportFactories[$protocol];
+ $factory = (is_callable($class)) ? $class : new $class();
+ assert($factory instanceof TransportFactoryInterface);
+
+ return $factory;
+ }
+
+ public static function metricExporterFactory(string $exporter): MetricExporterFactoryInterface
+ {
+ if (!array_key_exists($exporter, self::$metricExporterFactories)) {
+ throw new RuntimeException('Metric exporter factory not registered for protocol: ' . $exporter);
+ }
+ $class = self::$metricExporterFactories[$exporter];
+ $factory = (is_callable($class)) ? $class : new $class();
+ assert($factory instanceof MetricExporterFactoryInterface);
+
+ return $factory;
+ }
+
+ public static function textMapPropagator(string $name): TextMapPropagatorInterface
+ {
+ if (!array_key_exists($name, self::$textMapPropagators)) {
+ throw new RuntimeException('Text map propagator not registered for: ' . $name);
+ }
+
+ return self::$textMapPropagators[$name];
+ }
+
+ public static function resourceDetector(string $name): ResourceDetectorInterface
+ {
+ if (!array_key_exists($name, self::$resourceDetectors)) {
+ throw new RuntimeException('Resource detector not registered for: ' . $name);
+ }
+
+ return self::$resourceDetectors[$name];
+ }
+
+ /**
+ * @return array<int, ResourceDetectorInterface>
+ */
+ public static function resourceDetectors(): array
+ {
+ return array_values(self::$resourceDetectors);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Resource/Detectors/Composer.php b/vendor/open-telemetry/sdk/Resource/Detectors/Composer.php
new file mode 100644
index 000000000..56b136ef1
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Resource/Detectors/Composer.php
@@ -0,0 +1,30 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Resource\Detectors;
+
+use function class_exists;
+use Composer\InstalledVersions;
+use OpenTelemetry\SDK\Common\Attribute\Attributes;
+use OpenTelemetry\SDK\Resource\ResourceDetectorInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
+use OpenTelemetry\SemConv\ResourceAttributes;
+
+final class Composer implements ResourceDetectorInterface
+{
+ public function getResource(): ResourceInfo
+ {
+ if (!class_exists(InstalledVersions::class)) {
+ return ResourceInfoFactory::emptyResource();
+ }
+
+ $attributes = [
+ ResourceAttributes::SERVICE_NAME => InstalledVersions::getRootPackage()['name'],
+ ResourceAttributes::SERVICE_VERSION => InstalledVersions::getRootPackage()['pretty_version'],
+ ];
+
+ return ResourceInfo::create(Attributes::create($attributes), ResourceAttributes::SCHEMA_URL);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Resource/Detectors/Composite.php b/vendor/open-telemetry/sdk/Resource/Detectors/Composite.php
new file mode 100644
index 000000000..9da267743
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Resource/Detectors/Composite.php
@@ -0,0 +1,32 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Resource\Detectors;
+
+use OpenTelemetry\SDK\Resource\ResourceDetectorInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
+
+final class Composite implements ResourceDetectorInterface
+{
+ private iterable $resourceDetectors;
+
+ /**
+ * @param iterable<ResourceDetectorInterface> $resourceDetectors
+ */
+ public function __construct(iterable $resourceDetectors)
+ {
+ $this->resourceDetectors = $resourceDetectors;
+ }
+
+ public function getResource(): ResourceInfo
+ {
+ $resource = ResourceInfoFactory::emptyResource();
+ foreach ($this->resourceDetectors as $resourceDetector) {
+ $resource = $resource->merge($resourceDetector->getResource());
+ }
+
+ return $resource;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Resource/Detectors/Constant.php b/vendor/open-telemetry/sdk/Resource/Detectors/Constant.php
new file mode 100644
index 000000000..7ff9d19eb
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Resource/Detectors/Constant.php
@@ -0,0 +1,23 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Resource\Detectors;
+
+use OpenTelemetry\SDK\Resource\ResourceDetectorInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+
+final class Constant implements ResourceDetectorInterface
+{
+ private ResourceInfo $resourceInfo;
+
+ public function __construct(ResourceInfo $resourceInfo)
+ {
+ $this->resourceInfo = $resourceInfo;
+ }
+
+ public function getResource(): ResourceInfo
+ {
+ return $this->resourceInfo;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Resource/Detectors/Environment.php b/vendor/open-telemetry/sdk/Resource/Detectors/Environment.php
new file mode 100644
index 000000000..ceee8fcf7
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Resource/Detectors/Environment.php
@@ -0,0 +1,40 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Resource\Detectors;
+
+use OpenTelemetry\SDK\Common\Attribute\Attributes;
+use OpenTelemetry\SDK\Common\Configuration\Configuration;
+use OpenTelemetry\SDK\Common\Configuration\Variables;
+use OpenTelemetry\SDK\Resource\ResourceDetectorInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use OpenTelemetry\SemConv\ResourceAttributes;
+
+/**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md#specifying-resource-information-via-an-environment-variable
+ */
+final class Environment implements ResourceDetectorInterface
+{
+ public function getResource(): ResourceInfo
+ {
+ $attributes = Configuration::has(Variables::OTEL_RESOURCE_ATTRIBUTES)
+ ? self::decode(Configuration::getMap(Variables::OTEL_RESOURCE_ATTRIBUTES, []))
+ : [];
+
+ //@see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#general-sdk-configuration
+ $serviceName = Configuration::has(Variables::OTEL_SERVICE_NAME)
+ ? Configuration::getString(Variables::OTEL_SERVICE_NAME)
+ : null;
+ if ($serviceName) {
+ $attributes[ResourceAttributes::SERVICE_NAME] = $serviceName;
+ }
+
+ return ResourceInfo::create(Attributes::create($attributes), ResourceAttributes::SCHEMA_URL);
+ }
+
+ private static function decode(array $attributes): array
+ {
+ return array_map('urldecode', $attributes);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Resource/Detectors/Host.php b/vendor/open-telemetry/sdk/Resource/Detectors/Host.php
new file mode 100644
index 000000000..dd2554540
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Resource/Detectors/Host.php
@@ -0,0 +1,27 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Resource\Detectors;
+
+use OpenTelemetry\SDK\Common\Attribute\Attributes;
+use OpenTelemetry\SDK\Resource\ResourceDetectorInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use OpenTelemetry\SemConv\ResourceAttributes;
+use function php_uname;
+
+/**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.8.0/specification/resource/semantic_conventions/host.md#host
+ */
+final class Host implements ResourceDetectorInterface
+{
+ public function getResource(): ResourceInfo
+ {
+ $attributes = [
+ ResourceAttributes::HOST_NAME => php_uname('n'),
+ ResourceAttributes::HOST_ARCH => php_uname('m'),
+ ];
+
+ return ResourceInfo::create(Attributes::create($attributes), ResourceAttributes::SCHEMA_URL);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Resource/Detectors/OperatingSystem.php b/vendor/open-telemetry/sdk/Resource/Detectors/OperatingSystem.php
new file mode 100644
index 000000000..2cb350dc2
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Resource/Detectors/OperatingSystem.php
@@ -0,0 +1,32 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Resource\Detectors;
+
+use OpenTelemetry\SDK\Common\Attribute\Attributes;
+use OpenTelemetry\SDK\Resource\ResourceDetectorInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use OpenTelemetry\SemConv\ResourceAttributes;
+use const PHP_OS;
+use const PHP_OS_FAMILY;
+use function php_uname;
+use function strtolower;
+
+/**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.8.0/specification/resource/semantic_conventions/os.md
+ */
+final class OperatingSystem implements ResourceDetectorInterface
+{
+ public function getResource(): ResourceInfo
+ {
+ $attributes = [
+ ResourceAttributes::OS_TYPE => strtolower(PHP_OS_FAMILY),
+ ResourceAttributes::OS_DESCRIPTION => php_uname('r'),
+ ResourceAttributes::OS_NAME => PHP_OS,
+ ResourceAttributes::OS_VERSION => php_uname('v'),
+ ];
+
+ return ResourceInfo::create(Attributes::create($attributes), ResourceAttributes::SCHEMA_URL);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Resource/Detectors/Process.php b/vendor/open-telemetry/sdk/Resource/Detectors/Process.php
new file mode 100644
index 000000000..7f1d99386
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Resource/Detectors/Process.php
@@ -0,0 +1,43 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Resource\Detectors;
+
+use function extension_loaded;
+use function getmypid;
+use OpenTelemetry\SDK\Common\Attribute\Attributes;
+use OpenTelemetry\SDK\Resource\ResourceDetectorInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use OpenTelemetry\SemConv\ResourceAttributes;
+use const PHP_BINARY;
+
+/**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.8.0/specification/resource/semantic_conventions/process.md#process
+ */
+final class Process implements ResourceDetectorInterface
+{
+ /**
+ * @psalm-suppress PossiblyUndefinedArrayOffset
+ */
+ public function getResource(): ResourceInfo
+ {
+ $attributes = [];
+ $attributes[ResourceAttributes::PROCESS_PID] = getmypid();
+ $attributes[ResourceAttributes::PROCESS_EXECUTABLE_PATH] = PHP_BINARY;
+ /**
+ * @psalm-suppress PossiblyUndefinedArrayOffset
+ */
+ if ($_SERVER['argv'] ?? null) {
+ $attributes[ResourceAttributes::PROCESS_COMMAND] = $_SERVER['argv'][0];
+ $attributes[ResourceAttributes::PROCESS_COMMAND_ARGS] = $_SERVER['argv'];
+ }
+
+ /** @phan-suppress-next-line PhanTypeComparisonFromArray */
+ if (extension_loaded('posix') && ($user = \posix_getpwuid(\posix_geteuid())) !== false) {
+ $attributes[ResourceAttributes::PROCESS_OWNER] = $user['name'];
+ }
+
+ return ResourceInfo::create(Attributes::create($attributes), ResourceAttributes::SCHEMA_URL);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Resource/Detectors/ProcessRuntime.php b/vendor/open-telemetry/sdk/Resource/Detectors/ProcessRuntime.php
new file mode 100644
index 000000000..f29ddfc8f
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Resource/Detectors/ProcessRuntime.php
@@ -0,0 +1,28 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Resource\Detectors;
+
+use OpenTelemetry\SDK\Common\Attribute\Attributes;
+use OpenTelemetry\SDK\Resource\ResourceDetectorInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use OpenTelemetry\SemConv\ResourceAttributes;
+use function php_sapi_name;
+use const PHP_VERSION;
+
+/**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.8.0/specification/resource/semantic_conventions/process.md#process-runtimes
+ */
+final class ProcessRuntime implements ResourceDetectorInterface
+{
+ public function getResource(): ResourceInfo
+ {
+ $attributes = [
+ ResourceAttributes::PROCESS_RUNTIME_NAME => php_sapi_name(),
+ ResourceAttributes::PROCESS_RUNTIME_VERSION => PHP_VERSION,
+ ];
+
+ return ResourceInfo::create(Attributes::create($attributes), ResourceAttributes::SCHEMA_URL);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Resource/Detectors/Sdk.php b/vendor/open-telemetry/sdk/Resource/Detectors/Sdk.php
new file mode 100644
index 000000000..dba3eb8aa
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Resource/Detectors/Sdk.php
@@ -0,0 +1,53 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Resource\Detectors;
+
+use function class_exists;
+use Composer\InstalledVersions;
+use OpenTelemetry\SDK\Common\Attribute\Attributes;
+use OpenTelemetry\SDK\Resource\ResourceDetectorInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use OpenTelemetry\SemConv\ResourceAttributes;
+
+/**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.8.0/specification/resource/semantic_conventions/README.md#telemetry-sdk
+ */
+final class Sdk implements ResourceDetectorInterface
+{
+ private const PACKAGES = [
+ 'open-telemetry/sdk',
+ 'open-telemetry/opentelemetry',
+ ];
+
+ public function getResource(): ResourceInfo
+ {
+ $attributes = [
+ ResourceAttributes::TELEMETRY_SDK_NAME => 'opentelemetry',
+ ResourceAttributes::TELEMETRY_SDK_LANGUAGE => 'php',
+ ];
+
+ if (class_exists(InstalledVersions::class)) {
+ foreach (self::PACKAGES as $package) {
+ if (!InstalledVersions::isInstalled($package)) {
+ continue;
+ }
+ if (($version = InstalledVersions::getPrettyVersion($package)) === null) {
+ continue;
+ }
+
+ $attributes[ResourceAttributes::TELEMETRY_SDK_VERSION] = $version;
+
+ break;
+ }
+ }
+
+ if (extension_loaded('opentelemetry')) {
+ $attributes[ResourceAttributes::TELEMETRY_DISTRO_NAME] = 'opentelemetry-php-instrumentation';
+ $attributes[ResourceAttributes::TELEMETRY_DISTRO_VERSION] = phpversion('opentelemetry');
+ }
+
+ return ResourceInfo::create(Attributes::create($attributes), ResourceAttributes::SCHEMA_URL);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Resource/Detectors/SdkProvided.php b/vendor/open-telemetry/sdk/Resource/Detectors/SdkProvided.php
new file mode 100644
index 000000000..ec4ec7def
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Resource/Detectors/SdkProvided.php
@@ -0,0 +1,25 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Resource\Detectors;
+
+use OpenTelemetry\SDK\Common\Attribute\Attributes;
+use OpenTelemetry\SDK\Resource\ResourceDetectorInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use OpenTelemetry\SemConv\ResourceAttributes;
+
+/**
+ * @see https://github.com/open-telemetry/semantic-conventions/blob/main/docs/resource/README.md#semantic-attributes-with-sdk-provided-default-value
+ */
+final class SdkProvided implements ResourceDetectorInterface
+{
+ public function getResource(): ResourceInfo
+ {
+ $attributes = [
+ ResourceAttributes::SERVICE_NAME => 'unknown_service:php',
+ ];
+
+ return ResourceInfo::create(Attributes::create($attributes), ResourceAttributes::SCHEMA_URL);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Resource/ResourceDetectorInterface.php b/vendor/open-telemetry/sdk/Resource/ResourceDetectorInterface.php
new file mode 100644
index 000000000..f2cd5256b
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Resource/ResourceDetectorInterface.php
@@ -0,0 +1,10 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Resource;
+
+interface ResourceDetectorInterface
+{
+ public function getResource(): ResourceInfo;
+}
diff --git a/vendor/open-telemetry/sdk/Resource/ResourceInfo.php b/vendor/open-telemetry/sdk/Resource/ResourceInfo.php
new file mode 100644
index 000000000..4210a6142
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Resource/ResourceInfo.php
@@ -0,0 +1,125 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Resource;
+
+use OpenTelemetry\API\Behavior\LogsMessagesTrait;
+use OpenTelemetry\SDK\Common\Attribute\Attributes;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+use OpenTelemetry\SDK\Common\Dev\Compatibility\Util as BcUtil;
+
+/**
+ * A Resource is an immutable representation of the entity producing telemetry. For example, a process producing telemetry
+ * that is running in a container on Kubernetes has a Pod name, it is in a namespace and possibly is part of a Deployment
+ * which also has a name. All three of these attributes can be included in the Resource.
+ *
+ * The class named as ResourceInfo due to `resource` is the soft reserved word in PHP.
+ */
+class ResourceInfo
+{
+ use LogsMessagesTrait;
+
+ private AttributesInterface $attributes;
+ private ?string $schemaUrl;
+
+ private function __construct(AttributesInterface $attributes, ?string $schemaUrl = null)
+ {
+ $this->attributes = $attributes;
+ $this->schemaUrl = $schemaUrl;
+ }
+
+ public static function create(AttributesInterface $attributes, ?string $schemaUrl = null): self
+ {
+ return new ResourceInfo($attributes, $schemaUrl);
+ }
+
+ public function getAttributes(): AttributesInterface
+ {
+ return $this->attributes;
+ }
+
+ public function getSchemaUrl(): ?string
+ {
+ return $this->schemaUrl;
+ }
+
+ public function serialize(): string
+ {
+ $copyOfAttributesAsArray = array_slice($this->attributes->toArray(), 0); //This may be overly cautious (in trying to avoid mutating the source array)
+ ksort($copyOfAttributesAsArray); //sort the associative array by keys since the serializer will consider equal arrays different otherwise
+
+ //The exact return value doesn't matter, as long as it can distingusih between instances that represent the same/different resources
+ return serialize([
+ 'schemaUrl' => $this->schemaUrl,
+ 'attributes' => $copyOfAttributesAsArray,
+ ]);
+ }
+
+ /**
+ * Merge current resource with an updating resource, combining all attributes. If a key exists on both the old and updating
+ * resource, the value of the updating resource MUST be picked (even if the updated value is empty)
+ *
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/resource/sdk.md#merge
+ */
+ public function merge(ResourceInfo $updating): ResourceInfo
+ {
+ $schemaUrl = self::mergeSchemaUrl($this->getSchemaUrl(), $updating->getSchemaUrl());
+ $attributes = $updating->getAttributes()->toArray() + $this->getAttributes()->toArray();
+
+ return ResourceInfo::create(Attributes::create($attributes), $schemaUrl);
+ }
+
+ /**
+ * Merge the schema URLs from the old and updating resource.
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/resource/sdk.md#merge
+ */
+ private static function mergeSchemaUrl(?string $old, ?string $updating): ?string
+ {
+ if (empty($old)) {
+ return $updating;
+ }
+ if (empty($updating)) {
+ return $old;
+ }
+ if ($old === $updating) {
+ return $old;
+ }
+
+ self::logWarning('Merging resources with different schema URLs', [
+ 'old' => $old,
+ 'updating' => $updating,
+ ]);
+
+ return null;
+ }
+
+ /**
+ * @codeCoverageIgnore
+ */
+ public static function defaultResource(): ResourceInfo
+ {
+ BcUtil::triggerMethodDeprecationNotice(
+ __METHOD__,
+ 'defaultResource',
+ ResourceInfoFactory::class
+ );
+
+ return ResourceInfoFactory::defaultResource();
+ }
+
+ /**
+ * @codeCoverageIgnore
+ */
+ public static function emptyResource(): ResourceInfo
+ {
+ BcUtil::triggerMethodDeprecationNotice(
+ __METHOD__,
+ 'emptyResource',
+ ResourceInfoFactory::class
+ );
+
+ return ResourceInfoFactory::emptyResource();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Resource/ResourceInfoFactory.php b/vendor/open-telemetry/sdk/Resource/ResourceInfoFactory.php
new file mode 100644
index 000000000..7fc80bcd9
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Resource/ResourceInfoFactory.php
@@ -0,0 +1,95 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Resource;
+
+use function in_array;
+use OpenTelemetry\API\Behavior\LogsMessagesTrait;
+use OpenTelemetry\SDK\Common\Attribute\Attributes;
+use OpenTelemetry\SDK\Common\Configuration\Configuration;
+use OpenTelemetry\SDK\Common\Configuration\KnownValues as Values;
+use OpenTelemetry\SDK\Common\Configuration\Variables as Env;
+use OpenTelemetry\SDK\Registry;
+use RuntimeException;
+
+class ResourceInfoFactory
+{
+ use LogsMessagesTrait;
+
+ public static function defaultResource(): ResourceInfo
+ {
+ $detectors = Configuration::getList(Env::OTEL_PHP_DETECTORS);
+
+ if (in_array(Values::VALUE_ALL, $detectors)) {
+ // ascending priority: keys from later detectors will overwrite earlier
+ return (new Detectors\Composite([
+ new Detectors\Host(),
+ new Detectors\OperatingSystem(),
+ new Detectors\Process(),
+ new Detectors\ProcessRuntime(),
+ new Detectors\Sdk(),
+ new Detectors\SdkProvided(),
+ new Detectors\Composer(),
+ ...Registry::resourceDetectors(),
+ new Detectors\Environment(),
+ ]))->getResource();
+ }
+
+ $resourceDetectors = [];
+
+ foreach ($detectors as $detector) {
+ switch ($detector) {
+ case Values::VALUE_DETECTORS_ENVIRONMENT:
+ $resourceDetectors[] = new Detectors\Environment();
+
+ break;
+ case Values::VALUE_DETECTORS_HOST:
+ $resourceDetectors[] = new Detectors\Host();
+
+ break;
+ case Values::VALUE_DETECTORS_OS:
+ $resourceDetectors[] = new Detectors\OperatingSystem();
+
+ break;
+ case Values::VALUE_DETECTORS_PROCESS:
+ $resourceDetectors[] = new Detectors\Process();
+
+ break;
+ case Values::VALUE_DETECTORS_PROCESS_RUNTIME:
+ $resourceDetectors[] = new Detectors\ProcessRuntime();
+
+ break;
+ case Values::VALUE_DETECTORS_SDK:
+ $resourceDetectors[] = new Detectors\Sdk();
+
+ break;
+ case Values::VALUE_DETECTORS_SDK_PROVIDED:
+ $resourceDetectors[] = new Detectors\SdkProvided();
+
+ break;
+
+ case Values::VALUE_DETECTORS_COMPOSER:
+ $resourceDetectors[] = new Detectors\Composer();
+
+ break;
+ case Values::VALUE_NONE:
+
+ break;
+ default:
+ try {
+ $resourceDetectors[] = Registry::resourceDetector($detector);
+ } catch (RuntimeException $e) {
+ self::logWarning($e->getMessage());
+ }
+ }
+ }
+
+ return (new Detectors\Composite($resourceDetectors))->getResource();
+ }
+
+ public static function emptyResource(): ResourceInfo
+ {
+ return ResourceInfo::create(Attributes::create([]));
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Sdk.php b/vendor/open-telemetry/sdk/Sdk.php
new file mode 100644
index 000000000..3b63eb93a
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Sdk.php
@@ -0,0 +1,70 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK;
+
+use OpenTelemetry\API\Metrics\MeterProviderInterface;
+use OpenTelemetry\API\Trace\TracerProviderInterface;
+use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface;
+use OpenTelemetry\SDK\Common\Configuration\Configuration;
+use OpenTelemetry\SDK\Common\Configuration\Variables;
+use OpenTelemetry\SDK\Logs\LoggerProviderInterface;
+
+class Sdk
+{
+ private TracerProviderInterface $tracerProvider;
+ private MeterProviderInterface $meterProvider;
+ private LoggerProviderInterface $loggerProvider;
+ private TextMapPropagatorInterface $propagator;
+
+ public function __construct(
+ TracerProviderInterface $tracerProvider,
+ MeterProviderInterface $meterProvider,
+ LoggerProviderInterface $loggerProvider,
+ TextMapPropagatorInterface $propagator
+ ) {
+ $this->tracerProvider = $tracerProvider;
+ $this->meterProvider = $meterProvider;
+ $this->loggerProvider = $loggerProvider;
+ $this->propagator = $propagator;
+ }
+
+ public static function isDisabled(): bool
+ {
+ return Configuration::getBoolean(Variables::OTEL_SDK_DISABLED);
+ }
+
+ /**
+ * Tests whether an auto-instrumentation package has been disabled by config
+ */
+ public static function isInstrumentationDisabled(string $name): bool
+ {
+ return in_array($name, Configuration::getList(Variables::OTEL_PHP_DISABLED_INSTRUMENTATIONS));
+ }
+
+ public static function builder(): SdkBuilder
+ {
+ return new SdkBuilder();
+ }
+
+ public function getTracerProvider(): TracerProviderInterface
+ {
+ return $this->tracerProvider;
+ }
+
+ public function getMeterProvider(): MeterProviderInterface
+ {
+ return $this->meterProvider;
+ }
+
+ public function getLoggerProvider(): LoggerProviderInterface
+ {
+ return $this->loggerProvider;
+ }
+
+ public function getPropagator(): TextMapPropagatorInterface
+ {
+ return $this->propagator;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/SdkAutoloader.php b/vendor/open-telemetry/sdk/SdkAutoloader.php
new file mode 100644
index 000000000..c08195e19
--- /dev/null
+++ b/vendor/open-telemetry/sdk/SdkAutoloader.php
@@ -0,0 +1,76 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK;
+
+use InvalidArgumentException;
+use OpenTelemetry\API\Globals;
+use OpenTelemetry\API\Instrumentation\Configurator;
+use OpenTelemetry\SDK\Common\Configuration\Configuration;
+use OpenTelemetry\SDK\Common\Configuration\Variables;
+use OpenTelemetry\SDK\Common\Util\ShutdownHandler;
+use OpenTelemetry\SDK\Logs\LoggerProviderFactory;
+use OpenTelemetry\SDK\Metrics\MeterProviderFactory;
+use OpenTelemetry\SDK\Propagation\PropagatorFactory;
+use OpenTelemetry\SDK\Trace\ExporterFactory;
+use OpenTelemetry\SDK\Trace\SamplerFactory;
+use OpenTelemetry\SDK\Trace\SpanProcessorFactory;
+use OpenTelemetry\SDK\Trace\TracerProviderBuilder;
+
+class SdkAutoloader
+{
+ private static ?bool $enabled = null;
+
+ public static function autoload(): bool
+ {
+ try {
+ self::$enabled ??= Configuration::getBoolean(Variables::OTEL_PHP_AUTOLOAD_ENABLED);
+ } catch (InvalidArgumentException $e) {
+ //invalid setting, assume false
+ self::$enabled = false;
+ }
+ if (!self::$enabled) {
+ return false;
+ }
+ Globals::registerInitializer(function (Configurator $configurator) {
+ $propagator = (new PropagatorFactory())->create();
+ if (Sdk::isDisabled()) {
+ //@see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#general-sdk-configuration
+ return $configurator->withPropagator($propagator);
+ }
+ $emitMetrics = Configuration::getBoolean(Variables::OTEL_PHP_INTERNAL_METRICS_ENABLED);
+
+ $exporter = (new ExporterFactory())->create();
+ $meterProvider = (new MeterProviderFactory())->create();
+ $spanProcessor = (new SpanProcessorFactory())->create($exporter, $emitMetrics ? $meterProvider : null);
+ $tracerProvider = (new TracerProviderBuilder())
+ ->addSpanProcessor($spanProcessor)
+ ->setSampler((new SamplerFactory())->create())
+ ->build();
+
+ $loggerProvider = (new LoggerProviderFactory())->create($emitMetrics ? $meterProvider : null);
+
+ ShutdownHandler::register([$tracerProvider, 'shutdown']);
+ ShutdownHandler::register([$meterProvider, 'shutdown']);
+ ShutdownHandler::register([$loggerProvider, 'shutdown']);
+
+ return $configurator
+ ->withTracerProvider($tracerProvider)
+ ->withMeterProvider($meterProvider)
+ ->withLoggerProvider($loggerProvider)
+ ->withPropagator($propagator)
+ ;
+ });
+
+ return true;
+ }
+
+ /**
+ * @internal
+ */
+ public static function reset(): void
+ {
+ self::$enabled = null;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/SdkBuilder.php b/vendor/open-telemetry/sdk/SdkBuilder.php
new file mode 100644
index 000000000..2090c4731
--- /dev/null
+++ b/vendor/open-telemetry/sdk/SdkBuilder.php
@@ -0,0 +1,98 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK;
+
+use OpenTelemetry\API\Instrumentation\Configurator;
+use OpenTelemetry\Context\Context;
+use OpenTelemetry\Context\Propagation\NoopTextMapPropagator;
+use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface;
+use OpenTelemetry\Context\ScopeInterface;
+use OpenTelemetry\SDK\Common\Util\ShutdownHandler;
+use OpenTelemetry\SDK\Logs\LoggerProviderInterface;
+use OpenTelemetry\SDK\Logs\NoopLoggerProvider;
+use OpenTelemetry\SDK\Metrics\MeterProviderInterface;
+use OpenTelemetry\SDK\Metrics\NoopMeterProvider;
+use OpenTelemetry\SDK\Trace\NoopTracerProvider;
+use OpenTelemetry\SDK\Trace\TracerProviderInterface;
+
+class SdkBuilder
+{
+ private ?TracerProviderInterface $tracerProvider = null;
+ private ?MeterProviderInterface $meterProvider = null;
+ private ?LoggerProviderInterface $loggerProvider = null;
+ private ?TextMapPropagatorInterface $propagator = null;
+ private bool $autoShutdown = false;
+
+ /**
+ * Automatically shut down providers on process completion. If not set, the user is responsible for calling `shutdown`.
+ */
+ public function setAutoShutdown(bool $shutdown): self
+ {
+ $this->autoShutdown = $shutdown;
+
+ return $this;
+ }
+
+ public function setTracerProvider(TracerProviderInterface $provider): self
+ {
+ $this->tracerProvider = $provider;
+
+ return $this;
+ }
+
+ public function setMeterProvider(MeterProviderInterface $meterProvider): self
+ {
+ $this->meterProvider = $meterProvider;
+
+ return $this;
+ }
+
+ public function setLoggerProvider(LoggerProviderInterface $loggerProvider): self
+ {
+ $this->loggerProvider = $loggerProvider;
+
+ return $this;
+ }
+
+ public function setPropagator(TextMapPropagatorInterface $propagator): self
+ {
+ $this->propagator = $propagator;
+
+ return $this;
+ }
+
+ public function build(): Sdk
+ {
+ $tracerProvider = $this->tracerProvider ?? new NoopTracerProvider();
+ $meterProvider = $this->meterProvider ?? new NoopMeterProvider();
+ $loggerProvider = $this->loggerProvider ?? new NoopLoggerProvider();
+ if ($this->autoShutdown) {
+ // rector rule disabled in config, because ShutdownHandler::register() does not keep a strong reference to $this
+ ShutdownHandler::register([$tracerProvider, 'shutdown']);
+ ShutdownHandler::register([$meterProvider, 'shutdown']);
+ ShutdownHandler::register([$loggerProvider, 'shutdown']);
+ }
+
+ return new Sdk(
+ $tracerProvider,
+ $meterProvider,
+ $loggerProvider,
+ $this->propagator ?? NoopTextMapPropagator::getInstance(),
+ );
+ }
+
+ public function buildAndRegisterGlobal(): ScopeInterface
+ {
+ $sdk = $this->build();
+ $context = Configurator::create()
+ ->withPropagator($sdk->getPropagator())
+ ->withTracerProvider($sdk->getTracerProvider())
+ ->withMeterProvider($sdk->getMeterProvider())
+ ->withLoggerProvider($sdk->getLoggerProvider())
+ ->storeInContext();
+
+ return Context::storage()->attach($context);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/Behavior/LoggerAwareTrait.php b/vendor/open-telemetry/sdk/Trace/Behavior/LoggerAwareTrait.php
new file mode 100644
index 000000000..24f5e56a8
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/Behavior/LoggerAwareTrait.php
@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\Behavior;
+
+use Psr\Log\LoggerAwareTrait as PsrTrait;
+use Psr\Log\LoggerInterface;
+use Psr\Log\LogLevel;
+use Psr\Log\NullLogger;
+
+trait LoggerAwareTrait
+{
+ use PsrTrait;
+
+ private string $defaultLogLevel = LogLevel::INFO;
+
+ /**
+ * @param string $logLevel
+ */
+ public function setDefaultLogLevel(string $logLevel): void
+ {
+ $this->defaultLogLevel = $logLevel;
+ }
+
+ /**
+ * @param string $message
+ * @param array $context
+ * @param string|null $level
+ */
+ protected function log(string $message, array $context = [], ?string $level = null): void
+ {
+ $this->getLogger()->log(
+ $level ?? $this->defaultLogLevel,
+ $message,
+ $context
+ );
+ }
+
+ protected function getLogger(): LoggerInterface
+ {
+ if ($this->logger !== null) {
+ return $this->logger;
+ }
+
+ return new NullLogger();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/Behavior/SpanExporterDecoratorTrait.php b/vendor/open-telemetry/sdk/Trace/Behavior/SpanExporterDecoratorTrait.php
new file mode 100644
index 000000000..97839ec5b
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/Behavior/SpanExporterDecoratorTrait.php
@@ -0,0 +1,47 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\Behavior;
+
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Common\Future\FutureInterface;
+use OpenTelemetry\SDK\Trace\SpanDataInterface;
+use OpenTelemetry\SDK\Trace\SpanExporterInterface;
+
+trait SpanExporterDecoratorTrait
+{
+ protected SpanExporterInterface $decorated;
+
+ /**
+ * @param iterable<SpanDataInterface> $batch
+ * @return FutureInterface<bool>
+ */
+ public function export(iterable $batch, ?CancellationInterface $cancellation = null): FutureInterface
+ {
+ $batch = $this->beforeExport($batch);
+ $response = $this->decorated->export($batch, $cancellation);
+ $response->map(fn (bool $result) => $this->afterExport($batch, $result));
+
+ return $response;
+ }
+
+ abstract protected function beforeExport(iterable $spans): iterable;
+
+ abstract protected function afterExport(iterable $spans, bool $exportSuccess): void;
+
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ return $this->decorated->shutdown($cancellation);
+ }
+
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ return $this->decorated->forceFlush($cancellation);
+ }
+
+ public function setDecorated(SpanExporterInterface $decorated): void
+ {
+ $this->decorated = $decorated;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/Behavior/SpanExporterTrait.php b/vendor/open-telemetry/sdk/Trace/Behavior/SpanExporterTrait.php
new file mode 100644
index 000000000..339fecc1d
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/Behavior/SpanExporterTrait.php
@@ -0,0 +1,47 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\Behavior;
+
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Common\Future\CompletedFuture;
+use OpenTelemetry\SDK\Common\Future\FutureInterface;
+use OpenTelemetry\SDK\Trace\SpanDataInterface;
+
+trait SpanExporterTrait
+{
+ private bool $running = true;
+
+ /** @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/specification/trace/sdk.md#shutdown-2 */
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ $this->running = false;
+
+ return true;
+ }
+
+ /** @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/specification/trace/sdk.md#forceflush-2 */
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ return true;
+ }
+
+ /**
+ * @param iterable<SpanDataInterface> $batch
+ * @return FutureInterface<bool>
+ */
+ public function export(iterable $batch, ?CancellationInterface $cancellation = null): FutureInterface
+ {
+ if (!$this->running) {
+ return new CompletedFuture(false);
+ }
+
+ return new CompletedFuture($this->doExport($batch)); /** @phpstan-ignore-line */
+ }
+
+ /**
+ * @param iterable<SpanDataInterface> $spans Batch of spans to export
+ */
+ abstract protected function doExport(iterable $spans): bool; /** @phpstan-ignore-line */
+}
diff --git a/vendor/open-telemetry/sdk/Trace/Behavior/UsesSpanConverterTrait.php b/vendor/open-telemetry/sdk/Trace/Behavior/UsesSpanConverterTrait.php
new file mode 100644
index 000000000..4802cd15b
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/Behavior/UsesSpanConverterTrait.php
@@ -0,0 +1,41 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\Behavior;
+
+use OpenTelemetry\SDK\Trace\SpanConverterInterface;
+use OpenTelemetry\SDK\Trace\SpanDataInterface;
+use OpenTelemetry\SDK\Trace\SpanExporter\NullSpanConverter;
+
+trait UsesSpanConverterTrait
+{
+ private ?SpanConverterInterface $converter = null;
+
+ /**
+ * @param SpanConverterInterface $converter
+ */
+ protected function setSpanConverter(SpanConverterInterface $converter): void
+ {
+ $this->converter = $converter;
+ }
+
+ public function getSpanConverter(): SpanConverterInterface
+ {
+ if (null === $this->converter) {
+ $this->converter = new NullSpanConverter();
+ }
+
+ return $this->converter;
+ }
+
+ /**
+ * @param SpanDataInterface $span
+ * @return array
+ * @psalm-suppress PossiblyNullReference
+ */
+ protected function convertSpan(SpanDataInterface $span): array
+ {
+ return $this->getSpanConverter()->convert([$span]);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/Event.php b/vendor/open-telemetry/sdk/Trace/Event.php
new file mode 100644
index 000000000..28cb39bb1
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/Event.php
@@ -0,0 +1,47 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use function count;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+final class Event implements EventInterface
+{
+ private string $name;
+ private int $timestamp;
+ private AttributesInterface $attributes;
+
+ public function __construct(string $name, int $timestamp, AttributesInterface $attributes)
+ {
+ $this->name = $name;
+ $this->timestamp = $timestamp;
+ $this->attributes = $attributes;
+ }
+
+ public function getAttributes(): AttributesInterface
+ {
+ return $this->attributes;
+ }
+
+ public function getName(): string
+ {
+ return $this->name;
+ }
+
+ public function getEpochNanos(): int
+ {
+ return $this->timestamp;
+ }
+
+ public function getTotalAttributeCount(): int
+ {
+ return count($this->attributes);
+ }
+
+ public function getDroppedAttributesCount(): int
+ {
+ return $this->attributes->getDroppedAttributesCount();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/EventInterface.php b/vendor/open-telemetry/sdk/Trace/EventInterface.php
new file mode 100644
index 000000000..8b5ee2af6
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/EventInterface.php
@@ -0,0 +1,15 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+interface EventInterface
+{
+ public function getName(): string;
+ public function getAttributes(): AttributesInterface;
+ public function getEpochNanos(): int;
+ public function getTotalAttributeCount(): int;
+}
diff --git a/vendor/open-telemetry/sdk/Trace/ExporterFactory.php b/vendor/open-telemetry/sdk/Trace/ExporterFactory.php
new file mode 100644
index 000000000..9b652cc2f
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/ExporterFactory.php
@@ -0,0 +1,32 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use InvalidArgumentException;
+use OpenTelemetry\SDK\Common\Configuration\Configuration;
+use OpenTelemetry\SDK\Common\Configuration\Variables;
+use OpenTelemetry\SDK\Registry;
+use RuntimeException;
+
+class ExporterFactory
+{
+ /**
+ * @throws RuntimeException
+ */
+ public function create(): ?SpanExporterInterface
+ {
+ $exporters = Configuration::getList(Variables::OTEL_TRACES_EXPORTER);
+ if (1 !== count($exporters)) {
+ throw new InvalidArgumentException(sprintf('Configuration %s requires exactly 1 exporter', Variables::OTEL_TRACES_EXPORTER));
+ }
+ $exporter = $exporters[0];
+ if ($exporter === 'none') {
+ return null;
+ }
+ $factory = Registry::spanExporterFactory($exporter);
+
+ return $factory->create();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/IdGeneratorInterface.php b/vendor/open-telemetry/sdk/Trace/IdGeneratorInterface.php
new file mode 100644
index 000000000..ad622dccc
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/IdGeneratorInterface.php
@@ -0,0 +1,12 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+interface IdGeneratorInterface
+{
+ public function generateTraceId(): string;
+
+ public function generateSpanId(): string;
+}
diff --git a/vendor/open-telemetry/sdk/Trace/ImmutableSpan.php b/vendor/open-telemetry/sdk/Trace/ImmutableSpan.php
new file mode 100644
index 000000000..57836d4c3
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/ImmutableSpan.php
@@ -0,0 +1,153 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use function max;
+use OpenTelemetry\API\Trace as API;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+
+/**
+ * @psalm-immutable
+ */
+final class ImmutableSpan implements SpanDataInterface
+{
+ private Span $span;
+
+ /** @var non-empty-string */
+ private string $name;
+
+ /** @var list<EventInterface> */
+ private array $events;
+
+ /** @var list<LinkInterface> */
+ private array $links;
+
+ private AttributesInterface $attributes;
+ private int $totalRecordedEvents;
+ private StatusDataInterface $status;
+ private int $endEpochNanos;
+ private bool $hasEnded;
+
+ /**
+ * @param non-empty-string $name
+ * @param list<LinkInterface> $links
+ * @param list<EventInterface> $events
+ */
+ public function __construct(
+ Span $span,
+ string $name,
+ array $links,
+ array $events,
+ AttributesInterface $attributes,
+ int $totalRecordedEvents,
+ StatusDataInterface $status,
+ int $endEpochNanos,
+ bool $hasEnded
+ ) {
+ $this->span = $span;
+ $this->name = $name;
+ $this->links = $links;
+ $this->events = $events;
+ $this->attributes = $attributes;
+ $this->totalRecordedEvents = $totalRecordedEvents;
+ $this->status = $status;
+ $this->endEpochNanos = $endEpochNanos;
+ $this->hasEnded = $hasEnded;
+ }
+
+ public function getKind(): int
+ {
+ return $this->span->getKind();
+ }
+
+ public function getContext(): API\SpanContextInterface
+ {
+ return $this->span->getContext();
+ }
+
+ public function getParentContext(): API\SpanContextInterface
+ {
+ return $this->span->getParentContext();
+ }
+
+ public function getTraceId(): string
+ {
+ return $this->getContext()->getTraceId();
+ }
+
+ public function getSpanId(): string
+ {
+ return $this->getContext()->getSpanId();
+ }
+
+ public function getParentSpanId(): string
+ {
+ return $this->getParentContext()->getSpanId();
+ }
+
+ public function getStartEpochNanos(): int
+ {
+ return $this->span->getStartEpochNanos();
+ }
+
+ public function getEndEpochNanos(): int
+ {
+ return $this->endEpochNanos;
+ }
+
+ public function getInstrumentationScope(): InstrumentationScopeInterface
+ {
+ return $this->span->getInstrumentationScope();
+ }
+
+ public function getResource(): ResourceInfo
+ {
+ return $this->span->getResource();
+ }
+
+ public function getName(): string
+ {
+ return $this->name;
+ }
+
+ /** @inheritDoc */
+ public function getLinks(): array
+ {
+ return $this->links;
+ }
+
+ /** @inheritDoc */
+ public function getEvents(): array
+ {
+ return $this->events;
+ }
+
+ public function getAttributes(): AttributesInterface
+ {
+ return $this->attributes;
+ }
+
+ public function getTotalDroppedEvents(): int
+ {
+ return max(0, $this->totalRecordedEvents - count($this->events));
+ }
+
+ public function getTotalDroppedLinks(): int
+ {
+ return max(0, $this->span->getTotalRecordedLinks() - count($this->links));
+ }
+
+ public function getStatus(): StatusDataInterface
+ {
+ return $this->status;
+ }
+
+ public function hasEnded(): bool
+ {
+ return $this->hasEnded;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/Link.php b/vendor/open-telemetry/sdk/Trace/Link.php
new file mode 100644
index 000000000..9927839e7
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/Link.php
@@ -0,0 +1,30 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\API\Trace as API;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+final class Link implements LinkInterface
+{
+ private AttributesInterface $attributes;
+ private API\SpanContextInterface $context;
+
+ public function __construct(API\SpanContextInterface $context, AttributesInterface $attributes)
+ {
+ $this->context = $context;
+ $this->attributes = $attributes;
+ }
+
+ public function getSpanContext(): API\SpanContextInterface
+ {
+ return $this->context;
+ }
+
+ public function getAttributes(): AttributesInterface
+ {
+ return $this->attributes;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/LinkInterface.php b/vendor/open-telemetry/sdk/Trace/LinkInterface.php
new file mode 100644
index 000000000..8090fa1a5
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/LinkInterface.php
@@ -0,0 +1,14 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\API\Trace\SpanContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+interface LinkInterface
+{
+ public function getSpanContext(): SpanContextInterface;
+ public function getAttributes(): AttributesInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Trace/NoopTracerProvider.php b/vendor/open-telemetry/sdk/Trace/NoopTracerProvider.php
new file mode 100644
index 000000000..7cd4d4e7d
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/NoopTracerProvider.php
@@ -0,0 +1,21 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\API;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+
+class NoopTracerProvider extends API\Trace\NoopTracerProvider implements TracerProviderInterface
+{
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ return true;
+ }
+
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ return true;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/RandomIdGenerator.php b/vendor/open-telemetry/sdk/Trace/RandomIdGenerator.php
new file mode 100644
index 000000000..39767fb0f
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/RandomIdGenerator.php
@@ -0,0 +1,49 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\API\Trace\SpanContextValidator;
+use Throwable;
+
+class RandomIdGenerator implements IdGeneratorInterface
+{
+ private const TRACE_ID_HEX_LENGTH = 32;
+ private const SPAN_ID_HEX_LENGTH = 16;
+
+ public function generateTraceId(): string
+ {
+ do {
+ $traceId = $this->randomHex(self::TRACE_ID_HEX_LENGTH);
+ } while (!SpanContextValidator::isValidTraceId($traceId));
+
+ return $traceId;
+ }
+
+ public function generateSpanId(): string
+ {
+ do {
+ $spanId = $this->randomHex(self::SPAN_ID_HEX_LENGTH);
+ } while (!SpanContextValidator::isValidSpanId($spanId));
+
+ return $spanId;
+ }
+
+ /**
+ * @psalm-suppress ArgumentTypeCoercion $hexLength is always a positive integer
+ */
+ private function randomHex(int $hexLength): string
+ {
+ try {
+ return bin2hex(random_bytes(intdiv($hexLength, 2)));
+ } catch (Throwable $e) {
+ return $this->fallbackAlgorithm($hexLength);
+ }
+ }
+
+ private function fallbackAlgorithm(int $hexLength): string
+ {
+ return substr(str_shuffle(str_repeat('0123456789abcdef', $hexLength)), 1, $hexLength);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/ReadWriteSpanInterface.php b/vendor/open-telemetry/sdk/Trace/ReadWriteSpanInterface.php
new file mode 100644
index 000000000..60940ac01
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/ReadWriteSpanInterface.php
@@ -0,0 +1,11 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\API\Trace as API;
+
+interface ReadWriteSpanInterface extends API\SpanInterface, ReadableSpanInterface
+{
+}
diff --git a/vendor/open-telemetry/sdk/Trace/ReadableSpanInterface.php b/vendor/open-telemetry/sdk/Trace/ReadableSpanInterface.php
new file mode 100644
index 000000000..40704ab4e
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/ReadableSpanInterface.php
@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\API\Trace as API;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+
+/**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/trace/sdk.md#additional-span-interfaces
+ */
+interface ReadableSpanInterface
+{
+ public function getName(): string;
+
+ public function getContext(): API\SpanContextInterface;
+
+ public function getParentContext(): API\SpanContextInterface;
+
+ public function getInstrumentationScope(): InstrumentationScopeInterface;
+
+ public function hasEnded(): bool;
+
+ /**
+ * Returns an immutable representation of this instance.
+ */
+ public function toSpanData(): SpanDataInterface;
+
+ /**
+ * Returns the duration of the {@see API\SpanInterface} in nanoseconds.
+ * If still active, returns `now() - start`.
+ */
+ public function getDuration(): int;
+
+ /**
+ * @see API\SpanKind
+ */
+ public function getKind(): int;
+
+ /**
+ * Returns the value of the attribute with the provided *key*.
+ * Returns `null` if there are no attributes set, or no attribute with that key exists.
+ *
+ * @return mixed
+ */
+ public function getAttribute(string $key);
+}
diff --git a/vendor/open-telemetry/sdk/Trace/Sampler/AlwaysOffSampler.php b/vendor/open-telemetry/sdk/Trace/Sampler/AlwaysOffSampler.php
new file mode 100644
index 000000000..ee7e70a56
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/Sampler/AlwaysOffSampler.php
@@ -0,0 +1,50 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\Sampler;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Trace\SamplerInterface;
+use OpenTelemetry\SDK\Trace\SamplingResult;
+use OpenTelemetry\SDK\Trace\Span;
+
+/**
+ * This implementation of the SamplerInterface always skips record.
+ * Example:
+ * ```
+ * use OpenTelemetry\Sdk\Trace\AlwaysOffSampler;
+ * $sampler = new AlwaysOffSampler();
+ * ```
+ */
+class AlwaysOffSampler implements SamplerInterface
+{
+ /**
+ * Returns false because we never want to sample.
+ * {@inheritdoc}
+ */
+ public function shouldSample(
+ ContextInterface $parentContext,
+ string $traceId,
+ string $spanName,
+ int $spanKind,
+ AttributesInterface $attributes,
+ array $links
+ ): SamplingResult {
+ $parentSpan = Span::fromContext($parentContext);
+ $parentSpanContext = $parentSpan->getContext();
+ $traceState = $parentSpanContext->getTraceState();
+
+ return new SamplingResult(
+ SamplingResult::DROP,
+ [],
+ $traceState
+ );
+ }
+
+ public function getDescription(): string
+ {
+ return 'AlwaysOffSampler';
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/Sampler/AlwaysOnSampler.php b/vendor/open-telemetry/sdk/Trace/Sampler/AlwaysOnSampler.php
new file mode 100644
index 000000000..df61d1aee
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/Sampler/AlwaysOnSampler.php
@@ -0,0 +1,50 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\Sampler;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Trace\SamplerInterface;
+use OpenTelemetry\SDK\Trace\SamplingResult;
+use OpenTelemetry\SDK\Trace\Span;
+
+/**
+ * This implementation of the SamplerInterface always records.
+ * Example:
+ * ```
+ * use OpenTelemetry\Sdk\Trace\AlwaysOnSampler;
+ * $sampler = new AlwaysOnSampler();
+ * ```
+ */
+class AlwaysOnSampler implements SamplerInterface
+{
+ /**
+ * Returns true because we always want to sample.
+ * {@inheritdoc}
+ */
+ public function shouldSample(
+ ContextInterface $parentContext,
+ string $traceId,
+ string $spanName,
+ int $spanKind,
+ AttributesInterface $attributes,
+ array $links
+ ): SamplingResult {
+ $parentSpan = Span::fromContext($parentContext);
+ $parentSpanContext = $parentSpan->getContext();
+ $traceState = $parentSpanContext->getTraceState();
+
+ return new SamplingResult(
+ SamplingResult::RECORD_AND_SAMPLE,
+ [],
+ $traceState
+ );
+ }
+
+ public function getDescription(): string
+ {
+ return 'AlwaysOnSampler';
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/Sampler/ParentBased.php b/vendor/open-telemetry/sdk/Trace/Sampler/ParentBased.php
new file mode 100644
index 000000000..db801d3d8
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/Sampler/ParentBased.php
@@ -0,0 +1,100 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\Sampler;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Trace\SamplerInterface;
+use OpenTelemetry\SDK\Trace\SamplingResult;
+use OpenTelemetry\SDK\Trace\Span;
+
+/**
+ * Phan seems to struggle with the variadic arguments in the latest version
+ * @phan-file-suppress PhanParamTooFewUnpack
+ */
+
+/**
+ * This implementation of the SamplerInterface that respects parent context's sampling decision
+ * and delegates for the root span.
+ * Example:
+ * ```
+ * use OpenTelemetry\API\Trace\ParentBased;
+ * use OpenTelemetry\API\Trace\AlwaysOnSampler
+ *
+ * $rootSampler = new AlwaysOnSampler();
+ * $sampler = new ParentBased($rootSampler);
+ * ```
+ */
+class ParentBased implements SamplerInterface
+{
+ private SamplerInterface $root;
+
+ private SamplerInterface $remoteParentSampler;
+
+ private SamplerInterface $remoteParentNotSampler;
+
+ private SamplerInterface $localParentSampler;
+
+ private SamplerInterface $localParentNotSampler;
+
+ /**
+ * ParentBased sampler delegates the sampling decision based on the parent context.
+ *
+ * @param SamplerInterface $root Sampler called for the span with no parent (root span).
+ * @param SamplerInterface|null $remoteParentSampler Sampler called for the span with the remote sampled parent. When null, `AlwaysOnSampler` is used.
+ * @param SamplerInterface|null $remoteParentNotSampler Sampler called for the span with the remote not sampled parent. When null, `AlwaysOffSampler` is used.
+ * @param SamplerInterface|null $localParentSampler Sampler called for the span with local the sampled parent. When null, `AlwaysOnSampler` is used.
+ * @param SamplerInterface|null $localParentNotSampler Sampler called for the span with the local not sampled parent. When null, `AlwaysOffSampler` is used.
+ */
+ public function __construct(
+ SamplerInterface $root,
+ ?SamplerInterface $remoteParentSampler = null,
+ ?SamplerInterface $remoteParentNotSampler = null,
+ ?SamplerInterface $localParentSampler = null,
+ ?SamplerInterface $localParentNotSampler = null
+ ) {
+ $this->root = $root;
+ $this->remoteParentSampler = $remoteParentSampler ?? new AlwaysOnSampler();
+ $this->remoteParentNotSampler = $remoteParentNotSampler ?? new AlwaysOffSampler();
+ $this->localParentSampler = $localParentSampler ?? new AlwaysOnSampler();
+ $this->localParentNotSampler = $localParentNotSampler ?? new AlwaysOffSampler();
+ }
+
+ /**
+ * Invokes the respective delegate sampler when parent is set or uses root sampler for the root span.
+ * {@inheritdoc}
+ */
+ public function shouldSample(
+ ContextInterface $parentContext,
+ string $traceId,
+ string $spanName,
+ int $spanKind,
+ AttributesInterface $attributes,
+ array $links
+ ): SamplingResult {
+ $parentSpan = Span::fromContext($parentContext);
+ $parentSpanContext = $parentSpan->getContext();
+
+ // Invalid parent SpanContext indicates root span is being created
+ if (!$parentSpanContext->isValid()) {
+ return $this->root->shouldSample(...func_get_args());
+ }
+
+ if ($parentSpanContext->isRemote()) {
+ return $parentSpanContext->isSampled()
+ ? $this->remoteParentSampler->shouldSample(...func_get_args())
+ : $this->remoteParentNotSampler->shouldSample(...func_get_args());
+ }
+
+ return $parentSpanContext->isSampled()
+ ? $this->localParentSampler->shouldSample(...func_get_args())
+ : $this->localParentNotSampler->shouldSample(...func_get_args());
+ }
+
+ public function getDescription(): string
+ {
+ return 'ParentBased+' . $this->root->getDescription();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/Sampler/TraceIdRatioBasedSampler.php b/vendor/open-telemetry/sdk/Trace/Sampler/TraceIdRatioBasedSampler.php
new file mode 100644
index 000000000..c11a90d5d
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/Sampler/TraceIdRatioBasedSampler.php
@@ -0,0 +1,70 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\Sampler;
+
+use InvalidArgumentException;
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Trace\SamplerInterface;
+use OpenTelemetry\SDK\Trace\SamplingResult;
+use OpenTelemetry\SDK\Trace\Span;
+
+/**
+ * This implementation of the SamplerInterface records with given probability.
+ * Example:
+ * ```
+ * use OpenTelemetry\API\Trace\TraceIdRatioBasedSampler;
+ * $sampler = new TraceIdRatioBasedSampler(0.01);
+ * ```
+ */
+class TraceIdRatioBasedSampler implements SamplerInterface
+{
+ private float $probability;
+
+ /**
+ * TraceIdRatioBasedSampler constructor.
+ * @param float $probability Probability float value between 0.0 and 1.0.
+ */
+ public function __construct(float $probability)
+ {
+ if ($probability < 0.0 || $probability > 1.0) {
+ throw new InvalidArgumentException('probability should be be between 0.0 and 1.0.');
+ }
+ $this->probability = $probability;
+ }
+
+ /**
+ * Returns `SamplingResult` based on probability. Respects the parent `SampleFlag`
+ * {@inheritdoc}
+ */
+ public function shouldSample(
+ ContextInterface $parentContext,
+ string $traceId,
+ string $spanName,
+ int $spanKind,
+ AttributesInterface $attributes,
+ array $links
+ ): SamplingResult {
+ // TODO: Add config to adjust which spans get sampled (only default from specification is implemented)
+ $parentSpan = Span::fromContext($parentContext);
+ $parentSpanContext = $parentSpan->getContext();
+ $traceState = $parentSpanContext->getTraceState();
+
+ /**
+ * Since php can only store up to 63 bit positive integers
+ */
+ $traceIdLimit = (1 << 60) - 1;
+ $lowerOrderBytes = hexdec(substr($traceId, strlen($traceId) - 15, 15));
+ $traceIdCondition = $lowerOrderBytes < round($this->probability * $traceIdLimit);
+ $decision = $traceIdCondition ? SamplingResult::RECORD_AND_SAMPLE : SamplingResult::DROP;
+
+ return new SamplingResult($decision, [], $traceState);
+ }
+
+ public function getDescription(): string
+ {
+ return sprintf('%s{%.6F}', 'TraceIdRatioBasedSampler', $this->probability);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SamplerFactory.php b/vendor/open-telemetry/sdk/Trace/SamplerFactory.php
new file mode 100644
index 000000000..f99674d79
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SamplerFactory.php
@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use InvalidArgumentException;
+use OpenTelemetry\SDK\Common\Configuration\Configuration;
+use OpenTelemetry\SDK\Common\Configuration\KnownValues as Values;
+use OpenTelemetry\SDK\Common\Configuration\Variables as Env;
+use OpenTelemetry\SDK\Trace\Sampler\AlwaysOffSampler;
+use OpenTelemetry\SDK\Trace\Sampler\AlwaysOnSampler;
+use OpenTelemetry\SDK\Trace\Sampler\ParentBased;
+use OpenTelemetry\SDK\Trace\Sampler\TraceIdRatioBasedSampler;
+
+class SamplerFactory
+{
+ private const TRACEIDRATIO_PREFIX = 'traceidratio';
+
+ public function create(): SamplerInterface
+ {
+ $name = Configuration::getString(Env::OTEL_TRACES_SAMPLER);
+
+ if (strpos($name, self::TRACEIDRATIO_PREFIX) !== false) {
+ $arg = Configuration::getRatio(Env::OTEL_TRACES_SAMPLER_ARG);
+
+ switch ($name) {
+ case Values::VALUE_TRACE_ID_RATIO:
+ return new TraceIdRatioBasedSampler($arg);
+ case Values::VALUE_PARENT_BASED_TRACE_ID_RATIO:
+ return new ParentBased(new TraceIdRatioBasedSampler($arg));
+ }
+ }
+
+ switch ($name) {
+ case Values::VALUE_ALWAYS_ON:
+ return new AlwaysOnSampler();
+ case Values::VALUE_ALWAYS_OFF:
+ return new AlwaysOffSampler();
+ case Values::VALUE_PARENT_BASED_ALWAYS_ON:
+ return new ParentBased(new AlwaysOnSampler());
+ case Values::VALUE_PARENT_BASED_ALWAYS_OFF:
+ return new ParentBased(new AlwaysOffSampler());
+ default:
+ throw new InvalidArgumentException(sprintf('Unknown sampler: %s', $name));
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SamplerInterface.php b/vendor/open-telemetry/sdk/Trace/SamplerInterface.php
new file mode 100644
index 000000000..de1147fa6
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SamplerInterface.php
@@ -0,0 +1,46 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+
+/**
+ * This interface is used to organize sampling logic.
+ *
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#sampler
+ */
+interface SamplerInterface
+{
+ /**
+ * Returns SamplingResult.
+ *
+ * @param ContextInterface $parentContext Context with parent Span. The Span's SpanContext may be invalid to indicate a root span.
+ * @param string $traceId TraceId of the Span to be created. It can be different from the TraceId in the SpanContext.
+ * Typically in situations when the Span to be created starts a new Trace.
+ * @param string $spanName Name of the Span to be created.
+ * @param int $spanKind Span kind.
+ * @param AttributesInterface $attributes Initial set of Attributes for the Span being constructed.
+ * @param list<LinkInterface> $links Collection of links that will be associated with the Span to be created.
+ * Typically, useful for batch operations.
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/overview.md#links-between-spans
+ * @return SamplingResult
+ */
+ public function shouldSample(
+ ContextInterface $parentContext,
+ string $traceId,
+ string $spanName,
+ int $spanKind,
+ AttributesInterface $attributes,
+ array $links
+ ): SamplingResult;
+
+ /**
+ * Returns the sampler name or short description with the configuration.
+ * This may be displayed on debug pages or in the logs.
+ * Example: "TraceIdRatioBasedSampler{0.000100}"
+ */
+ public function getDescription(): string;
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SamplingResult.php b/vendor/open-telemetry/sdk/Trace/SamplingResult.php
new file mode 100644
index 000000000..5701b7bc6
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SamplingResult.php
@@ -0,0 +1,71 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\API\Trace as API;
+
+final class SamplingResult
+{
+ /**
+ * Span will not be recorded and all events and attributes will be dropped.
+ */
+ public const DROP = 0;
+
+ /**
+ * Span will be recorded but SpanExporters will not receive this Span.
+ */
+ public const RECORD_ONLY = 1;
+
+ /**
+ * Span will be recorder and exported.
+ */
+ public const RECORD_AND_SAMPLE = 2;
+
+ /**
+ * @var int A sampling Decision.
+ */
+ private int $decision;
+
+ /**
+ * @var iterable A set of span Attributes that will also be added to the Span.
+ */
+ private iterable $attributes;
+
+ /**
+ * @var ?API\TraceStateInterface A Tracestate that will be associated with the Span through the new SpanContext.
+ */
+ private ?API\TraceStateInterface $traceState;
+
+ public function __construct(int $decision, iterable $attributes = [], ?API\TraceStateInterface $traceState = null)
+ {
+ $this->decision = $decision;
+ $this->attributes = $attributes;
+ $this->traceState = $traceState;
+ }
+
+ /**
+ * Return sampling decision whether span should be recorded or not.
+ */
+ public function getDecision(): int
+ {
+ return $this->decision;
+ }
+
+ /**
+ * Return attributes which will be attached to the span.
+ */
+ public function getAttributes(): iterable
+ {
+ return $this->attributes;
+ }
+
+ /**
+ * Return a collection of links that will be associated with the Span to be created.
+ */
+ public function getTraceState(): ?API\TraceStateInterface
+ {
+ return $this->traceState;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/Span.php b/vendor/open-telemetry/sdk/Trace/Span.php
new file mode 100644
index 000000000..f72ec1bd7
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/Span.php
@@ -0,0 +1,359 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use function get_class;
+use OpenTelemetry\API\Trace as API;
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesBuilderInterface;
+use OpenTelemetry\SDK\Common\Dev\Compatibility\Util as BcUtil;
+use OpenTelemetry\SDK\Common\Exception\StackTraceFormatter;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Common\Time\ClockFactory;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use Throwable;
+
+final class Span extends API\Span implements ReadWriteSpanInterface
+{
+
+ /** @readonly */
+ private API\SpanContextInterface $context;
+
+ /** @readonly */
+ private API\SpanContextInterface $parentSpanContext;
+
+ /** @readonly */
+ private SpanLimits $spanLimits;
+
+ /** @readonly */
+ private SpanProcessorInterface $spanProcessor;
+
+ /**
+ * @readonly
+ *
+ * @var list<LinkInterface>
+ */
+ private array $links;
+
+ /** @readonly */
+ private int $totalRecordedLinks;
+
+ /** @readonly */
+ private int $kind;
+
+ /** @readonly */
+ private ResourceInfo $resource;
+
+ /** @readonly */
+ private InstrumentationScopeInterface $instrumentationScope;
+
+ /** @readonly */
+ private int $startEpochNanos;
+
+ /** @var non-empty-string */
+ private string $name;
+
+ /** @var list<EventInterface> */
+ private array $events = [];
+
+ private AttributesBuilderInterface $attributesBuilder;
+ private int $totalRecordedEvents = 0;
+ private StatusDataInterface $status;
+ private int $endEpochNanos = 0;
+ private bool $hasEnded = false;
+
+ /**
+ * @param non-empty-string $name
+ * @param list<LinkInterface> $links
+ */
+ private function __construct(
+ string $name,
+ API\SpanContextInterface $context,
+ InstrumentationScopeInterface $instrumentationScope,
+ int $kind,
+ API\SpanContextInterface $parentSpanContext,
+ SpanLimits $spanLimits,
+ SpanProcessorInterface $spanProcessor,
+ ResourceInfo $resource,
+ AttributesBuilderInterface $attributesBuilder,
+ array $links,
+ int $totalRecordedLinks,
+ int $startEpochNanos
+ ) {
+ $this->context = $context;
+ $this->instrumentationScope = $instrumentationScope;
+ $this->parentSpanContext = $parentSpanContext;
+ $this->links = $links;
+ $this->totalRecordedLinks = $totalRecordedLinks;
+ $this->name = $name;
+ $this->kind = $kind;
+ $this->spanProcessor = $spanProcessor;
+ $this->resource = $resource;
+ $this->startEpochNanos = $startEpochNanos;
+ $this->attributesBuilder = $attributesBuilder;
+ $this->status = StatusData::unset();
+ $this->spanLimits = $spanLimits;
+ }
+
+ /**
+ * This method _MUST_ not be used directly.
+ * End users should use a {@see API\TracerInterface} in order to create spans.
+ *
+ * @param non-empty-string $name
+ * @psalm-param API\SpanKind::KIND_* $kind
+ * @param list<LinkInterface> $links
+ *
+ * @internal
+ * @psalm-internal OpenTelemetry
+ */
+ public static function startSpan(
+ string $name,
+ API\SpanContextInterface $context,
+ InstrumentationScopeInterface $instrumentationScope,
+ int $kind,
+ API\SpanInterface $parentSpan,
+ ContextInterface $parentContext,
+ SpanLimits $spanLimits,
+ SpanProcessorInterface $spanProcessor,
+ ResourceInfo $resource,
+ AttributesBuilderInterface $attributesBuilder,
+ array $links,
+ int $totalRecordedLinks,
+ int $startEpochNanos
+ ): self {
+ $span = new self(
+ $name,
+ $context,
+ $instrumentationScope,
+ $kind,
+ $parentSpan->getContext(),
+ $spanLimits,
+ $spanProcessor,
+ $resource,
+ $attributesBuilder,
+ $links,
+ $totalRecordedLinks,
+ $startEpochNanos !== 0 ? $startEpochNanos : ClockFactory::getDefault()->now()
+ );
+
+ // Call onStart here to ensure the span is fully initialized.
+ $spanProcessor->onStart($span, $parentContext);
+
+ return $span;
+ }
+
+ /**
+ * Backward compatibility methods
+ *
+ * @codeCoverageIgnore
+ */
+ public static function formatStackTrace(Throwable $e, array &$seen = null): string
+ {
+ BcUtil::triggerMethodDeprecationNotice(
+ __METHOD__,
+ 'format',
+ StackTraceFormatter::class
+ );
+
+ return StackTraceFormatter::format($e);
+ }
+
+ /** @inheritDoc */
+ public function getContext(): API\SpanContextInterface
+ {
+ return $this->context;
+ }
+
+ /** @inheritDoc */
+ public function isRecording(): bool
+ {
+ return !$this->hasEnded;
+ }
+
+ /** @inheritDoc */
+ public function setAttribute(string $key, $value): self
+ {
+ if ($this->hasEnded) {
+ return $this;
+ }
+
+ $this->attributesBuilder[$key] = $value;
+
+ return $this;
+ }
+
+ /** @inheritDoc */
+ public function setAttributes(iterable $attributes): self
+ {
+ foreach ($attributes as $key => $value) {
+ $this->attributesBuilder[$key] = $value;
+ }
+
+ return $this;
+ }
+
+ /** @inheritDoc */
+ public function addEvent(string $name, iterable $attributes = [], ?int $timestamp = null): self
+ {
+ if ($this->hasEnded) {
+ return $this;
+ }
+ if (++$this->totalRecordedEvents > $this->spanLimits->getEventCountLimit()) {
+ return $this;
+ }
+
+ $timestamp ??= ClockFactory::getDefault()->now();
+ $eventAttributesBuilder = $this->spanLimits->getEventAttributesFactory()->builder($attributes);
+
+ $this->events[] = new Event($name, $timestamp, $eventAttributesBuilder->build());
+
+ return $this;
+ }
+
+ /** @inheritDoc */
+ public function recordException(Throwable $exception, iterable $attributes = [], ?int $timestamp = null): self
+ {
+ if ($this->hasEnded) {
+ return $this;
+ }
+ if (++$this->totalRecordedEvents > $this->spanLimits->getEventCountLimit()) {
+ return $this;
+ }
+
+ $timestamp ??= ClockFactory::getDefault()->now();
+ $eventAttributesBuilder = $this->spanLimits->getEventAttributesFactory()->builder([
+ 'exception.type' => get_class($exception),
+ 'exception.message' => $exception->getMessage(),
+ 'exception.stacktrace' => StackTraceFormatter::format($exception),
+ ]);
+
+ foreach ($attributes as $key => $value) {
+ $eventAttributesBuilder[$key] = $value;
+ }
+
+ $this->events[] = new Event('exception', $timestamp, $eventAttributesBuilder->build());
+
+ return $this;
+ }
+
+ /** @inheritDoc */
+ public function updateName(string $name): self
+ {
+ if ($this->hasEnded) {
+ return $this;
+ }
+ $this->name = $name;
+
+ return $this;
+ }
+
+ /** @inheritDoc */
+ public function setStatus(string $code, string $description = null): self
+ {
+ if ($this->hasEnded) {
+ return $this;
+ }
+
+ // An attempt to set value Unset SHOULD be ignored.
+ if ($code === API\StatusCode::STATUS_UNSET) {
+ return $this;
+ }
+
+ // When span status is set to Ok it SHOULD be considered final and any further attempts to change it SHOULD be ignored.
+ if ($this->status->getCode() === API\StatusCode::STATUS_OK) {
+ return $this;
+ }
+ $this->status = StatusData::create($code, $description);
+
+ return $this;
+ }
+
+ /** @inheritDoc */
+ public function end(int $endEpochNanos = null): void
+ {
+ if ($this->hasEnded) {
+ return;
+ }
+
+ $this->endEpochNanos = $endEpochNanos ?? ClockFactory::getDefault()->now();
+ $this->hasEnded = true;
+
+ $this->spanProcessor->onEnd($this);
+ }
+
+ /** @inheritDoc */
+ public function getName(): string
+ {
+ return $this->name;
+ }
+
+ public function getParentContext(): API\SpanContextInterface
+ {
+ return $this->parentSpanContext;
+ }
+
+ public function getInstrumentationScope(): InstrumentationScopeInterface
+ {
+ return $this->instrumentationScope;
+ }
+
+ public function hasEnded(): bool
+ {
+ return $this->hasEnded;
+ }
+
+ public function toSpanData(): SpanDataInterface
+ {
+ return new ImmutableSpan(
+ $this,
+ $this->name,
+ $this->links,
+ $this->events,
+ $this->attributesBuilder->build(),
+ $this->totalRecordedEvents,
+ $this->status,
+ $this->endEpochNanos,
+ $this->hasEnded
+ );
+ }
+
+ /** @inheritDoc */
+ public function getDuration(): int
+ {
+ return ($this->hasEnded ? $this->endEpochNanos : ClockFactory::getDefault()->now()) - $this->startEpochNanos;
+ }
+
+ /** @inheritDoc */
+ public function getKind(): int
+ {
+ return $this->kind;
+ }
+
+ /** @inheritDoc */
+ public function getAttribute(string $key)
+ {
+ return $this->attributesBuilder[$key];
+ }
+
+ public function getStartEpochNanos(): int
+ {
+ return $this->startEpochNanos;
+ }
+
+ public function getTotalRecordedLinks(): int
+ {
+ return $this->totalRecordedLinks;
+ }
+
+ public function getTotalRecordedEvents(): int
+ {
+ return $this->totalRecordedEvents;
+ }
+
+ public function getResource(): ResourceInfo
+ {
+ return $this->resource;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanBuilder.php b/vendor/open-telemetry/sdk/Trace/SpanBuilder.php
new file mode 100644
index 000000000..2867c01c8
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanBuilder.php
@@ -0,0 +1,191 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use function in_array;
+use OpenTelemetry\API\Trace as API;
+use OpenTelemetry\Context\Context;
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Attribute\AttributesBuilderInterface;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+
+final class SpanBuilder implements API\SpanBuilderInterface
+{
+ /**
+ * @var non-empty-string
+ * @readonly
+ */
+ private string $spanName;
+
+ /** @readonly */
+ private InstrumentationScopeInterface $instrumentationScope;
+
+ /** @readonly */
+ private TracerSharedState $tracerSharedState;
+
+ /** @var ContextInterface|false|null */
+ private $parentContext = null;
+
+ /**
+ * @psalm-var API\SpanKind::KIND_*
+ */
+ private int $spanKind = API\SpanKind::KIND_INTERNAL;
+
+ /** @var list<LinkInterface> */
+ private array $links = [];
+
+ private AttributesBuilderInterface $attributesBuilder;
+ private int $totalNumberOfLinksAdded = 0;
+ private int $startEpochNanos = 0;
+
+ /** @param non-empty-string $spanName */
+ public function __construct(
+ string $spanName,
+ InstrumentationScopeInterface $instrumentationScope,
+ TracerSharedState $tracerSharedState
+ ) {
+ $this->spanName = $spanName;
+ $this->instrumentationScope = $instrumentationScope;
+ $this->tracerSharedState = $tracerSharedState;
+ $this->attributesBuilder = $tracerSharedState->getSpanLimits()->getAttributesFactory()->builder();
+ }
+
+ /** @inheritDoc */
+ public function setParent($context): API\SpanBuilderInterface
+ {
+ $this->parentContext = $context;
+
+ return $this;
+ }
+
+ /** @inheritDoc */
+ public function addLink(API\SpanContextInterface $context, iterable $attributes = []): API\SpanBuilderInterface
+ {
+ if (!$context->isValid()) {
+ return $this;
+ }
+
+ $this->totalNumberOfLinksAdded++;
+
+ if (count($this->links) === $this->tracerSharedState->getSpanLimits()->getLinkCountLimit()) {
+ return $this;
+ }
+
+ $this->links[] = new Link(
+ $context,
+ $this->tracerSharedState
+ ->getSpanLimits()
+ ->getLinkAttributesFactory()
+ ->builder($attributes)
+ ->build(),
+ );
+
+ return $this;
+ }
+
+ /** @inheritDoc */
+ public function setAttribute(string $key, $value): API\SpanBuilderInterface
+ {
+ $this->attributesBuilder[$key] = $value;
+
+ return $this;
+ }
+
+ /** @inheritDoc */
+ public function setAttributes(iterable $attributes): API\SpanBuilderInterface
+ {
+ foreach ($attributes as $key => $value) {
+ $this->attributesBuilder[$key] = $value;
+ }
+
+ return $this;
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @psalm-param API\SpanKind::KIND_* $spanKind
+ */
+ public function setSpanKind(int $spanKind): API\SpanBuilderInterface
+ {
+ $this->spanKind = $spanKind;
+
+ return $this;
+ }
+
+ /** @inheritDoc */
+ public function setStartTimestamp(int $timestampNanos): API\SpanBuilderInterface
+ {
+ if (0 > $timestampNanos) {
+ return $this;
+ }
+
+ $this->startEpochNanos = $timestampNanos;
+
+ return $this;
+ }
+
+ /** @inheritDoc */
+ public function startSpan(): API\SpanInterface
+ {
+ $parentContext = Context::resolve($this->parentContext);
+ $parentSpan = Span::fromContext($parentContext);
+ $parentSpanContext = $parentSpan->getContext();
+
+ $spanId = $this->tracerSharedState->getIdGenerator()->generateSpanId();
+
+ if (!$parentSpanContext->isValid()) {
+ $traceId = $this->tracerSharedState->getIdGenerator()->generateTraceId();
+ } else {
+ $traceId = $parentSpanContext->getTraceId();
+ }
+
+ $samplingResult = $this
+ ->tracerSharedState
+ ->getSampler()
+ ->shouldSample(
+ $parentContext,
+ $traceId,
+ $this->spanName,
+ $this->spanKind,
+ $this->attributesBuilder->build(),
+ $this->links,
+ );
+ $samplingDecision = $samplingResult->getDecision();
+ $samplingResultTraceState = $samplingResult->getTraceState();
+
+ $spanContext = API\SpanContext::create(
+ $traceId,
+ $spanId,
+ SamplingResult::RECORD_AND_SAMPLE === $samplingDecision ? API\TraceFlags::SAMPLED : API\TraceFlags::DEFAULT,
+ $samplingResultTraceState,
+ );
+
+ if (!in_array($samplingDecision, [SamplingResult::RECORD_AND_SAMPLE, SamplingResult::RECORD_ONLY], true)) {
+ return Span::wrap($spanContext);
+ }
+
+ $attributesBuilder = clone $this->attributesBuilder;
+ foreach ($samplingResult->getAttributes() as $key => $value) {
+ $attributesBuilder[$key] = $value;
+ }
+
+ return Span::startSpan(
+ $this->spanName,
+ $spanContext,
+ $this->instrumentationScope,
+ $this->spanKind,
+ $parentSpan,
+ $parentContext,
+ $this->tracerSharedState->getSpanLimits(),
+ $this->tracerSharedState->getSpanProcessor(),
+ $this->tracerSharedState->getResource(),
+ $attributesBuilder,
+ $this->links,
+ $this->totalNumberOfLinksAdded,
+ $this->startEpochNanos
+ );
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanConverterInterface.php b/vendor/open-telemetry/sdk/Trace/SpanConverterInterface.php
new file mode 100644
index 000000000..40552e440
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanConverterInterface.php
@@ -0,0 +1,10 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+interface SpanConverterInterface
+{
+ public function convert(iterable $spans): array;
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanDataInterface.php b/vendor/open-telemetry/sdk/Trace/SpanDataInterface.php
new file mode 100644
index 000000000..37132b9e5
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanDataInterface.php
@@ -0,0 +1,46 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\API\Trace as API;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+
+/**
+ * Represents an immutable snapshot of a {@see API\SpanInterface}.
+ *
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/trace/sdk.md#additional-span-interfaces
+ */
+interface SpanDataInterface
+{
+ public function getName(): string;
+ public function getKind(): int;
+ public function getContext(): API\SpanContextInterface;
+ public function getParentContext(): API\SpanContextInterface;
+ public function getTraceId(): string;
+ public function getSpanId(): string;
+ public function getParentSpanId(): string;
+ public function getStatus(): StatusDataInterface;
+ public function getStartEpochNanos(): int;
+ public function getAttributes(): AttributesInterface;
+
+ /** @return list<EventInterface> */
+ public function getEvents(): array;
+
+ /** @return list<LinkInterface> */
+ public function getLinks(): array;
+
+ public function getEndEpochNanos(): int;
+ public function hasEnded(): bool;
+ public function getInstrumentationScope(): InstrumentationScopeInterface;
+ public function getResource(): ResourceInfo;
+
+ /** @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/trace/sdk_exporters/non-otlp.md#dropped-events-count */
+ public function getTotalDroppedEvents(): int;
+
+ /** @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/trace/sdk_exporters/non-otlp.md#dropped-links-count */
+ public function getTotalDroppedLinks(): int;
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanExporter/AbstractDecorator.php b/vendor/open-telemetry/sdk/Trace/SpanExporter/AbstractDecorator.php
new file mode 100644
index 000000000..42f49e815
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanExporter/AbstractDecorator.php
@@ -0,0 +1,12 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanExporter;
+
+use OpenTelemetry\SDK\Trace\Behavior\SpanExporterDecoratorTrait;
+
+abstract class AbstractDecorator
+{
+ use SpanExporterDecoratorTrait;
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanExporter/ConsoleSpanExporter.php b/vendor/open-telemetry/sdk/Trace/SpanExporter/ConsoleSpanExporter.php
new file mode 100644
index 000000000..482d122cc
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanExporter/ConsoleSpanExporter.php
@@ -0,0 +1,57 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanExporter;
+
+use JsonException;
+use OpenTelemetry\API\Behavior\LogsMessagesTrait;
+use OpenTelemetry\SDK\Common\Export\TransportInterface;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Common\Future\FutureInterface;
+use OpenTelemetry\SDK\Trace\Behavior\UsesSpanConverterTrait;
+use OpenTelemetry\SDK\Trace\SpanConverterInterface;
+use OpenTelemetry\SDK\Trace\SpanExporterInterface;
+
+class ConsoleSpanExporter implements SpanExporterInterface
+{
+ use UsesSpanConverterTrait;
+ use LogsMessagesTrait;
+
+ private TransportInterface $transport;
+
+ public function __construct(TransportInterface $transport, ?SpanConverterInterface $converter = null)
+ {
+ $this->transport = $transport;
+ $this->setSpanConverter($converter ?? new FriendlySpanConverter());
+ }
+
+ public function export(iterable $batch, ?CancellationInterface $cancellation = null): FutureInterface
+ {
+ $payload = '';
+ foreach ($batch as $span) {
+ try {
+ $payload .= json_encode(
+ $this->getSpanConverter()->convert([$span]),
+ JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT
+ ) . PHP_EOL;
+ } catch (JsonException $e) {
+ self::logWarning('Error converting span: ' . $e->getMessage());
+ }
+ }
+
+ return $this->transport->send($payload)
+ ->map(fn () => true)
+ ->catch(fn () => false);
+ }
+
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ return $this->transport->shutdown();
+ }
+
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ return $this->transport->forceFlush();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanExporter/ConsoleSpanExporterFactory.php b/vendor/open-telemetry/sdk/Trace/SpanExporter/ConsoleSpanExporterFactory.php
new file mode 100644
index 000000000..7e45fb549
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanExporter/ConsoleSpanExporterFactory.php
@@ -0,0 +1,18 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanExporter;
+
+use OpenTelemetry\SDK\Registry;
+use OpenTelemetry\SDK\Trace\SpanExporterInterface;
+
+class ConsoleSpanExporterFactory implements SpanExporterFactoryInterface
+{
+ public function create(): SpanExporterInterface
+ {
+ $transport = Registry::transportFactory('stream')->create('php://stdout', 'application/json');
+
+ return new ConsoleSpanExporter($transport);
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanExporter/FriendlySpanConverter.php b/vendor/open-telemetry/sdk/Trace/SpanExporter/FriendlySpanConverter.php
new file mode 100644
index 000000000..1f8178e10
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanExporter/FriendlySpanConverter.php
@@ -0,0 +1,173 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanExporter;
+
+use OpenTelemetry\API\Trace\SpanContextInterface;
+use OpenTelemetry\API\Trace\SpanKind;
+use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use OpenTelemetry\SDK\Trace\EventInterface;
+use OpenTelemetry\SDK\Trace\LinkInterface;
+use OpenTelemetry\SDK\Trace\SpanConverterInterface;
+use OpenTelemetry\SDK\Trace\SpanDataInterface;
+use OpenTelemetry\SDK\Trace\StatusDataInterface;
+use ReflectionClass;
+
+class FriendlySpanConverter implements SpanConverterInterface
+{
+ private const NAME_ATTR = 'name';
+ private const CONTEXT_ATTR = 'context';
+ private const TRACE_ID_ATTR = 'trace_id';
+ private const SPAN_ID_ATTR = 'span_id';
+ private const TRACE_STATE_ATTR = 'trace_state';
+ private const RESOURCE_ATTR = 'resource';
+ private const PARENT_SPAN_ATTR = 'parent_span_id';
+ private const KIND_ATTR = 'kind';
+ private const START_ATTR = 'start';
+ private const END_ATTR = 'end';
+ private const ATTRIBUTES_ATTR = 'attributes';
+ private const STATUS_ATTR = 'status';
+ private const CODE_ATTR = 'code';
+ private const DESCRIPTION_ATTR = 'description';
+ private const EVENTS_ATTR = 'events';
+ private const TIMESTAMP_ATTR = 'timestamp';
+ private const LINKS_ATTR = 'links';
+
+ public function convert(iterable $spans): array
+ {
+ $aggregate = [];
+ foreach ($spans as $span) {
+ $aggregate[] = $this->convertSpan($span);
+ }
+
+ return $aggregate;
+ }
+
+ /**
+ * friendlySpan does the heavy lifting converting a span into an array
+ *
+ * @param SpanDataInterface $span
+ * @return array
+ */
+ private function convertSpan(SpanDataInterface $span): array
+ {
+ return [
+ self::NAME_ATTR => $span->getName(),
+ self::CONTEXT_ATTR => $this->convertContext($span->getContext()),
+ self::RESOURCE_ATTR => $this->convertResource($span->getResource()),
+ self::PARENT_SPAN_ATTR => $this->covertParentContext($span->getParentContext()),
+ self::KIND_ATTR => $this->convertKind($span->getKind()),
+ self::START_ATTR => $span->getStartEpochNanos(),
+ self::END_ATTR => $span->getEndEpochNanos(),
+ self::ATTRIBUTES_ATTR => $this->convertAttributes($span->getAttributes()),
+ self::STATUS_ATTR => $this->covertStatus($span->getStatus()),
+ self::EVENTS_ATTR => $this->convertEvents($span->getEvents()),
+ self::LINKS_ATTR => $this->convertLinks($span->getLinks()),
+ ];
+ }
+
+ /**
+ * @param SpanContextInterface $context
+ * @return array
+ */
+ private function convertContext(SpanContextInterface $context): array
+ {
+ return [
+ self::TRACE_ID_ATTR => $context->getTraceId(),
+ self::SPAN_ID_ATTR => $context->getSpanId(),
+ self::TRACE_STATE_ATTR => (string) $context->getTraceState(),
+ ];
+ }
+
+ /**
+ * @param ResourceInfo $resource
+ * @return array
+ */
+ private function convertResource(ResourceInfo $resource): array
+ {
+ return $resource->getAttributes()->toArray();
+ }
+
+ /**
+ * @param SpanContextInterface $context
+ * @return string
+ */
+ private function covertParentContext(SpanContextInterface $context): string
+ {
+ return $context->isValid() ? $context->getSpanId() : '';
+ }
+
+ /**
+ * Translates SpanKind from its integer representation to a more human friendly string.
+ *
+ * @param int $kind
+ * @return string
+ */
+ private function convertKind(int $kind): string
+ {
+ return array_flip(
+ (new ReflectionClass(SpanKind::class))
+ ->getConstants()
+ )[$kind];
+ }
+
+ /**
+ * @param \OpenTelemetry\SDK\Common\Attribute\AttributesInterface $attributes
+ * @return array
+ */
+ private function convertAttributes(AttributesInterface $attributes): array
+ {
+ return $attributes->toArray();
+ }
+
+ /**
+ * @param StatusDataInterface $status
+ * @return array
+ */
+ private function covertStatus(StatusDataInterface $status): array
+ {
+ return [
+ self::CODE_ATTR => $status->getCode(),
+ self::DESCRIPTION_ATTR => $status->getDescription(),
+ ];
+ }
+
+ /**
+ * @param array<EventInterface> $events
+ * @return array
+ */
+ private function convertEvents(array $events): array
+ {
+ $result = [];
+
+ foreach ($events as $event) {
+ $result[] = [
+ self::NAME_ATTR => $event->getName(),
+ self::TIMESTAMP_ATTR => $event->getEpochNanos(),
+ self::ATTRIBUTES_ATTR => $this->convertAttributes($event->getAttributes()),
+ ];
+ }
+
+ return $result;
+ }
+
+ /**
+ * @param array<LinkInterface> $links
+ * @return array
+ */
+ private function convertLinks(array $links): array
+ {
+ $result = [];
+
+ foreach ($links as $link) {
+ $result[] = [
+ self::CONTEXT_ATTR => $this->convertContext($link->getSpanContext()),
+ self::ATTRIBUTES_ATTR => $this->convertAttributes($link->getAttributes()),
+ ];
+ }
+
+ return $result;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanExporter/InMemoryExporter.php b/vendor/open-telemetry/sdk/Trace/SpanExporter/InMemoryExporter.php
new file mode 100644
index 000000000..ebb022595
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanExporter/InMemoryExporter.php
@@ -0,0 +1,40 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanExporter;
+
+use ArrayObject;
+use OpenTelemetry\SDK\Trace\Behavior\SpanExporterTrait;
+use OpenTelemetry\SDK\Trace\SpanExporterInterface;
+
+class InMemoryExporter implements SpanExporterInterface
+{
+ use SpanExporterTrait;
+
+ private ArrayObject $storage;
+
+ public function __construct(?ArrayObject $storage = null)
+ {
+ $this->storage = $storage ?? new ArrayObject();
+ }
+
+ protected function doExport(iterable $spans): bool
+ {
+ foreach ($spans as $span) {
+ $this->storage[] = $span;
+ }
+
+ return true;
+ }
+
+ public function getSpans(): array
+ {
+ return (array) $this->storage;
+ }
+
+ public function getStorage(): ArrayObject
+ {
+ return $this->storage;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanExporter/InMemorySpanExporterFactory.php b/vendor/open-telemetry/sdk/Trace/SpanExporter/InMemorySpanExporterFactory.php
new file mode 100644
index 000000000..c19686fac
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanExporter/InMemorySpanExporterFactory.php
@@ -0,0 +1,15 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanExporter;
+
+use OpenTelemetry\SDK\Trace\SpanExporterInterface;
+
+class InMemorySpanExporterFactory implements SpanExporterFactoryInterface
+{
+ public function create(): SpanExporterInterface
+ {
+ return new InMemoryExporter();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanExporter/LoggerDecorator.php b/vendor/open-telemetry/sdk/Trace/SpanExporter/LoggerDecorator.php
new file mode 100644
index 000000000..b7cf511a5
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanExporter/LoggerDecorator.php
@@ -0,0 +1,58 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanExporter;
+
+use OpenTelemetry\SDK\Trace\Behavior\LoggerAwareTrait;
+use OpenTelemetry\SDK\Trace\Behavior\SpanExporterDecoratorTrait;
+use OpenTelemetry\SDK\Trace\Behavior\UsesSpanConverterTrait;
+use OpenTelemetry\SDK\Trace\SpanConverterInterface;
+use OpenTelemetry\SDK\Trace\SpanExporterInterface;
+use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerInterface;
+use Psr\Log\LogLevel;
+use Psr\Log\NullLogger;
+
+class LoggerDecorator implements SpanExporterInterface, LoggerAwareInterface
+{
+ use SpanExporterDecoratorTrait;
+ use UsesSpanConverterTrait;
+ use LoggerAwareTrait;
+
+ public function __construct(
+ SpanExporterInterface $decorated,
+ ?LoggerInterface $logger = null,
+ ?SpanConverterInterface $converter = null
+ ) {
+ $this->setDecorated($decorated);
+ $this->setLogger($logger ?? new NullLogger());
+ $this->setSpanConverter($converter ?? new FriendlySpanConverter());
+ }
+
+ protected function beforeExport(iterable $spans): iterable
+ {
+ return $spans;
+ }
+
+ /**
+ * @param iterable $spans
+ * @param bool $exportSuccess
+ */
+ protected function afterExport(iterable $spans, bool $exportSuccess): void
+ {
+ if ($exportSuccess) {
+ $this->log(
+ 'Status Success',
+ $this->getSpanConverter()->convert($spans),
+ LogLevel::INFO,
+ );
+ } else {
+ $this->log(
+ 'Status Failed Retryable',
+ $this->getSpanConverter()->convert($spans),
+ LogLevel::ERROR,
+ );
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanExporter/LoggerExporter.php b/vendor/open-telemetry/sdk/Trace/SpanExporter/LoggerExporter.php
new file mode 100644
index 000000000..1969a5426
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanExporter/LoggerExporter.php
@@ -0,0 +1,96 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanExporter;
+
+use OpenTelemetry\SDK\Trace\Behavior\LoggerAwareTrait;
+use OpenTelemetry\SDK\Trace\Behavior\SpanExporterTrait;
+use OpenTelemetry\SDK\Trace\Behavior\UsesSpanConverterTrait;
+use OpenTelemetry\SDK\Trace\SpanConverterInterface;
+use OpenTelemetry\SDK\Trace\SpanExporterInterface;
+use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerInterface;
+use Psr\Log\LogLevel;
+use Psr\Log\NullLogger;
+use Throwable;
+
+class LoggerExporter implements SpanExporterInterface, LoggerAwareInterface
+{
+ use SpanExporterTrait;
+ use UsesSpanConverterTrait;
+ use LoggerAwareTrait;
+
+ public const GRANULARITY_AGGREGATE = 1;
+ public const GRANULARITY_SPAN = 2;
+
+ private string $serviceName;
+ private int $granularity = self::GRANULARITY_AGGREGATE;
+
+ /**
+ * @param string $serviceName
+ * @param LoggerInterface|null $logger
+ * @param string|null $defaultLogLevel
+ * @param SpanConverterInterface|null $converter
+ * @param int $granularity
+ */
+ public function __construct(
+ string $serviceName,
+ ?LoggerInterface $logger = null,
+ ?string $defaultLogLevel = LogLevel::DEBUG,
+ ?SpanConverterInterface $converter = null,
+ int $granularity = 1
+ ) {
+ $this->setServiceName($serviceName);
+ $this->setLogger($logger ?? new NullLogger());
+ $this->setDefaultLogLevel($defaultLogLevel ?? LogLevel::DEBUG);
+ $this->setSpanConverter($converter ?? new FriendlySpanConverter());
+ $this->setGranularity($granularity);
+ }
+
+ /** @inheritDoc */
+ public function doExport(iterable $spans): bool
+ {
+ try {
+ $this->doLog($spans);
+ } catch (Throwable $t) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * @param string $serviceName
+ */
+ private function setServiceName(string $serviceName): void
+ {
+ $this->serviceName = $serviceName;
+ }
+
+ /**
+ * @param int $granularity
+ */
+ public function setGranularity(int $granularity): void
+ {
+ $this->granularity = $granularity === self::GRANULARITY_SPAN
+ ? self::GRANULARITY_SPAN
+ : self::GRANULARITY_AGGREGATE;
+ }
+
+ /**
+ * @param iterable $spans
+ */
+ private function doLog(iterable $spans): void
+ {
+ if ($this->granularity === self::GRANULARITY_AGGREGATE) {
+ $this->log($this->serviceName, $this->getSpanConverter()->convert($spans));
+
+ return;
+ }
+
+ foreach ($spans as $span) {
+ $this->log($this->serviceName, $this->getSpanConverter()->convert([$span]));
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanExporter/NullSpanConverter.php b/vendor/open-telemetry/sdk/Trace/SpanExporter/NullSpanConverter.php
new file mode 100644
index 000000000..1e55431a8
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanExporter/NullSpanConverter.php
@@ -0,0 +1,15 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanExporter;
+
+use OpenTelemetry\SDK\Trace\SpanConverterInterface;
+
+class NullSpanConverter implements SpanConverterInterface
+{
+ public function convert(iterable $spans): array
+ {
+ return [[]];
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanExporter/SpanExporterFactoryInterface.php b/vendor/open-telemetry/sdk/Trace/SpanExporter/SpanExporterFactoryInterface.php
new file mode 100644
index 000000000..8d44b35eb
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanExporter/SpanExporterFactoryInterface.php
@@ -0,0 +1,12 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanExporter;
+
+use OpenTelemetry\SDK\Trace\SpanExporterInterface;
+
+interface SpanExporterFactoryInterface
+{
+ public function create(): SpanExporterInterface;
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanExporter/_register.php b/vendor/open-telemetry/sdk/Trace/SpanExporter/_register.php
new file mode 100644
index 000000000..aad07be42
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanExporter/_register.php
@@ -0,0 +1,7 @@
+<?php
+
+declare(strict_types=1);
+\OpenTelemetry\SDK\Registry::registerSpanExporterFactory('console', \OpenTelemetry\SDK\Trace\SpanExporter\ConsoleSpanExporterFactory::class);
+\OpenTelemetry\SDK\Registry::registerSpanExporterFactory('memory', \OpenTelemetry\SDK\Trace\SpanExporter\InMemorySpanExporterFactory::class);
+
+\OpenTelemetry\SDK\Registry::registerTransportFactory('stream', \OpenTelemetry\SDK\Common\Export\Stream\StreamTransportFactory::class);
diff --git a/vendor/open-telemetry/sdk/Trace/SpanExporterInterface.php b/vendor/open-telemetry/sdk/Trace/SpanExporterInterface.php
new file mode 100644
index 000000000..fca336896
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanExporterInterface.php
@@ -0,0 +1,29 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Common\Future\FutureInterface;
+
+/**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/specification/trace/sdk.md#span-exporter
+ */
+interface SpanExporterInterface
+{
+ /**
+ * @param iterable<SpanDataInterface> $batch Batch of spans to export
+ *
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/specification/trace/sdk.md#exportbatch
+ *
+ * @psalm-return FutureInterface<bool>
+ */
+ public function export(iterable $batch, ?CancellationInterface $cancellation = null): FutureInterface;
+
+ /** @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/specification/trace/sdk.md#shutdown-2 */
+ public function shutdown(?CancellationInterface $cancellation = null): bool;
+
+ /** @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/specification/trace/sdk.md#forceflush-2 */
+ public function forceFlush(?CancellationInterface $cancellation = null): bool;
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanLimits.php b/vendor/open-telemetry/sdk/Trace/SpanLimits.php
new file mode 100644
index 000000000..4b07649fc
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanLimits.php
@@ -0,0 +1,67 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\SDK\Common\Attribute\AttributesFactoryInterface;
+
+final class SpanLimits
+{
+ public const DEFAULT_SPAN_ATTRIBUTE_LENGTH_LIMIT = PHP_INT_MAX;
+ public const DEFAULT_SPAN_ATTRIBUTE_COUNT_LIMIT = 128;
+ public const DEFAULT_SPAN_EVENT_COUNT_LIMIT = 128;
+ public const DEFAULT_SPAN_LINK_COUNT_LIMIT = 128;
+ public const DEFAULT_EVENT_ATTRIBUTE_COUNT_LIMIT = 128;
+ public const DEFAULT_LINK_ATTRIBUTE_COUNT_LIMIT = 128;
+
+ private AttributesFactoryInterface $attributesFactory;
+ private AttributesFactoryInterface $eventAttributesFactory;
+ private AttributesFactoryInterface $linkAttributesFactory;
+ private int $eventCountLimit;
+ private int $linkCountLimit;
+
+ public function getAttributesFactory(): AttributesFactoryInterface
+ {
+ return $this->attributesFactory;
+ }
+
+ public function getEventAttributesFactory(): AttributesFactoryInterface
+ {
+ return $this->eventAttributesFactory;
+ }
+
+ public function getLinkAttributesFactory(): AttributesFactoryInterface
+ {
+ return $this->linkAttributesFactory;
+ }
+
+ /** @return int Maximum allowed span event count */
+ public function getEventCountLimit(): int
+ {
+ return $this->eventCountLimit;
+ }
+
+ /** @return int Maximum allowed span link count */
+ public function getLinkCountLimit(): int
+ {
+ return $this->linkCountLimit;
+ }
+
+ /**
+ * @internal Use {@see SpanLimitsBuilder} to create {@see SpanLimits} instance.
+ */
+ public function __construct(
+ AttributesFactoryInterface $attributesFactory,
+ AttributesFactoryInterface $eventAttributesFactory,
+ AttributesFactoryInterface $linkAttributesFactory,
+ int $eventCountLimit,
+ int $linkCountLimit
+ ) {
+ $this->attributesFactory = $attributesFactory;
+ $this->eventAttributesFactory = $eventAttributesFactory;
+ $this->linkAttributesFactory = $linkAttributesFactory;
+ $this->eventCountLimit = $eventCountLimit;
+ $this->linkCountLimit = $linkCountLimit;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanLimitsBuilder.php b/vendor/open-telemetry/sdk/Trace/SpanLimitsBuilder.php
new file mode 100644
index 000000000..11ed5a82b
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanLimitsBuilder.php
@@ -0,0 +1,148 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\SDK\Common\Attribute\Attributes;
+use OpenTelemetry\SDK\Common\Attribute\FilteredAttributesFactory;
+use OpenTelemetry\SDK\Common\Configuration\Configuration;
+use OpenTelemetry\SDK\Common\Configuration\Variables as Env;
+use OpenTelemetry\SemConv\TraceAttributes;
+use const PHP_INT_MAX;
+
+class SpanLimitsBuilder
+{
+ /** @var ?int Maximum allowed attribute count per record */
+ private ?int $attributeCountLimit = null;
+
+ /** @var ?int Maximum allowed attribute value length */
+ private ?int $attributeValueLengthLimit = null;
+
+ /** @var ?int Maximum allowed span event count */
+ private ?int $eventCountLimit = null;
+
+ /** @var ?int Maximum allowed span link count */
+ private ?int $linkCountLimit = null;
+
+ /** @var ?int Maximum allowed attribute per span event count */
+ private ?int $attributePerEventCountLimit = null;
+
+ /** @var ?int Maximum allowed attribute per span link count */
+ private ?int $attributePerLinkCountLimit = null;
+
+ private bool $retainGeneralIdentityAttributes = false;
+
+ /**
+ * @param int $attributeCountLimit Maximum allowed attribute count per record
+ */
+ public function setAttributeCountLimit(int $attributeCountLimit): SpanLimitsBuilder
+ {
+ $this->attributeCountLimit = $attributeCountLimit;
+
+ return $this;
+ }
+
+ /**
+ * @param int $attributeValueLengthLimit Maximum allowed attribute value length
+ */
+ public function setAttributeValueLengthLimit(int $attributeValueLengthLimit): SpanLimitsBuilder
+ {
+ $this->attributeValueLengthLimit = $attributeValueLengthLimit;
+
+ return $this;
+ }
+
+ /**
+ * @param int $eventCountLimit Maximum allowed span event count
+ */
+ public function setEventCountLimit(int $eventCountLimit): SpanLimitsBuilder
+ {
+ $this->eventCountLimit = $eventCountLimit;
+
+ return $this;
+ }
+
+ /**
+ * @param int $linkCountLimit Maximum allowed span link count
+ */
+ public function setLinkCountLimit(int $linkCountLimit): SpanLimitsBuilder
+ {
+ $this->linkCountLimit = $linkCountLimit;
+
+ return $this;
+ }
+
+ /**
+ * @param int $attributePerEventCountLimit Maximum allowed attribute per span event count
+ */
+ public function setAttributePerEventCountLimit(int $attributePerEventCountLimit): SpanLimitsBuilder
+ {
+ $this->attributePerEventCountLimit = $attributePerEventCountLimit;
+
+ return $this;
+ }
+
+ /**
+ * @param int $attributePerLinkCountLimit Maximum allowed attribute per span link count
+ */
+ public function setAttributePerLinkCountLimit(int $attributePerLinkCountLimit): SpanLimitsBuilder
+ {
+ $this->attributePerLinkCountLimit = $attributePerLinkCountLimit;
+
+ return $this;
+ }
+
+ /**
+ * @param bool $retain whether general identity attributes should be retained
+ *
+ * @see https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/attributes.md#general-identity-attributes
+ */
+ public function retainGeneralIdentityAttributes(bool $retain = true): SpanLimitsBuilder
+ {
+ $this->retainGeneralIdentityAttributes = $retain;
+
+ return $this;
+ }
+
+ /**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#span-limits
+ */
+ public function build(): SpanLimits
+ {
+ $attributeCountLimit = $this->attributeCountLimit
+ ?: Configuration::getInt(Env::OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT, SpanLimits::DEFAULT_SPAN_ATTRIBUTE_COUNT_LIMIT);
+ $attributeValueLengthLimit = $this->attributeValueLengthLimit
+ ?: Configuration::getInt(Env::OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT, SpanLimits::DEFAULT_SPAN_ATTRIBUTE_LENGTH_LIMIT);
+ $eventCountLimit = $this->eventCountLimit
+ ?: Configuration::getInt(Env::OTEL_SPAN_EVENT_COUNT_LIMIT, SpanLimits::DEFAULT_SPAN_EVENT_COUNT_LIMIT);
+ $linkCountLimit = $this->linkCountLimit
+ ?: Configuration::getInt(Env::OTEL_SPAN_LINK_COUNT_LIMIT, SpanLimits::DEFAULT_SPAN_LINK_COUNT_LIMIT);
+ $attributePerEventCountLimit = $this->attributePerEventCountLimit
+ ?: Configuration::getInt(Env::OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT, SpanLimits::DEFAULT_EVENT_ATTRIBUTE_COUNT_LIMIT);
+ $attributePerLinkCountLimit = $this->attributePerLinkCountLimit
+ ?: Configuration::getInt(Env::OTEL_LINK_ATTRIBUTE_COUNT_LIMIT, SpanLimits::DEFAULT_LINK_ATTRIBUTE_COUNT_LIMIT);
+
+ if ($attributeValueLengthLimit === PHP_INT_MAX) {
+ $attributeValueLengthLimit = null;
+ }
+
+ $spanAttributesFactory = Attributes::factory($attributeCountLimit, $attributeValueLengthLimit);
+
+ if (!$this->retainGeneralIdentityAttributes) {
+ $spanAttributesFactory = new FilteredAttributesFactory($spanAttributesFactory, [
+ TraceAttributes::ENDUSER_ID,
+ TraceAttributes::ENDUSER_ROLE,
+ TraceAttributes::ENDUSER_SCOPE,
+ ]);
+ }
+
+ return new SpanLimits(
+ $spanAttributesFactory,
+ Attributes::factory($attributePerEventCountLimit, $attributeValueLengthLimit),
+ Attributes::factory($attributePerLinkCountLimit, $attributeValueLengthLimit),
+ $eventCountLimit,
+ $linkCountLimit,
+ );
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanProcessor/BatchSpanProcessor.php b/vendor/open-telemetry/sdk/Trace/SpanProcessor/BatchSpanProcessor.php
new file mode 100644
index 000000000..58032749e
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanProcessor/BatchSpanProcessor.php
@@ -0,0 +1,290 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanProcessor;
+
+use function assert;
+use function count;
+use InvalidArgumentException;
+use OpenTelemetry\API\Behavior\LogsMessagesTrait;
+use OpenTelemetry\API\Metrics\MeterProviderInterface;
+use OpenTelemetry\API\Metrics\ObserverInterface;
+use OpenTelemetry\Context\Context;
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Common\Time\ClockInterface;
+use OpenTelemetry\SDK\Trace\ReadableSpanInterface;
+use OpenTelemetry\SDK\Trace\ReadWriteSpanInterface;
+use OpenTelemetry\SDK\Trace\SpanDataInterface;
+use OpenTelemetry\SDK\Trace\SpanExporterInterface;
+use OpenTelemetry\SDK\Trace\SpanProcessorInterface;
+use SplQueue;
+use function sprintf;
+use Throwable;
+
+class BatchSpanProcessor implements SpanProcessorInterface
+{
+ use LogsMessagesTrait;
+
+ public const DEFAULT_SCHEDULE_DELAY = 5000;
+ public const DEFAULT_EXPORT_TIMEOUT = 30000;
+ public const DEFAULT_MAX_QUEUE_SIZE = 2048;
+ public const DEFAULT_MAX_EXPORT_BATCH_SIZE = 512;
+
+ private const ATTRIBUTES_PROCESSOR = ['processor' => 'batching'];
+ private const ATTRIBUTES_QUEUED = self::ATTRIBUTES_PROCESSOR + ['state' => 'queued'];
+ private const ATTRIBUTES_PENDING = self::ATTRIBUTES_PROCESSOR + ['state' => 'pending'];
+ private const ATTRIBUTES_PROCESSED = self::ATTRIBUTES_PROCESSOR + ['state' => 'processed'];
+ private const ATTRIBUTES_DROPPED = self::ATTRIBUTES_PROCESSOR + ['state' => 'dropped'];
+ private const ATTRIBUTES_FREE = self::ATTRIBUTES_PROCESSOR + ['state' => 'free'];
+
+ private SpanExporterInterface $exporter;
+ private ClockInterface $clock;
+ private int $maxQueueSize;
+ private int $scheduledDelayNanos;
+ private int $maxExportBatchSize;
+ private bool $autoFlush;
+ private ContextInterface $exportContext;
+
+ private ?int $nextScheduledRun = null;
+ private bool $running = false;
+ private int $dropped = 0;
+ private int $processed = 0;
+ private int $batchId = 0;
+ private int $queueSize = 0;
+ /** @var list<SpanDataInterface> */
+ private array $batch = [];
+ /** @var SplQueue<list<SpanDataInterface>> */
+ private SplQueue $queue;
+ /** @var SplQueue<array{int, string, ?CancellationInterface, bool, ContextInterface}> */
+ private SplQueue $flush;
+
+ private bool $closed = false;
+
+ public function __construct(
+ SpanExporterInterface $exporter,
+ ClockInterface $clock,
+ int $maxQueueSize = self::DEFAULT_MAX_QUEUE_SIZE,
+ int $scheduledDelayMillis = self::DEFAULT_SCHEDULE_DELAY,
+ int $exportTimeoutMillis = self::DEFAULT_EXPORT_TIMEOUT,
+ int $maxExportBatchSize = self::DEFAULT_MAX_EXPORT_BATCH_SIZE,
+ bool $autoFlush = true,
+ ?MeterProviderInterface $meterProvider = null
+ ) {
+ if ($maxQueueSize <= 0) {
+ throw new InvalidArgumentException(sprintf('Maximum queue size (%d) must be greater than zero', $maxQueueSize));
+ }
+ if ($scheduledDelayMillis <= 0) {
+ throw new InvalidArgumentException(sprintf('Scheduled delay (%d) must be greater than zero', $scheduledDelayMillis));
+ }
+ if ($exportTimeoutMillis <= 0) {
+ throw new InvalidArgumentException(sprintf('Export timeout (%d) must be greater than zero', $exportTimeoutMillis));
+ }
+ if ($maxExportBatchSize <= 0) {
+ throw new InvalidArgumentException(sprintf('Maximum export batch size (%d) must be greater than zero', $maxExportBatchSize));
+ }
+ if ($maxExportBatchSize > $maxQueueSize) {
+ throw new InvalidArgumentException(sprintf('Maximum export batch size (%d) must be less than or equal to maximum queue size (%d)', $maxExportBatchSize, $maxQueueSize));
+ }
+
+ $this->exporter = $exporter;
+ $this->clock = $clock;
+ $this->maxQueueSize = $maxQueueSize;
+ $this->scheduledDelayNanos = $scheduledDelayMillis * 1_000_000;
+ $this->maxExportBatchSize = $maxExportBatchSize;
+ $this->autoFlush = $autoFlush;
+
+ $this->exportContext = Context::getCurrent();
+ $this->queue = new SplQueue();
+ $this->flush = new SplQueue();
+
+ if ($meterProvider === null) {
+ return;
+ }
+
+ $meter = $meterProvider->getMeter('io.opentelemetry.sdk');
+ $meter
+ ->createObservableUpDownCounter(
+ 'otel.trace.span_processor.spans',
+ '{spans}',
+ 'The number of sampled spans received by the span processor',
+ )
+ ->observe(function (ObserverInterface $observer): void {
+ $queued = $this->queue->count() * $this->maxExportBatchSize + count($this->batch);
+ $pending = $this->queueSize - $queued;
+ $processed = $this->processed;
+ $dropped = $this->dropped;
+
+ $observer->observe($queued, self::ATTRIBUTES_QUEUED);
+ $observer->observe($pending, self::ATTRIBUTES_PENDING);
+ $observer->observe($processed, self::ATTRIBUTES_PROCESSED);
+ $observer->observe($dropped, self::ATTRIBUTES_DROPPED);
+ });
+ $meter
+ ->createObservableUpDownCounter(
+ 'otel.trace.span_processor.queue.limit',
+ '{spans}',
+ 'The queue size limit',
+ )
+ ->observe(function (ObserverInterface $observer): void {
+ $observer->observe($this->maxQueueSize, self::ATTRIBUTES_PROCESSOR);
+ });
+ $meter
+ ->createObservableUpDownCounter(
+ 'otel.trace.span_processor.queue.usage',
+ '{spans}',
+ 'The current queue usage',
+ )
+ ->observe(function (ObserverInterface $observer): void {
+ $queued = $this->queue->count() * $this->maxExportBatchSize + count($this->batch);
+ $pending = $this->queueSize - $queued;
+ $free = $this->maxQueueSize - $this->queueSize;
+
+ $observer->observe($queued, self::ATTRIBUTES_QUEUED);
+ $observer->observe($pending, self::ATTRIBUTES_PENDING);
+ $observer->observe($free, self::ATTRIBUTES_FREE);
+ });
+ }
+
+ public function onStart(ReadWriteSpanInterface $span, ContextInterface $parentContext): void
+ {
+ }
+
+ public function onEnd(ReadableSpanInterface $span): void
+ {
+ if ($this->closed) {
+ return;
+ }
+ if (!$span->getContext()->isSampled()) {
+ return;
+ }
+
+ if ($this->queueSize === $this->maxQueueSize) {
+ $this->dropped++;
+
+ return;
+ }
+
+ $this->queueSize++;
+ $this->batch[] = $span->toSpanData();
+ $this->nextScheduledRun ??= $this->clock->now() + $this->scheduledDelayNanos;
+
+ if (count($this->batch) === $this->maxExportBatchSize) {
+ $this->enqueueBatch();
+ }
+ if ($this->autoFlush) {
+ $this->flush();
+ }
+ }
+
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ if ($this->closed) {
+ return false;
+ }
+
+ return $this->flush(__FUNCTION__, $cancellation);
+ }
+
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ if ($this->closed) {
+ return false;
+ }
+
+ $this->closed = true;
+
+ return $this->flush(__FUNCTION__, $cancellation);
+ }
+
+ public static function builder(SpanExporterInterface $exporter): BatchSpanProcessorBuilder
+ {
+ return new BatchSpanProcessorBuilder($exporter);
+ }
+
+ private function flush(?string $flushMethod = null, ?CancellationInterface $cancellation = null): bool
+ {
+ if ($flushMethod !== null) {
+ $flushId = $this->batchId + $this->queue->count() + (int) (bool) $this->batch;
+ $this->flush->enqueue([$flushId, $flushMethod, $cancellation, !$this->running, Context::getCurrent()]);
+ }
+
+ if ($this->running) {
+ return false;
+ }
+
+ $success = true;
+ $exception = null;
+ $this->running = true;
+
+ try {
+ for (;;) {
+ while (!$this->flush->isEmpty() && $this->flush->bottom()[0] <= $this->batchId) {
+ [, $flushMethod, $cancellation, $propagateResult, $context] = $this->flush->dequeue();
+ $scope = $context->activate();
+
+ try {
+ $result = $this->exporter->$flushMethod($cancellation);
+ if ($propagateResult) {
+ $success = $result;
+ }
+ } catch (Throwable $e) {
+ if ($propagateResult) {
+ $exception = $e;
+ } else {
+ self::logError(sprintf('Unhandled %s error', $flushMethod), ['exception' => $e]);
+ }
+ } finally {
+ $scope->detach();
+ }
+ }
+
+ if (!$this->shouldFlush()) {
+ break;
+ }
+
+ if ($this->queue->isEmpty()) {
+ $this->enqueueBatch();
+ }
+ $batchSize = count($this->queue->bottom());
+ $this->batchId++;
+ $scope = $this->exportContext->activate();
+
+ try {
+ $this->exporter->export($this->queue->dequeue())->await();
+ } catch (Throwable $e) {
+ self::logError('Unhandled export error', ['exception' => $e]);
+ } finally {
+ $this->processed += $batchSize;
+ $this->queueSize -= $batchSize;
+ $scope->detach();
+ }
+ }
+ } finally {
+ $this->running = false;
+ }
+
+ if ($exception !== null) {
+ throw $exception;
+ }
+
+ return $success;
+ }
+
+ private function shouldFlush(): bool
+ {
+ return !$this->flush->isEmpty()
+ || $this->autoFlush && !$this->queue->isEmpty()
+ || $this->autoFlush && $this->nextScheduledRun !== null && $this->clock->now() > $this->nextScheduledRun;
+ }
+
+ private function enqueueBatch(): void
+ {
+ assert($this->batch !== []);
+
+ $this->queue->enqueue($this->batch);
+ $this->batch = [];
+ $this->nextScheduledRun = null;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanProcessor/BatchSpanProcessorBuilder.php b/vendor/open-telemetry/sdk/Trace/SpanProcessor/BatchSpanProcessorBuilder.php
new file mode 100644
index 000000000..8e81e7dd6
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanProcessor/BatchSpanProcessorBuilder.php
@@ -0,0 +1,41 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanProcessor;
+
+use OpenTelemetry\SDK\Common\Time\ClockFactory;
+use OpenTelemetry\SDK\Metrics\MeterProviderInterface;
+use OpenTelemetry\SDK\Trace\SpanExporterInterface;
+
+class BatchSpanProcessorBuilder
+{
+ private SpanExporterInterface $exporter;
+ private ?MeterProviderInterface $meterProvider = null;
+
+ public function __construct(SpanExporterInterface $exporter)
+ {
+ $this->exporter = $exporter;
+ }
+
+ public function setMeterProvider(MeterProviderInterface $meterProvider): self
+ {
+ $this->meterProvider = $meterProvider;
+
+ return $this;
+ }
+
+ public function build(): BatchSpanProcessor
+ {
+ return new BatchSpanProcessor(
+ $this->exporter,
+ ClockFactory::getDefault(),
+ BatchSpanProcessor::DEFAULT_MAX_QUEUE_SIZE,
+ BatchSpanProcessor::DEFAULT_SCHEDULE_DELAY,
+ BatchSpanProcessor::DEFAULT_EXPORT_TIMEOUT,
+ BatchSpanProcessor::DEFAULT_MAX_EXPORT_BATCH_SIZE,
+ true,
+ $this->meterProvider
+ );
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanProcessor/MultiSpanProcessor.php b/vendor/open-telemetry/sdk/Trace/SpanProcessor/MultiSpanProcessor.php
new file mode 100644
index 000000000..e690791f2
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanProcessor/MultiSpanProcessor.php
@@ -0,0 +1,79 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanProcessor;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Trace\ReadableSpanInterface;
+use OpenTelemetry\SDK\Trace\ReadWriteSpanInterface;
+use OpenTelemetry\SDK\Trace\SpanProcessorInterface;
+
+/**
+ * Class SpanMultiProcessor is a SpanProcessor that forwards all events to an
+ * array of SpanProcessors.
+ */
+final class MultiSpanProcessor implements SpanProcessorInterface
+{
+ /** @var list<SpanProcessorInterface> */
+ private array $processors = [];
+
+ public function __construct(SpanProcessorInterface ...$spanProcessors)
+ {
+ foreach ($spanProcessors as $processor) {
+ $this->addSpanProcessor($processor);
+ }
+ }
+
+ public function addSpanProcessor(SpanProcessorInterface $processor): void
+ {
+ $this->processors[] = $processor;
+ }
+
+ /** @return list<SpanProcessorInterface> */
+ public function getSpanProcessors(): array
+ {
+ return $this->processors;
+ }
+
+ /** @inheritDoc */
+ public function onStart(ReadWriteSpanInterface $span, ContextInterface $parentContext): void
+ {
+ foreach ($this->processors as $processor) {
+ $processor->onStart($span, $parentContext);
+ }
+ }
+
+ /** @inheritDoc */
+ public function onEnd(ReadableSpanInterface $span): void
+ {
+ foreach ($this->processors as $processor) {
+ $processor->onEnd($span);
+ }
+ }
+
+ /** @inheritDoc */
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ $result = true;
+
+ foreach ($this->processors as $processor) {
+ $result = $result && $processor->shutdown();
+ }
+
+ return $result;
+ }
+
+ /** @inheritDoc */
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ $result = true;
+
+ foreach ($this->processors as $processor) {
+ $result = $result && $processor->forceFlush();
+ }
+
+ return $result;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanProcessor/NoopSpanProcessor.php b/vendor/open-telemetry/sdk/Trace/SpanProcessor/NoopSpanProcessor.php
new file mode 100644
index 000000000..9c4d1eabe
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanProcessor/NoopSpanProcessor.php
@@ -0,0 +1,47 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanProcessor;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Trace\ReadableSpanInterface;
+use OpenTelemetry\SDK\Trace\ReadWriteSpanInterface;
+use OpenTelemetry\SDK\Trace\SpanProcessorInterface;
+
+class NoopSpanProcessor implements SpanProcessorInterface
+{
+ private static ?SpanProcessorInterface $instance = null;
+
+ public static function getInstance(): SpanProcessorInterface
+ {
+ if (null === self::$instance) {
+ self::$instance = new self();
+ }
+
+ return self::$instance;
+ }
+
+ /** @inheritDoc */
+ public function onStart(ReadWriteSpanInterface $span, ContextInterface $parentContext): void
+ {
+ } //@codeCoverageIgnore
+
+ /** @inheritDoc */
+ public function onEnd(ReadableSpanInterface $span): void
+ {
+ } //@codeCoverageIgnore
+
+ /** @inheritDoc */
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ return true;
+ }
+
+ /** @inheritDoc */
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ return $this->forceFlush();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanProcessor/SimpleSpanProcessor.php b/vendor/open-telemetry/sdk/Trace/SpanProcessor/SimpleSpanProcessor.php
new file mode 100644
index 000000000..4e86e79ab
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanProcessor/SimpleSpanProcessor.php
@@ -0,0 +1,120 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace\SpanProcessor;
+
+use Closure;
+use OpenTelemetry\API\Behavior\LogsMessagesTrait;
+use OpenTelemetry\Context\Context;
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Trace\ReadableSpanInterface;
+use OpenTelemetry\SDK\Trace\ReadWriteSpanInterface;
+use OpenTelemetry\SDK\Trace\SpanExporterInterface;
+use OpenTelemetry\SDK\Trace\SpanProcessorInterface;
+use SplQueue;
+use function sprintf;
+use Throwable;
+
+class SimpleSpanProcessor implements SpanProcessorInterface
+{
+ use LogsMessagesTrait;
+
+ private SpanExporterInterface $exporter;
+ private ContextInterface $exportContext;
+
+ private bool $running = false;
+ /** @var SplQueue<array{Closure, string, bool, ContextInterface}> */
+ private SplQueue $queue;
+
+ private bool $closed = false;
+
+ public function __construct(SpanExporterInterface $exporter)
+ {
+ $this->exporter = $exporter;
+
+ $this->exportContext = Context::getCurrent();
+ $this->queue = new SplQueue();
+ }
+
+ public function onStart(ReadWriteSpanInterface $span, ContextInterface $parentContext): void
+ {
+ }
+
+ public function onEnd(ReadableSpanInterface $span): void
+ {
+ if ($this->closed) {
+ return;
+ }
+ if (!$span->getContext()->isSampled()) {
+ return;
+ }
+
+ $spanData = $span->toSpanData();
+ $this->flush(fn () => $this->exporter->export([$spanData])->await(), 'export', false, $this->exportContext);
+ }
+
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ if ($this->closed) {
+ return false;
+ }
+
+ return $this->flush(fn (): bool => $this->exporter->forceFlush($cancellation), __FUNCTION__, true, Context::getCurrent());
+ }
+
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ if ($this->closed) {
+ return false;
+ }
+
+ $this->closed = true;
+
+ return $this->flush(fn (): bool => $this->exporter->shutdown($cancellation), __FUNCTION__, true, Context::getCurrent());
+ }
+
+ private function flush(Closure $task, string $taskName, bool $propagateResult, ContextInterface $context): bool
+ {
+ $this->queue->enqueue([$task, $taskName, $propagateResult && !$this->running, $context]);
+
+ if ($this->running) {
+ return false;
+ }
+
+ $success = true;
+ $exception = null;
+ $this->running = true;
+
+ try {
+ while (!$this->queue->isEmpty()) {
+ [$task, $taskName, $propagateResult, $context] = $this->queue->dequeue();
+ $scope = $context->activate();
+
+ try {
+ $result = $task();
+ if ($propagateResult) {
+ $success = $result;
+ }
+ } catch (Throwable $e) {
+ if ($propagateResult) {
+ $exception = $e;
+ } else {
+ self::logError(sprintf('Unhandled %s error', $taskName), ['exception' => $e]);
+ }
+ } finally {
+ $scope->detach();
+ }
+ }
+ } finally {
+ $this->running = false;
+ }
+
+ if ($exception !== null) {
+ throw $exception;
+ }
+
+ return $success;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanProcessorFactory.php b/vendor/open-telemetry/sdk/Trace/SpanProcessorFactory.php
new file mode 100644
index 000000000..39144cdf6
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanProcessorFactory.php
@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use InvalidArgumentException;
+use OpenTelemetry\SDK\Common\Configuration\Configuration;
+use OpenTelemetry\SDK\Common\Configuration\KnownValues as Values;
+use OpenTelemetry\SDK\Common\Configuration\Variables as Env;
+use OpenTelemetry\SDK\Common\Time\ClockFactory;
+use OpenTelemetry\SDK\Metrics\MeterProviderInterface;
+use OpenTelemetry\SDK\Metrics\NoopMeterProvider;
+use OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessor;
+use OpenTelemetry\SDK\Trace\SpanProcessor\NoopSpanProcessor;
+use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
+
+class SpanProcessorFactory
+{
+ public function create(?SpanExporterInterface $exporter = null, ?MeterProviderInterface $meterProvider = null): SpanProcessorInterface
+ {
+ if ($exporter === null) {
+ return new NoopSpanProcessor();
+ }
+
+ $name = Configuration::getEnum(Env::OTEL_PHP_TRACES_PROCESSOR);
+ switch ($name) {
+ case Values::VALUE_BATCH:
+ return new BatchSpanProcessor(
+ $exporter,
+ ClockFactory::getDefault(),
+ Configuration::getInt(Env::OTEL_BSP_MAX_QUEUE_SIZE, BatchSpanProcessor::DEFAULT_MAX_QUEUE_SIZE),
+ Configuration::getInt(Env::OTEL_BSP_SCHEDULE_DELAY, BatchSpanProcessor::DEFAULT_SCHEDULE_DELAY),
+ Configuration::getInt(Env::OTEL_BSP_EXPORT_TIMEOUT, BatchSpanProcessor::DEFAULT_EXPORT_TIMEOUT),
+ Configuration::getInt(Env::OTEL_BSP_MAX_EXPORT_BATCH_SIZE, BatchSpanProcessor::DEFAULT_MAX_EXPORT_BATCH_SIZE),
+ true, //autoflush
+ $meterProvider ?? new NoopMeterProvider(),
+ );
+ case Values::VALUE_SIMPLE:
+ return new SimpleSpanProcessor($exporter);
+ case Values::VALUE_NOOP:
+ case Values::VALUE_NONE:
+ return NoopSpanProcessor::getInstance();
+ default:
+ throw new InvalidArgumentException('Unknown processor: ' . $name);
+ }
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/SpanProcessorInterface.php b/vendor/open-telemetry/sdk/Trace/SpanProcessorInterface.php
new file mode 100644
index 000000000..24bcea2dd
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/SpanProcessorInterface.php
@@ -0,0 +1,38 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\Context\ContextInterface;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+
+/** @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/trace/sdk.md#span-processor */
+interface SpanProcessorInterface
+{
+ /**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/specification/trace/sdk.md#onstart
+ */
+ public function onStart(ReadWriteSpanInterface $span, ContextInterface $parentContext): void;
+
+ /**
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/specification/trace/sdk.md#onendspan
+ */
+ public function onEnd(ReadableSpanInterface $span): void;
+
+ /**
+ * Export all ended spans to the configured Exporter that have not yet been exported.
+ * Returns `true` if the flush was successful, otherwise `false`.
+ *
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/specification/trace/sdk.md#forceflush-1
+ */
+ public function forceFlush(?CancellationInterface $cancellation = null): bool;
+
+ /**
+ * Cleanup; after shutdown, calling onStart, onEnd, or forceFlush is invalid
+ * Returns `false` is the processor is already shutdown, otherwise `true`.
+ *
+ * @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/specification/trace/sdk.md#shutdown-1
+ */
+ public function shutdown(?CancellationInterface $cancellation = null): bool;
+}
diff --git a/vendor/open-telemetry/sdk/Trace/StatusData.php b/vendor/open-telemetry/sdk/Trace/StatusData.php
new file mode 100644
index 000000000..c28ea22ab
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/StatusData.php
@@ -0,0 +1,84 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\API\Trace as API;
+
+final class StatusData implements StatusDataInterface
+{
+ private static ?self $ok = null;
+ private static ?self $unset = null;
+ private static ?self $error = null;
+ private string $code;
+ private string $description;
+
+ /** @psalm-param API\StatusCode::STATUS_* $code */
+ public function __construct(
+ string $code,
+ string $description
+ ) {
+ $this->code = $code;
+ $this->description = $description;
+ }
+
+ /** @psalm-param API\StatusCode::STATUS_* $code */
+ public static function create(string $code, ?string $description = null): self
+ {
+ if (empty($description)) {
+ switch ($code) {
+ case API\StatusCode::STATUS_UNSET:
+ return self::unset();
+ case API\StatusCode::STATUS_ERROR:
+ return self::error();
+ case API\StatusCode::STATUS_OK:
+ return self::ok();
+ }
+ }
+
+ // Ignore description for non Error statuses.
+ if (API\StatusCode::STATUS_ERROR !== $code) {
+ $description = '';
+ }
+
+ return new self($code, $description); /** @phan-suppress-current-line PhanTypeMismatchArgumentNullable */
+ }
+
+ public static function ok(): self
+ {
+ if (null === self::$ok) {
+ self::$ok = new self(API\StatusCode::STATUS_OK, '');
+ }
+
+ return self::$ok;
+ }
+
+ public static function error(): self
+ {
+ if (null === self::$error) {
+ self::$error = new self(API\StatusCode::STATUS_ERROR, '');
+ }
+
+ return self::$error;
+ }
+
+ public static function unset(): self
+ {
+ if (null === self::$unset) {
+ self::$unset = new self(API\StatusCode::STATUS_UNSET, '');
+ }
+
+ return self::$unset;
+ }
+
+ public function getCode(): string
+ {
+ return $this->code;
+ }
+
+ public function getDescription(): string
+ {
+ return $this->description;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/StatusDataInterface.php b/vendor/open-telemetry/sdk/Trace/StatusDataInterface.php
new file mode 100644
index 000000000..973d2b519
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/StatusDataInterface.php
@@ -0,0 +1,18 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+interface StatusDataInterface
+{
+ public static function ok(): self;
+
+ public static function error(): self;
+
+ public static function unset(): self;
+
+ public function getCode(): string;
+
+ public function getDescription(): string;
+}
diff --git a/vendor/open-telemetry/sdk/Trace/Tracer.php b/vendor/open-telemetry/sdk/Trace/Tracer.php
new file mode 100644
index 000000000..913773f60
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/Tracer.php
@@ -0,0 +1,52 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use function ctype_space;
+use OpenTelemetry\API\Trace as API;
+use OpenTelemetry\Context\Context;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeInterface;
+
+class Tracer implements API\TracerInterface
+{
+ public const FALLBACK_SPAN_NAME = 'empty';
+
+ /** @readonly */
+ private TracerSharedState $tracerSharedState;
+
+ /** @readonly */
+ private InstrumentationScopeInterface $instrumentationScope;
+
+ public function __construct(
+ TracerSharedState $tracerSharedState,
+ InstrumentationScopeInterface $instrumentationScope
+ ) {
+ $this->tracerSharedState = $tracerSharedState;
+ $this->instrumentationScope = $instrumentationScope;
+ }
+
+ /** @inheritDoc */
+ public function spanBuilder(string $spanName): API\SpanBuilderInterface
+ {
+ if (ctype_space($spanName)) {
+ $spanName = self::FALLBACK_SPAN_NAME;
+ }
+
+ if ($this->tracerSharedState->hasShutdown()) {
+ return new API\NoopSpanBuilder(Context::storage());
+ }
+
+ return new SpanBuilder(
+ $spanName,
+ $this->instrumentationScope,
+ $this->tracerSharedState,
+ );
+ }
+
+ public function getInstrumentationScope(): InstrumentationScopeInterface
+ {
+ return $this->instrumentationScope;
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/TracerProvider.php b/vendor/open-telemetry/sdk/Trace/TracerProvider.php
new file mode 100644
index 000000000..fdae4aea2
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/TracerProvider.php
@@ -0,0 +1,99 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use function is_array;
+use OpenTelemetry\API\Trace as API;
+use OpenTelemetry\API\Trace\NoopTracer;
+use OpenTelemetry\SDK\Common\Attribute\Attributes;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeFactory;
+use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeFactoryInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
+use OpenTelemetry\SDK\Trace\Sampler\AlwaysOnSampler;
+use OpenTelemetry\SDK\Trace\Sampler\ParentBased;
+
+final class TracerProvider implements TracerProviderInterface
+{
+ /** @readonly */
+ private TracerSharedState $tracerSharedState;
+ private InstrumentationScopeFactoryInterface $instrumentationScopeFactory;
+
+ /** @param list<SpanProcessorInterface>|SpanProcessorInterface|null $spanProcessors */
+ public function __construct(
+ $spanProcessors = [],
+ SamplerInterface $sampler = null,
+ ResourceInfo $resource = null,
+ SpanLimits $spanLimits = null,
+ IdGeneratorInterface $idGenerator = null,
+ ?InstrumentationScopeFactoryInterface $instrumentationScopeFactory = null
+ ) {
+ if (null === $spanProcessors) {
+ $spanProcessors = [];
+ }
+
+ $spanProcessors = is_array($spanProcessors) ? $spanProcessors : [$spanProcessors];
+ $resource ??= ResourceInfoFactory::defaultResource();
+ $sampler ??= new ParentBased(new AlwaysOnSampler());
+ $idGenerator ??= new RandomIdGenerator();
+ $spanLimits ??= (new SpanLimitsBuilder())->build();
+
+ $this->tracerSharedState = new TracerSharedState(
+ $idGenerator,
+ $resource,
+ $spanLimits,
+ $sampler,
+ $spanProcessors
+ );
+ $this->instrumentationScopeFactory = $instrumentationScopeFactory ?? new InstrumentationScopeFactory(Attributes::factory());
+ }
+
+ public function forceFlush(?CancellationInterface $cancellation = null): bool
+ {
+ return $this->tracerSharedState->getSpanProcessor()->forceFlush($cancellation);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getTracer(
+ string $name,
+ ?string $version = null,
+ ?string $schemaUrl = null,
+ iterable $attributes = []
+ ): API\TracerInterface {
+ if ($this->tracerSharedState->hasShutdown()) {
+ return NoopTracer::getInstance();
+ }
+
+ return new Tracer(
+ $this->tracerSharedState,
+ $this->instrumentationScopeFactory->create($name, $version, $schemaUrl, $attributes),
+ );
+ }
+
+ public function getSampler(): SamplerInterface
+ {
+ return $this->tracerSharedState->getSampler();
+ }
+
+ /**
+ * Returns `false` is the provider is already shutdown, otherwise `true`.
+ */
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ if ($this->tracerSharedState->hasShutdown()) {
+ return true;
+ }
+
+ return $this->tracerSharedState->shutdown($cancellation);
+ }
+
+ public static function builder(): TracerProviderBuilder
+ {
+ return new TracerProviderBuilder();
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/TracerProviderBuilder.php b/vendor/open-telemetry/sdk/Trace/TracerProviderBuilder.php
new file mode 100644
index 000000000..8dcfdc700
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/TracerProviderBuilder.php
@@ -0,0 +1,45 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+
+class TracerProviderBuilder
+{
+ // @var array<SpanProcessorInterface>
+ private ?array $spanProcessors = [];
+ private ?ResourceInfo $resource = null;
+ private ?SamplerInterface $sampler = null;
+
+ public function addSpanProcessor(SpanProcessorInterface $spanProcessor): self
+ {
+ $this->spanProcessors[] = $spanProcessor;
+
+ return $this;
+ }
+
+ public function setResource(ResourceInfo $resource): self
+ {
+ $this->resource = $resource;
+
+ return $this;
+ }
+
+ public function setSampler(SamplerInterface $sampler): self
+ {
+ $this->sampler = $sampler;
+
+ return $this;
+ }
+
+ public function build(): TracerProviderInterface
+ {
+ return new TracerProvider(
+ $this->spanProcessors,
+ $this->sampler,
+ $this->resource,
+ );
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/TracerProviderFactory.php b/vendor/open-telemetry/sdk/Trace/TracerProviderFactory.php
new file mode 100644
index 000000000..a545319b6
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/TracerProviderFactory.php
@@ -0,0 +1,60 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\API\Behavior\LogsMessagesTrait;
+use OpenTelemetry\SDK\Sdk;
+
+final class TracerProviderFactory
+{
+ use LogsMessagesTrait;
+
+ private ExporterFactory $exporterFactory;
+ private SamplerFactory $samplerFactory;
+ private SpanProcessorFactory $spanProcessorFactory;
+
+ public function __construct(
+ ?ExporterFactory $exporterFactory = null,
+ ?SamplerFactory $samplerFactory = null,
+ ?SpanProcessorFactory $spanProcessorFactory = null
+ ) {
+ $this->exporterFactory = $exporterFactory ?: new ExporterFactory();
+ $this->samplerFactory = $samplerFactory ?: new SamplerFactory();
+ $this->spanProcessorFactory = $spanProcessorFactory ?: new SpanProcessorFactory();
+ }
+
+ public function create(): TracerProviderInterface
+ {
+ if (Sdk::isDisabled()) {
+ return new NoopTracerProvider();
+ }
+
+ try {
+ $exporter = $this->exporterFactory->create();
+ } catch (\Throwable $t) {
+ self::logWarning('Unable to create exporter', ['exception' => $t]);
+ $exporter = null;
+ }
+
+ try {
+ $sampler = $this->samplerFactory->create();
+ } catch (\Throwable $t) {
+ self::logWarning('Unable to create sampler', ['exception' => $t]);
+ $sampler = null;
+ }
+
+ try {
+ $spanProcessor = $this->spanProcessorFactory->create($exporter);
+ } catch (\Throwable $t) {
+ self::logWarning('Unable to create span processor', ['exception' => $t]);
+ $spanProcessor = null;
+ }
+
+ return new TracerProvider(
+ $spanProcessor,
+ $sampler,
+ );
+ }
+}
diff --git a/vendor/open-telemetry/sdk/Trace/TracerProviderInterface.php b/vendor/open-telemetry/sdk/Trace/TracerProviderInterface.php
new file mode 100644
index 000000000..d61c1ea8f
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/TracerProviderInterface.php
@@ -0,0 +1,15 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\API\Trace as API;
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+
+interface TracerProviderInterface extends API\TracerProviderInterface
+{
+ public function forceFlush(?CancellationInterface $cancellation = null): bool;
+
+ public function shutdown(?CancellationInterface $cancellation = null): bool;
+}
diff --git a/vendor/open-telemetry/sdk/Trace/TracerSharedState.php b/vendor/open-telemetry/sdk/Trace/TracerSharedState.php
new file mode 100644
index 000000000..d0540cc1f
--- /dev/null
+++ b/vendor/open-telemetry/sdk/Trace/TracerSharedState.php
@@ -0,0 +1,100 @@
+<?php
+
+declare(strict_types=1);
+
+namespace OpenTelemetry\SDK\Trace;
+
+use OpenTelemetry\API\Trace as API; /** @phan-suppress-current-line PhanUnreferencedUseNormal */
+use OpenTelemetry\SDK\Common\Future\CancellationInterface;
+use OpenTelemetry\SDK\Resource\ResourceInfo;
+use OpenTelemetry\SDK\Trace\SpanProcessor\MultiSpanProcessor;
+use OpenTelemetry\SDK\Trace\SpanProcessor\NoopSpanProcessor;
+
+/**
+ * Stores shared state/config between all {@see API\TracerInterface} created via the same {@see API\TracerProviderInterface}.
+ */
+final class TracerSharedState
+{
+ /** @readonly */
+ private IdGeneratorInterface $idGenerator;
+
+ /** @readonly */
+ private ResourceInfo $resource;
+
+ /** @readonly */
+ private SpanLimits $spanLimits;
+
+ /** @readonly */
+ private SamplerInterface $sampler;
+
+ /** @readonly */
+ private SpanProcessorInterface $spanProcessor;
+
+ private ?bool $shutdownResult = null;
+
+ public function __construct(
+ IdGeneratorInterface $idGenerator,
+ ResourceInfo $resource,
+ SpanLimits $spanLimits,
+ SamplerInterface $sampler,
+ array $spanProcessors
+ ) {
+ $this->idGenerator = $idGenerator;
+ $this->resource = $resource;
+ $this->spanLimits = $spanLimits;
+ $this->sampler = $sampler;
+
+ switch (count($spanProcessors)) {
+ case 0:
+ $this->spanProcessor = NoopSpanProcessor::getInstance();
+
+ break;
+ case 1:
+ $this->spanProcessor = $spanProcessors[0];
+
+ break;
+ default:
+ $this->spanProcessor = new MultiSpanProcessor(...$spanProcessors);
+
+ break;
+ }
+ }
+
+ public function hasShutdown(): bool
+ {
+ return null !== $this->shutdownResult;
+ }
+
+ public function getIdGenerator(): IdGeneratorInterface
+ {
+ return $this->idGenerator;
+ }
+
+ public function getResource(): ResourceInfo
+ {
+ return $this->resource;
+ }
+
+ public function getSpanLimits(): SpanLimits
+ {
+ return $this->spanLimits;
+ }
+
+ public function getSampler(): SamplerInterface
+ {
+ return $this->sampler;
+ }
+
+ public function getSpanProcessor(): SpanProcessorInterface
+ {
+ return $this->spanProcessor;
+ }
+
+ /**
+ * Returns `false` is the provider is already shutdown, otherwise `true`.
+ */
+ public function shutdown(?CancellationInterface $cancellation = null): bool
+ {
+ return $this->shutdownResult ?? ($this->shutdownResult = $this->spanProcessor->shutdown($cancellation));
+ }
+}
diff --git a/vendor/open-telemetry/sdk/_autoload.php b/vendor/open-telemetry/sdk/_autoload.php
new file mode 100644
index 000000000..4e1de3450
--- /dev/null
+++ b/vendor/open-telemetry/sdk/_autoload.php
@@ -0,0 +1,5 @@
+<?php
+
+declare(strict_types=1);
+
+\OpenTelemetry\SDK\SdkAutoloader::autoload();
diff --git a/vendor/open-telemetry/sdk/composer.json b/vendor/open-telemetry/sdk/composer.json
new file mode 100644
index 000000000..4497c9400
--- /dev/null
+++ b/vendor/open-telemetry/sdk/composer.json
@@ -0,0 +1,59 @@
+{
+ "name": "open-telemetry/sdk",
+ "description": "SDK for OpenTelemetry PHP.",
+ "keywords": ["opentelemetry", "otel", "metrics", "tracing", "logging", "apm", "sdk"],
+ "type": "library",
+ "support": {
+ "issues": "https://github.com/open-telemetry/opentelemetry-php/issues",
+ "source": "https://github.com/open-telemetry/opentelemetry-php",
+ "docs": "https://opentelemetry.io/docs/php",
+ "chat": "https://app.slack.com/client/T08PSQ7BQ/C01NFPCV44V"
+ },
+ "license": "Apache-2.0",
+ "authors": [
+ {
+ "name": "opentelemetry-php contributors",
+ "homepage": "https://github.com/open-telemetry/opentelemetry-php/graphs/contributors"
+ }
+ ],
+ "require": {
+ "php": "^7.4 || ^8.0",
+ "ext-json": "*",
+ "open-telemetry/api": "^1.0",
+ "open-telemetry/context": "^1.0",
+ "open-telemetry/sem-conv": "^1.0",
+ "php-http/discovery": "^1.14",
+ "psr/http-client-implementation": "^1.0",
+ "psr/http-factory-implementation": "^1.0",
+ "psr/http-client": "^1.0",
+ "psr/http-message": "^1.0.1|^2.0",
+ "psr/log": "^1.1|^2.0|^3.0",
+ "symfony/polyfill-mbstring": "^1.23",
+ "symfony/polyfill-php80": "^1.26",
+ "symfony/polyfill-php81": "^1.26",
+ "symfony/polyfill-php82": "^1.26"
+ },
+ "autoload": {
+ "psr-4": {
+ "OpenTelemetry\\SDK\\": "."
+ },
+ "files": [
+ "Common/Util/functions.php",
+ "Logs/Exporter/_register.php",
+ "Metrics/MetricExporter/_register.php",
+ "Propagation/_register.php",
+ "Trace/SpanExporter/_register.php",
+ "Common/Dev/Compatibility/_load.php",
+ "_autoload.php"
+ ]
+ },
+ "suggest": {
+ "ext-gmp": "To support unlimited number of synchronous metric readers",
+ "ext-mbstring": "To increase performance of string operations"
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.0.x-dev"
+ }
+ }
+}