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

Add aws-smithy-observability and aws-smithy-observability-otel crates #3912

Open
wants to merge 22 commits into
base: main
Choose a base branch
from

Conversation

landonxjames
Copy link
Contributor

Motivation and Context

We would like to have a consistent way to measure the performance of the SDK going forward so we can evaluate how updates change the performance over time. The changes in this PR are a first step towards that, adding the interfaces (and one implementation) that we will use to instrument our runtime crates.

Description

Add two new crates

  • aws-smithy-observability - contains traits for our observability solution and a global module for managing the global telemetry provider
  • aws-smithy-observability-otel - contains an OpenTelemetry based implementation of the traits

Testing

Added new tests in both crates

Checklist

Note: leaving out a changelog entry for now since these crates are somewhat useless until we instrument our runtime crates


By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@landonxjames landonxjames changed the title Landonxjames/obs Add aws-smithy-observability and aws-smithy-observability-otel crates Nov 11, 2024
Copy link

A new generated diff is ready to view.

A new doc preview is ready to view.

@landonxjames landonxjames marked this pull request as ready for review November 11, 2024 20:34
@landonxjames landonxjames requested review from a team as code owners November 11, 2024 20:34
Copy link

A new generated diff is ready to view.

A new doc preview is ready to view.

Copy link
Contributor

@aajtodd aajtodd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good start but I have some questions and concerns to be discussed.

rust-runtime/aws-smithy-observability/README.md Outdated Show resolved Hide resolved
/// Provides named instances of [Meter].
pub trait MeterProvider {
/// Get or create a named [Meter].
fn get_meter(&self, scope: &'static str, attributes: Option<&Attributes>) -> Box<dyn Meter>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

discuss Should this be -> impl Meter?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that would work. Returning impl Meter would make MeterProvider not object safe and so we couldn't pass it around as a dyn everywhere.

From docs:

  • All associated functions must either be dispatchable from a trait object or be explicitly non-dispatchable:
    • Dispatchable functions must:
      • Not have an opaque return type; that is,
        • Not have a return position impl Trait type (fn example(&self) -> impl Trait).

rust-runtime/aws-smithy-observability/src/meter.rs Outdated Show resolved Hide resolved
callback: Box<dyn Fn(&dyn AsyncMeasurement<Value = f64>) + Send + Sync>,
units: Option<String>,
description: Option<String>,
) -> Box<dyn AsyncMeasurement<Value = f64>>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question should these be Box<T> or should they be impl -> T?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See response above, using impl T would make these not object safe
#3912 (comment)

#[allow(clippy::type_complexity)]
fn create_gauge(
&self,
name: String,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should probably be more flexible like impl Into<String> or impl Into<Cow<'static, str>>, etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried that, but once again it makes the Meter trait no longer object safe

}

/// Get the set [MeterProvider]
pub fn meter_provider(&self) -> &(dyn MeterProvider + Send + Sync) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this return impl MeterProvider + Send + Sync?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you can return a reference to an impl Trait, and I didn't want to hand ownership of the MeterProvider to the caller, so settled for the &dyn that is there now.

//TODO(smithyobservability): once we have finalized everything and integrated metrics with our runtime
// libraries update this with detailed usage docs and examples

pub mod attributes;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Several of these modules probably should be private and just re-export their type instead.

use aws_smithy_observability::Error;
use aws_smithy_observability::Attributes`

vs

use aws_smithy_observability::error::Error;
use aws_smithy_observability::attributes::Attributes`

In other words consider how you'd like the API to be exposed and consumed.

Also missing docs on public modules.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some pub uses for these types in 0559e8b

The public modules are already documented, but the docs are in the module file instead of in lib.rs. I prefer keeping them there because I think it is cleaner than putting them all in lib.rs, but will move them if that is a consensus.

rust-runtime/aws-smithy-observability/src/attributes.rs Outdated Show resolved Hide resolved
rust-runtime/aws-smithy-observability/src/meter.rs Outdated Show resolved Hide resolved
}

/// Collects a set of events with an event count and sum for all events.
pub trait Histogram {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to consider whether we want to force (or need) instrument types to implement Clone?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sized is a supertrait of Clone and Sized supertraits break object safety

Copy link
Contributor

@ysaito1001 ysaito1001 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the work! Will circle back, leaving initial comments...

Copy link

A new generated diff is ready to view.

A new doc preview is ready to view.

@ysaito1001
Copy link
Contributor

I see that the design specifies an async API such as create_guage returns an async measurement handle. Do we need to support that, not necessarily in this PR but before the aws-smithy-observability goes 1.0 (in which case, like many traits do in the smithy runtime crates, a trait needs to return a struct and that struct implements the Future trait)?

Copy link

A new generated diff is ready to view.

A new doc preview is ready to view.

@landonxjames
Copy link
Contributor Author

I see that the design specifies an async API such as create_guage returns an async measurement handle. Do we need to support that, not necessarily in this PR but before the aws-smithy-observability goes 1.0 (in which case, like many traits do in the smithy runtime crates, a trait needs to return a struct and that struct implements the Future trait)?

The AsyncMeasurement name is kind of a confusing one in Rust since it doesn't really map to async fn, but is really a synchronous callback function registered when the instrument is created that is invoked when a instrument is observed. This bit in the SRA was inspired by OpenTelemetry and you can see their description of it here and their Rust implementation of it here

Copy link

A new generated diff is ready to view.

A new doc preview is ready to view.

Copy link

A new generated diff is ready to view.

A new doc preview is ready to view.

Copy link

A new generated diff is ready to view.

A new doc preview is ready to view.

Copy link
Contributor

@ysaito1001 ysaito1001 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the great work! Left the final round of comments.

rust-runtime/aws-smithy-observability/src/attributes.rs Outdated Show resolved Hide resolved
rust-runtime/aws-smithy-observability/src/global.rs Outdated Show resolved Hide resolved
Copy link

A new generated diff is ready to view.

A new doc preview is ready to view.

Copy link

A new generated diff is ready to view.

A new doc preview is ready to view.

Copy link

A new generated diff is ready to view.

A new doc preview is ready to view.

Copy link

A new generated diff is ready to view.

A new doc preview is ready to view.

Copy link

A new generated diff is ready to view.

A new doc preview is ready to view.

Copy link

github-actions bot commented Dec 2, 2024

A new generated diff is ready to view.

A new doc preview is ready to view.

landonxjames and others added 22 commits December 3, 2024 12:07
Also fix all warnings in both observability crates
The updates caused CI to fail since it depended on the newly added
crates, but those were not yet present in the main lockfile that is
copied around for tests
* Update some clippy style issues
* Config the aws-smithy-observability-otel crate to not compile on powerpc
* Run tests for global module serially so they don't poison the RwLock
Pin version of value-bag in otel crate

Powerpc dep updates

Pin more transitive deps
Aligns with standard introduced in #3065

Update doc comments

External types updates
Remove non-public type from docs
Copy link

github-actions bot commented Dec 3, 2024

A new generated diff is ready to view.

A new doc preview is ready to view.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants