Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Code Generation with Weaver - Example of Code Generation for SemConv Attribute Registry and SemConv Metrics #136

Merged
merged 47 commits into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
328a89f
feat(codegen): create an example of codegen for SemConv Rust
lquerel Apr 26, 2024
d430eb6
feat(codegen): create lib.rs and one rs file per group prefix
lquerel Apr 26, 2024
35959a7
feat(codegen): remove old tera templates
lquerel Apr 26, 2024
618b8d2
feat(codegen): add support for semconv_experimental feature
lquerel Apr 26, 2024
db4dec4
chore: bump minijinja version to 1.0.21
lquerel Apr 27, 2024
d404191
chore: Fix fmt and clippy issues
lquerel Apr 27, 2024
628d46e
feat(forge): Add type_mapping filter
lquerel Apr 28, 2024
65c2464
doc(forge): Update documentation
lquerel Apr 28, 2024
7d26226
chore(forge): Improve test coverage
lquerel Apr 28, 2024
c821e55
feat(forge): Improve SemConv codegen example for Rust
lquerel Apr 29, 2024
00e11d2
chore(forge): Add mini registry and prepare for unit tests
lquerel Apr 29, 2024
37acc4b
chore(forge): Simplify mini_registry
lquerel Apr 29, 2024
074fe69
doc(forge): Add documentation on the JQ filter.
lquerel Apr 29, 2024
f930e80
chore(forge): Fix clippy issue
lquerel Apr 30, 2024
d65680c
Merge branch 'main' into example-codegen-semconv-rust
lquerel Apr 30, 2024
30876fc
chore(forge): Add experimental and deprecated attributes in the gener…
lquerel Apr 30, 2024
9483d63
feat(forge): Add enum string representation support.
lquerel Apr 30, 2024
e2e2df1
feat(forge): Use attribute registry namespace instead of group prefix.
lquerel Apr 30, 2024
8f6826b
feat(forge): Generate metrics and attributes
lquerel May 1, 2024
48403fc
feat(forge): Generate type-safe API for metrics
lquerel May 2, 2024
5fc3248
Merge branch 'main' into example-codegen-semconv-rust
lquerel May 2, 2024
ecbd76d
feat(forge): Separate required from optional attributes in the genera…
lquerel May 2, 2024
34db6ad
feat(forge): Improve metrics type-safe API
lquerel May 3, 2024
405331f
Merge branch 'main' into example-codegen-semconv-rust
lquerel May 3, 2024
581c08c
feat(forge): Add support for Counter and Gauge
lquerel May 3, 2024
0832fb2
feat(forge): Update generated code
lquerel May 3, 2024
5d8bf55
feat(forge): Update documentation
lquerel May 3, 2024
064e844
feat(forge): Fix Clippy lint issues
lquerel May 4, 2024
3f2e188
chore(forge): Exclude generated file from code coverage
lquerel May 4, 2024
3b26644
Merge branch 'main' into example-codegen-semconv-rust
lquerel May 4, 2024
7ec190d
chore(forge): Test infra for code gen [WIP]
lquerel May 4, 2024
da441c3
chore(forge): Remove build.rs
lquerel May 5, 2024
7ee2235
Merge branch 'main' into example-codegen-semconv-rust
lquerel May 6, 2024
c006d17
chore(forge): Move to not_required filter
lquerel May 6, 2024
8757379
Merge remote-tracking branch 'origin/example-codegen-semconv-rust' in…
lquerel May 6, 2024
97ee4a3
chore(forge): Improve error messages
lquerel May 6, 2024
9045e05
chore(forge): Create code generation test infrastructure
lquerel May 7, 2024
423111b
chore(forge): Create code generation test infrastructure
lquerel May 7, 2024
1306e6a
chore(forge): Create code generation test infrastructure
lquerel May 7, 2024
19e07c2
chore(forge): Remove duplicated codes and semconv registry
lquerel May 7, 2024
3534c42
chore(forge): Fix Windows specific issue.
lquerel May 7, 2024
964a5cb
Merge branch 'main' into example-codegen-semconv-rust
lquerel May 7, 2024
b858e7c
chore(forge): Improve error message to debug Windows specific issue.
lquerel May 7, 2024
c0aea47
Merge remote-tracking branch 'origin/example-codegen-semconv-rust' in…
lquerel May 7, 2024
baa9e2a
chore(forge): Add traces to debug Windows specific issue.
lquerel May 7, 2024
2f2ce45
chore(forge): Fix MiniJinja template loader for Windows.
lquerel May 8, 2024
dd0dc61
chore(forge): Fix MiniJinja template loader for Windows.
lquerel May 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/codecov.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ coverage:

