Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update semantic conventions to v1.19 #965

Merged
merged 8 commits into from
Apr 26, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 21 additions & 17 deletions script/semantic-conventions/semconv.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,81 +12,85 @@ SPEC_DIR="${ROOT_DIR}/var/opentelemetry-specification"
CODE_DIR="${ROOT_DIR}/src/SemConv"

# freeze the spec & generator tools versions to make SemanticAttributes generation reproducible
SEMCONV_VERSION=${SEMCONV_VERSION:=1.12.0}
SEMCONV_VERSION=${SEMCONV_VERSION:=1.19.0}
SPEC_VERSION=v$SEMCONV_VERSION
SCHEMA_URL=https://opentelemetry.io/schemas/$SEMCONV_VERSION
GENERATOR_VERSION=0.11.0
GENERATOR_VERSION=0.18.0

cd "${SCRIPT_DIR}" || exit

rm -rf "${SPEC_DIR}" || true
mkdir "${SPEC_DIR}"
cd "${SPEC_DIR}" || exit

git init
git init -b main
git remote add origin https://github.com/open-telemetry/opentelemetry-specification.git
git fetch origin "$SPEC_VERSION"
git reset --hard FETCH_HEAD

cd "${SCRIPT_DIR}" || exit

rm -rf "${CODE_DIR}" || true
mkdir -p "${CODE_DIR}"
git checkout HEAD "${CODE_DIR}/composer.json"
find "${CODE_DIR}" -name "*.php" -exec rm -f {} \;

# Trace
docker run --rm \
-v "${SPEC_DIR}/semantic_conventions/trace:/source" \
-v "${SPEC_DIR}/semantic_conventions:/source" \
-v "${SCRIPT_DIR}/templates:/templates" \
-v "${CODE_DIR}:/output" \
-u "${UID}" \
otel/semconvgen:$GENERATOR_VERSION \
--only span \
-f /source code \
--template /templates/Attributes.php.j2 \
--output "/output/TraceAttributes.php" \
-Dnamespace="OpenTelemetry\\SemConv" \
-Dclass="Trace" \
-DschemaUrl=$SCHEMA_URL

# Event
docker run --rm \
-v "${SPEC_DIR}/semantic_conventions/trace:/source" \
-v "${SPEC_DIR}/semantic_conventions:/source" \
-v "${SCRIPT_DIR}/templates:/templates" \
-v "${CODE_DIR}:/"output \
-v "${CODE_DIR}:/output" \
-u "${UID}" \
otel/semconvgen:$GENERATOR_VERSION \
--only event \
-f /source code \
--template /templates/AttributeValues.php.j2 \
--output "/output/TraceAttributeValues.php" \
--template /templates/Attributes.php.j2 \
--output "/output/EventAttributes.php" \
-Dnamespace="OpenTelemetry\\SemConv" \
-Dclass="Trace" \
-Dclass="Event" \
-DschemaUrl=$SCHEMA_URL


# Resource
docker run --rm \
-v "${SPEC_DIR}/semantic_conventions/resource:/source" \
-v "${SPEC_DIR}/semantic_conventions:/source" \
-v "${SCRIPT_DIR}/templates:/templates" \
-v "${CODE_DIR}:/output" \
-u "${UID}" \
otel/semconvgen:$GENERATOR_VERSION \
--only resource \
-f /source code \
--template /templates/Attributes.php.j2 \
--output "/output/ResourceAttributes.php" \
-Dnamespace="OpenTelemetry\\SemConv" \
-Dclass="Resource" \
-DschemaUrl=$SCHEMA_URL

# Metric
docker run --rm \
-v "${SPEC_DIR}/semantic_conventions/resource:/source" \
-v "${SPEC_DIR}/semantic_conventions:/source" \
-v "${SCRIPT_DIR}/templates:/templates" \
-v "${CODE_DIR}:/output" \
-u "${UID}" \
otel/semconvgen:$GENERATOR_VERSION \
--only metric \
-f /source code \
--template /templates/AttributeValues.php.j2 \
--output "/output/ResourceAttributeValues.php" \
--template /templates/Attributes.php.j2 \
--output "/output/MetricAttributes.php" \
-Dnamespace="OpenTelemetry\\SemConv" \
-Dclass="Resource" \
-Dclass="Metric" \
-DschemaUrl=$SCHEMA_URL

rm -rf "${SPEC_DIR}" || true
4 changes: 2 additions & 2 deletions src/API/Trace/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace OpenTelemetry\API\Trace;

use Closure;
use OpenTelemetry\SemConv\TraceAttributes;
use OpenTelemetry\SemConv\EventAttributes;
use Throwable;

/**
Expand Down Expand Up @@ -35,7 +35,7 @@ function trace(SpanInterface $span, Closure $closure, iterable $args = [])
return $c(...$a, ...($a = []));
} catch (Throwable $e) {
$s->setStatus(StatusCode::STATUS_ERROR, $e->getMessage());
$s->recordException($e, [TraceAttributes::EXCEPTION_ESCAPED => true]);
$s->recordException($e, [EventAttributes::EXCEPTION_ESCAPED => true]);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
$s->recordException($e, [EventAttributes::EXCEPTION_ESCAPED => true]);
$s->recordException($e, ['exception.escaped' => true]);

Can we drop the open-telemetry/sem-conv from the API-package to avoid breaking the API on sem-conv updates?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That's a good question. If we did drop it, what is the point of having the sem-conv package? I've noticed that other SIGs version their semantic convention package the same as the spec version (eg 1.19.0 in this case), and presumably then pin APIs etc to that version. I have a feeling that might be very painful if packages are dependant on different versions, though.

The other thing some SIGs are doing is moving all attributes into two classes: ResourceAttributes, and SemanticAttributes, the latter being "everything except resources". That should at least solve the problem of things moving about as the spec evolves.

Copy link
Contributor

Choose a reason for hiding this comment

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

IMO contrib/instrumentation packages are the main consumers of the sem-conv package.
(Java added removed attributes to the template to avoid a BC-break open-telemetry/opentelemetry-java@188210b, I like this approach because it makes pinning to a specific version in instrumentation packages obsolete when specifying the schema url as literal instead of relying on TraceAttributes::SCHEMA_URL.)

Regarding the API dependency: even if we resolve the BC-break I don't see a reason to keep the sem-conv dependency in the API package, we only use it for a small helper function. Iff ::recordException() / exception.escaped are changed in v1 in a breaking way, we should deprecate the trace() function. (The SDK uses literals for the other 'exception.' attributes in ::recordException() too / any breaking change would very likely also affect the SDK.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks for pointing that out - adding removed items to the template and marking them as @deprecated is a good idea. I've loosely copied java's deprecation pattern, and decided to remove the new semver classes I've added, since java hasn't done anything yet and I'd be more comfortable if they go first and we copy.


throw $e;
} finally {
Expand Down
108 changes: 108 additions & 0 deletions src/SemConv/EventAttributes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?php

// DO NOT EDIT, this is an Auto-generated file from script/semantic-convention/templates/Attributes.php.j2

declare(strict_types=1);

namespace OpenTelemetry\SemConv;

interface EventAttributes
{
/**
* The URL of the OpenTelemetry schema for these keys and values.
*/
public const SCHEMA_URL = 'https://opentelemetry.io/schemas/1.19.0';

/**
* The unique identifier of the feature flag.
*
* @example logo-color
*/
public const FEATURE_FLAG_KEY = 'feature_flag.key';

/**
* The name of the service provider that performs the flag evaluation.
*
* @example Flag Manager
*/
public const FEATURE_FLAG_PROVIDER_NAME = 'feature_flag.provider_name';

/**
* SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used.
*
* A semantic identifier, commonly referred to as a variant, provides a means
* for referring to a value without including the value itself. This can
* provide additional context for understanding the meaning behind a value.
* For example, the variant `red` maybe be used for the value `#c05543`.A stringified version of the value can be used in situations where a
* semantic identifier is unavailable. String representation of the value
* should be determined by the implementer.
*
* @example red
* @example true
* @example on
*/
public const FEATURE_FLAG_VARIANT = 'feature_flag.variant';

/**
* Whether this is a received or sent message.
*/
public const MESSAGE_TYPE = 'message.type';

/**
* MUST be calculated as two different counters starting from `1` one for sent messages and one for received message.
*
* This way we guarantee that the values will be consistent between different implementations.
*/
public const MESSAGE_ID = 'message.id';

/**
* Compressed size of the message in bytes.
*/
public const MESSAGE_COMPRESSED_SIZE = 'message.compressed_size';

/**
* Uncompressed size of the message in bytes.
*/
public const MESSAGE_UNCOMPRESSED_SIZE = 'message.uncompressed_size';

/**
* The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it.
*
* @example java.net.ConnectException
* @example OSError
*/
public const EXCEPTION_TYPE = 'exception.type';

/**
* The exception message.
*
* @example Division by zero
* @example Can't convert 'int' object to str implicitly
*/
public const EXCEPTION_MESSAGE = 'exception.message';

/**
* A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG.
*
* @example Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)
*/
public const EXCEPTION_STACKTRACE = 'exception.stacktrace';

/**
* SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span.
*
* An exception is considered to have escaped (or left) the scope of a span,
* if that span is ended while the exception is still logically &quot;in flight&quot;.
* This may be actually &quot;in flight&quot; in some languages (e.g. if the exception
* is passed to a Context manager's `__exit__` method in Python) but will
* usually be caught at the point of recording the exception in most languages.It is usually not possible to determine at the point where an exception is thrown
* whether it will escape the scope of a span.
* However, it is trivial to know that an exception
* will escape, if one checks for an active exception just before ending the span,
* as done in the example above.It follows that an exception may still escape the scope of the span
* even if the `exception.escaped` attribute was not set or set to false,
* since the event might have been recorded at a time where it was not
* clear whether the exception will escape.
*/
public const EXCEPTION_ESCAPED = 'exception.escaped';
}
118 changes: 118 additions & 0 deletions src/SemConv/MetricAttributes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?php

// DO NOT EDIT, this is an Auto-generated file from script/semantic-convention/templates/Attributes.php.j2

declare(strict_types=1);

namespace OpenTelemetry\SemConv;

interface MetricAttributes
{
/**
* The URL of the OpenTelemetry schema for these keys and values.
*/
public const SCHEMA_URL = 'https://opentelemetry.io/schemas/1.19.0';

/**
* The URI scheme identifying the used protocol.
*
* @example http
* @example https
*/
public const HTTP_SCHEME = 'http.scheme';

/**
* The matched route (path template in the format used by the respective server framework). See note below.
*
* MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it.
* SHOULD include the application root if there is one.
*
* @example /users/:userID?
* @example {controller}/{action}/{id?}
*/
public const HTTP_ROUTE = 'http.route';

/**
* Name of the local HTTP server that received the request.
*
* Determined by using the first of the following that applies<ul>
* <li>The primary server name of the matched virtual host. MUST only
* include host identifier.</li>
* <li>Host identifier of the request target
* if it's sent in absolute-form.</li>
* <li>Host identifier of the `Host` header</li>
* </ul>
* SHOULD NOT be set if only IP address is available and capturing name would require a reverse DNS lookup.
*
* @example localhost
*/
public const NET_HOST_NAME = 'net.host.name';

/**
* Port of the local HTTP server that received the request.
*
* Determined by using the first of the following that applies<ul>
* <li>Port identifier of the primary server host of the matched virtual host.</li>
* <li>Port identifier of the request target
* if it's sent in absolute-form.</li>
* <li>Port identifier of the `Host` header</li>
* </ul>
*
* @example 8080
*/
public const NET_HOST_PORT = 'net.host.port';

/**
* HTTP request method.
*
* @example GET
* @example POST
* @example HEAD
*/
public const HTTP_METHOD = 'http.method';

/**
* HTTP response status code.
*
* @example 200
*/
public const HTTP_STATUS_CODE = 'http.status_code';

/**
* Kind of HTTP protocol used.
*/
public const HTTP_FLAVOR = 'http.flavor';

/**
* Host identifier of the &quot;URI origin&quot; HTTP request is sent to.
*
* Determined by using the first of the following that applies<ul>
* <li>Host identifier of the request target
* if it's sent in absolute-form</li>
* <li>Host identifier of the `Host` header</li>
* </ul>
* SHOULD NOT be set if capturing it would require an extra DNS lookup.
*
* @example example.com
*/
public const NET_PEER_NAME = 'net.peer.name';

/**
* Port identifier of the &quot;URI origin&quot; HTTP request is sent to.
*
* When request target is absolute URI, `net.peer.name` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier.
*
* @example 80
* @example 8080
* @example 443
*/
public const NET_PEER_PORT = 'net.peer.port';

/**
* Remote socket peer address: IPv4 or IPv6 for internet protocols, path for local communication, etc.
*
* @example 127.0.0.1
* @example /tmp/mysql.sock
*/
public const NET_SOCK_PEER_ADDR = 'net.sock.peer.addr';
}
10 changes: 10 additions & 0 deletions src/SemConv/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
# OpenTelemetry Semantic Conventions

Common semantic conventions used by OpenTelemetry implementations across all languages.

See https://opentelemetry.io/docs/concepts/semantic-conventions/.

## Installation

```shell
composer require open-telemetry/sem-conv
```
Loading