Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
riticksingh committed Nov 21, 2020
2 parents 1cc76d4 + bed3ec2 commit 7a3fdcd
Show file tree
Hide file tree
Showing 16 changed files with 1,005 additions and 34 deletions.
13 changes: 0 additions & 13 deletions .github/phpcs.sh

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
run: composer install --prefer-dist --no-progress --no-suggest

- name: Check Style
run: .github/phpcs.sh
run: vendor/bin/php-cs-fixer fix --config=.php_cs -v --dry-run --stop-on-violation --using-cache=no

- name: Run Phan
env:
Expand Down
2 changes: 1 addition & 1 deletion api/Trace/PropagationSetter.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ interface PropagationSetter
* @param string $value
* @return void
*/
public function set($carrier, string $key, string $value) : void;
public function set(&$carrier, string $key, string $value) : void;
}
6 changes: 3 additions & 3 deletions api/Trace/TextMapFormatPropagator.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ interface TextMapFormatPropagator
*
* @return array
*/
public function fields() : array;
public static function fields() : array;

/**
* Encodes the given SpanContext into propagator specific format and injects
Expand All @@ -22,7 +22,7 @@ public function fields() : array;
* @param PropagationSetter $setter
* @return void
*/
public function inject(SpanContext $context, $carrier, PropagationSetter $setter) : void;
public static function inject(SpanContext $context, &$carrier, PropagationSetter $setter) : void;

/**
* Retrieves encoded SpanContext using Getter from the associated carrier.
Expand All @@ -31,5 +31,5 @@ public function inject(SpanContext $context, $carrier, PropagationSetter $setter
* @param PropagationGetter $getter
* @return SpanContext
*/
public function extract($carrier, PropagationGetter $getter): SpanContext;
public static function extract($carrier, PropagationGetter $getter): SpanContext;
}
21 changes: 20 additions & 1 deletion sdk/Resource/ResourceInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,15 @@ private function __construct(Attributes $attributes)

public static function create(Attributes $attributes): self
{
return new ResourceInfo(clone $attributes);
$resource = self::merge(self::defaultResource(), new ResourceInfo(clone $attributes));
/*
* The SDK MUST extract information from the OTEL_RESOURCE_ATTRIBUTES environment
* variable and merge this.
* todo: after resource detection is implemented, merge it here.
* return $resource.merge(....);
*
*/
return $resource;
}

/**
Expand Down Expand Up @@ -53,6 +61,17 @@ public static function merge(ResourceInfo $primary, ResourceInfo $secondary): se
return new ResourceInfo($mergedAttributes);
}

public static function defaultResource(): self
{
return new ResourceInfo(new Attributes(
[
ResourceConstants::TELEMETRY_SDK_NAME => 'opentelemetry',
ResourceConstants::TELEMETRY_SDK_LANGUAGE => 'php',
ResourceConstants::TELEMETRY_SDK_VERSION => 'dev',
]
));
}

public static function emptyResource(): self
{
return new ResourceInfo(new Attributes());
Expand Down
68 changes: 68 additions & 0 deletions sdk/Trace/PropagationMap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\Sdk\Trace;

use ArrayAccess;
use OpenTelemetry\Trace as API;

class PropagationMap implements API\PropagationGetter, API\PropagationSetter
{
/**
* {@inheritdoc}
*/
public function get($carrier, string $key): ?string
{
$lKey = \strtolower($key);
if ($carrier instanceof ArrayAccess) {
return $carrier->offsetExists($lKey) ? $carrier->offsetGet($lKey) : null;
}

if (\is_array($carrier)) {
if (empty($carrier)) {
return null;
}

foreach ($carrier as $k => $value) {
if (strtolower($k) === $lKey) {
return $value;
}
}

return null;
}

throw new \InvalidArgumentException(
sprintf(
'Invalid carrier of type %s. Unable to get value associated with key:%s',
\is_object($carrier) ? \get_class($carrier) : \gettype($carrier),
$key
)
);
}