ignore:
- "crates/xtask" # Part of the build system
- "src" # CLI (not tested yet)
- "src" # CLI (not tested yet)
- "crates/weaver_forge/codegen_examples/expected_codegen" # Generated code
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ jobs:
- name: Install cargo-tarpaulin
run: cargo install cargo-tarpaulin
- name: Gather coverage
run: cargo tarpaulin --workspace --output-dir coverage --out lcov -e xtask -e weaver
run: cargo tarpaulin --workspace --output-dir coverage --out lcov -e xtask -e weaver --exclude-files 'crates/weaver_forge/codegen_examples/expected_codegen/*'
- name: Upload coverage reports to Codecov
uses: codecov/[email protected]
with:
Expand Down
90 changes: 90 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ categories = ["command-line-utilities"]
license = "Apache-2.0"
readme = "README.md"
publish = false
resolver = "2"

# Workspace definition ========================================================
[workspace]
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![build](https://github.com/open-telemetry/weaver/actions/workflows/audit.yml/badge.svg)](https://github.com/open-telemetry/weaver/actions/workflows/audit.yml)
[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
----
(CONTRIBUTING.md) | [Links](#links) |

[Getting started](#getting-started) | [Main commands](#main-commands) | [Generate Doc & Code](crates/weaver_forge/README.md) | [Architecture](docs/architecture.md) | [Change log](CHANGELOG.md) | [Contributing](CONTRIBUTING.md) | [Links](#links) |

## What is OpenTelemetry Weaver?
Expand Down
5 changes: 5 additions & 0 deletions crates/weaver_forge/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,8 @@ serde_json.workspace = true
rayon.workspace = true
walkdir.workspace = true

[dev-dependencies]
opentelemetry = { version = "0.22.0", features = ["trace", "metrics", "logs", "otel_unstable"] }
opentelemetry_sdk = { version = "0.22.1", features = ["trace", "metrics", "logs"] }
opentelemetry-stdout = { version = "0.3.0", features = ["trace", "metrics", "logs"] }

20 changes: 20 additions & 0 deletions crates/weaver_forge/codegen_examples/expected_codegen/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Semantic Conventions for Rust

# Usage

```rust
fn main() {
// Display the KeyValue of the attribute CLIENT_ADDRESS initialized with the value "145.34.23.56"
println!("{:?}", semconv::client::CLIENT_ADDRESS.value("145.34.23.56".into()));
// Display the key of the attribute CLIENT_ADDRESS
println!("{:?}", semconv::client::CLIENT_ADDRESS.key());

// Display the KeyValue of the attribute CLIENT_PORT initialized with the value 8080
println!("{:?}", semconv::client::CLIENT_PORT.value(8080));
// Display the key of the attribute CLIENT_PORT
println!("{:?}", semconv::client::CLIENT_PORT.key());

// Display the string representation of the enum variant HttpRequestMethod::Connect
println!("{}", semconv::http::HttpRequestMethod::Connect);
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

//! These attributes may be used to describe the client in a connection-based network interaction where there is one side that initiates the connection (the client is the side that initiates the connection). This covers all TCP network interactions since TCP is connection-based and one side initiates the connection (an exception is made for peer-to-peer communication over TCP where the "user-facing" surface of the protocol / API doesn't expose a clear notion of client and server). This also covers UDP network interactions where one side initiates the interaction, e.g. QUIC (HTTP/3) and DNS.
//! DO NOT EDIT, this is an Auto-generated file from templates/registry/rust/attributes/attributes.rs.j2

/// Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name.
///
/// Notes:
/// When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available.
///
/// Examples:
/// - client.example.com
/// - 10.1.2.80
/// - /tmp/my.sock
pub const CLIENT_ADDRESS: crate::attributes::AttributeKey<opentelemetry::StringValue> = crate::attributes::AttributeKey::new("client.address");

/// Client port number.
///
/// Notes:
/// When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available.
///
/// Examples:
/// - 65123
pub const CLIENT_PORT: crate::attributes::AttributeKey<i64> = crate::attributes::AttributeKey::new("client.port");
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

//! This document defines the shared attributes used to report an error.
//! DO NOT EDIT, this is an Auto-generated file from templates/registry/rust/attributes/attributes.rs.j2

/// Describes a class of error the operation ended with.
///
/// Notes:
/// The `error.type` SHOULD be predictable, and SHOULD have low cardinality.
///
/// When `error.type` is set to a type (e.g., an exception type), its
/// canonical class name identifying the type within the artifact SHOULD be used.
///
/// Instrumentations SHOULD document the list of errors they report.
///
/// The cardinality of `error.type` within one instrumentation library SHOULD be low.
/// Telemetry consumers that aggregate data from multiple instrumentation libraries and applications
/// should be prepared for `error.type` to have high cardinality at query time when no
/// additional filters are applied.
///
/// If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`.
///
/// If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes),
/// it's RECOMMENDED to:
///
/// * Use a domain-specific attribute
/// * Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not.
///
/// Examples:
/// - timeout
/// - java.net.UnknownHostException
/// - server_certificate_invalid
/// - 500
pub const ERROR_TYPE: crate::attributes::AttributeKey<ErrorType> = crate::attributes::AttributeKey::new("error.type");

/// Describes a class of error the operation ended with.
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum ErrorType { /// A fallback error value to be used when the instrumentation doesn't define a custom value.
Other,
/// This variant allows defining a custom entry in the enum.
_Custom(String),
}

impl ErrorType {
/// Returns the string representation of the [`ErrorType`].
pub fn as_str(&self) -> &str {
match self {
ErrorType::Other => "_OTHER",
ErrorType::_Custom(v) => v.as_str(),
// Without this default case, the match expression would not
// contain any variants if all variants are annotated with the
// 'semconv_experimental' feature and the feature is not enabled.
#[allow(unreachable_patterns)]
_ => unreachable!(),
}
}
}

impl core::fmt::Display for ErrorType {
/// Formats the value using the given formatter.
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{}", self.as_str())
}
}

impl crate::attributes::AttributeKey<ErrorType> {
/// Returns a [`KeyValue`] pair for the given value.
pub fn value(&self, v: &ErrorType) -> opentelemetry::KeyValue {
opentelemetry::KeyValue::new(self.key.clone(), v.to_string())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

//! This document defines the shared attributes used to report a single exception associated with a span or log.
//! DO NOT EDIT, this is an Auto-generated file from templates/registry/rust/attributes/attributes.rs.j2

/// SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span.
///
/// Notes:
/// An exception is considered to have escaped (or left) the scope of a span,
/// if that span is ended while the exception is still logically "in flight".
/// This may be actually "in flight" in some languages (e.g. if the exception
/// is passed to a Context manager's `__exit__` method in Python) but will
/// usually be caught at the point of recording the exception in most languages.
///
/// It is usually not possible to determine at the point where an exception is thrown
/// whether it will escape the scope of a span.
/// However, it is trivial to know that an exception
/// will escape, if one checks for an active exception just before ending the span,
/// as done in the [example for recording span exceptions](#recording-an-exception).
///
/// It follows that an exception may still escape the scope of the span
/// even if the `exception.escaped` attribute was not set or set to false,
/// since the event might have been recorded at a time where it was not
/// clear whether the exception will escape.
pub const EXCEPTION_ESCAPED: crate::attributes::AttributeKey<bool> = crate::attributes::AttributeKey::new("exception.escaped");

/// The exception message.
///
/// Examples:
/// - Division by zero
/// - Can't convert 'int' object to str implicitly
pub const EXCEPTION_MESSAGE: crate::attributes::AttributeKey<opentelemetry::StringValue> = crate::attributes::AttributeKey::new("exception.message");

/// A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG.
///
/// Example: Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)
pub const EXCEPTION_STACKTRACE: crate::attributes::AttributeKey<opentelemetry::StringValue> = crate::attributes::AttributeKey::new("exception.stacktrace");

/// The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it.
///
/// Examples:
/// - java.net.ConnectException
/// - OSError
pub const EXCEPTION_TYPE: crate::attributes::AttributeKey<opentelemetry::StringValue> = crate::attributes::AttributeKey::new("exception.type");
Loading
Loading