Skip to content

Commit 50add91

Browse files
authored
Make stability required, fix ref and extends, render badges on metrics (#272)
1 parent ca02f82 commit 50add91

File tree

148 files changed

+1117
-186
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

148 files changed

+1117
-186
lines changed

semantic-conventions/src/opentelemetry/semconv/model/semantic_attribute.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,12 @@ def parse(
128128
if "type" in attribute:
129129
msg = f"Ref attribute '{ref}' must not declare a type"
130130
raise ValidationError.from_yaml_pos(position, msg)
131+
if "stability" in attribute:
132+
msg = f"Ref attribute '{ref}' must not override stability"
133+
raise ValidationError.from_yaml_pos(position, msg)
134+
if "deprecated" in attribute:
135+
msg = f"Ref attribute '{ref}' must not override deprecation status"
136+
raise ValidationError.from_yaml_pos(position, msg)
131137
brief = attribute.get("brief")
132138
examples = attribute.get("examples")
133139
ref = ref.strip()
@@ -224,7 +230,7 @@ def parse(
224230

225231
@staticmethod
226232
def parse_attribute(attribute):
227-
check_no_missing_keys(attribute, ["type", "brief"])
233+
check_no_missing_keys(attribute, ["type", "brief", "stability"])
228234
attr_val = attribute["type"]
229235
try:
230236
attr_type = EnumAttributeType.parse(attr_val)
@@ -284,7 +290,7 @@ def parse_attribute(attribute):
284290
@staticmethod
285291
def parse_stability(stability, position_data, strict_validation=True):
286292
if stability is None:
287-
return StabilityLevel.EXPERIMENTAL
293+
return None
288294

289295
stability_value_map = {
290296
"experimental": StabilityLevel.EXPERIMENTAL,

semantic-conventions/src/opentelemetry/semconv/model/semantic_convention.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ class BaseSemanticConvention(ValidatableYamlNode):
104104
"extends",
105105
"attributes",
106106
"constraints",
107+
"deprecated",
107108
)
108109

109110
GROUP_TYPE_NAME: str
@@ -268,11 +269,11 @@ def __init__(self, group, strict_validation=True):
268269
self.validate()
269270

270271
def validate(self):
271-
val_tuple = (self.metric_name, self.unit, self.instrument)
272+
val_tuple = (self.metric_name, self.unit, self.instrument, self.stability)
272273
if not all(val_tuple):
273274
raise ValidationError.from_yaml_pos(
274275
self._position,
275-
"All of metric_name, units, and instrument must be defined",
276+
"All of metric_name, units, instrument, and stability must be defined",
276277
)
277278

278279
if self.instrument not in self.allowed_instruments:
@@ -483,6 +484,8 @@ def _fill_inherited_attribute(self, attr, semconv):
483484

484485
def _merge_attribute(self, child, parent):
485486
child.attr_type = parent.attr_type
487+
child.stability = parent.stability
488+
child.deprecated = parent.deprecated
486489
if not child.brief:
487490
child.brief = parent.brief
488491
if not child.requirement_level:

semantic-conventions/src/opentelemetry/semconv/templating/markdown/__init__.py

+24-20
Original file line numberDiff line numberDiff line change
@@ -124,25 +124,7 @@ def to_markdown_attr(
124124
if isinstance(attribute.attr_type, EnumAttributeType)
125125
else AttributeType.get_instantiated_type(attribute.attr_type)
126126
)
127-
description = ""
128-
if attribute.deprecated and self.options.enable_deprecated:
129-
if "deprecated" in attribute.deprecated.lower():
130-
description = f"**{attribute.deprecated}**<br>"
131-
else:
132-
deprecated_msg = self.options.deprecated_md_snippet().format(
133-
attribute.deprecated
134-
)
135-
description = f"{deprecated_msg}<br>"
136-
elif (
137-
attribute.stability == StabilityLevel.STABLE and self.options.enable_stable
138-
):
139-
description = f"{self.options.stable_md_snippet()}<br>"
140-
elif (
141-
attribute.stability == StabilityLevel.EXPERIMENTAL
142-
and self.options.enable_experimental
143-
):
144-
description = f"{self.options.experimental_md_snippet()}<br>"
145-
description += attribute.brief
127+
description = self._description_with_badge(attribute) + attribute.brief
146128
if attribute.note:
147129
self.render_ctx.add_note(attribute.note)
148130
description += f" [{len(self.render_ctx.notes)}]"
@@ -258,7 +240,7 @@ def to_markdown_metric_table(
258240
"| -------- | --------------- | ----------- | -------------- |\n"
259241
)
260242

261-
description = semconv.brief
243+
description = self._description_with_badge(semconv) + semconv.brief
262244
if semconv.note:
263245
self.render_ctx.add_note(semconv.note)
264246
description += f" [{len(self.render_ctx.notes)}]"
@@ -544,3 +526,25 @@ def _render_group(self, semconv, parameters, output):
544526
self.to_markdown_unit_table(semconv.members, output)
545527

546528
output.write("<!-- endsemconv -->")
529+
530+
def _description_with_badge(
531+
self, item: typing.Union[SemanticAttribute | BaseSemanticConvention]
532+
):
533+
description = ""
534+
if item.deprecated and self.options.enable_deprecated:
535+
if "deprecated" in item.deprecated.lower():
536+
description = f"**{item.deprecated}**<br>"
537+
else:
538+
deprecated_msg = self.options.deprecated_md_snippet().format(
539+
item.deprecated
540+
)
541+
description = f"{deprecated_msg}<br>"
542+
elif item.stability == StabilityLevel.STABLE and self.options.enable_stable:
543+
description = f"{self.options.stable_md_snippet()}<br>"
544+
elif (
545+
item.stability == StabilityLevel.EXPERIMENTAL
546+
and self.options.enable_experimental
547+
):
548+
description = f"{self.options.experimental_md_snippet()}<br>"
549+
550+
return description

semantic-conventions/src/tests/data/compat/attribute_stable_to_experimental/vnext.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ groups:
2222
brief: "Request headers."
2323
note: "Request headers note."
2424
examples: '`first.fifth_attr.bar=["foo"]`'
25+
stability: experimental

semantic-conventions/src/tests/data/compat/attribute_stable_to_experimental/vprev.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ groups:
1010
brief: "first attribute"
1111
note: "first attribute note"
1212
examples: "first example"
13+
stability: experimental
1314
- id: second_attr
1415
type: int
1516
brief: "second attribute"

semantic-conventions/src/tests/data/compat/attribute_type_changed/vprev.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ groups:
1010
brief: "first attribute"
1111
note: "first attribute note"
1212
examples: "first example"
13+
stability: experimental
1314
- id: second_attr
1415
type: int
1516
brief: "second attribute"

semantic-conventions/src/tests/data/compat/removed_attribute/vprev.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ groups:
1010
brief: "first attribute"
1111
note: "first attribute note"
1212
examples: "first example"
13+
stability: experimental
1314
- id: second_attr
1415
type: int
1516
brief: "second attribute"
@@ -20,3 +21,4 @@ groups:
2021
type: template[string[]]
2122
brief: "request headers"
2223
examples: '`first.fifth_attr.foo=["bar"]`'
24+
stability: experimental

semantic-conventions/src/tests/data/compat/success/vprev.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ groups:
1010
brief: "first attribute"
1111
note: "first attribute note"
1212
examples: "first example"
13+
stability: experimental
1314
- id: second_attr
1415
type: int
1516
brief: "second attribute"

semantic-conventions/src/tests/data/markdown/attribute_group/attribute_group.yaml

+4-2
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ groups:
66
attributes:
77
- id: bar
88
type: string
9-
requirement_level:
9+
requirement_level:
1010
recommended: if available
1111
brief: Attribute 1
1212
examples: ['baz']
13+
stability: experimental
1314

1415
- id: derived_attributes
1516
type: attribute_group
@@ -19,10 +20,11 @@ groups:
1920
attributes:
2021
- id: qux
2122
type: int
22-
requirement_level:
23+
requirement_level:
2324
conditionally_required: if available
2425
brief: Attribute 2
2526
examples: [42]
27+
stability: experimental
2628

2729
- id: span_attribute_group
2830
prefix: ""

semantic-conventions/src/tests/data/markdown/attribute_templates/attribute_templates.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ groups:
1414
HTTP request headers, `<key>` being the normalized HTTP Header name
1515
(lowercase, with - characters replaced by _), the value being the header values.
1616
examples: '`http.request.header.content_type=["application/json"]`'
17+
stability: experimental
1718
- id: request.method
1819
type: string
1920
requirement_level: required
2021
sampling_relevant: false
2122
brief: 'HTTP request method.'
2223
examples: ["GET", "POST", "HEAD"]
24+
stability: experimental
2325
- ref: referenced_http.request.referenced.header
2426
- id: referenced_http_id
2527
type: span
@@ -31,6 +33,7 @@ groups:
3133
brief: >
3234
This is a referenced attribute.
3335
examples: '`http.request.header.content_type=["application/json"]`'
36+
stability: experimental
3437
- id: general
3538
type: span
3639
prefix: general
@@ -41,3 +44,4 @@ groups:
4144
brief: >
4245
This is a general attribute.
4346
examples: '`some_general_attribute.some_key="abc"`'
47+
stability: experimental

semantic-conventions/src/tests/data/markdown/deprecated/general.yaml

+10
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ groups:
66
These attributes may be used for any network related operation.
77
attributes:
88
- id: transport
9+
stability: experimental
910
type:
1011
allow_custom_values: false
1112
members:
@@ -36,28 +37,34 @@ groups:
3637
Transport protocol used. See note below.
3738
examples: 'IP.TCP'
3839
- id: peer.ip
40+
stability: experimental
3941
type: string
4042
brief: >
4143
Remote address of the peer (dotted decimal for IPv4 or
4244
[RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6)
4345
examples: '127.0.0.1'
4446
- id: peer.port
47+
stability: experimental
4548
type: int
4649
brief: 'Remote port number.'
4750
examples: [80, 8080, 443]
4851
- id: peer.name
52+
stability: experimental
4953
type: string
5054
brief: 'Remote hostname or similar, see note below.'
5155
examples: 'example.com'
5256
- id: host.ip
57+
stability: experimental
5358
type: string
5459
brief: 'Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host.'
5560
examples: '192.168.0.1'
5661
- id: host.port
62+
stability: experimental
5763
type: int
5864
brief: 'Like `net.peer.port` but for the host port.'
5965
examples: 35555
6066
- id: host.name
67+
stability: experimental
6168
type: string
6269
brief: 'Local hostname or similar, see note below.'
6370
examples: 'localhost'
@@ -68,16 +75,19 @@ groups:
6875
These attributes may be used for any operation with an authenticated and/or authorized enduser.
6976
attributes:
7077
- id: id
78+
stability: experimental
7179
type: string
7280
brief: >
7381
Username or client_id extracted from the access token or Authorization header
7482
in the inbound request from outside the system.
7583
examples: 'username'
7684
- id: role
85+
stability: experimental
7786
type: string
7887
brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.'
7988
examples: 'admin'
8089
- id: scope
90+
stability: experimental
8191
type: string
8292
brief: >
8393
Scopes or granted authorities the client currently possesses extracted from token

semantic-conventions/src/tests/data/markdown/deprecated/http.yaml

+10
Original file line numberDiff line numberDiff line change
@@ -8,43 +8,51 @@ groups:
88
and various HTTP versions like 1.1, 2 and SPDY.
99
attributes:
1010
- id: method
11+
stability: experimental
1112
type: string
1213
requirement_level: required
1314
sampling_relevant: false
1415
brief: 'HTTP request method.'
1516
examples: ["GET", "POST", "HEAD"]
1617
- id: url
18+
stability: experimental
1719
type: string
1820
brief: >
1921
Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`.
2022
Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless.
2123
examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv']
2224
- id: target
25+
stability: experimental
2326
type: string
2427
brief: 'The full request target as passed in a HTTP request line or equivalent.'
2528
examples: ['/path/12314/?q=ddds#123']
2629
- id: host
30+
stability: experimental
2731
type: string
2832
brief: >
2933
The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4).
3034
When the header is empty or not present, this attribute should be the same.
3135
examples: ['www.example.org']
3236
- id: scheme
37+
stability: experimental
3338
type: string
3439
brief: 'The URI scheme identifying the used protocol.'
3540
examples: ["http", "https"]
3641
- id: status_code
42+
stability: experimental
3743
type: int
3844
requirement_level:
3945
conditionally_required: "if and only if one was received/sent"
4046
brief: '[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).'
4147
examples: [200]
4248
- id: status_text
49+
stability: experimental
4350
type: string
4451
brief: '[HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2).'
4552
deprecated: Use attribute `status_description` instead.
4653
examples: ['OK']
4754
- id: flavor
55+
stability: experimental
4856
type:
4957
# Default value: `true`. If false, it helps the code gen tool to
5058
# encode checks that only accept the listed values.
@@ -72,6 +80,7 @@ groups:
7280
is `QUIC`, in which case `IP.UDP` is assumed.
7381
examples: ['1.0']
7482
- id: user_agent
83+
stability: experimental
7584
type: string
7685
brief: 'Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client.'
7786
examples: ['CERN-LineMode/2.15 libwww/2.17b3']
@@ -95,6 +104,7 @@ groups:
95104
brief: 'Semantic Convention for HTTP Server'
96105
attributes:
97106
- id: server_name
107+
stability: experimental
98108
type: string
99109
requirement_level:
100110
conditionally_required: >

0 commit comments

Comments
 (0)