Drop PHP 7.4 support (#1244)

* drop php 7.4 support
update composer.json minimums, and run rector over the code to update what it can. changed some static analysis
config to fix some rector-induced failures.

* adding union typehints

* reformat constructor property promotions

* updating/removing phpdoc

* suppress protobuf extension complaint
submitted a PR upstream to fix phan stubs

* don't validate packages against 7.4

* remove php8 polyfill

* fix readonly comments

* apply trailing commas to multiline fixer
upgrade php-cs-fixer, and apply a new rule for multiline comments

* remove unreachable default match arms for protobuf serializer

* adding more union types to vars

* use weakmap directly

* remove handling for not-supported WeakMap

* spacing
This commit is contained in:
Brett McBride 2024-03-04 12:21:16 +11:00 committed by GitHub
parent cc56628c4d
commit f798bb6f01
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
223 changed files with 883 additions and 2092 deletions

View File

@ -13,7 +13,7 @@ jobs:
strategy:
fail-fast: false
matrix:
php-version: ['7.4', '8.0', '8.1', '8.2', '8.3']
php-version: ['8.0', '8.1', '8.2', '8.3']
experimental: [false]
composer_args: [""]
include:
@ -138,4 +138,5 @@ jobs:
needs: php
with:
matrix_extension: '["ast, json, grpc"]'
matrix_php_version: '["8.0", "8.1", "8.2", "8.3"]'
install_directory: '~/.test/.packages'

View File

@ -8,7 +8,7 @@ jobs:
name: OpenTelemetry PHP base docker image creation
strategy:
matrix:
php-version: ['7.4', '8.0', '8.1', '8.2', '8.3']
php-version: ['8.0', '8.1', '8.2', '8.3']
runs-on: ubuntu-latest
permissions:
packages: write

View File

@ -44,7 +44,7 @@ return [
//
// Note that the **only** effect of choosing `'5.6'` is to infer that functions removed in php 7.0 exist.
// (See `backward_compatibility_checks` for additional options)
'target_php_version' => '7.4',
'target_php_version' => '8.0',
// If enabled, missing properties will be created when
// they are first seen. If false, we'll report an

View File

@ -25,10 +25,10 @@ return $config->setRules([
'blank_line_before_statement' => true,
'cast_spaces' => true,
'declare_strict_types' => true,
'function_typehint_space' => true,
'type_declaration_spaces' => true,
'include' => true,
'lowercase_cast' => true,
'new_with_braces' => true,
'new_with_parentheses' => true,
'no_extra_blank_lines' => true,
'no_leading_import_slash' => true,
'no_trailing_whitespace' => true,
@ -41,9 +41,9 @@ return $config->setRules([
'phpdoc_scalar' => true,
'phpdoc_types' => true,
'short_scalar_cast' => true,
'single_blank_line_before_namespace' => true,
'blank_lines_before_namespace' => true,
'single_quote' => true,
'trailing_comma_in_multiline' => true,
'trailing_comma_in_multiline' => ['elements' => ['arrays', 'parameters', 'match']],
])
->setRiskyAllowed(true)
->setFinder($finder);

View File

@ -71,8 +71,8 @@ This does the following things:
### Other PHP versions
We aim to support officially supported PHP versions, according to https://www.php.net/supported-versions.php. The
developer image `ghcr.io/open-telemetry/opentelemetry-php/opentelemetry-php-base` is tagged as `7.4`, `8.0`, `8.1` and `8.2`
respectively, with `7.4` being the default. You can execute the test suite against other PHP versions by running the
developer image `ghcr.io/open-telemetry/opentelemetry-php/opentelemetry-php-base` is tagged as `8.0`, `8.1`, `8.2` and `8.3`
respectively, with `8.0` being the default. You can execute the test suite against other PHP versions by running the
following command:
```bash

View File

@ -1,6 +1,6 @@
include .env
PHP_VERSION ?= 7.4
PHP_VERSION ?= 8.0
DOCKER_COMPOSE ?= docker-compose
DC_RUN_PHP = $(DOCKER_COMPOSE) run --rm php

View File

@ -7,7 +7,7 @@
"readme": "./README.md",
"license": "Apache-2.0",
"require": {
"php": "^7.4 || ^8.0",
"php": "^8.0",
"ext-json": "*",
"google/protobuf": "^3.22",
"php-http/discovery": "^1.14",
@ -17,7 +17,6 @@
"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"
},
@ -77,9 +76,9 @@
"ext-grpc": "*",
"grpc/grpc": "^1.30",
"assertwell/phpunit-global-state": "^0.2.2",
"composer/xdebug-handler": "^2.0",
"composer/xdebug-handler": "^3.0",
"dg/bypass-finals": "^1.4",
"friendsofphp/php-cs-fixer": "^3.4",
"friendsofphp/php-cs-fixer": "^3.51",
"guzzlehttp/guzzle": "^7.4",
"guzzlehttp/psr7": "^2.1",
"mikey179/vfsstream": "^1.6.11",

View File

@ -1,7 +1,7 @@
version: '3.7'
services:
php:
image: ghcr.io/open-telemetry/opentelemetry-php/opentelemetry-php-base:${PHP_VERSION:-7.4}
image: ghcr.io/open-telemetry/opentelemetry-php/opentelemetry-php-base:${PHP_VERSION:-8.0}
volumes:
- ./:/usr/src/myapp
depends_on:

View File

@ -23,7 +23,7 @@ services:
context: .
dockerfile: docker/examples/Dockerfile
args:
- PHP_VERSION=7.4-fpm
- PHP_VERSION=8.0-fpm
- EXT_ENABLE=redis
volumes:
- ./examples/prometheus/index.php:/var/www/public/index.php

View File

@ -1,7 +1,7 @@
version: '3.7'
services:
php:
image: ghcr.io/open-telemetry/opentelemetry-php/opentelemetry-php-base:${PHP_VERSION:-7.4}
image: ghcr.io/open-telemetry/opentelemetry-php/opentelemetry-php-base:${PHP_VERSION:-8.0}
volumes:
- ./:/usr/src/myapp
- ./:/usr/src/open-telemetry/

View File

@ -1,7 +1,7 @@
version: '3.7'
services:
php:
image: ghcr.io/open-telemetry/opentelemetry-php/opentelemetry-php-base:${PHP_VERSION:-7.4}
image: ghcr.io/open-telemetry/opentelemetry-php/opentelemetry-php-base:${PHP_VERSION:-8.0}
volumes:
- ./:/usr/src/myapp
user: "${PHP_USER}:root"

View File

@ -1,4 +1,4 @@
ARG PHP_VERSION=7.4
ARG PHP_VERSION=8.0
FROM php:${PHP_VERSION}-cli-alpine as php_build
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/

View File

@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace OpenTelemetry\Example;
use OpenTelemetry\API\Globals;
putenv('OTEL_PHP_AUTOLOAD_ENABLED=true');
putenv('OTEL_TRACES_EXPORTER=console');
putenv('OTEL_METRICS_EXPORTER=console');
putenv('OTEL_PHP_INTERNAL_METRICS_ENABLED=true');
require __DIR__ . '/../../../vendor/autoload.php';
/**
* Demonstrates batch span processing which also emits metrics for the internal state
* of the processor (eg spans received, queue length)
*/
echo 'Starting ConsoleSpanExporter with BatchSpanProcessor and metrics' . PHP_EOL;
$tracer = Globals::tracerProvider()->getTracer('io.opentelemetry.contrib.php');
$tracer->spanBuilder('root')->startSpan()->end();
echo PHP_EOL . 'Example complete! ' . PHP_EOL;

View File

@ -17,7 +17,7 @@
}
],
"require": {
"php": "^7.4 || ^8.0",
"php": "^8.0",
"google/protobuf": "^3.3.0"
},
"autoload": {

View File

@ -18,4 +18,11 @@
<pluginClass class="Psalm\PhpUnitPlugin\Plugin"/>
<pluginClass class="Psalm\MockeryPlugin\Plugin"/>
</plugins>
<issueHandlers>
<UndefinedClass>
<errorLevel type="suppress">
<referencedClass name="GMP" />
</errorLevel>
</UndefinedClass>
</issueHandlers>
</psalm>

View File

@ -5,18 +5,18 @@ declare(strict_types=1);
use Rector\CodeQuality\Rector\Array_\CallableThisArrayToAnonymousFunctionRector;
use Rector\CodeQuality\Rector\Identical\FlipTypeControlToUseExclusiveTypeRector;
use Rector\Config\RectorConfig;
use Rector\Core\ValueObject\PhpVersion;
use Rector\ValueObject\PhpVersion;
use Rector\Set\ValueObject\SetList;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->phpVersion(PhpVersion::PHP_74);
$rectorConfig->phpVersion(PhpVersion::PHP_80);
$rectorConfig->paths([
__DIR__ . '/src',
]);
$rectorConfig->sets([
SetList::PHP_74,
SetList::PHP_80,
SetList::CODE_QUALITY,
]);
$rectorConfig->skip([

View File

@ -41,13 +41,9 @@ final class Baggage implements BaggageInterface
return self::$emptyBaggage;
}
/** @var array<string, Entry> */
private array $entries;
/** @param array<string, Entry> $entries */
public function __construct(array $entries = [])
public function __construct(private array $entries = [])
{
$this->entries = $entries;
}
/** @inheritDoc */

View File

@ -6,13 +6,9 @@ namespace OpenTelemetry\API\Baggage;
final class BaggageBuilder implements BaggageBuilderInterface
{
/** @var array<string, Entry> */
private array $entries;
/** @param array<string, Entry> $entries */
public function __construct(array $entries = [])
public function __construct(private array $entries = [])
{
$this->entries = $entries;
}
/** @inheritDoc */

View File

@ -10,9 +10,8 @@ interface BaggageBuilderInterface
{
/**
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/baggage/api.md#set-value
* @param mixed $value
*/
public function set(string $key, $value, API\MetadataInterface $metadata = null): API\BaggageBuilderInterface;
public function set(string $key, mixed $value, API\MetadataInterface $metadata = null): API\BaggageBuilderInterface;
/**
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/baggage/api.md#remove-value

View File

@ -6,27 +6,13 @@ namespace OpenTelemetry\API\Baggage;
final class Entry
{
/** @var mixed */
private $value;
private MetadataInterface $metadata;
/**
* @param mixed $value
* @param MetadataInterface $metadata
*/
public function __construct(
$value,
MetadataInterface $metadata
private mixed $value,
private MetadataInterface $metadata,
) {
$this->value = $value;
$this->metadata = $metadata;
}
/**
* @return mixed
*/
public function getValue()
public function getValue(): mixed
{
return $this->value;
}

View File

@ -13,11 +13,8 @@ final class Metadata implements MetadataInterface
return self::$instance ??= new self('');
}
private string $metadata;
public function __construct(string $metadata)
public function __construct(private string $metadata)
{
$this->metadata = $metadata;
}
public function getValue(): string

View File

@ -17,12 +17,10 @@ final class Parser
private const EXCLUDED_VALUE_CHARS = [' ', '"', ',', ';', '\\'];
private const EQUALS = '=';
/** @readonly */
private string $baggageHeader;
public function __construct(string $baggageHeader)
{
$this->baggageHeader = $baggageHeader;
public function __construct(
/** @readonly */
private string $baggageHeader,
) {
}
public function parseInto(BaggageBuilderInterface $baggageBuilder): void

View File

@ -8,11 +8,8 @@ use Psr\Log\LoggerInterface;
class Psr3LogWriter implements LogWriterInterface
{
private LoggerInterface $logger;
public function __construct(LoggerInterface $logger)
public function __construct(private LoggerInterface $logger)
{
$this->logger = $logger;
}
public function write($level, string $message, array $context): void

View File

@ -33,6 +33,7 @@ class LogWriterFactory
return new Psr3LogWriter($logger);
}
error_log('OpenTelemetry: cannot use OTEL_PHP_LOG_DESTINATION=psr3 without providing a PSR-3 logger');
//default to error log
return new ErrorLogWriter();
case 'error_log':

View File

@ -27,21 +27,12 @@ final class Globals
private static array $initializers = [];
private static ?self $globals = null;
private TracerProviderInterface $tracerProvider;
private MeterProviderInterface $meterProvider;
private TextMapPropagatorInterface $propagator;
private LoggerProviderInterface $loggerProvider;
public function __construct(
TracerProviderInterface $tracerProvider,
MeterProviderInterface $meterProvider,
LoggerProviderInterface $loggerProvider,
TextMapPropagatorInterface $propagator
private TracerProviderInterface $tracerProvider,
private MeterProviderInterface $meterProvider,
private LoggerProviderInterface $loggerProvider,
private TextMapPropagatorInterface $propagator,
) {
$this->tracerProvider = $tracerProvider;
$this->meterProvider = $meterProvider;
$this->loggerProvider = $loggerProvider;
$this->propagator = $propagator;
}
public static function tracerProvider(): TracerProviderInterface

View File

@ -4,9 +4,6 @@ declare(strict_types=1);
namespace OpenTelemetry\API\Instrumentation;
use ArrayAccess;
use function assert;
use function class_exists;
use OpenTelemetry\API\Globals;
use OpenTelemetry\API\Logs\LoggerInterface;
use OpenTelemetry\API\Logs\LoggerProviderInterface;
@ -14,7 +11,7 @@ use OpenTelemetry\API\Metrics\MeterInterface;
use OpenTelemetry\API\Metrics\MeterProviderInterface;
use OpenTelemetry\API\Trace\TracerInterface;
use OpenTelemetry\API\Trace\TracerProviderInterface;
use const PHP_VERSION_ID;
use WeakMap;
/**
* Provides access to cached {@link TracerInterface} and {@link MeterInterface}
@ -26,51 +23,31 @@ use const PHP_VERSION_ID;
*/
final class CachedInstrumentation
{
private string $name;
private ?string $version;
private ?string $schemaUrl;
private iterable $attributes;
/** @var ArrayAccess<TracerProviderInterface, TracerInterface>|null */
private ?ArrayAccess $tracers;
/** @var ArrayAccess<MeterProviderInterface, MeterInterface>|null */
private ?ArrayAccess $meters;
/** @var ArrayAccess<LoggerProviderInterface, LoggerInterface>|null */
private ?ArrayAccess $loggers;
/** @var WeakMap<TracerProviderInterface, TracerInterface> */
private WeakMap $tracers;
/** @var WeakMap<MeterProviderInterface, MeterInterface> */
private WeakMap $meters;
/** @var WeakMap<LoggerProviderInterface, LoggerInterface> */
private WeakMap $loggers;
public function __construct(string $name, ?string $version = null, ?string $schemaUrl = null, iterable $attributes = [])
{
$this->name = $name;
$this->version = $version;
$this->schemaUrl = $schemaUrl;
$this->attributes = $attributes;
$this->tracers = self::createWeakMap();
$this->meters = self::createWeakMap();
$this->loggers = self::createWeakMap();
}
private static function createWeakMap(): ?ArrayAccess
{
if (PHP_VERSION_ID < 80000) {
return null;
}
/** @phan-suppress-next-line PhanUndeclaredClassReference */
assert(class_exists(\WeakMap::class, false));
/** @phan-suppress-next-line PhanUndeclaredClassMethod */
$map = new \WeakMap();
assert($map instanceof ArrayAccess);
return $map;
/**
* @psalm-suppress PropertyTypeCoercion
*/
public function __construct(
private string $name,
private ?string $version = null,
private ?string $schemaUrl = null,
private iterable $attributes = [],
) {
$this->tracers = new \WeakMap();
$this->meters = new \WeakMap();
$this->loggers = new \WeakMap();
}
public function tracer(): TracerInterface
{
$tracerProvider = Globals::tracerProvider();
if ($this->tracers === null) {
return $tracerProvider->getTracer($this->name, $this->version, $this->schemaUrl, $this->attributes);
}
return $this->tracers[$tracerProvider] ??= $tracerProvider->getTracer($this->name, $this->version, $this->schemaUrl, $this->attributes);
}
@ -78,20 +55,12 @@ final class CachedInstrumentation
{
$meterProvider = Globals::meterProvider();
if ($this->meters === null) {
return $meterProvider->getMeter($this->name, $this->version, $this->schemaUrl, $this->attributes);
}
return $this->meters[$meterProvider] ??= $meterProvider->getMeter($this->name, $this->version, $this->schemaUrl, $this->attributes);
}
public function logger(): LoggerInterface
{
$loggerProvider = Globals::loggerProvider();
if ($this->loggers === null) {
return $loggerProvider->getLogger($this->name, $this->version, $this->schemaUrl, $this->attributes);
}
return $this->loggers[$loggerProvider] ??= $loggerProvider->getLogger($this->name, $this->version, $this->schemaUrl, $this->attributes);
}
}

View File

@ -111,6 +111,7 @@ trait InstrumentationTrait
public function activate(): bool
{
$this->validateImplementation();
// activate instrumentation with the API. not implemented yet.
return true;
}

View File

@ -6,13 +6,10 @@ namespace OpenTelemetry\API\Logs;
class EventLogger implements EventLoggerInterface
{
private LoggerInterface $logger;
private string $domain;
public function __construct(LoggerInterface $logger, string $domain)
{
$this->logger = $logger;
$this->domain = $domain;
public function __construct(
private LoggerInterface $logger,
private string $domain,
) {
}
public function logEvent(string $eventName, LogRecord $logRecord): void

View File

@ -15,15 +15,10 @@ class LogRecord
protected ?ContextInterface $context = null;
protected int $severityNumber = 0;
protected ?string $severityText = null;
protected $body = null;
protected array $attributes = [];
/**
* @param mixed $body
*/
public function __construct($body = null)
public function __construct(protected mixed $body = null)
{
$this->body = $body;
}
/**
@ -45,7 +40,6 @@ class LogRecord
}
/**
* @param int $severityNumber Severity number
* @see https://opentelemetry.io/docs/reference/specification/logs/data-model/#field-severitynumber
*/
public function setSeverityNumber(int $severityNumber): self
@ -79,7 +73,7 @@ class LogRecord
return $this;
}
public function setAttribute(string $name, $value): self
public function setAttribute(string $name, mixed $value): self
{
$this->attributes[$name] = $value;
@ -89,7 +83,7 @@ class LogRecord
/**
* @param mixed $body The log record body
*/
public function setBody($body = null): self
public function setBody(mixed $body = null): self
{
$this->body = $body;

View File

@ -13,6 +13,6 @@ interface LoggerProviderInterface
string $name,
?string $version = null,
?string $schemaUrl = null,
iterable $attributes = [] //instrumentation scope attributes
iterable $attributes = [], //instrumentation scope attributes
): LoggerInterface;
}

View File

@ -16,25 +16,16 @@ class Psr3
*/
public static function severityNumber(string $level): int
{
switch (strtolower($level)) {
case LogLevel::DEBUG:
return 5;
case LogLevel::INFO:
return 9;
case LogLevel::NOTICE:
return 10;
case LogLevel::WARNING:
return 13;
case LogLevel::ERROR:
return 17;
case LogLevel::CRITICAL:
return 18;
case LogLevel::ALERT:
return 19;
case LogLevel::EMERGENCY:
return 21;
default:
return 0;
}
return match (strtolower($level)) {
LogLevel::DEBUG => 5,
LogLevel::INFO => 9,
LogLevel::NOTICE => 10,
LogLevel::WARNING => 13,
LogLevel::ERROR => 17,
LogLevel::CRITICAL => 18,
LogLevel::ALERT => 19,
LogLevel::EMERGENCY => 21,
default => 0,
};
}
}

View File

@ -13,9 +13,8 @@ interface CounterInterface extends SynchronousInstrument
* @param float|int $amount non-negative amount to increment by
* @param iterable<non-empty-string, string|bool|float|int|array|null> $attributes
* attributes of the data point
* @param ContextInterface|false|null $context execution context
*
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#add
*/
public function add($amount, iterable $attributes = [], $context = null): void;
public function add(float|int $amount, iterable $attributes = [], ContextInterface|false|null $context = null): void;
}

View File

@ -17,5 +17,5 @@ interface HistogramInterface extends SynchronousInstrument
*
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#record
*/
public function record($amount, iterable $attributes = [], $context = null): void;
public function record(float|int $amount, iterable $attributes = [], ContextInterface|false|null $context = null): void;
}

View File

@ -38,15 +38,15 @@ interface MeterInterface
public function batchObserve(
callable $callback,
AsynchronousInstrument $instrument,
AsynchronousInstrument ...$instruments
AsynchronousInstrument ...$instruments,
): ObservableCallbackInterface;
/**
* Creates a `Counter`.
*
* @param string $name name of the instrument
* @param string|null $unit unit of measure
* @param string|null $description description of the instrument
* @param ?string $unit unit of measure
* @param ?string $description description of the instrument
* @param array $advisory an optional set of recommendations
* @return CounterInterface created instrument
*
@ -56,15 +56,15 @@ interface MeterInterface
string $name,
?string $unit = null,
?string $description = null,
array $advisory = []
array $advisory = [],
): CounterInterface;
/**
* Creates an `ObservableCounter`.
*
* @param string $name name of the instrument
* @param string|null $unit unit of measure
* @param string|null $description description of the instrument
* @param ?string $unit unit of measure
* @param ?string $description description of the instrument
* @param array|callable $advisory an optional set of recommendations, or
* deprecated: the first callback to report measurements
* @param callable ...$callbacks responsible for reporting measurements
@ -76,8 +76,8 @@ interface MeterInterface
string $name,
?string $unit = null,
?string $description = null,
$advisory = [],
callable ...$callbacks
array|callable $advisory = [],
callable ...$callbacks,
): ObservableCounterInterface;
/**
@ -96,7 +96,7 @@ interface MeterInterface
string $name,
?string $unit = null,
?string $description = null,
array $advisory = []
array $advisory = [],
): HistogramInterface;
/**
@ -116,8 +116,8 @@ interface MeterInterface
string $name,
?string $unit = null,
?string $description = null,
$advisory = [],
callable ...$callbacks
array|callable $advisory = [],
callable ...$callbacks,
): ObservableGaugeInterface;
/**
@ -135,7 +135,7 @@ interface MeterInterface
string $name,
?string $unit = null,
?string $description = null,
array $advisory = []
array $advisory = [],
): UpDownCounterInterface;
/**
@ -155,7 +155,7 @@ interface MeterInterface
string $name,
?string $unit = null,
?string $description = null,
$advisory = [],
callable ...$callbacks
array|callable $advisory = [],
callable ...$callbacks,
): ObservableUpDownCounterInterface;
}

View File

@ -23,6 +23,6 @@ interface MeterProviderInterface
string $name,
?string $version = null,
?string $schemaUrl = null,
iterable $attributes = []
iterable $attributes = [],
): MeterInterface;
}

View File

@ -13,7 +13,7 @@ final class NoopMeterProvider implements MeterProviderInterface
string $name,
?string $version = null,
?string $schemaUrl = null,
iterable $attributes = []
iterable $attributes = [],
): MeterInterface {
return new NoopMeter();
}

View File

@ -14,5 +14,5 @@ interface ObserverInterface
* @param iterable<non-empty-string, string|bool|float|int|array|null> $attributes
* attributes of the data point
*/
public function observe($amount, iterable $attributes = []): void;
public function observe(float|int $amount, iterable $attributes = []): void;
}

View File

@ -13,12 +13,8 @@ use Throwable;
*/
final class NonRecordingSpan extends Span
{
private SpanContextInterface $context;
public function __construct(
SpanContextInterface $context
) {
$this->context = $context;
public function __construct(private SpanContextInterface $context)
{
}
/** @inheritDoc */

View File

@ -10,17 +10,13 @@ use OpenTelemetry\Context\ContextStorageInterface;
final class NoopSpanBuilder implements SpanBuilderInterface
{
private ContextStorageInterface $contextStorage;
private ContextInterface|false|null $parentContext = null;
/** @var ContextInterface|false|null */
private $parentContext = null;
public function __construct(ContextStorageInterface $contextStorage)
public function __construct(private ContextStorageInterface $contextStorage)
{
$this->contextStorage = $contextStorage;
}
public function setParent($context): SpanBuilderInterface
public function setParent(ContextInterface|false|null $context): SpanBuilderInterface
{
$this->parentContext = $context;
@ -32,7 +28,7 @@ final class NoopSpanBuilder implements SpanBuilderInterface
return $this;
}
public function setAttribute(string $key, $value): SpanBuilderInterface
public function setAttribute(string $key, mixed $value): SpanBuilderInterface
{
return $this;
}

View File

@ -10,7 +10,7 @@ class NoopTracerProvider implements TracerProviderInterface
string $name,
?string $version = null,
?string $schemaUrl = null,
iterable $attributes = []
iterable $attributes = [],
): TracerInterface {
return NoopTracer::getInstance();
}

View File

@ -11,10 +11,6 @@ class TraceContextValidator
public const TRACE_FLAG_LENGTH = 2;
public const TRACE_VERSION_REGEX = '/^(?!ff)[\da-f]{2}$/';
/**
* @param string $traceVersion
* @return bool Returns a value that indicates whether a trace version is valid.
*/
public static function isValidTraceVersion(string $traceVersion): bool
{
return 1 === preg_match(self::TRACE_VERSION_REGEX, $traceVersion);

View File

@ -20,10 +20,10 @@ interface SpanBuilderInterface
*
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#span-creation
*/
public function setParent($context): SpanBuilderInterface;
public function setParent(ContextInterface|false|null $context): SpanBuilderInterface;
public function addLink(SpanContextInterface $context, iterable $attributes = []): SpanBuilderInterface;
public function setAttribute(string $key, $value): SpanBuilderInterface;
public function setAttribute(string $key, mixed $value): SpanBuilderInterface;
public function setAttributes(iterable $attributes): SpanBuilderInterface;
/**

View File

@ -15,35 +15,24 @@ final class SpanContext implements SpanContextInterface
* @see https://www.w3.org/TR/trace-context/#sampled-flag
*/
private bool $isSampled;
private string $traceId;
private string $spanId;
private ?TraceStateInterface $traceState;
private bool $isValid = true;
private bool $isRemote;
private int $traceFlags;
private function __construct(
string $traceId,
string $spanId,
int $traceFlags,
bool $isRemote,
TraceStateInterface $traceState = null
private string $traceId,
private string $spanId,
private int $traceFlags,
private bool $isRemote,
private ?TraceStateInterface $traceState = null,
) {
// TraceId must be exactly 16 bytes (32 chars) and at least one non-zero byte
// SpanId must be exactly 8 bytes (16 chars) and at least one non-zero byte
if (!SpanContextValidator::isValidTraceId($traceId) || !SpanContextValidator::isValidSpanId($spanId)) {
$traceId = SpanContextValidator::INVALID_TRACE;
$spanId = SpanContextValidator::INVALID_SPAN;
$this->traceId = SpanContextValidator::INVALID_TRACE;
$this->spanId = SpanContextValidator::INVALID_SPAN;
$this->isValid=false;
}
$this->traceId = $traceId;
$this->spanId = $spanId;
$this->traceState = $traceState;
$this->isRemote = $isRemote;
$this->isSampled = ($traceFlags & TraceFlags::SAMPLED) === TraceFlags::SAMPLED;
$this->traceFlags = $traceFlags;
}
public function getTraceId(): string

View File

@ -55,7 +55,7 @@ interface SpanInterface extends ImplicitContextKeyedInterface
* @param non-empty-string $key
* @param bool|int|float|string|array|null $value Note: arrays MUST be homogeneous, i.e. it MUST NOT contain values of different types.
*/
public function setAttribute(string $key, $value): SpanInterface;
public function setAttribute(string $key, bool|int|float|string|array|null $value): SpanInterface;
/**
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/trace/api.md#set-attributes

View File

@ -24,8 +24,6 @@ interface TraceStateInterface
* Return a new TraceState object that inherits from this TraceState
* and contains the given key value pair.
*
* @param string $key
* @param string $value
* @return TraceStateInterface
*/
public function with(string $key, string $value): TraceStateInterface;
@ -34,7 +32,6 @@ interface TraceStateInterface
* Return a new TraceState object that inherits from this TraceState
* without the given key value pair.
*
* @param string $key
* @return TraceStateInterface
*/
public function without(string $key): TraceStateInterface;
@ -42,7 +39,6 @@ interface TraceStateInterface
/**
* Return the value of a given key from this TraceState if it exists
*
* @param string $key
* @return string|null
*/
public function get(string $key): ?string;

View File

@ -14,6 +14,6 @@ interface TracerProviderInterface
string $name,
?string $version = null,
?string $schemaUrl = null,
iterable $attributes = []
iterable $attributes = [],
): TracerInterface;
}

View File

@ -17,10 +17,9 @@
}
],
"require": {
"php": "^7.4 || ^8.0",
"php": "^8.0",
"open-telemetry/context": "^1.0",
"psr/log": "^1.1|^2.0|^3.0",
"symfony/polyfill-php80": "^1.26",
"symfony/polyfill-php81": "^1.26",
"symfony/polyfill-php82": "^1.26"
},

View File

@ -39,6 +39,7 @@ final class Context implements ContextInterface
/**
* @param ContextStorageInterface&ExecutionContextAwareInterface $storage
* @todo update type-hint (php >= 8.1)
*/
public static function setStorage(ContextStorageInterface $storage): void
{
@ -47,6 +48,7 @@ final class Context implements ContextInterface
/**
* @return ContextStorageInterface&ExecutionContextAwareInterface
* @todo update return type-hint (php >= 8.1)
*/
public static function storage(): ContextStorageInterface
{
@ -55,11 +57,9 @@ final class Context implements ContextInterface
}
/**
* @param ContextInterface|false|null $context
*
* @internal OpenTelemetry
*/
public static function resolve($context, ?ContextStorageInterface $contextStorage = null): ContextInterface
public static function resolve(ContextInterface|false|null $context, ?ContextStorageInterface $contextStorage = null): ContextInterface
{
return $context
?? ($contextStorage ?? self::storage())->current()

View File

@ -9,11 +9,8 @@ namespace OpenTelemetry\Context;
*/
final class ContextKey implements ContextKeyInterface
{
private ?string $name;
public function __construct(?string $name=null)
public function __construct(private ?string $name = null)
{
$this->name = $name;
}
public function name(): ?string

View File

@ -9,11 +9,9 @@ namespace OpenTelemetry\Context;
*/
final class ContextStorageHead
{
public ContextStorage $storage;
public ?ContextStorageNode $node = null;
public function __construct(ContextStorage $storage)
public function __construct(public ContextStorage $storage)
{
$this->storage = $storage;
}
}

View File

@ -11,19 +11,13 @@ use function assert;
*/
final class ContextStorageNode implements ScopeInterface, ContextStorageScopeInterface
{
public ContextInterface $context;
public ContextStorageHead $head;
private ?ContextStorageNode $previous;
private array $localStorage = [];
public function __construct(
ContextInterface $context,
ContextStorageHead $head,
?ContextStorageNode $previous = null
public ContextInterface $context,
public ContextStorageHead $head,
private ?ContextStorageNode $previous = null,
) {
$this->context = $context;
$this->head = $head;
$this->previous = $previous;
}
public function offsetExists($offset): bool
@ -76,8 +70,8 @@ final class ContextStorageNode implements ScopeInterface, ContextStorageScopeInt
assert($this->head->node !== null);
for ($n = $this->head->node, $depth = 1;
$n->previous !== $this;
$n = $n->previous, $depth++) {
$n->previous !== $this;
$n = $n->previous, $depth++) {
assert($n->previous !== null);
}
$n->previous = $this->previous;

View File

@ -24,15 +24,12 @@ final class DebugScope implements ScopeInterface
{
private static bool $shutdownHandlerInitialized = false;
private static bool $finalShutdownPhase = false;
private ContextStorageScopeInterface $scope;
private ?int $fiberId;
private array $createdAt;
private ?array $detachedAt = null;
public function __construct(ContextStorageScopeInterface $scope)
public function __construct(private ContextStorageScopeInterface $scope)
{
$this->scope = $scope;
$this->fiberId = self::currentFiberId();
$this->createdAt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);

View File

@ -20,15 +20,11 @@ use function trigger_error;
*/
final class FiberBoundContextStorage implements ContextStorageInterface, ExecutionContextAwareInterface
{
/** @var ContextStorageInterface&ExecutionContextAwareInterface */
private ContextStorageInterface $storage;
/**
* @param ContextStorageInterface&ExecutionContextAwareInterface $storage
*/
public function __construct(ContextStorageInterface $storage)
public function __construct(private ContextStorageInterface $storage)
{
$this->storage = $storage;
}
public function fork($id): void

View File

@ -18,11 +18,8 @@ use Fiber;
*/
final class FiberBoundContextStorageScope implements ScopeInterface, ContextStorageScopeInterface
{
private ContextStorageScopeInterface $scope;
public function __construct(ContextStorageScopeInterface $scope)
public function __construct(private ContextStorageScopeInterface $scope)
{
$this->scope = $scope;
}
public function offsetExists($offset): bool

View File

@ -6,11 +6,8 @@ namespace OpenTelemetry\Context\Propagation;
use function array_key_first;
use ArrayAccess;
use function get_class;
use function gettype;
use InvalidArgumentException;
use function is_array;
use function is_object;
use function is_string;
use function sprintf;
use function strcasecmp;
@ -53,7 +50,7 @@ final class ArrayAccessGetterSetter implements PropagationGetterInterface, Propa
throw new InvalidArgumentException(
sprintf(
'Unsupported carrier type: %s.',
is_object($carrier) ? get_class($carrier) : gettype($carrier),
get_debug_type($carrier),
)
);
}
@ -75,7 +72,7 @@ final class ArrayAccessGetterSetter implements PropagationGetterInterface, Propa
throw new InvalidArgumentException(
sprintf(
'Unsupported carrier type: %s. Unable to get value associated with key:%s',
is_object($carrier) ? get_class($carrier) : gettype($carrier),
get_debug_type($carrier),
$key
)
);
@ -100,7 +97,7 @@ final class ArrayAccessGetterSetter implements PropagationGetterInterface, Propa
throw new InvalidArgumentException(
sprintf(
'Unsupported carrier type: %s. Unable to set value associated with key:%s',
is_object($carrier) ? get_class($carrier) : gettype($carrier),
get_debug_type($carrier),
$key
)
);

View File

@ -15,14 +15,6 @@ final class MultiTextMapPropagator implements TextMapPropagatorInterface
{
/**
* @readonly
*
* @var list<TextMapPropagatorInterface>
*/
private array $propagators = [];
/**
* @readonly
*
* @var list<string>
*/
private array $fields;
@ -32,10 +24,11 @@ final class MultiTextMapPropagator implements TextMapPropagatorInterface
*
* @param list<TextMapPropagatorInterface> $propagators
*/
public function __construct(array $propagators)
{
$this->propagators = $propagators;
$this->fields = $this->extractFields($propagators);
public function __construct(
/** @readonly */
private array $propagators,
) {
$this->fields = $this->extractFields($this->propagators);
}
public function fields(): array

View File

@ -18,11 +18,8 @@ final class SanitizeCombinedHeadersPropagationGetter implements PropagationGette
private const SERVER_CONCAT_HEADERS_REGEX = '/;(?=[^,=;]*=|$)/';
private const TRAILING_LEADING_SEPARATOR_REGEX = '/^' . self::LIST_MEMBERS_SEPARATOR . '+|' . self::LIST_MEMBERS_SEPARATOR . '+$/';
private PropagationGetterInterface $getter;
public function __construct(PropagationGetterInterface $getter)
public function __construct(private PropagationGetterInterface $getter)
{
$this->getter = $getter;
}
public function keys($carrier): array

View File

@ -25,10 +25,8 @@ interface TextMapPropagatorInterface
* via an {@see PropagationSetterInterface}.
*
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.6.1/specification/context/api-propagators.md#textmap-inject
*
* @param mixed $carrier
*/
public function inject(&$carrier, PropagationSetterInterface $setter = null, ContextInterface $context = null): void;
public function inject(mixed &$carrier, PropagationSetterInterface $setter = null, ContextInterface $context = null): void;
/**
* Extracts specific values from the provided carrier into the provided {@see ContextInterface}

View File

@ -17,8 +17,7 @@
}
],
"require": {
"php": "^7.4 || ^8.0",
"symfony/polyfill-php80": "^1.26",
"php": "^8.0",
"symfony/polyfill-php81": "^1.26",
"symfony/polyfill-php82": "^1.26"
},

View File

@ -18,6 +18,7 @@ use const Grpc\OP_SEND_INITIAL_METADATA;
use const Grpc\OP_SEND_MESSAGE;
use const Grpc\STATUS_OK;
use Grpc\Timeval;
use OpenTelemetry\Contrib\Otlp\ContentTypes;
use OpenTelemetry\SDK\Common\Export\TransportInterface;
use OpenTelemetry\SDK\Common\Future\CancellationInterface;
use OpenTelemetry\SDK\Common\Future\CompletedFuture;
@ -36,23 +37,21 @@ final class GrpcTransport implements TransportInterface
{
private array $metadata;
private Channel $channel;
private string $method;
private bool $closed = false;
public function __construct(
string $endpoint,
array $opts,
string $method,
array $headers = []
private string $method,
array $headers = [],
) {
$this->channel = new Channel($endpoint, $opts);
$this->method = $method;
$this->metadata = $this->formatMetadata(array_change_key_case($headers));
}
public function contentType(): string
{
return 'application/x-protobuf';
return ContentTypes::PROTOBUF;
}
public function send(string $payload, ?CancellationInterface $cancellation = null): FutureInterface

View File

@ -12,6 +12,7 @@ use function in_array;
use InvalidArgumentException;
use function json_encode;
use OpenTelemetry\API\Behavior\LogsMessagesTrait;
use OpenTelemetry\Contrib\Otlp\ContentTypes;
use OpenTelemetry\SDK\Common\Export\TransportFactoryInterface;
use OpenTelemetry\SDK\Common\Export\TransportInterface;
use function parse_url;
@ -31,7 +32,7 @@ final class GrpcTransportFactory implements TransportFactoryInterface
*/
public function create(
string $endpoint,
string $contentType = 'application/x-protobuf',
string $contentType = ContentTypes::PROTOBUF,
array $headers = [],
$compression = null,
float $timeout = 10.,
@ -39,15 +40,15 @@ final class GrpcTransportFactory implements TransportFactoryInterface
int $maxRetries = 3,
?string $cacert = null,
?string $cert = null,
?string $key = null
?string $key = null,
): TransportInterface {
$parts = parse_url($endpoint);
if (!isset($parts['scheme'], $parts['host'], $parts['path'])) {
throw new InvalidArgumentException('Endpoint has to contain scheme, host and path');
}
/** @phpstan-ignore-next-line */
if ($contentType !== 'application/x-protobuf') {
throw new InvalidArgumentException(sprintf('Unsupported content type "%s", grpc transport supports only application/x-protobuf', $contentType));
if ($contentType !== ContentTypes::PROTOBUF) {
throw new InvalidArgumentException(sprintf('Unsupported content type "%s", grpc transport supports only %s', $contentType, ContentTypes::PROTOBUF));
}
$scheme = $parts['scheme'];
@ -86,7 +87,7 @@ final class GrpcTransportFactory implements TransportFactoryInterface
$compression,
float $timeout,
int $maxRetries,
int $retryDelay
int $retryDelay,
): array {
$opts = [];

View File

@ -17,7 +17,7 @@
}
],
"require": {
"php": "^7.4 || ^8.0",
"php": "^8.0",
"ext-grpc": "*",
"grpc/grpc": "*",
"open-telemetry/sdk": "^1.0"

View File

@ -20,20 +20,17 @@ use Throwable;
class LogsExporter implements LogRecordExporterInterface
{
use LogsMessagesTrait;
private TransportInterface $transport;
private ProtobufSerializer $serializer;
/**
* @psalm-param TransportInterface<SUPPORTED_CONTENT_TYPES> $transport
*/
public function __construct(TransportInterface $transport)
public function __construct(private TransportInterface $transport)
{
if (!class_exists('\Google\Protobuf\Api')) {
throw new RuntimeException('No protobuf implementation found (ext-protobuf or google/protobuf)');
}
$this->transport = $transport;
$this->serializer = ProtobufSerializer::forTransport($transport);
$this->serializer = ProtobufSerializer::forTransport($this->transport);
}
/**

View File

@ -18,11 +18,8 @@ class LogsExporterFactory implements LogRecordExporterFactoryInterface
{
private const DEFAULT_COMPRESSION = 'none';
private ?TransportFactoryInterface $transportFactory;
public function __construct(?TransportFactoryInterface $transportFactory = null)
public function __construct(private ?TransportFactoryInterface $transportFactory = null)
{
$this->transportFactory = $transportFactory;
}
/**

View File

@ -132,15 +132,11 @@ final class MetricConverter
private function convertTemporality($temporality): int
{
switch ($temporality) {
case SDK\Metrics\Data\Temporality::DELTA:
return AggregationTemporality::AGGREGATION_TEMPORALITY_DELTA;
case SDK\Metrics\Data\Temporality::CUMULATIVE:
return AggregationTemporality::AGGREGATION_TEMPORALITY_CUMULATIVE;
}
// @codeCoverageIgnoreStart
return AggregationTemporality::AGGREGATION_TEMPORALITY_UNSPECIFIED;
return match ($temporality) {
SDK\Metrics\Data\Temporality::DELTA => AggregationTemporality::AGGREGATION_TEMPORALITY_DELTA,
SDK\Metrics\Data\Temporality::CUMULATIVE => AggregationTemporality::AGGREGATION_TEMPORALITY_CUMULATIVE,
default => AggregationTemporality::AGGREGATION_TEMPORALITY_UNSPECIFIED,
};
// @codeCoverageIgnoreEnd
}

View File

@ -22,27 +22,19 @@ use Throwable;
final class MetricExporter implements PushMetricExporterInterface, AggregationTemporalitySelectorInterface
{
use LogsMessagesTrait;
private TransportInterface $transport;
private ProtobufSerializer $serializer;
/**
* @var string|Temporality|null
*/
private $temporality;
/**
* @param string|Temporality|null $temporality
*
* @psalm-param TransportInterface<SUPPORTED_CONTENT_TYPES> $transport
*/
public function __construct(TransportInterface $transport, $temporality = null)
{
public function __construct(
private TransportInterface $transport,
private string|Temporality|null $temporality = null,
) {
if (!class_exists('\Google\Protobuf\Api')) {
throw new RuntimeException('No protobuf implementation found (ext-protobuf or google/protobuf)');
}
$this->transport = $transport;
$this->serializer = ProtobufSerializer::forTransport($transport);
$this->temporality = $temporality;
$this->serializer = ProtobufSerializer::forTransport($this->transport);
}
public function temporality(MetricMetadataInterface $metric)

View File

@ -19,11 +19,8 @@ class MetricExporterFactory implements MetricExporterFactoryInterface
{
private const DEFAULT_COMPRESSION = 'none';
private ?TransportFactoryInterface $transportFactory;
public function __construct(?TransportFactoryInterface $transportFactory = null)
public function __construct(private ?TransportFactoryInterface $transportFactory = null)
{
$this->transportFactory = $transportFactory;
}
/**
@ -66,21 +63,18 @@ class MetricExporterFactory implements MetricExporterFactoryInterface
}
/**
* @todo return string|Temporality|null (php >= 8.0)
* @phpstan-ignore-next-line
*/
private function getTemporality()
private function getTemporality(): string|Temporality|null
{
$value = Configuration::getEnum(Variables::OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE);
switch (strtolower($value)) {
case 'cumulative':
return Temporality::CUMULATIVE;
case 'delta':
return Temporality::DELTA;
case 'lowmemory':
return null;
default:
throw new \UnexpectedValueException('Unknown temporality: ' . $value);
}
return match (strtolower($value)) {
'cumulative' => Temporality::CUMULATIVE,
'delta' => Temporality::DELTA,
'lowmemory' => null,
default => throw new \UnexpectedValueException('Unknown temporality: ' . $value),
};
}
private function getCompression(): string

View File

@ -22,7 +22,7 @@ class OtlpHttpTransportFactory implements TransportFactoryInterface
int $maxRetries = 3,
?string $cacert = null,
?string $cert = null,
?string $key = null
?string $key = null,
): PsrTransport {
if ($compression === self::DEFAULT_COMPRESSION) {
$compression = null;

View File

@ -4,11 +4,9 @@ declare(strict_types=1);
namespace OpenTelemetry\Contrib\Otlp;
use AssertionError;
use function base64_decode;
use function bin2hex;
use Exception;
use function get_class;
use Google\Protobuf\Descriptor;
use Google\Protobuf\DescriptorPool;
use Google\Protobuf\FieldDescriptor;
@ -28,25 +26,17 @@ use function ucwords;
/**
* @internal
*
* @psalm-type SUPPORTED_CONTENT_TYPES = self::PROTOBUF|self::JSON|self::NDJSON
* @psalm-type SUPPORTED_CONTENT_TYPES = ContentTypes::PROTOBUF|ContentTypes::JSON|ContentTypes::NDJSON
*/
final class ProtobufSerializer
{
private const PROTOBUF = 'application/x-protobuf';
private const JSON = 'application/json';
private const NDJSON = 'application/x-ndjson';
private string $contentType;
private function __construct(string $contentType)
private function __construct(private string $contentType)
{
$this->contentType = $contentType;
}
public static function getDefault(): ProtobufSerializer
{
return new self(self::PROTOBUF);
return new self(ContentTypes::PROTOBUF);
}
/**
@ -54,75 +44,51 @@ final class ProtobufSerializer
*/
public static function forTransport(TransportInterface $transport): ProtobufSerializer
{
switch ($contentType = $transport->contentType()) {
case self::PROTOBUF:
case self::JSON:
case self::NDJSON:
return new self($contentType);
default:
throw new InvalidArgumentException(sprintf('Not supported content type "%s"', $contentType));
}
return match ($contentType = $transport->contentType()) {
ContentTypes::PROTOBUF, ContentTypes::JSON, ContentTypes::NDJSON => new self($contentType),
default => throw new InvalidArgumentException(sprintf('Not supported content type "%s"', $contentType)),
};
}
public function serializeTraceId(string $traceId): string
{
switch ($this->contentType) {
case self::PROTOBUF:
return $traceId;
case self::JSON:
case self::NDJSON:
return base64_decode(bin2hex($traceId));
default:
throw new AssertionError();
}
// @phpstan-ignore-next-line
return match ($this->contentType) {
ContentTypes::PROTOBUF => $traceId,
ContentTypes::JSON, ContentTypes::NDJSON => base64_decode(bin2hex($traceId)),
};
}
public function serializeSpanId(string $spanId): string
{
switch ($this->contentType) {
case self::PROTOBUF:
return $spanId;
case self::JSON:
case self::NDJSON:
return base64_decode(bin2hex($spanId));
default:
throw new AssertionError();
}
// @phpstan-ignore-next-line
return match ($this->contentType) {
ContentTypes::PROTOBUF => $spanId,
ContentTypes::JSON, ContentTypes::NDJSON => base64_decode(bin2hex($spanId)),
};
}
public function serialize(Message $message): string
{
switch ($this->contentType) {
case self::PROTOBUF:
return $message->serializeToString();
case self::JSON:
return self::postProcessJsonEnumValues($message, $message->serializeToJsonString());
case self::NDJSON:
return self::postProcessJsonEnumValues($message, $message->serializeToJsonString()) . "\n";
default:
throw new AssertionError();
}
// @phpstan-ignore-next-line
return match ($this->contentType) {
ContentTypes::PROTOBUF => $message->serializeToString(),
ContentTypes::JSON => self::postProcessJsonEnumValues($message, $message->serializeToJsonString()),
ContentTypes::NDJSON => self::postProcessJsonEnumValues($message, $message->serializeToJsonString()) . "\n",
};
}
/**
* @phan-suppress PhanParamTooManyInternal (@see https://github.com/phan/phan/pull/4840)
* @throws Exception
*/
public function hydrate(Message $message, string $payload): void
{
switch ($this->contentType) {
case self::PROTOBUF:
$message->mergeFromString($payload);
break;
case self::JSON:
case self::NDJSON:
// @phan-suppress-next-line PhanParamTooManyInternal
$message->mergeFromJsonString($payload, true);
break;
default:
throw new AssertionError();
}
// @phpstan-ignore-next-line
match ($this->contentType) {
ContentTypes::PROTOBUF => $message->mergeFromString($payload),
ContentTypes::JSON, ContentTypes::NDJSON => $message->mergeFromJsonString($payload, true),
};
}
/**
@ -137,7 +103,7 @@ final class ProtobufSerializer
private static function postProcessJsonEnumValues(Message $message, string $payload): string
{
$pool = DescriptorPool::getGeneratedPool();
$desc = $pool->getDescriptorByClassName(get_class($message));
$desc = $pool->getDescriptorByClassName($message::class);
if (!$desc instanceof Descriptor) {
return $payload;
}

View File

@ -121,15 +121,14 @@ final class SpanConverter
private function convertSpanKind(int $kind): int
{
switch ($kind) {
case API\SpanKind::KIND_INTERNAL: return SpanKind::SPAN_KIND_INTERNAL;
case API\SpanKind::KIND_CLIENT: return SpanKind::SPAN_KIND_CLIENT;
case API\SpanKind::KIND_SERVER: return SpanKind::SPAN_KIND_SERVER;
case API\SpanKind::KIND_PRODUCER: return SpanKind::SPAN_KIND_PRODUCER;
case API\SpanKind::KIND_CONSUMER: return SpanKind::SPAN_KIND_CONSUMER;
}
return SpanKind::SPAN_KIND_UNSPECIFIED;
return match ($kind) {
API\SpanKind::KIND_INTERNAL => SpanKind::SPAN_KIND_INTERNAL,
API\SpanKind::KIND_CLIENT => SpanKind::SPAN_KIND_CLIENT,
API\SpanKind::KIND_SERVER => SpanKind::SPAN_KIND_SERVER,
API\SpanKind::KIND_PRODUCER => SpanKind::SPAN_KIND_PRODUCER,
API\SpanKind::KIND_CONSUMER => SpanKind::SPAN_KIND_CONSUMER,
default => SpanKind::SPAN_KIND_UNSPECIFIED,
};
}
private function convertStatusCode(string $status): int

View File

@ -19,20 +19,17 @@ use Throwable;
final class SpanExporter implements SpanExporterInterface
{
use LogsMessagesTrait;
private TransportInterface $transport;
private ProtobufSerializer $serializer;
/**
* @psalm-param TransportInterface<SUPPORTED_CONTENT_TYPES> $transport
*/
public function __construct(TransportInterface $transport)
public function __construct(private TransportInterface $transport)
{
if (!class_exists('\Google\Protobuf\Api')) {
throw new RuntimeException('No protobuf implementation found (ext-protobuf or google/protobuf)');
}
$this->transport = $transport;
$this->serializer = ProtobufSerializer::forTransport($transport);
$this->serializer = ProtobufSerializer::forTransport($this->transport);
}
public function export(iterable $batch, ?CancellationInterface $cancellation = null): FutureInterface

View File

@ -19,13 +19,10 @@ class SpanExporterFactory implements SpanExporterFactoryInterface
{
use LogsMessagesTrait;
private ?TransportFactoryInterface $transportFactory;
private const DEFAULT_COMPRESSION = 'none';
public function __construct(?TransportFactoryInterface $transportFactory = null)
public function __construct(private ?TransportFactoryInterface $transportFactory = null)
{
$this->transportFactory = $transportFactory;
}
/**

View File

@ -17,7 +17,7 @@
}
],
"require": {
"php": "^7.4 || ^8.0",
"php": "^8.0",
"php-http/discovery": "^1.14",
"open-telemetry/gen-otlp-protobuf": "^1.1",
"open-telemetry/api": "^1.0",

View File

@ -23,13 +23,10 @@ class Exporter implements SpanExporterInterface
use LogsMessagesTrait;
use UsesSpanConverterTrait;
private TransportInterface $transport;
public function __construct(
TransportInterface $transport,
SpanConverterInterface $spanConverter = null
private TransportInterface $transport,
SpanConverterInterface $spanConverter = null,
) {
$this->transport = $transport;
$this->setSpanConverter($spanConverter ?? new SpanConverter());
}

View File

@ -171,20 +171,14 @@ class SpanConverter implements SpanConverterInterface
private static function toSpanKind(SpanDataInterface $span): ?string
{
switch ($span->getKind()) {
case SpanKind::KIND_SERVER:
return ZipkinSpanKind::SERVER;
case SpanKind::KIND_CLIENT:
return ZipkinSpanKind::CLIENT;
case SpanKind::KIND_PRODUCER:
return ZipkinSpanKind::PRODUCER;
case SpanKind::KIND_CONSUMER:
return ZipkinSpanKind::CONSUMER;
case SpanKind::KIND_INTERNAL:
return null;
}
return null;
return match ($span->getKind()) {
SpanKind::KIND_SERVER => ZipkinSpanKind::SERVER,
SpanKind::KIND_CLIENT => ZipkinSpanKind::CLIENT,
SpanKind::KIND_PRODUCER => ZipkinSpanKind::PRODUCER,
SpanKind::KIND_CONSUMER => ZipkinSpanKind::CONSUMER,
SpanKind::KIND_INTERNAL => null,
default => null,
};
}
private static function toAnnotation(EventInterface $event): array
@ -231,17 +225,15 @@ class SpanConverter implements SpanConverterInterface
return null;
}
switch ($key) {
case SpanConverter::NET_PEER_IP_KEY:
return SpanConverter::getRemoteEndpointDataFromIpAddressAndPort(
$value,
SpanConverter::getPortNumberFromSpanAttributes($span)
);
default:
return [
'serviceName' => $value,
];
}
return match ($key) {
SpanConverter::NET_PEER_IP_KEY => SpanConverter::getRemoteEndpointDataFromIpAddressAndPort(
$value,
SpanConverter::getPortNumberFromSpanAttributes($span)
),
default => [
'serviceName' => $value,
],
};
}
private static function findRemoteEndpointPreferredAttribute(SpanDataInterface $span): ?array

View File

@ -17,7 +17,7 @@
}
],
"require": {
"php": "^7.4 || ^8.0",
"php": "^8.0",
"open-telemetry/api": "^1.0",
"open-telemetry/sdk": "^1.0",
"php-http/async-client-implementation": "^1.0",

View File

@ -11,7 +11,7 @@
}
],
"require": {
"php": "^7.4 || ^8.0",
"php": "^8.0",
"ext-json": "*",
"open-telemetry/api": "^1.0",
"open-telemetry/context": "^1.0",
@ -23,7 +23,6 @@
"psr/http-factory-implementation": "^1.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"
},

View File

@ -18,11 +18,8 @@ use OpenTelemetry\Context\Propagation\TextMapPropagatorInterface;
*/
final class B3Propagator implements TextMapPropagatorInterface
{
private TextMapPropagatorInterface $propagator;
private function __construct(TextMapPropagatorInterface $propagator)
private function __construct(private TextMapPropagatorInterface $propagator)
{
$this->propagator = $propagator;
}
public static function getB3SingleHeaderInstance(): self

View File

@ -17,7 +17,7 @@
}
],
"require": {
"php": "^7.4 || ^8.0",
"php": "^8.0",
"open-telemetry/api": "^1.0",
"open-telemetry/context": "^1.0"
},

View File

@ -20,9 +20,6 @@ final class CloudTraceFormatter
/**
* Generate a SpanContext object from the Trace Context header
*
* @param string $header
* @return SpanContextInterface
*/
public static function deserialize(string $header) : SpanContextInterface
{
@ -47,9 +44,6 @@ final class CloudTraceFormatter
/**
* Convert a SpanContextInterface to header string
*
* @param SpanContextInterface $context
* @return string
*/
public static function serialize(SpanContextInterface $context) : string
{

View File

@ -46,11 +46,8 @@ final class CloudTracePropagator implements TextMapPropagatorInterface
self::XCLOUD,
];
private bool $oneWay;
private function __construct(bool $oneWay)
private function __construct(private bool $oneWay)
{
$this->oneWay = $oneWay;
}
/** {@inheritdoc} */

View File

@ -17,7 +17,7 @@
}
],
"require": {
"php": "^7.4 || ^8.0",
"php": "^8.0",
"open-telemetry/api": "^1.0",
"open-telemetry/context": "^1.0"
},

View File

@ -73,7 +73,7 @@ class JaegerBaggagePropagator implements TextMapPropagatorInterface
$baggageBuilder = Baggage::getBuilder();
foreach ($baggageKeys as $key) {
if (strpos($key, self::UBER_BAGGAGE_HEADER_PREFIX) === 0) {
if (str_starts_with($key, self::UBER_BAGGAGE_HEADER_PREFIX)) {
$baggageKey = substr($key, strlen(self::UBER_BAGGAGE_HEADER_PREFIX));
$value = $getter->get($carrier, $key) ?? '';
$baggageBuilder->set($baggageKey, rawurldecode($value));

View File

@ -26,7 +26,7 @@ final class DependencyResolver implements DependencyResolverInterface
public function __construct(
?MessageFactoryResolverInterface $messageFactoryResolver = null,
?PsrClientResolverInterface $psrClientResolver = null,
?HttpPlugClientResolverInterface $httpPlugClientResolver = null
?HttpPlugClientResolverInterface $httpPlugClientResolver = null,
) {
$this->messageFactoryResolver = $messageFactoryResolver ?? MessageFactoryResolver::create();
$this->psrClientResolver = $psrClientResolver ?? PsrClientResolver::create();
@ -36,7 +36,7 @@ final class DependencyResolver implements DependencyResolverInterface
public static function create(
?MessageFactoryResolverInterface $messageFactoryResolver = null,
?PsrClientResolverInterface $psrClientResolver = null,
?HttpPlugClientResolverInterface $httpPlugClientResolver = null
?HttpPlugClientResolverInterface $httpPlugClientResolver = null,
): self {
return new self($messageFactoryResolver, $psrClientResolver, $httpPlugClientResolver);
}

View File

@ -10,11 +10,8 @@ use OpenTelemetry\SDK\Common\Http\HttpPlug\Client\ResolverInterface;
final class HttpPlugClientResolver implements ResolverInterface
{
private ?HttpAsyncClient $httpAsyncClient;
public function __construct(?HttpAsyncClient $httpAsyncClient = null)
public function __construct(private ?HttpAsyncClient $httpAsyncClient = null)
{
$this->httpAsyncClient = $httpAsyncClient;
}
public static function create(?HttpAsyncClient $httpAsyncClient = null): self

View File

@ -15,27 +15,14 @@ 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
private ?RequestFactoryInterface $requestFactory = null,
private ?ResponseFactoryInterface $responseFactory = null,
private ?ServerRequestFactoryInterface $serverRequestFactory = null,
private ?StreamFactoryInterface $streamFactory = null,
private ?UploadedFileFactoryInterface $uploadedFileFactory = null,
private ?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(
@ -44,7 +31,7 @@ final class MessageFactoryResolver implements FactoryResolverInterface
?ServerRequestFactoryInterface $serverRequestFactory = null,
?StreamFactoryInterface $streamFactory = null,
?UploadedFileFactoryInterface $uploadedFileFactory = null,
?UriFactoryInterface $uriFactory = null
?UriFactoryInterface $uriFactory = null,
): self {
return new self(
$requestFactory,

View File

@ -10,11 +10,8 @@ use Psr\Http\Client\ClientInterface;
final class PsrClientResolver implements ResolverInterface
{
private ?ClientInterface $client;
public function __construct(?ClientInterface $client = null)
public function __construct(private ?ClientInterface $client = null)
{
$this->client = $client;
}
public static function create(?ClientInterface $client = null): self

View File

@ -10,16 +10,13 @@ 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 function __construct(
private array $attributes,
private int $droppedAttributesCount,
) {
}
public static function create(iterable $attributes): AttributesInterface

View File

@ -17,24 +17,15 @@ use OpenTelemetry\API\Behavior\LogsMessagesTrait;
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
private array $attributes,
private ?int $attributeCountLimit,
private ?int $attributeValueLengthLimit,
private int $droppedAttributesCount,
?AttributeValidatorInterface $attributeValidator,
) {
$this->attributes = $attributes;
$this->attributeCountLimit = $attributeCountLimit;
$this->attributeValueLengthLimit = $attributeValueLengthLimit;
$this->droppedAttributesCount = $droppedAttributesCount;
$this->attributeValidator = $attributeValidator ?? new AttributeValidator();
}

View File

@ -9,13 +9,10 @@ namespace OpenTelemetry\SDK\Common\Attribute;
*/
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 __construct(
private ?int $attributeCountLimit = null,
private ?int $attributeValueLengthLimit = null,
) {
}
public function builder(iterable $attributes = [], ?AttributeValidatorInterface $attributeValidator = null): AttributesBuilderInterface

View File

@ -11,17 +11,15 @@ use function in_array;
*/
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 __construct(
private AttributesBuilderInterface $builder,
private array $rejectedKeys,
) {
}
public function __clone()

View File

@ -9,16 +9,13 @@ namespace OpenTelemetry\SDK\Common\Attribute;
*/
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 __construct(
private AttributesFactoryInterface $factory,
private array $rejectedKeys,
) {
}
public function builder(iterable $attributes = [], ?AttributeValidatorInterface $attributeValidator = null): AttributesBuilderInterface

View File

@ -61,7 +61,7 @@ class Configuration
try {
return BooleanParser::parse($resolved);
} catch (InvalidArgumentException $e) {
} catch (InvalidArgumentException) {
self::logWarning(sprintf('Invalid boolean value "%s" interpreted as "false" for %s', $resolved, $key));
return false;

View File

@ -34,7 +34,7 @@ class MapParser
private static function validateKeyValuePair(string $pair)
{
if (strpos($pair, self::KEY_VALUE_SEPARATOR) === false) {
if (!str_contains($pair, self::KEY_VALUE_SEPARATOR)) {
throw new InvalidArgumentException(sprintf(
'Key-Value pair "%s" does not contain separator "%s"',
$pair,

View File

@ -57,7 +57,7 @@ class Util
public static function triggerMethodDeprecationNotice(
string $methodName,
string $alternativeMethodName = null,
string $alternativeClassName = null
string $alternativeClassName = null,
): void {
if (self::getErrorLevel() === self::E_NONE) {
return;

View File

@ -6,7 +6,6 @@ namespace OpenTelemetry\SDK\Common\Exception;
use function basename;
use function count;
use function get_class;
use function sprintf;
use function str_repeat;
@ -77,8 +76,8 @@ final class StackTraceFormatter
$n = count($frames);
if ($enclosing) {
for ($m = count($enclosing);
$n && $m && $frames[$n - 1] === $enclosing[$m - 1];
$n--, $m--) {
$n && $m && $frames[$n - 1] === $enclosing[$m - 1];
$n--, $m--) {
}
}
for ($i = 0; $i < $n; $i++) {
@ -110,7 +109,7 @@ final class StackTraceFormatter
private static function writeInlineHeader(string &$s, Throwable $e): void
{
$s .= self::formatName(get_class($e));
$s .= self::formatName($e::class);
if ($e->getMessage() !== '') {
$s .= ': ';
$s .= $e->getMessage();

View File

@ -30,42 +30,22 @@ use function trim;
*/
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
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,
) {
$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

View File

@ -16,18 +16,11 @@ 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
private ClientInterface $client,
private RequestFactoryInterface $requestFactory,
private StreamFactoryInterface $streamFactory,
) {
$this->client = $client;
$this->requestFactory = $requestFactory;
$this->streamFactory = $streamFactory;
}
/**
@ -43,7 +36,7 @@ final class PsrTransportFactory implements TransportFactoryInterface
int $maxRetries = 3,
?string $cacert = null,
?string $cert = null,
?string $key = null
?string $key = null,
): PsrTransport {
if (!filter_var($endpoint, FILTER_VALIDATE_URL)) {
throw new InvalidArgumentException(sprintf('Invalid endpoint url "%s"', $endpoint));

View File

@ -75,7 +75,7 @@ final class PsrUtils
try {
$value = $encoder($value);
} catch (Throwable $e) {
} catch (Throwable) {
unset($encodings[$i]);
}
}
@ -115,7 +115,7 @@ final class PsrUtils
if (!$compression) {
return [];
}
if (strpos($compression, ',') === false) {
if (!str_contains($compression, ',')) {
return [$compression];
}

View File

@ -28,20 +28,14 @@ use Throwable;
final class StreamTransport implements TransportInterface
{
/**
* @var resource|null
*/
private $stream;
private string $contentType;
/**
* @param resource $stream
* @param resource|null $stream
*
* @psalm-param CONTENT_TYPE $contentType
*/
public function __construct($stream, string $contentType)
{
$this->stream = $stream;
$this->contentType = $contentType;
public function __construct(
private $stream,
private string $contentType,
) {
}
public function contentType(): string

Some files were not shown because too many files have changed in this diff Show More