/**
* {@inheritdoc}
*/
public function set(&$carrier, string $key, string $value): void
{
if ($key === '') {
throw new \InvalidArgumentException('Unable to set value with an empty key');
}

if ($carrier instanceof ArrayAccess || \is_array($carrier)) {
$carrier[\strtolower($key)] = $value;

return;
}

throw new \InvalidArgumentException(
sprintf(
'Invalid carrier of type %s. Unable to set value associated with key:%s',
\is_object($carrier) ? \get_class($carrier) : \gettype($carrier),
$key
)
);
}
}
13 changes: 13 additions & 0 deletions sdk/Trace/Span.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace OpenTelemetry\Sdk\Trace;

use OpenTelemetry\Sdk\Resource\ResourceInfo;
use OpenTelemetry\Trace as API;

class Span implements API\Span
Expand All @@ -20,6 +21,11 @@ class Span implements API\Span
private $statusCode;
private $statusDescription;

/**
* @var ResourceInfo
*/
private $resource; // An immutable representation of the entity producing telemetry.

private $attributes;
private $events;
private $links = null;
Expand All @@ -44,13 +50,15 @@ public function __construct(
API\SpanContext $spanContext,
?API\SpanContext $parentSpanContext = null,
?Sampler $sampler = null,
?ResourceInfo $resource = null,
int $spanKind = API\SpanKind::KIND_INTERNAL
) {
$this->name = $name;
$this->spanContext = $spanContext;
$this->parentSpanContext = $parentSpanContext;
$this->spanKind = $spanKind;
$this->sampler = $sampler;
$this->resource = $resource ?? ResourceInfo::emptyResource();
$moment = Clock::get()->moment();
$this->startEpochTimestamp = $moment[0];
$this->start = $moment[1];
Expand All @@ -62,6 +70,11 @@ public function __construct(
$this->events = new Events();
}

public function getResource(): ResourceInfo
{
return clone $this->resource;
}

public function getContext(): API\SpanContext
{
return clone $this->spanContext;
Expand Down
2 changes: 1 addition & 1 deletion sdk/Trace/SpanOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public function toSpan(): API\Span
? SpanContext::fork($span->getContext()->getTraceId())
: SpanContext::generate();

$span = new Span($this->name, $context, $this->parent, null, $this->kind);
$span = new Span($this->name, $context, $this->parent, null, $this->tracer->getResource(), $this->kind);

if ($this->startEpochTimestamp !== null) {
$span->setStartEpochTimestamp($this->startEpochTimestamp);
Expand Down
96 changes: 96 additions & 0 deletions sdk/Trace/TraceContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\Sdk\Trace;

use OpenTelemetry\Trace as API;

final class TraceContext implements API\TextMapFormatPropagator
{
public const TRACEPARENT = 'http_traceparent';
public const TRACESTATE = 'http_tracestate';

// TODO Consolidate these and the validity checks in SpanContext.php
private const SUPPORTED_VERSION = '00';
private const INVALID_TRACE = '00000000000000000000000000000000';
private const INVALID_SPAN = '0000000000000000';
private const VALID_VERSION = '/^[0-9a-f]{2}$/';
private const VALID_TRACE = '/^[0-9a-f]{32}$/';
private const VALID_SPAN = '/^[0-9a-f]{16}$/';
private const VALID_TRACEFLAGS = '/^[0-9a-f]{2}$/';
private const SAMPLED_FLAG = 1;

/**
* {@inheritdoc}
*/
public static function fields(): array
{
return [self::TRACEPARENT, self::TRACESTATE];
}

/**
* {@inheritdoc}
*/
public static function inject(API\SpanContext $context, &$carrier, API\PropagationSetter $setter): void
{
$traceparent = self::SUPPORTED_VERSION . '-' . $context->getTraceId() . '-' . $context->getSpanId() . '-' . ($context->isSampled() ? '01' : '00');
$setter->set($carrier, self::TRACEPARENT, $traceparent);
}

/**
* {@inheritdoc}
*/
public static function extract($carrier, API\PropagationGetter $getter): API\SpanContext
{
$traceparent = $getter->get($carrier, self::TRACEPARENT);
if ($traceparent === null) {
throw new \InvalidArgumentException('Traceparent not present');
}

// Traceparent = {version}-{trace-id}-{parent-id}-{trace-flags}
$pieces = explode('-', $traceparent);

$peicesCount = count($pieces);
if ($peicesCount != 4) {
throw new \InvalidArgumentException(
sprintf('Unable to extract traceparent. Expected 4 values, got %d', $peicesCount)
);
}

// Parse the traceparent version. Currently only '00' is supported.
$version = $pieces[0];
if ((preg_match(self::VALID_VERSION, $version) === 0) || ($version !== self::SUPPORTED_VERSION)) {
throw new \InvalidArgumentException(
sprintf('Only version 00 is supported, got %s', $version)
);
}

$traceId = $pieces[1];
if ((preg_match(self::VALID_TRACE, $traceId) === 0) || ($traceId === self::INVALID_TRACE)) {
throw new \InvalidArgumentException(
sprintf('TraceID must be exactly 16 bytes (32 chars) and at least one non-zero byte, got %s', $traceId)
);
}

$spanId = $pieces[2];
if ((preg_match(self::VALID_SPAN, $spanId) === 0) || ($spanId === self::INVALID_SPAN)) {
throw new \InvalidArgumentException(
sprintf('SpanID must be exactly 8 bytes (16 chars) and at least one non-zero byte, got %s', $spanId)
);
}

$traceFlags = $pieces[3];
if (preg_match(self::VALID_TRACEFLAGS, $traceFlags) === 0) {
throw new \InvalidArgumentException(
sprintf('TraceFlags must be exactly 1 bytes (1 char) representing a bit field, got %s', $traceFlags)
);
}

// Only the sampled flag is extracted from the traceFlags (00000001)
$convertedTraceFlags = hexdec($traceFlags);
$isSampled = ($convertedTraceFlags & self::SAMPLED_FLAG) === self::SAMPLED_FLAG;

return SpanContext::restore($traceId, $spanId, $isSampled, true);
}
}
16 changes: 10 additions & 6 deletions sdk/Trace/Tracer.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ class Tracer implements API\Tracer

public function __construct(
TracerProvider $provider,
ResourceInfo $resource,
ResourceInfo $resource = null,
API\SpanContext $context = null
) {
$this->provider = $provider;
$this->resource = $resource;
$this->resource = $resource ?? ResourceInfo::emptyResource();
$this->importedContext = $context;
}

Expand All @@ -50,6 +50,7 @@ public function setActiveSpan(API\Span $span): void
* @param string $name
* @param API\SpanContext $parentContext
* @param bool $isRemote
* @param int $spanKind
* @return Span
*/

Expand Down Expand Up @@ -81,7 +82,7 @@ public function startActiveSpan(string $name, API\SpanContext $parentContext, bo
if (SamplingResult::NOT_RECORD == $samplingResult->getDecision()) {
$span = $this->generateSpanInstance('', $context);
} else {
$span = $this->generateSpanInstance($name, $context, $sampler);
$span = $this->generateSpanInstance($name, $context, $sampler, $this->resource);

if ($span->isRecording()) {
$this->provider->getSpanProcessor()->onStart($span);
Expand Down Expand Up @@ -167,7 +168,10 @@ public function getSpans(): array
{
return $this->spans;
}

public function getResource(): ResourceInfo
{
return clone $this->resource;
}
public function endActiveSpan(?int $timestamp = null)
{
/**
Expand All @@ -182,7 +186,7 @@ public function endActiveSpan(?int $timestamp = null)
}
}

private function generateSpanInstance(string $name, API\SpanContext $context, Sampler $sampler = null): API\Span
private function generateSpanInstance(string $name, API\SpanContext $context, Sampler $sampler = null, ResourceInfo $resource = null): API\Span
{
$parent = null;

Expand All @@ -193,7 +197,7 @@ private function generateSpanInstance(string $name, API\SpanContext $context, Sa
$parent = $this->getActiveSpan()->getContext();
}

$span = new Span($name, $context, $parent, $sampler);
$span = new Span($name, $context, $parent, $sampler, $resource);
}
$this->spans[] = $span;

Expand Down
Loading

0 comments on commit 7a3fdcd

Please sign in to comment.