Skip to content

Commit 161929d

Browse files
lquerelTommyCpplalitb
authored
Use weaver for semantic convention codegen (open-telemetry#2098)
Co-authored-by: Zhongyang Wu <[email protected]> Co-authored-by: Lalit Kumar Bhasin <[email protected]>
1 parent 0f15d21 commit 161929d

18 files changed

+4139
-1508
lines changed

opentelemetry-semantic-conventions/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
## vNext
44

5+
### Changed
6+
7+
- Starting with this version, this crate will use Weaver for the generation of
8+
the semantic conventions.
9+
- **Breaking** Introduced a new feature `semconv_experimental` to enable experimental semantic conventions.
10+
This feature is disabled by default.
11+
512
## v0.25.0
613
### Changed
714

opentelemetry-semantic-conventions/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ rust-version = "1.65"
1919
all-features = true
2020
rustdoc-args = ["--cfg", "docsrs"]
2121

22+
[features]
23+
default = []
24+
semconv_experimental = []
25+
2226
[dev-dependencies]
2327
opentelemetry = { default-features = false, path = "../opentelemetry" } # for doctests
2428
opentelemetry_sdk = { features = ["trace"], path = "../opentelemetry-sdk" } # for doctests

opentelemetry-semantic-conventions/scripts/generate-consts-from-spec.sh

Lines changed: 13 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ CRATE_DIR="${SCRIPT_DIR}/../"
66

77
# freeze the spec version and generator version to make generation reproducible
88
SPEC_VERSION=1.27.0
9-
SEMCOVGEN_VERSION=0.25.0
9+
WEAVER_VERSION=v0.10.0
1010

1111
cd "$CRATE_DIR"
1212

@@ -20,54 +20,24 @@ git fetch origin "v$SPEC_VERSION"
2020
git reset --hard FETCH_HEAD
2121
cd "$CRATE_DIR"
2222

23-
docker run --rm \
24-
-v "${CRATE_DIR}/semantic-conventions/model:/source" \
25-
-v "${CRATE_DIR}/scripts/templates:/templates" \
26-
-v "${CRATE_DIR}/src:/output" \
27-
otel/semconvgen:$SEMCOVGEN_VERSION \
28-
-f /source code \
29-
--template /templates/semantic_attributes.rs.j2 \
30-
--output /output/attribute.rs \
31-
--parameters conventions=attribute
32-
33-
docker run --rm \
34-
-v "${CRATE_DIR}/semantic-conventions/model:/source" \
35-
-v "${CRATE_DIR}/scripts/templates:/templates" \
36-
-v "${CRATE_DIR}/src:/output" \
37-
otel/semconvgen:$SEMCOVGEN_VERSION \
38-
--only span,event \
39-
-f /source code \
40-
--template /templates/semantic_attributes.rs.j2 \
41-
--output /output/trace.rs \
42-
--parameters conventions=trace
43-
44-
docker run --rm \
45-
-v "${CRATE_DIR}/semantic-conventions/model:/source" \
46-
-v "${CRATE_DIR}/scripts/templates:/templates" \
47-
-v "${CRATE_DIR}/src:/output" \
48-
otel/semconvgen:$SEMCOVGEN_VERSION \
49-
--only resource \
50-
-f /source code \
51-
--template /templates/semantic_attributes.rs.j2 \
52-
--output /output/resource.rs \
53-
--parameters conventions=resource
54-
55-
docker run --rm \
56-
-v "${CRATE_DIR}/semantic-conventions/model:/source" \
57-
-v "${CRATE_DIR}/scripts/templates:/templates" \
58-
-v "${CRATE_DIR}/src:/output" \
59-
otel/semconvgen:$SEMCOVGEN_VERSION \
60-
-f /source code \
61-
--template /templates/semantic_metrics.rs.j2 \
62-
--output /output/metric.rs
63-
6423
SED=(sed -i)
6524
if [[ "$(uname)" = "Darwin" ]]; then
6625
SED=(sed -i "")
6726
fi
6827

6928
# Keep `SCHEMA_URL` key in sync with spec version
70-
"${SED[@]}" "s/\(opentelemetry.io\/schemas\/\)[^\"]*\"/\1$SPEC_VERSION\"/" src/lib.rs
29+
"${SED[@]}" "s/\(opentelemetry.io\/schemas\/\)[^\"]*\"/\1$SPEC_VERSION\"/" scripts/templates/registry/rust/weaver.yaml
30+
31+
docker run --rm \
32+
--mount type=bind,source=$CRATE_DIR/semantic-conventions/model,target=/home/weaver/source,readonly \
33+
--mount type=bind,source=$CRATE_DIR/scripts/templates,target=/home/weaver/templates,readonly \
34+
--mount type=bind,source=$CRATE_DIR/src,target=/home/weaver/target \
35+
otel/weaver:$WEAVER_VERSION \
36+
registry generate \
37+
--registry=/home/weaver/source \
38+
--templates=/home/weaver/templates \
39+
rust \
40+
/home/weaver/target/
7141

7242
# handle doc generation failures
7343
"${SED[@]}" 's/\[2\]\.$//' src/attribute.rs # remove trailing [2] from few of the doc comments

opentelemetry-semantic-conventions/scripts/templates/header_attribute.rs

Lines changed: 0 additions & 3 deletions
This file was deleted.

opentelemetry-semantic-conventions/scripts/templates/header_metric.rs

Lines changed: 0 additions & 23 deletions
This file was deleted.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{%- import 'macros.j2' as attr_macros -%}
2+
// DO NOT EDIT, this is an auto-generated file
3+
//
4+
// If you want to update the file:
5+
// - Edit the template at scripts/templates/registry/rust/attributes.rs.j2
6+
// - Run the script at scripts/generate-consts-from-spec.sh
7+
8+
//! # Semantic Attributes
9+
//!
10+
//! The entire set of semantic attributes (or [conventions](https://opentelemetry.io/docs/concepts/semantic-conventions/)) defined by the project. The resource, metric, and trace modules reference these attributes.
11+
12+
{% for root_ns in ctx %}
13+
{% for attr in root_ns.attributes | rejectattr("name", "in", params.excluded_attributes) %}
14+
{{ [attr.brief, concat_if("\n\n## Notes\n\n", attr.note), attr_macros.examples(attr)] | comment }}
15+
{% if attr is experimental %}
16+
#[cfg(feature = "semconv_experimental")]
17+
{% endif %}
18+
{% if attr is deprecated %}
19+
#[deprecated(note="{{ attr.deprecated.strip(" \n\"") }}")]
20+
{% endif %}
21+
pub const {{ attr.name | screaming_snake_case }}: &str = "{{ attr.name }}";
22+
23+
{% endfor %}
24+
{% endfor %}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//! OpenTelemetry semantic conventions are agreed standardized naming patterns
2+
//! for OpenTelemetry things. This crate aims to be the centralized place to
3+
//! interact with these conventions.
4+
#![warn(
5+
future_incompatible,
6+
missing_debug_implementations,
7+
missing_docs,
8+
nonstandard_style,
9+
rust_2018_idioms,
10+
unreachable_pub,
11+
unused
12+
)]
13+
#![cfg_attr(test, deny(warnings))]
14+
#![doc(
15+
html_logo_url = "https://raw.githubusercontent.com/open-telemetry/opentelemetry-rust/main/assets/logo.svg"
16+
)]
17+
18+
pub mod attribute;
19+
pub mod metric;
20+
pub mod resource;
21+
pub mod trace;
22+
23+
/// The schema URL that matches the version of the semantic conventions that
24+
/// this crate defines.
25+
pub const SCHEMA_URL: &str = "{{ params.schema_url }}";
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{%- macro examples(entity) -%}
2+
{% if entity.examples %}
3+
# Examples
4+
5+
{% if entity.examples is sequence %}
6+
{% for example in entity.examples %}
7+
- `{{ example | pprint }}`
8+
{% endfor %}
9+
{% else %}
10+
- `{{ entity.examples | pprint }}`
11+
{% endif %}
12+
{% endif %}
13+
{% endmacro %}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
{%- import 'macros.j2' as metric_macros -%}
2+
// DO NOT EDIT, this is an auto-generated file
3+
//
4+
// If you want to update the file:
5+
// - Edit the template at scripts/templates/registry/rust/metric.rs.j2
6+
// - Run the script at scripts/generate-consts-from-spec.sh
7+
8+
//! # Metric Semantic Conventions
9+
//!
10+
//! The [metric semantic conventions] define a set of standardized attributes to
11+
//! be used in `Meter`s.
12+
//!
13+
//! [metric semantic conventions]: https://github.com/open-telemetry/semantic-conventions/tree/main/model/metric
14+
//!
15+
//! ## Usage
16+
//!
17+
//! ```rust
18+
//! use opentelemetry::{global, KeyValue};
19+
//! use opentelemetry_semantic_conventions as semconv;
20+
//!
21+
//! // Assumes we already have an initialized `MeterProvider`
22+
//! // See: https://github.com/open-telemetry/opentelemetry-rust/blob/main/examples/metrics-basic/src/main.rs
23+
//! // for an example
24+
//! let meter = global::meter("mylibraryname");
25+
//! let histogram = meter
26+
//! .u64_histogram(semconv::metric::HTTP_SERVER_REQUEST_DURATION)
27+
//! .with_unit("By")
28+
//! .with_description("Duration of HTTP server requests.")
29+
//! .init();
30+
//! ```
31+
32+
{% for root_ns in ctx %}
33+
{% for metric in root_ns.metrics %}
34+
{{ ["## Description\n\n", metric.brief, concat_if("\n\n## Notes\n\n", metric.note), metric_macros.examples(metric)] | comment }}
35+
/// ## Metadata
36+
/// | | |
37+
/// |:-|:-
38+
/// | Instrument: | `{{ metric.instrument }}` |
39+
/// | Unit: | `{{ metric.unit }}` |
40+
/// | Status: | `{{ metric.stability | capitalize }}` |
41+
{% if metric.attributes %}
42+
///
43+
/// ## Attributes
44+
/// | Name | Requirement |
45+
/// |:-|:- |
46+
{% endif %}
47+
{% for attribute in metric.attributes | rejectattr("name", "in", params.excluded_attributes) | sort(attribute="name") %}
48+
{% if attribute.requirement_level %}
49+
{% if attribute.requirement_level.conditionally_required %}
50+
{% set req_level = "Conditionally_required" %}
51+
{% set req_message = attribute.requirement_level.conditionally_required %}
52+
{% else %}
53+
{% set req_level = (attribute.requirement_level | capitalize) %}
54+
{% set req_message = attribute.requirement_level_msg %}
55+
{% endif %}
56+
{% else %}
57+
{% set req_level = "Unspecified" %}
58+
{% set req_message = '' %}
59+
{% endif %}
60+
/// | [`crate::attribute::{{ attribute.name | screaming_snake_case }}`] | `{{ req_level }}`{{ (': ' + req_message if req_message else '') }}
61+
{% endfor %}
62+
{% if metric.examples %}
63+
///
64+
/// ## Examples
65+
///
66+
{% for example in metric.examples %}
67+
/// - `{{ example }}`
68+
{% endfor %}
69+
{% endif %}
70+
{% if metric is experimental %}
71+
#[cfg(feature = "semconv_experimental")]
72+
{% endif %}
73+
{% if metric is deprecated %}
74+
#[deprecated(note="{{ metric.deprecated.strip(" \n\"") }}")]
75+
{% endif %}
76+
pub const {{ metric.metric_name | screaming_snake_case }}: &str = "{{ metric.metric_name }}";
77+
78+
{% endfor %}
79+
{% endfor %}
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,39 @@
1-
//! # Resource Semantic Conventions
2-
//!
3-
//! The [resource semantic conventions] define a set of standardized attributes
4-
//! to be used in `Resource`s.
5-
//!
6-
//! [resource semantic conventions]: https://github.com/open-telemetry/semantic-conventions/tree/main/model/resource
7-
//!
8-
//! ## Usage
9-
//!
10-
//! ```rust
11-
//! use opentelemetry::KeyValue;
12-
//! use opentelemetry_sdk::{trace::{config, TracerProvider}, Resource};
13-
//! use opentelemetry_semantic_conventions as semconv;
14-
//!
15-
//! let _tracer = TracerProvider::builder()
16-
//! .with_config(config().with_resource(Resource::new(vec![
17-
//! KeyValue::new(semconv::resource::SERVICE_NAME, "my-service"),
18-
//! KeyValue::new(semconv::resource::SERVICE_NAMESPACE, "my-namespace"),
19-
//! ])))
20-
//! .build();
21-
//! ```
1+
{%- import 'macros.j2' as attr_macros -%}
2+
// DO NOT EDIT, this is an auto-generated file
3+
//
4+
// If you want to update the file:
5+
// - Edit the template at scripts/templates/registry/rust/resource.rs.j2
6+
// - Run the script at scripts/generate-consts-from-spec.sh
7+
8+
//! # Resource Semantic Conventions
9+
//!
10+
//! The [resource semantic conventions] define a set of standardized attributes
11+
//! to be used in `Resource`s.
12+
//!
13+
//! [resource semantic conventions]: https://github.com/open-telemetry/semantic-conventions/tree/main/model/resource
14+
//!
15+
//! ## Usage
16+
//!
17+
//! ```rust
18+
//! use opentelemetry::KeyValue;
19+
//! use opentelemetry_sdk::{trace::{config, TracerProvider}, Resource};
20+
//! use opentelemetry_semantic_conventions as semconv;
21+
//!
22+
//! let _tracer = TracerProvider::builder()
23+
//! .with_config(config().with_resource(Resource::new(vec![
24+
//! KeyValue::new(semconv::resource::SERVICE_NAME, "my-service"),
25+
//! KeyValue::new(semconv::resource::SERVICE_NAMESPACE, "my-namespace"),
26+
//! ])))
27+
//! .build();
28+
//! ```
29+
30+
{% for attr in ctx | rejectattr("name", "in", params.excluded_attributes) %}
31+
{% if attr is experimental %}
32+
#[cfg(feature = "semconv_experimental")]
33+
{% endif %}
34+
{% if attr is deprecated %}
35+
#[allow(deprecated)]
36+
{% endif %}
37+
pub use crate::attribute::{{ attr.name | screaming_snake_case }};
38+
39+
{% endfor %}

0 commit comments

Comments
 (0)