Skip to content

Commit e966e83

Browse files
Add link to requirement levels on Markdown table headers (#222)
Co-authored-by: Joao Grassi <[email protected]>
1 parent 1325b9c commit e966e83

File tree

42 files changed

+317
-282
lines changed

Some content is hidden

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

42 files changed

+317
-282
lines changed

semantic-conventions/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ Please update the changelog as part of any significant pull request.
88
([#244](https://github.com/open-telemetry/build-tools/pull/244))
99
- Add backward-compatibility check mode.
1010
([#271](https://github.com/open-telemetry/build-tools/pull/271))
11+
- Add link to requirement levels definition from Markdown table title.
12+
([#222](https://github.com/open-telemetry/build-tools/pull/222))
1113

1214
## v0.23.0
1315

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

+24-14
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@
3939
from opentelemetry.semconv.model.utils import ID_RE
4040
from opentelemetry.semconv.templating.markdown.options import MarkdownOptions
4141

42+
_REQUIREMENT_LEVEL_URL = (
43+
"https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/"
44+
)
45+
4246

4347
class RenderContext:
4448
def __init__(self):
@@ -80,10 +84,6 @@ class MarkdownRenderer:
8084
]
8185

8286
prelude = "<!-- semconv {} -->\n"
83-
table_headers = "| Attribute | Type | Description | Examples | Requirement Level |\n|---|---|---|---|---|\n"
84-
table_headers_omitting_req_level = (
85-
"| Attribute | Type | Description | Examples |\n|---|---|---|---|\n"
86-
)
8787

8888
def __init__(
8989
self, md_folder, semconvset: SemanticConventionSet, options=MarkdownOptions()
@@ -100,6 +100,16 @@ def __init__(
100100
# that contains it
101101
self.filename_for_attr_fqn = self._create_attribute_location_dict()
102102

103+
req_level = f"[Requirement Level]({_REQUIREMENT_LEVEL_URL})"
104+
105+
self.table_headers = (
106+
f"| Attribute | Type | Description | Examples | {req_level} |"
107+
"\n|---|---|---|---|---|\n"
108+
)
109+
self.table_headers_omitting_req_level = (
110+
"| Attribute | Type | Description | Examples |\n|---|---|---|---|\n"
111+
)
112+
103113
def to_markdown_attr(
104114
self,
105115
attribute: SemanticAttribute,
@@ -169,14 +179,14 @@ def to_markdown_attr(
169179

170180
def derive_requirement_level(self, attribute: SemanticAttribute):
171181
if attribute.requirement_level == RequirementLevel.REQUIRED:
172-
required = "Required"
182+
required = "`Required`"
173183
elif attribute.requirement_level == RequirementLevel.CONDITIONALLY_REQUIRED:
174184
if len(attribute.requirement_level_msg) < self.options.break_count:
175-
required = "Conditionally Required: " + attribute.requirement_level_msg
185+
required = "`Conditionally Required` " + attribute.requirement_level_msg
176186
else:
177187
# We put the condition in the notes after the table
178188
self.render_ctx.add_note(attribute.requirement_level_msg)
179-
required = f"Conditionally Required: [{len(self.render_ctx.notes)}]"
189+
required = f"`Conditionally Required` [{len(self.render_ctx.notes)}]"
180190
elif attribute.requirement_level == RequirementLevel.OPT_IN:
181191
required = "Opt-In"
182192
else: # attribute.requirement_level == Required.RECOMMENDED or None
@@ -188,20 +198,20 @@ def derive_requirement_level(self, attribute: SemanticAttribute):
188198
required = "See below"
189199
else:
190200
if not attribute.requirement_level_msg:
191-
required = "Recommended"
201+
required = "`Recommended`"
192202
elif len(attribute.requirement_level_msg) < self.options.break_count:
193-
required = "Recommended: " + attribute.requirement_level_msg
203+
required = "`Recommended` " + attribute.requirement_level_msg
194204
else:
195205
# We put the condition in the notes after the table
196206
self.render_ctx.add_note(attribute.requirement_level_msg)
197-
required = f"Recommended: [{len(self.render_ctx.notes)}]"
207+
required = f"`Recommended` [{len(self.render_ctx.notes)}]"
198208
return required
199209

200210
def write_table_header(self, output: io.StringIO):
201211
if self.render_ctx.is_omit_requirement_level:
202-
output.write(MarkdownRenderer.table_headers_omitting_req_level)
212+
output.write(self.table_headers_omitting_req_level)
203213
else:
204-
output.write(MarkdownRenderer.table_headers)
214+
output.write(self.table_headers)
205215

206216
def to_markdown_attribute_table(
207217
self, semconv: BaseSemanticConvention, output: io.StringIO
@@ -322,8 +332,8 @@ def to_markdown_enum(self, output: io.StringIO):
322332
if enum.custom_values:
323333
output.write(
324334
"has the following list of well-known values."
325-
+ " If one of them applies, then the respective value MUST be used,"
326-
+ " otherwise a custom value MAY be used."
335+
+ " If one of them applies, then the respective value MUST be used;"
336+
+ " otherwise, a custom value MAY be used."
327337
)
328338
else:
329339
output.write("MUST be one of the following:")
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Attribute Group Example
22

33
<!-- semconv span_attribute_group -->
4-
| Attribute | Type | Description | Examples | Requirement Level |
4+
| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) |
55
|---|---|---|---|---|
6-
| `foo.bar` | string | Attribute 1 | `baz` | Recommended: if available |
7-
| `foo.qux` | int | Attribute 2 | `42` | Conditionally Required: if available |
6+
| `foo.bar` | string | Attribute 1 | `baz` | `Recommended` if available |
7+
| `foo.qux` | int | Attribute 2 | `42` | `Conditionally Required` if available |
88
<!-- endsemconv -->
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# Custom HTTP Semantic Conventions
22

33
<!-- semconv custom_http(full) -->
4-
| Attribute | Type | Description | Examples | Requirement Level |
4+
| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) |
55
|---|---|---|---|---|
6-
| `custom_http.request.header.<key>` | string[] | HTTP request headers, `<key>` being the normalized HTTP Header name (lowercase, with - characters replaced by _), the value being the header values. | ``http.request.header.content_type=["application/json"]`` | Recommended |
7-
| `custom_http.request.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Required |
8-
| `general.some_general_attribute.<key>` | string | This is a general attribute. | ``some_general_attribute.some_key="abc"`` | Recommended |
9-
| `referenced_http.request.referenced.header.<key>` | string[] | This is a referenced attribute. | ``http.request.header.content_type=["application/json"]`` | Recommended |
6+
| `custom_http.request.header.<key>` | string[] | HTTP request headers, `<key>` being the normalized HTTP Header name (lowercase, with - characters replaced by _), the value being the header values. | ``http.request.header.content_type=["application/json"]`` | `Recommended` |
7+
| `custom_http.request.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` |
8+
| `general.some_general_attribute.<key>` | string | This is a general attribute. | ``some_general_attribute.some_key="abc"`` | `Recommended` |
9+
| `referenced_http.request.referenced.header.<key>` | string[] | This is a referenced attribute. | ``http.request.header.content_type=["application/json"]`` | `Recommended` |
1010
<!-- endsemconv -->

semantic-conventions/src/tests/data/markdown/deprecated/expected.md

+11-11
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,21 @@
22

33
<!-- Re-generate TOC with `TODO: ADD cmd` -->
44
<!-- semconv http -->
5-
| Attribute | Type | Description | Examples | Requirement Level |
5+
| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) |
66
|---|---|---|---|---|
7-
| `http.flavor` | string | **Deprecated. Use attribute `flavor_new` instead.**<br>Kind of HTTP protocol used [1] | `1.0` | Recommended |
8-
| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | Recommended |
9-
| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Required |
10-
| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | Recommended |
11-
| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: if and only if one was received/sent |
12-
| `http.status_text` | string | **Deprecated: Use attribute `status_description` instead.**<br>[HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | Recommended |
13-
| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | Recommended |
14-
| `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | Recommended |
15-
| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | Recommended |
7+
| `http.flavor` | string | **Deprecated. Use attribute `flavor_new` instead.**<br>Kind of HTTP protocol used [1] | `1.0` | `Recommended` |
8+
| `http.host` | string | The value of the [HTTP host header](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is empty or not present, this attribute should be the same. | `www.example.org` | `Recommended` |
9+
| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | `Required` |
10+
| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | `Recommended` |
11+
| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` if and only if one was received/sent |
12+
| `http.status_text` | string | **Deprecated: Use attribute `status_description` instead.**<br>[HTTP reason phrase](https://tools.ietf.org/html/rfc7230#section-3.1.2). | `OK` | `Recommended` |
13+
| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds#123` | `Recommended` |
14+
| `http.url` | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | `Recommended` |
15+
| `http.user_agent` | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | `Recommended` |
1616

1717
**[1]:** If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed.
1818

19-
`http.flavor` has the following list of well-known values. If one of them applies, then the respective value MUST be used, otherwise a custom value MAY be used.
19+
`http.flavor` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.
2020

2121
| Value | Description |
2222
|---|---|

semantic-conventions/src/tests/data/markdown/deprecated/input.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@
33
<!-- Re-generate TOC with `TODO: ADD cmd` -->
44
<!-- semconv http -->
55

6-
| Attribute name | Notes and examples | Required? |
6+
| Attribute name | Notes and examples | `Required`? |
77
| :------------- | :----------------------------------------------------------- | --------- |
8-
| `http.method` | HTTP request method. E.g. `"GET"`. | Required |
8+
| `http.method` | HTTP request method. E.g. `"GET"`. | `Required` |
99
| `http.url` | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | Defined later. |
1010
| `http.target` | The full request target as passed in a [HTTP request line][] or equivalent, e.g. `"/path/12314/?q=ddds#123"`. | Defined later. |
1111
| `http.host` | The value of the [HTTP host header][]. When the header is empty or not present, this attribute should be the same. | Defined later. |
1212
| `http.scheme` | The URI scheme identifying the used protocol: `"http"` or `"https"` | Defined later. |
13-
| `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | Conditionally Required: if and only if one was received/sent. |
14-
| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | Recommended |
13+
| `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | `Conditionally Required` if and only if one was received/sent. |
14+
| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | `Recommended` |
1515
| `http.flavor` | Kind of HTTP protocol used: `"1.0"`, `"1.1"`, `"2"`, `"SPDY"` or `"QUIC"`. | No |
16-
| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | Recommended |
16+
| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | `Recommended` |
1717

1818
<!-- endsemconv -->
1919

semantic-conventions/src/tests/data/markdown/empty/expected.md

+8-8
Original file line numberDiff line numberDiff line change
@@ -70,17 +70,17 @@ Note that the items marked with [1] are different from the mapping defined in th
7070

7171
<!-- Re-generate TOC with `TODO: ADD cmd` -->
7272

73-
| Attribute name | Notes and examples | Required? |
73+
| Attribute name | Notes and examples | `Required`? |
7474
| :------------- | :----------------------------------------------------------- | --------- |
75-
| `http.method` | HTTP request method. E.g. `"GET"`. | Required |
75+
| `http.method` | HTTP request method. E.g. `"GET"`. | `Required` |
7676
| `http.url` | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. | Defined later. |
7777
| `http.target` | The full request target as passed in a [HTTP request line][] or equivalent, e.g. `"/path/12314/?q=ddds#123"`. | Defined later. |
7878
| `http.host` | The value of the [HTTP host header][]. When the header is empty or not present, this attribute should be the same. | Defined later. |
7979
| `http.scheme` | The URI scheme identifying the used protocol: `"http"` or `"https"` | Defined later. |
80-
| `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | Conditionally Required: if and only if one was received/sent. |
81-
| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | Recommended |
80+
| `http.status_code` | [HTTP response status code][]. E.g. `200` (integer) | `Conditionally Required` if and only if one was received/sent. |
81+
| `http.status_text` | [HTTP reason phrase][]. E.g. `"OK"` | `Recommended` |
8282
| `http.flavor` | Kind of HTTP protocol used: `"1.0"`, `"1.1"`, `"2"`, `"SPDY"` or `"QUIC"`. | Opt-In |
83-
| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | Recommended |
83+
| `http.user_agent` | Value of the HTTP [User-Agent][] header sent by the client. | `Recommended` |
8484

8585
It is recommended to also use the general [network attributes][], especially `net.peer.ip`. If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed.
8686

@@ -183,11 +183,11 @@ If the route does not include the application root, it SHOULD be prepended to th
183183

184184
If the route cannot be determined, the `name` attribute MUST be set as defined in the general semantic conventions for HTTP.
185185

186-
| Attribute name | Notes and examples | Required? |
186+
| Attribute name | Notes and examples | `Required`? |
187187
| :------------- | :----------------------------------------------------------- | --------- |
188188
| `http.server_name` | The primary server name of the matched virtual host. This should be obtained via configuration. If no such configuration can be obtained, this attribute MUST NOT be set ( `net.host.name` should be used instead). | [1] |
189-
| `http.route` | The matched route (path template). (TODO: Define whether to prepend application root) E.g. `"/users/:userID?"`. | Recommended |
190-
| `http.client_ip` | The IP address of the original client behind all proxies, if known (e.g. from [X-Forwarded-For][]). Note that this is not necessarily the same as `net.peer.ip`, which would identify the network-level peer, which may be a proxy. | Recommended |
189+
| `http.route` | The matched route (path template). (TODO: Define whether to prepend application root) E.g. `"/users/:userID?"`. | `Recommended` |
190+
| `http.client_ip` | The IP address of the original client behind all proxies, if known (e.g. from [X-Forwarded-For][]). Note that this is not necessarily the same as `net.peer.ip`, which would identify the network-level peer, which may be a proxy. | `Recommended` |
191191

192192
[HTTP request line]: https://tools.ietf.org/html/rfc7230#section-3.1.1
193193
[HTTP host header]: https://tools.ietf.org/html/rfc7230#section-5.4

0 commit comments

Comments
 (0)