1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-01-01 22:09:57 +02:00

Use Weaver to generate semconv

Use new workflow to generate v1.27.0.
This commit is contained in:
Josh Suereth 2024-09-05 22:30:17 -04:00 committed by Tyler Yahn
parent bf6a7e1e85
commit dab26e9d2c
No known key found for this signature in database
GPG Key ID: 46B0F3E1A8B1BA5A
9 changed files with 13195 additions and 10077 deletions

View File

@ -99,6 +99,12 @@ $(PYTOOLS)/%: $(PYTOOLS)
CODESPELL = $(PYTOOLS)/codespell
$(CODESPELL): PACKAGE=codespell
# Definitions for semconvgen
DOCKER_USER=$(shell id -u):$(shell id -g)
# TODO - Pull docker image versions from rennovate-friendly source, e.g.
# $(shell cat dependencies.Dockerfile | awk '$$4=="weaver" {print $$2}')
WEAVER_CONTAINER=otel/weaver:v0.10.0
# Generate
.PHONY: generate
@ -257,11 +263,25 @@ check-clean-work-tree:
SEMCONVPKG ?= "semconv/"
.PHONY: semconv-generate
semconv-generate: $(SEMCONVGEN) $(SEMCONVKIT)
semconv-generate: $(SEMCONVKIT)
[ "$(TAG)" ] || ( echo "TAG unset: missing opentelemetry semantic-conventions tag"; exit 1 )
[ "$(OTEL_SEMCONV_REPO)" ] || ( echo "OTEL_SEMCONV_REPO unset: missing path to opentelemetry semantic-conventions repo"; exit 1 )
$(SEMCONVGEN) -i "$(OTEL_SEMCONV_REPO)/model/." --only=attribute_group -p conventionType=trace -f attribute_group.go -z "$(SEMCONVPKG)/capitalizations.txt" -t "$(SEMCONVPKG)/template.j2" -s "$(TAG)"
$(SEMCONVGEN) -i "$(OTEL_SEMCONV_REPO)/model/." --only=metric -f metric.go -t "$(SEMCONVPKG)/metric_template.j2" -s "$(TAG)"
# Ensure the target directory for source code is available.
mkdir -p $(PWD)/$(SEMCONVPKG)/${TAG}
# Note: We mount a home directory for downloading/storing the semconv repository.
# Weaver will automatically clean the cache when finished, but the directories will remain.
mkdir -p ~/.weaver
docker run --rm \
-u $(DOCKER_USER) \
--env HOME=/tmp/weaver \
--mount 'type=bind,source=$(PWD)/semconv,target=/home/weaver/templates/registry/go,readonly' \
--mount 'type=bind,source=$(PWD)/semconv/${TAG},target=/home/weaver/target' \
--mount 'type=bind,source=$(HOME)/.weaver,target=/tmp/weaver/.weaver' \
$(WEAVER_CONTAINER) registry generate \
--registry=https://github.com/open-telemetry/semantic-conventions.git@$(TAG)#model \
--templates=/home/weaver/templates \
--param tag=$(TAG) \
go \
/home/weaver/target
$(SEMCONVKIT) -output "$(SEMCONVPKG)/$(TAG)" -tag "$(TAG)"
.PHONY: gorelease

View File

@ -0,0 +1,81 @@
{% import 'helpers.j2' as h %}
{# TODO - REQUIREMNET LEVEL SHOULD NOT BE USED IN ATTRIBUTE REGISTRY #}
{%- macro requirement_level_doc(attr) -%}
{%- if attr.requirement_level == "required" -%}
Requirement Level: Required
{% elif attr.requirement_level.conditionally_required %}
Requirement Level: Conditionally Required - {{ attr.requirement_level.conditionally_required }}
{%- elif attr.requirement_level == "recommended" -%}
Requirement Level: Recommended
{% elif attr.requirement_level.recommended %}
Requirement Level: Recommended - {{ attr.requirement_level.recommended }}
{%- else -%}
Requirement Level: Optional
{%- endif %}
{%- endmacro -%}
{%- macro deprecated_doc(attr) -%}
{% if attr is deprecated %}Deprecated: {{ attr.deprecated }}{% endif %}
{%- endmacro -%}
{%- macro notes_doc(attr) -%}
{% if attr.note %}Note: {{ attr.note }}{% endif %}
{%- endmacro -%}
{%- macro examples_doc(attr) -%}
{%- if attr.examples is iterable %}
Examples: {{ attr.examples | pprint | trim("[]") }}
{%- endif -%}
{%- endmacro -%}
{%- macro keydoc(attr) -%}
{{ attr.brief }}
Stability: {{ attr.stability | title }}
{% if attr is enum %}Type: Enum{% else %}Type: {{ attr.type }}{% endif %}
{{ deprecated_doc(attr) }}
{{ examples_doc(attr) }}
{{ notes_doc(attr) }}
{%- endmacro -%}
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
// Code generated from semantic convention specification. DO NOT EDIT.
package semconv // import "go.opentelemetry.io/otel/semconv/{{params.tag}}"
import "go.opentelemetry.io/otel/attribute"
{% for group in ctx %}
{% if group.attributes | length > 0 %}
{# TODO - we're grouping by registry namespace, not attribute group, so we lose group docs #}
{{ ["Namespace: " ~ group.root_namespace] | comment(format="go") }}
const (
{% for attribute in group.attributes %}
{%- if not attribute.type is template_type %}{# TODO - Go does not handle template attributes yet!!! #}
{{ keydoc(attribute) | comment(format="go_1tab") }}
{{h.to_go_name(attribute.name)}}Key = attribute.Key("{{attribute.name}}")
{%- endif %}
{%- endfor %}
)
{# Render a construction function #}
{% for attribute in group.attributes %}
{# TODO - Go does not handle template attributes yet!!! #}
{%- if not attribute.type is template_type %}
{{ [h.to_go_name(attribute.name) ~ " returns an attribute KeyValue conforming to the \"" ~ attribute.name ~"\"semantic conventions."] | comment(format="go") }}
{{ ["It represents the " ~ attribute.brief] | comment(format="go") }}
func {{h.to_go_name(attribute.name)}}(val {{attribute.type | instantiated_type | map_text("attribute_type_value")}}) attribute.KeyValue {
return {{h.to_go_name(attribute.name)}}Key.{{attribute.type | instantiated_type | map_text("attribute_type_method")}}(val)
}
{%- endif %}
{% endfor %}
{# Render values for enums #}
{%- for attribute in group.attributes %}
{%- if attribute is enum %}
{{ ["Enum values for " ~ attribute.name] | comment(format="go") }}
var (
{% for value in attribute.type.members %}
{{ [value.brief or value.id, "Stability: " ~ value.stability] | comment(format="go_1tab") }}
{%- if value.deprecated %}{{ value.deprecated | comment(format="go_1tab") }}{% endif %}
{{h.to_go_name(attribute.name ~ "." ~ value.id)}} = {{ h.to_go_name(attribute.name) }}Key.{{attribute.type | instantiated_type | map_text("attribute_type_method")}}({{ value.value | print_member_value }})
{%- endfor %}
)
{%- endif %}
{% endfor %}
{%- endif %}
{% endfor %}

3
semconv/helpers.j2 Normal file
View File

@ -0,0 +1,3 @@
{%- macro to_go_name(fqn) -%}
{{ fqn | title_case | replace(" ", "") | acronym }}
{%- endmacro -%}

41
semconv/metric.go.j2 Normal file
View File

@ -0,0 +1,41 @@
{% import 'helpers.j2' as h %}
{%- macro it_reps(brief) -%}
It represents {% if brief[:2] == "A " or brief[:3] == "An " or brief[:4] == "The " -%}
{{ brief[0]|lower }}{{ brief[1:] }}
{%- else -%}
the {{ brief[0]|lower }}{{ brief[1:] }}
{%- endif -%}
{%- endmacro -%}
{%- macro keydoc(metric) -%}
{%- if not metric.brief -%}
{{ h.to_go_name(metric.metric_name) }} is the metric conforming to the "{{ metric.metric_name}}" semantic conventions.
{%- else -%}
{{ h.to_go_name(metric.metric_name) }} is the metric conforming to the "{{ metric.metric_name}}" semantic conventions. {{ it_reps(metric.brief)|trim(".") }}.
{%- endif %}
{%- endmacro -%}
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
// Code generated from semantic convention specification. DO NOT EDIT.
package semconv // import "go.opentelemetry.io/otel/semconv/{{params.tag}}"
const (
{% for metric in ctx %}
{{ keydoc(metric) | comment(indent=2) }}
// Instrument: {{ metric.instrument }}
// Unit: {{ metric.unit }}
// Stability: {{ metric.stability }}
{%- if metric is deprecated %}
// Deprecated: {{ metric.deprecated }}
{%- endif %}
{%- if not metric.brief %}
// NOTE: The description (brief) for this metric is not defined in the semantic-conventions repository.
{%- endif %}
{{ h.to_go_name(metric.metric_name) }}Name = "{{ metric.metric_name }}"
{{ h.to_go_name(metric.metric_name) }}Unit = "{{ metric.unit }}"
{%- if metric.brief %}
{{ h.to_go_name(metric.metric_name) }}Description = "{{ metric.brief | trim }}"
{%- endif %}
{% endfor %}
)

View File

@ -1,49 +0,0 @@
{%- macro to_go_name(fqn) -%}
{{fqn | replace(".", " ") | replace("_", " ") | title | replace(" ", "")}}
{%- endmacro -%}
{%- macro it_reps(brief) -%}
It represents {% if brief[:2] == "A " or brief[:3] == "An " or brief[:4] == "The " -%}
{{ brief[0]|lower }}{{ brief[1:] }}
{%- else -%}
the {{ brief[0]|lower }}{{ brief[1:] }}
{%- endif -%}
{%- endmacro -%}
{%- macro keydoc(metric) -%}
{%- if metric.stability|string() == "StabilityLevel.DEPRECATED" or not metric.brief-%}
{{ to_go_name(metric.metric_name) }} is the metric conforming to the "{{ metric.metric_name}}" semantic conventions.
{%- else -%}
{{ to_go_name(metric.metric_name) }} is the metric conforming to the "{{ metric.metric_name}}" semantic conventions. {{ it_reps(metric.brief)|trim(".") }}.
{%- endif %}
{%- endmacro -%}
{%- macro format_stability(stability) -%}
{%- if not stability -%}
Experimental
{%- else -%}
{{ stability|replace("StabilityLevel.", "")|capitalize() }}
{%- endif %}
{%- endmacro -%}
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
// Code generated from semantic convention specification. DO NOT EDIT.
package semconv // import [[IMPORTPATH]]
const (
{% for id in semconvs %}
{%- if semconvs[id].GROUP_TYPE_NAME == 'metric' %}{% set metric = semconvs[id] %}
// {{ keydoc(metric) | wordwrap(76, break_long_words=false, break_on_hyphens=false, wrapstring="\n// ") }}
// Instrument: {{ metric.instrument }}
// Unit: {{ metric.unit }}
// Stability: {{ format_stability(metric.stability) }}
{%- if not metric.brief %}
// NOTE: The description (brief) for this metric is not defined in the semantic-conventions repository.
{%- endif %}
{{to_go_name(metric.metric_name)}}Name = "{{metric.metric_name}}"
{{to_go_name(metric.metric_name)}}Unit = "{{metric.unit}}"
{%- if metric.brief %}
{{to_go_name(metric.metric_name)}}Description = "{{metric.brief}}"
{%- endif %}
{%- endif %}
{% endfor %}
)

View File

@ -1,145 +0,0 @@
{%- macro keyval_method(type) -%}
{%- if type == "string" -%}
String
{%- elif type == "string[]" -%}
StringSlice
{%- elif type == "int" -%}
Int
{%- elif type == "int[]" -%}
IntSlice
{%- elif type == "double" -%}
Float64
{%- elif type == "double[]" -%}
Float64Slice
{%- elif type == "boolean" -%}
Bool
{%- elif type == "boolean[]" -%}
BoolSlice
{%- endif -%}
{%- endmacro -%}
{%- macro to_go_attr_type(type, val) -%}
{{keyval_method(type)}}({% if type == "string" %}"{{val}}"{% else %}{{val}}{% endif %})
{%- endmacro -%}
{%- macro to_go_name(fqn) -%}
{{fqn | replace(".", " ") | replace("_", " ") | title | replace(" ", "")}}
{%- endmacro -%}
{%- macro it_reps(brief) -%}
It represents {% if brief[:2] == "A " or brief[:3] == "An " or brief[:4] == "The " -%}
{{ brief[0]|lower }}{{ brief[1:] }}
{%- else -%}
the {{ brief[0]|lower }}{{ brief[1:] }}
{%- endif -%}
{%- endmacro -%}
{%- macro keydoc(attr) -%}
{%- if attr.stability|string() == "StabilityLevel.DEPRECATED" -%}
{{ to_go_name(attr.fqn) }}Key is the attribute Key conforming to the "{{ attr.fqn }}" semantic conventions.
{%- else -%}
{{ to_go_name(attr.fqn) }}Key is the attribute Key conforming to the "{{ attr.fqn }}" semantic conventions. {{ it_reps(attr.brief) }}
{%- endif %}
{%- endmacro -%}
{%- macro keydetails(attr) -%}
{%- if attr.attr_type is string %}
Type: {{ attr.attr_type }}
{%- else %}
Type: Enum
{%- endif %}
{%- if attr.requirement_level == RequirementLevel.REQUIRED %}
RequirementLevel: Required
{%- elif attr.requirement_level == RequirementLevel.CONDITIONALLY_REQUIRED %}
RequirementLevel: ConditionallyRequired
{%- if attr.requirement_level_msg != "" %} ({{ attr.requirement_level_msg }}){%- endif %}
{%- elif attr.requirement_level == RequirementLevel.RECOMMENDED %}
RequirementLevel: Recommended
{%- if attr.requirement_level_msg != "" %} ({{ attr.requirement_level_msg }}){%- endif %}
{%- else %}
RequirementLevel: Optional
{%- endif %}
{{ attr.stability | replace("Level.", ": ") | capitalize }}
{%- if attr.examples is iterable %}
Examples: {{ attr.examples | pprint | trim("[]") }}
{%- endif %}
{%- if attr.note %}
Note: {{ attr.note }}
{%- endif %}
{%- if attr.stability|string() == "StabilityLevel.DEPRECATED" %}
Deprecated: {{ attr.brief | replace("Deprecated, ", "") }}
{%- endif %}
{%- endmacro -%}
{%- macro fndoc(attr) -%}
{%- if attr.stability|string() == "StabilityLevel.DEPRECATED" -%}
// {{ to_go_name(attr.fqn) }} returns an attribute KeyValue conforming to the "{{ attr.fqn }}" semantic conventions.
Deprecated: {{ attr.brief | replace("Deprecated, ", "") }}
{%- else -%}
// {{ to_go_name(attr.fqn) }} returns an attribute KeyValue conforming to the "{{ attr.fqn }}" semantic conventions. {{ it_reps(attr.brief) }}
{%- endif %}
{%- endmacro -%}
{%- macro to_go_func(type, name) -%}
{%- if type == "string" -%}
func {{name}}(val string) attribute.KeyValue {
{%- elif type == "string[]" -%}
func {{name}}(val ...string) attribute.KeyValue {
{%- elif type == "int" -%}
func {{name}}(val int) attribute.KeyValue {
{%- elif type == "int[]" -%}
func {{name}}(val ...int) attribute.KeyValue {
{%- elif type == "double" -%}
func {{name}}(val float64) attribute.KeyValue {
{%- elif type == "double[]" -%}
func {{name}}(val ...float64) attribute.KeyValue {
{%- elif type == "boolean" -%}
func {{name}}(val bool) attribute.KeyValue {
{%- elif type == "boolean[]" -%}
func {{name}}(val ...bool) attribute.KeyValue {
{%- endif -%}
return {{name}}Key.{{keyval_method(type)}}(val)
}
{%- endmacro -%}
{%- macro sentence_case(text) -%}
{{ text[0]|upper}}{{text[1:] }}
{%- endmacro -%}
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
// Code generated from semantic convention specification. DO NOT EDIT.
package semconv // import [[IMPORTPATH]]
import "go.opentelemetry.io/otel/attribute"
{% for semconv in semconvs -%}
{%- if semconvs[semconv].attributes | rejectattr("ref") | rejectattr("deprecated") | selectattr("is_local") | sort(attribute=fqn) | length > 0 -%}
// {{ sentence_case(semconvs[semconv].brief | replace("This document defines ", "")) | wordwrap(76, break_long_words=false, break_on_hyphens=false, wrapstring="\n// ") }}
const (
{%- for attr in semconvs[semconv].attributes if attr.is_local and not attr.ref and not attr.deprecated %}
// {{ keydoc(attr) | wordwrap(72, break_long_words=false, break_on_hyphens=false, wrapstring="\n\t// ") }}
// {{ keydetails(attr) | wordwrap(72, break_long_words=false, break_on_hyphens=false, wrapstring="\n\t// ") }}
{{to_go_name(attr.fqn)}}Key = attribute.Key("{{attr.fqn}}")
{% endfor -%}
)
{%- for attr in semconvs[semconv].attributes if attr.is_local and not attr.ref and not attr.deprecated -%}
{%- if attr.attr_type is not string %}
var (
{%- for val in attr.attr_type.members %}
// {{ val.brief | to_doc_brief }}
{%- if attr.stability|string() == "StabilityLevel.DEPRECATED" %}
//
// Deprecated: {{ attr.brief | replace("Deprecated, ", "") | wordwrap(76, break_long_words=false, break_on_hyphens=false, wrapstring="\n// ") }}
{%- endif %}
{{to_go_name("{}.{}".format(attr.fqn, val.member_id))}} = {{to_go_name(attr.fqn)}}Key.{{to_go_attr_type(attr.attr_type.enum_type, val.value)}}
{%- endfor %}
)
{%- endif -%}
{%- endfor %}
{%- for attr in semconvs[semconv].attributes if attr.is_local and not attr.ref and not attr.deprecated -%}
{%- if attr.attr_type is string %}
{{ fndoc(attr) | wordwrap(76, break_long_words=false, break_on_hyphens=false, wrapstring="\n// ") }}
{{to_go_func(attr.attr_type, to_go_name(attr.fqn))}}
{%- endif -%}
{%- endfor %}
{% endif %}
{% endfor -%}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

161
semconv/weaver.yaml Normal file
View File

@ -0,0 +1,161 @@
params:
excluded_namespaces: []
excluded_attributes: ["messaging.client_id"]
templates:
- pattern: attribute_group.go.j2
filter: >
semconv_grouped_attributes({
"exclude_deprecated": false,
"exclude_root_namespace": $excluded_namespaces,
})
| map({
root_namespace: .root_namespace,
attributes: .attributes | map(select(.name as $st | $excluded_attributes[] | index($st) | not)),
})
application_mode: single
file_name: attribute_group.go
- pattern: metric.go.j2
filter: >
semconv_metrics({
"exclude_root_namespace": $excluded_namespaces,
})
application_mode: single
file_name: metric.go
comment_formats:
go:
format: markdown
prefix: "// "
indent_first_level_list_items: true
shortcut_reference_link: true
trim: true
remove_trailing_dots: true
go_1tab:
format: markdown
prefix: " // "
indent_first_level_list_items: true
shortcut_reference_link: true
trim: true
remove_trailing_dots: true
default_comment_format: go
text_maps:
attribute_type_method:
string: String
string[]: StringSlice
int: Int
int[]: IntSlice
double: Float64
double[]: FloatSlice
boolean: Bool
boolean[]: BoolSlice
attribute_type_value:
string: string
string[]: "...string"
int: int
int[]: "...int"
double: float64
double[]: "...float64"
boolean: bool
boolean[]: "...bool"
acronyms:
- ACL
- AI
- AIX
- AKS
- AMD64
- API
- ARM32
- ARM64
- ARN
- ARNs
- ASCII
- ASPNETCore
- AWS
- CICD
- CPP
- CPU
- CSS
- CosmosDB
- CouchDB
- CronJob
- DB
- DC
- DNS
- DaemonSet
- DragonflyBSD
- DynamoDB
- EC2
- ECS
- EDB
- EKS
- EOF
- FaaS
- FirstSQL
- FreeBSD
- GC
- GCP
- GRPC
- GUID
- HBase
- HPUX
- HSQLDB
- HTML
- HTTP
- HTTPS
- HanaDB
- IA64
- ID
- IP
- InProc
- InstantDB
- JDBC
- JSON
- JVM
- K8S
- LHS
- MSSQL
- MariaDB
- MaxDB
- MongoDB
- MySQL
- NetBSD
- OS
- OTel
- OpenBSD
- PHP
- PID
- PPC32
- PPC64
- PostgreSQL
- QPS
- QUIC
- RAM
- RHS
- RPC
- ReplicaSet
- SDK
- SLA
- SMTP
- SPDY
- SQL
- SSH
- StatefulSet
- TCP
- TLS
- TTL
- UDP
- UI
- UID
- URI
- URL
- UTF8
- UUID
- V8JS
- VCS
- VM
- WebEngine
- XML
- XMPP
- XSRF
- XSS
- ZOS