use weaver to generate semconv (#1398)

update semconv generation to use the new tooling. This is fairly close to a 1:1 of what we have now,
although I noted a couple of TODOs which we might consider in future to align with what Java is
doing: split attribute up into file-per-type, and split stable/unstable.
This commit is contained in:
Brett McBride 2024-10-17 20:57:37 +11:00 committed by GitHub
parent 01d0fd3618
commit d2b15077df
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 1383 additions and 2657 deletions

View File

@ -22,7 +22,7 @@ $resource = ResourceInfoFactory::defaultResource()->merge(ResourceInfo::create(A
ResourceAttributes::SERVICE_NAME => 'bar',
ResourceAttributes::SERVICE_INSTANCE_ID => 1,
ResourceAttributes::SERVICE_VERSION => '0.1',
ResourceAttributes::DEPLOYMENT_ENVIRONMENT => 'development',
ResourceAttributes::DEPLOYMENT_ENVIRONMENT_NAME => 'development',
])));
$tracerProvider = new TracerProvider(

View File

@ -9,20 +9,18 @@
# Source repositories:
# - https://github.com/open-telemetry/semantic-conventions/releases
# - https://github.com/open-telemetry/build-tools/releases
set -e
set -ex
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
ROOT_DIR="${SCRIPT_DIR}/../../"
ROOT_DIR="${SCRIPT_DIR}/../.."
SPEC_DIR="${ROOT_DIR}/var/semantic-conventions"
CODE_DIR="${ROOT_DIR}/src/SemConv"
# freeze the spec & generator tools versions to make SemanticAttributes generation reproducible
SEMCONV_VERSION=${SEMCONV_VERSION:=1.27.0}
SEMCONV_VERSION=1.27.0
SPEC_VERSION=v$SEMCONV_VERSION
SCHEMA_URL=https://opentelemetry.io/schemas/$SEMCONV_VERSION
GENERATOR_VERSION=0.25.0
cd "${SCRIPT_DIR}"
OTEL_WEAVER_IMG_VERSION=v0.10.0
rm -rf "${SPEC_DIR}"
mkdir "${SPEC_DIR}"
@ -38,68 +36,18 @@ cd "${SCRIPT_DIR}"
mkdir -p "${CODE_DIR}"
find "${CODE_DIR}" -name "*.php" ! -name "Version.php" -exec rm -f {} \;
# Trace
docker run --rm \
-v "${SPEC_DIR}/model:/source" \
-v "${SCRIPT_DIR}/templates:/templates" \
-v "${CODE_DIR}:/output" \
-u "${UID}" \
otel/semconvgen:$GENERATOR_VERSION \
--only span,event,attribute_group \
--yaml-root /source \
code \
--template /templates/Attributes.php.j2 \
--output "/output/TraceAttributes.php" \
-Dnamespace="OpenTelemetry\\SemConv" \
-Dclass="Trace" \
-DschemaUrl=$SCHEMA_URL
echo "${SCHEMA_URL}" > ${SCRIPT_DIR}/templates/registry/php/version.txt
# Resource
docker run --rm \
-v "${SPEC_DIR}/model:/source" \
-v "${SCRIPT_DIR}/templates:/templates" \
-v "${CODE_DIR}:/output" \
-u "${UID}" \
otel/semconvgen:$GENERATOR_VERSION \
--only resource \
--yaml-root /source \
code \
--template /templates/Attributes.php.j2 \
--output "/output/ResourceAttributes.php" \
-Dnamespace="OpenTelemetry\\SemConv" \
-Dclass="Resource" \
-DschemaUrl=$SCHEMA_URL
generate () {
docker run --rm \
-v "${SPEC_DIR}/model:/home/weaver/model" \
-v "${SCRIPT_DIR}/templates:/home/weaver/templates" \
-v "${CODE_DIR}:/home/weaver/output" \
-u "1000" \
otel/weaver:$OTEL_WEAVER_IMG_VERSION \
registry generate php
}
# Trace attribute values
docker run --rm \
-v "${SPEC_DIR}/model:/source" \
-v "${SCRIPT_DIR}/templates:/templates" \
-v "${CODE_DIR}:/output" \
-u "${UID}" \
otel/semconvgen:$GENERATOR_VERSION \
--only span,event,attribute_group \
--yaml-root /source \
code \
--template /templates/AttributeValues.php.j2 \
--output "/output/TraceAttributeValues.php" \
-Dnamespace="OpenTelemetry\\SemConv" \
-Dclass="Trace" \
-DschemaUrl=$SCHEMA_URL
# Resource attribute values
docker run --rm \
-v "${SPEC_DIR}/model:/source" \
-v "${SCRIPT_DIR}/templates:/templates" \
-v "${CODE_DIR}:/output" \
-u "${UID}" \
otel/semconvgen:$GENERATOR_VERSION \
--only resource \
--yaml-root /source \
code \
--template /templates/AttributeValues.php.j2 \
--output "/output/ResourceAttributeValues.php" \
-Dnamespace="OpenTelemetry\\SemConv" \
-Dclass="Resource" \
-DschemaUrl=$SCHEMA_URL
rm -rf "${SPEC_DIR}"
#TODO split stable from experimental
#TODO one file per group? (see java's implementation)
generate

View File

@ -1,42 +0,0 @@
<?php
// DO NOT EDIT, this is an Auto-generated file from script/semantic-convention{{template}}
declare(strict_types=1);
namespace {{ namespace }};
interface {{ class }}AttributeValues
{
/**
* The URL of the OpenTelemetry schema for these keys and values.
*/
public const SCHEMA_URL = '{{schemaUrl}}';
{%- for attribute in attributes | unique(attribute="fqn") | sort(attribute="fqn") %}
{%- if attribute.attr_type.members %}
{%- for member in attribute.attr_type.members %}
{%- if member.brief %}
/**
* {% filter escape %}{{member.brief | to_doc_brief}}{% endfilter %}
*
* @see {{ class }}Attributes::{{ attribute.fqn | to_const_name }}
{%- if member.note %}
*
* {{ member.note | render_markdown(code="<code>{0}</code>", paragraph="{0}") | regex_replace(pattern="\n", replace="\n * ") }}
{%- endif %}
{%- if member | is_deprecated %}
* @deprecated {{ member.deprecated | to_doc_brief }}.
{%- endif %}
*/
{%- endif %}
public const {{ attribute.fqn | to_const_name }}_{{ member.member_id | to_const_name }} = '{{ member.value }}';
{% if not loop.last %}{# blank line #}{% endif %}
{%- endfor -%}
{%- endif -%}
{% if not loop.last %}{# blank line #}{% endif %}
{%- endfor -%}
{# add our own deprecations for moved/removed values, so we don't break things #}
{% include class|lower + "_values_deprecations.php.partial" ignore missing without context %}
}
{# blank line #}

View File

@ -1,39 +0,0 @@
<?php
// DO NOT EDIT, this is an Auto-generated file from script/semantic-convention{{template}}
declare(strict_types=1);
namespace {{ namespace }};
interface {{ class }}Attributes
{
/**
* The URL of the OpenTelemetry schema for these keys and values.
*/
public const SCHEMA_URL = '{{schemaUrl}}';
{% for attribute in attributes | unique(attribute="fqn") | sort(attribute="fqn") %}
/**
* {{ attribute.brief | render_markdown(code="`{0}`", paragraph="{0}", link="{1}") | to_doc_brief | regex_replace(pattern="\n", replace="\n * ") }}.
{%- if attribute.note %}
*
* {{ attribute.note | render_markdown(code="`{0}`", paragraph="{0}", link="{1}") | trim("\n")| regex_replace(pattern="\n", replace="\n * ") }}
{%- endif %}
{%- if attribute | is_deprecated %}
*
* @deprecated {{ attribute.deprecated | to_doc_brief }}.
{%- endif %}
{%- if attribute.examples %}
*
{%- for example in attribute.examples if example %}
* @example {{ example }}
{%- endfor %}
{%- endif %}
*/
public const {{ attribute.fqn | to_const_name }} = '{{ attribute.fqn }}';
{% if not loop.last %}{# blank line #}{% endif %}
{%- endfor -%}
{# add our own deprecations for moved/removed attributes, so we don't break things #}
{% include class|lower + "_deprecations.php.partial" ignore missing without context %}
}
{# blank line #}

View File

@ -0,0 +1 @@
version.txt

View File

@ -0,0 +1,30 @@
{% import 'common.j2' as c %}
<?php
// DO NOT EDIT, this is an Auto-generated file from script/semantic-conventions/
declare(strict_types=1);
namespace OpenTelemetry\SemConv;
interface TraceAttributeValues
{
/**
* The URL of the OpenTelemetry schema for these values.
*/
public const SCHEMA_URL = '{% include "version.txt" without context %}';
{% for section in ctx %}
{% for attribute in section.attributes %}
{% if "members" in attribute.type and attribute.type.members | length > 0 %}
{% for member in attribute.type.members %}
{%- set see = "@see TraceAttributes::" ~ c.attribute_name(attribute) -%}
{%- set deprecated = "@deprecated " ~ member.deprecated if member.deprecated != none else "" -%}
{{ [member.brief or member.id, '\n', see, deprecated] | comment(indent=4) | replace(' \n', '\n') }}
public const {{ c.attribute_name(attribute) + "_" + c.attribute_value_name(member) }} = '{{ member.value }}';
{% endfor %}
{% endif %}
{% endfor %}
{% endfor %}
}
{# blank line #}

View File

@ -0,0 +1,33 @@
{% import 'common.j2' as c %}
<?php
// DO NOT EDIT, this is an Auto-generated file from script/semantic-conventions
declare(strict_types=1);
namespace OpenTelemetry\SemConv;
interface TraceAttributes
{
/**
* The URL of the OpenTelemetry schema for these keys and values.
*/
public const SCHEMA_URL = '{% include "version.txt" without context %}';
{% for section in ctx %}
{#{ debug(section) }#}
{% for attribute in section.attributes %}
{% if attribute.name not in section.excluded_attributes %}
{%- if attribute is deprecated %}
{%- set deprecated_phpdoc = "@deprecated " ~ attribute.deprecated -%}
{% else %}
{% set deprecated_phpdoc = "" %}
{%- endif -%}
{{ [attribute.brief, concat_if(attribute.note), deprecated_phpdoc] | comment(indent=4) | replace(' \n', '\n') }}
public const {{ c.attribute_name(attribute) }} = '{{ attribute.name }}';
{% endif %}
{% endfor %}
{% endfor %}
}
{# blank line #}

View File

@ -0,0 +1,34 @@
{% import 'common.j2' as c %}
<?php
// DO NOT EDIT, this is an Auto-generated file from script/semantic-conventions
declare(strict_types=1);
namespace OpenTelemetry\SemConv;
interface ResourceAttributeValues
{
/**
* The URL of the OpenTelemetry schema for these values.
*/
public const SCHEMA_URL = '{% include "version.txt" without context %}';
{% for attribute in ctx %}
{% if "members" in attribute.type and attribute.type.members | length > 0 %}
{% for member in attribute.type.members %}
/**
* {{ member.brief or member.id }}
*
* @see ResourceAttributes::{{ c.attribute_name(attribute) }}
{% if attribute.deprecated %}
* @deprecated {{ attribute.deprecated }}
{% endif %}
*/
public const {{ c.attribute_name(attribute) + "_" + c.attribute_value_name(member) }} = '{{ member.value }}';
{% endfor %}
{% endif %}
{% endfor %}
}
{# blank line #}

View File

@ -0,0 +1,26 @@
{% import 'common.j2' as c %}
<?php
// DO NOT EDIT, this is an Auto-generated file from script/semantic-conventions
declare(strict_types=1);
namespace OpenTelemetry\SemConv;
interface ResourceAttributes
{
/**
* The URL of the OpenTelemetry schema for these keys and values.
*/
public const SCHEMA_URL = '{% include "version.txt" without context %}';
{% for attribute in ctx %}
{%- if attribute is deprecated %}
{%- set deprecated_phpdoc = "@deprecated " ~ attribute.deprecated -%}
{%- endif -%}
{{ [attribute.brief, concat_if(attribute.note), deprecated_phpdoc] | comment(indent=4) | replace(' \n', '\n') }}
public const {{ c.attribute_name(attribute) }} = '{{ attribute.name }}';
{% endfor %}
}
{# blank line #}

View File

@ -0,0 +1,36 @@
{%- macro file_header() -%}
# Copyright The OpenTelemetry Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
{% endmacro -%}
{%- macro to_const_name(attr_name) -%}
{{attr_name | upper | replace('.', '_')}}
{%- endmacro %}
{%- macro print_value(type, value) -%}
{%- if type == "string" -%}"{{value}}"{%-else-%}{{value}}{%-endif-%}
{%- endmacro -%}
{%- macro attribute_name(attribute) -%}
{{to_const_name(attribute.name)}}
{%- endmacro -%}
{%- macro attribute_value_name(member) -%}
{{to_const_name(member.id)}}
{%- endmacro -%}
{%- macro attribute_stability(attribute) -%}
{% if attribute.deprecated %}deprecated{% else %}{{attribute.stability}}{%endif%}
{%- endmacro -%}

View File

@ -0,0 +1,71 @@
params:
# excluded namespaces will not be generated
# this behavior is fully controlled by jinja templates
# TODO exclude more namespaces, eg: ios, aspnetcore, signalr, android, dotnet, jvm, kestrel, browser, device, ...
excluded_namespaces: [cloudfoundry, dotnet, hw, nodejs, profile]
# excluded attributes will be commented out in the generated code
# this behavior is fully controlled by jinja templates
excluded_attributes: ["messaging.client_id"]
text_maps:
php_types:
int: int
double: int
boolean: bool
string: string
string[]: string[]
template[string]: string
template[string[]]: string[]
templates:
- pattern: Attributes.php.j2
filter: >
semconv_grouped_attributes({
"exclude_root_namespace": $excluded_namespaces,
"exclude_stability": [],
}) | map({
root_namespace: .root_namespace,
attributes: .attributes,
excluded_attributes: $excluded_attributes
})
application_mode: single
file_name: "TraceAttributes.php"
- pattern: AttributeValues.php.j2
filter: >
semconv_grouped_attributes({
"exclude_root_namespace": $excluded_namespaces,
"exclude_stability": [],
})
application_mode: single
file_name: "TraceAttributeValues.php"
- pattern: ResourceAttributes.php.j2
filter: >
semconv_signal("resource"; {})
| map(.attributes[])
| group_by(.name)
| map(.[-1])
application_mode: single
file_name: "ResourceAttributes.php"
- pattern: ResourceAttributeValues.php.j2
filter: >
semconv_signal("resource"; {})
| map(.attributes[])
| group_by(.name)
| map(.[-1])
application_mode: single
file_name: "ResourceAttributeValues.php"
whitespace_control:
trim_blocks: true
lstrip_blocks: true
comment_formats:
php:
format: markdown
header: " /**"
prefix: " * "
footer: " */"
trim: true
remove_trailing_dots: false
default_comment_format: php

View File

@ -1,34 +0,0 @@
/**
* @deprecated Use USER_AGENT_ORIGINAL
*/
public const BROWSER_USER_AGENT = 'browser.user_agent';
/**
* @deprecated Use CLOUD_RESOURCE_ID
*/
public const FAAS_ID = 'faas.id';
/**
* @deprecated Use TELEMETRY_DISTRO_VERSION
*/
public const TELEMETRY_AUTO_VERSION = 'telemetry.auto.version';
/**
* @deprecated Use CONTAINER_IMAGE_TAGS
*/
public const CONTAINER_IMAGE_TAG = 'container.image.tag';
/**
* @deprecated Use `otel.scope.name`
*/
public const OTEL_LIBRARY_NAME = 'otel.library.name';
/**
* @deprecated Use `otel.scope.version`
*/
public const OTEL_LIBRARY_VERSION = 'otel.library.version';
/**
* @deprecated Use `deployment.environment.name`
*/
public const DEPLOYMENT_ENVIRONMENT = 'deployment.environment';

View File

@ -1,179 +0,0 @@
/**
* @deprecated
*/
public const FAAS_EXECUTION = 'faas.execution';
/**
* @deprecated
*/
public const HTTP_RETRY_COUNT = 'http.retry_count';
/**
* @deprecated
*/
public const MESSAGING_CONVERSATION_ID = 'messaging.conversation_id';
/**
* @deprecated
*/
public const MESSAGING_DESTINATION = 'messaging.destination';
/**
* @deprecated
*/
public const MESSAGING_KAFKA_PARTITION = 'messaging.kafka.partition';
/**
* @deprecated
*/
public const MESSAGING_KAFKA_TOMBSTONE = 'messaging.kafka.tombstone';
/**
* @deprecated
*/
public const MESSAGING_PROTOCOL = 'messaging.protocol';
/**
* @deprecated
*/
public const MESSAGING_PROTOCOL_VERSION = 'messaging.protocol_version';
/**
* @deprecated
*/
public const MESSAGING_RABBITMQ_ROUTING_KEY = 'messaging.rabbitmq.routing_key';
/**
* @deprecated
*/
public const MESSAGING_TEMP_DESTINATION = 'messaging.temp_destination';
/**
* @deprecated
*/
public const MESSAGING_URL = 'messaging.url';
/**
* @deprecated
*/
public const MESSAGING_CONSUMER_ID = 'messaging.consumer.id';
/**
* @deprecated
*/
public const MESSAGING_DESTINATION_KIND = 'messaging.destination.kind';
/**
* @deprecated
*/
public const MESSAGING_KAFKA_CLIENT_ID = 'messaging.kafka.client_id';
/**
* @deprecated
*/
public const MESSAGING_KAFKA_SOURCE_PARTITION = 'messaging.kafka.source.partition';
/**
* @deprecated
*/
public const MESSAGING_MESSAGE_PAYLOAD_COMPRESSED_SIZE_BYTES = 'messaging.message.payload_compressed_size_bytes';
/**
* @deprecated
*/
public const MESSAGING_MESSAGE_PAYLOAD_SIZE_BYTES = 'messaging.message.payload_size_bytes';
/**
* @deprecated
*/
public const MESSAGING_ROCKETMQ_CLIENT_ID = 'messaging.rocketmq.client_id';
/**
* @deprecated
*/
public const MESSAGING_SOURCE_ANONYMOUS = 'messaging.source.anonymous';
/**
* @deprecated
*/
public const MESSAGING_SOURCE_KIND = 'messaging.source.kind';
/**
* @deprecated
*/
public const MESSAGING_SOURCE_NAME = 'messaging.source.name';
/**
* @deprecated
*/
public const MESSAGING_SOURCE_TEMPLATE = 'messaging.source.template';
/**
* @deprecated
*/
public const MESSAGING_SOURCE_TEMPORARY = 'messaging.source.temporary';
/**
* @deprecated
*/
public const NET_APP_PROTOCOL_NAME = 'net.app.protocol.name';
/**
* @deprecated
*/
public const NET_APP_PROTOCOL_VERSION = 'net.app.protocol.version';
/**
* @deprecated
*/
public const NET_HOST_CARRIER_ICC = 'net.host.carrier.icc';
/**
* @deprecated
*/
public const NET_HOST_CARRIER_MCC = 'net.host.carrier.mcc';
/**
* @deprecated
*/
public const NET_HOST_CARRIER_MNC = 'net.host.carrier.mnc';
/**
* @deprecated
*/
public const NET_HOST_CARRIER_NAME = 'net.host.carrier.name';
/**
* @deprecated
*/
public const NET_HOST_CONNECTION_SUBTYPE = 'net.host.connection.subtype';
/**
* @deprecated
*/
public const NET_HOST_CONNECTION_TYPE = 'net.host.connection.type';
/**
* @deprecated
*/
public const HTTP_RESEND_COUNT = 'http.resend_count';
/**
* @deprecated
*/
public const THREAD_DAEMON = 'thread.daemon';
/**
* @deprecated
*/
public const EVENT_DOMAIN = 'event.domain';
/**
* @deprecated
*/
public const SYSTEM_DISK_DIRECTION = 'system.disk.direction';
/**
* @deprecated
*/
public const SYSTEM_NETWORK_DIRECTION = 'system.network.direction';

View File

@ -1,24 +0,0 @@
/**
* @deprecated Use `messaging.operation.type.publish`
*/
public const MESSAGING_OPERATION_PUBLISH = 'publish';
/**
* @deprecated Use `messaging.operation.type.create`
*/
public const MESSAGING_OPERATION_CREATE = 'create';
/**
* @deprecated Use `messaging.operation.type.receive`
*/
public const MESSAGING_OPERATION_RECEIVE = 'receive';
/**
* @deprecated Use `messaging.operation.type.deliver`
*/
public const MESSAGING_OPERATION_DELIVER = 'process';
/**
* @deprecated Use `messaging.operation.type.settle`
*/
public const MESSAGING_OPERATION_SETTLE = 'settle';

View File

@ -1,6 +1,6 @@
<?php
// DO NOT EDIT, this is an Auto-generated file from script/semantic-convention/templates/AttributeValues.php.j2
// DO NOT EDIT, this is an Auto-generated file from script/semantic-conventions
declare(strict_types=1);
@ -9,9 +9,10 @@ namespace OpenTelemetry\SemConv;
interface ResourceAttributeValues
{
/**
* The URL of the OpenTelemetry schema for these keys and values.
* The URL of the OpenTelemetry schema for these values.
*/
public const SCHEMA_URL = 'https://opentelemetry.io/schemas/1.27.0';
/**
* ec2
*

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff