Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
249 changes: 193 additions & 56 deletions rust-runtime/Cargo.lock

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ proc-macro = true

[package]
name = "aws-smithy-http-server-metrics-macro"
version = "0.1.0"
version = "0.1.1"
authors = [
"AWS Rust SDK Team <aws-sdk-rust@amazon.com>",
"Jason Gin <jasgin@amazon.com>",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ fn generate_ext_trait_impl(
{
fn build(self) -> aws_smithy_http_server_metrics::layer::MetricsLayer<#struct_ident, Sink, Init, Res> {
let default_metrics_extension_fn =
|req: &mut http::Request<aws_smithy_http_server_metrics::types::ReqBody>,
|req: &mut aws_smithy_http_server_metrics::types::HttpRequest,
metrics: &mut #struct_ident,
req_config: aws_smithy_http_server_metrics::default::DefaultRequestMetricsConfig,
res_config: aws_smithy_http_server_metrics::default::DefaultResponseMetricsConfig,
Expand Down
34 changes: 24 additions & 10 deletions rust-runtime/aws-smithy-http-server-metrics/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "aws-smithy-http-server-metrics"
version = "0.1.0"
version = "0.1.1"
authors = [
"AWS Rust SDK Team <aws-sdk-rust@amazon.com>",
"Jason Gin <jasgin@amazon.com>",
Expand All @@ -12,28 +12,42 @@ repository = "https://github.com/smithy-lang/smithy-rs"
rust-version = "1.91"

[dependencies]
metrique = "0.1.17"
metrique-core = "0.1.15"
metrique-writer = "0.1.17"

tower = "0.4.13"
futures = "0.3"
aws-smithy-http-server = { path = "../aws-smithy-http-server", features = [
"request-id",
] }
aws-smithy-http-server-metrics-macro = { path = "../aws-smithy-http-server-metrics-macro" }
http = "1.3.1"
http-body = "1.0.1"
hyper = "1.6.0"
thiserror = "2"
futures = "0.3"
metrique = "0.1.17"
metrique-core = "0.1.15"
metrique-writer = "0.1.17"
pin-project-lite = "0.2.14"
thiserror = "2"
tower = "0.4.13"
tracing = "0.1.44"

aws-smithy-http-server = { path = "../aws-smithy-http-server", features = [
# Optional dependencies for aws-smithy-http-server 0.65 support
aws-smithy-http-server-065 = { package = "aws-smithy-http-server", version = "0.65", optional = true, features = [
"request-id",
] }
aws-smithy-http-server-metrics-macro = { path = "../aws-smithy-http-server-metrics-macro" }
http-02 = { package = "http", version = "0.2.12", optional = true }
http-body-04 = { package = "http-body", version = "0.4.6", optional = true }
hyper-014 = { package = "hyper", version = "0.14.26", optional = true }

[dev-dependencies]
tracing-appender = "0.2"
metrique-writer-format-emf = "0.1.16"

[features]
aws-smithy-http-server-065 = [
"dep:aws-smithy-http-server-065",
"dep:http-02",
"dep:hyper-014",
"dep:http-body-04",
]

[package.metadata.docs.rs]
all-features = true
targets = ["x86_64-unknown-linux-gnu"]
Expand Down
7 changes: 3 additions & 4 deletions rust-runtime/aws-smithy-http-server-metrics/src/layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

use std::marker::PhantomData;

use http::Request;
use metrique::DefaultSink;
use metrique::ServiceMetrics;
use metrique_writer::GlobalEntrySink;
Expand All @@ -26,7 +25,7 @@ use crate::traits::ThreadSafeCloseEntry;
use crate::traits::ThreadSafeEntrySink;
use crate::types::DefaultInit;
use crate::types::DefaultRs;
use crate::types::ReqBody;
use crate::types::HttpRequest;

pub mod builder;

Expand Down Expand Up @@ -100,7 +99,7 @@ pub struct MetricsLayer<
pub(crate) init_metrics: Init,
pub(crate) response_metrics: Option<Res>,
pub(crate) default_metrics_extension_fn: fn(
&mut Request<ReqBody>,
&mut HttpRequest,
&mut Entry,
DefaultRequestMetricsConfig,
DefaultResponseMetricsConfig,
Expand Down Expand Up @@ -134,7 +133,7 @@ where
init_metrics: Init,
response_metrics: Option<Res>,
default_metrics_extension_fn: fn(
&mut Request<ReqBody>,
&mut HttpRequest,
&mut Entry,
DefaultRequestMetricsConfig,
DefaultResponseMetricsConfig,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use std::marker::PhantomData;
use std::sync::Arc;
use std::sync::Mutex;

use http::Request;
use metrique::DefaultSink;
use metrique::OnParentDrop;
use metrique::Slot;
Expand All @@ -28,7 +27,7 @@ use crate::traits::ThreadSafeCloseEntry;
use crate::traits::ThreadSafeEntrySink;
use crate::types::DefaultInit;
use crate::types::DefaultRs;
use crate::types::ReqBody;
use crate::types::HttpRequest;

// Macro to generate disable methods for configuration
macro_rules! impl_disable_methods {
Expand Down Expand Up @@ -217,7 +216,7 @@ macro_rules! impl_build_for_state {
{
fn build(self) -> MetricsLayer<DefaultMetrics, Sink, Init, Res> {
let default_metrics_extension_fn =
|req: &mut Request<ReqBody>,
|req: &mut HttpRequest,
metrics: &mut DefaultMetrics,
req_config: DefaultRequestMetricsConfig,
res_config: DefaultResponseMetricsConfig,
Expand Down Expand Up @@ -275,14 +274,13 @@ impl_build_for_state!(WithRqAndRs);

#[cfg(test)]
mod tests {
use http::Response;
use metrique::AppendAndCloseOnDrop;
use metrique::ServiceMetrics;
use metrique_writer::GlobalEntrySink;

use super::*;
use crate::layer::MetricsLayer;
use crate::types::ResBody;
use crate::types::HttpResponse;

// Compile-time guarantees that methods exist on the correct states
macro_rules! assert_methods_callable {
Expand Down Expand Up @@ -314,13 +312,11 @@ mod tests {
assert_state!(assert_with_rq, WithRq);
assert_state!(assert_with_rq_and_rs, WithRqAndRs);

fn dummy_init(
_req: &mut Request<ReqBody>,
) -> AppendAndCloseOnDrop<DefaultMetrics, DefaultSink> {
fn dummy_init(_req: &mut HttpRequest) -> AppendAndCloseOnDrop<DefaultMetrics, DefaultSink> {
DefaultMetrics::default().append_on_drop(ServiceMetrics::sink())
}

fn dummy_response_fn(_res: &mut Response<ResBody>, _metrics: &mut DefaultMetrics) {}
fn dummy_response_fn(_res: &mut HttpResponse, _metrics: &mut DefaultMetrics) {}

#[test]
fn test_needs_initialization_state() {
Expand Down
2 changes: 1 addition & 1 deletion rust-runtime/aws-smithy-http-server-metrics/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
//! [`DefaultMetricsPlugin`] automatically collects standard metrics for every request at operation time.
//! See the Collected Metrics section below:
//!
//! ```rust
//! ```rust, ignore
//! use aws_smithy_http_server_metrics::plugin::DefaultMetricsPlugin;
//! use aws_smithy_http_server::plugin::HttpPlugins;
//!
Expand Down
18 changes: 10 additions & 8 deletions rust-runtime/aws-smithy-http-server-metrics/src/operation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,18 @@ use std::ops::DerefMut;
use std::sync::Arc;
use std::sync::Mutex;

use aws_smithy_http_server::body::empty;
use aws_smithy_http_server::request::FromParts;
use aws_smithy_http_server::response::IntoResponse;
use http::StatusCode;
use metrique::OnParentDrop;
use metrique::Slot;
use metrique::SlotGuard;
use thiserror::Error;

use crate::traits::ThreadSafeCloseEntry;
use crate::types::aws_smithy_http_server::request::FromParts;
use crate::types::aws_smithy_http_server::response::IntoResponse;
use crate::types::empty_response_body;
use crate::types::HttpRequestParts;
use crate::types::HttpResponse;
use crate::types::HttpStatusCode;

/// Type for metrics that can be extracted in operation handlers.
///
Expand Down Expand Up @@ -116,7 +118,7 @@ where
{
type Rejection = MetricsError;

fn from_parts(parts: &mut http::request::Parts) -> Result<Self, Self::Rejection> {
fn from_parts(parts: &mut HttpRequestParts) -> Result<Self, Self::Rejection> {
// Get a reference to the MetricsInExtensions without removing it from the request.
// This keeps the outer guard alive in the extensions.
let Some(metrics_slot) = parts.extensions.get::<MetricsExtension<T>>() else {
Expand Down Expand Up @@ -181,9 +183,9 @@ pub enum MetricsError {
}

impl<Protocol> IntoResponse<Protocol> for MetricsError {
fn into_response(self) -> http::Response<aws_smithy_http_server::body::BoxBody> {
let mut response = http::Response::new(empty());
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
fn into_response(self) -> HttpResponse {
let mut response = HttpResponse::new(empty_response_body());
*response.status_mut() = HttpStatusCode::INTERNAL_SERVER_ERROR;
response
}
}
32 changes: 15 additions & 17 deletions rust-runtime/aws-smithy-http-server-metrics/src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,6 @@ use std::task::Context;
use std::task::Poll;
use std::time::Duration;

use aws_smithy_http_server::operation::OperationShape;
use aws_smithy_http_server::plugin::HttpMarker;
use aws_smithy_http_server::plugin::Plugin;
use aws_smithy_http_server::request::request_id::ServerRequestId;
use aws_smithy_http_server::service::ServiceShape;
use http::Request;
use http::Response;
use metrique::timers::OwnedTimerGuard;
use metrique::timers::Stopwatch;
use metrique::OnParentDrop;
Expand All @@ -33,8 +26,13 @@ use crate::default::DefaultRequestMetrics;
use crate::default::DefaultResponseMetrics;
use crate::default::DefaultResponseMetricsConfig;
use crate::default::DefaultResponseMetricsExtension;
use crate::types::ReqBody;
use crate::types::ResBody;
use crate::types::aws_smithy_http_server::operation::OperationShape;
use crate::types::aws_smithy_http_server::plugin::HttpMarker;
use crate::types::aws_smithy_http_server::plugin::Plugin;
use crate::types::aws_smithy_http_server::request::request_id::ServerRequestId;
use crate::types::aws_smithy_http_server::service::ServiceShape;
use crate::types::HttpRequest;
use crate::types::HttpResponse;

pin_project! {
/// Future returned by [`DefaultMetricsPluginService`].
Expand Down Expand Up @@ -66,9 +64,9 @@ pin_project! {

impl<F, Err> Future for DefaultMetricsFuture<F>
where
F: Future<Output = Result<Response<ResBody>, Err>>,
F: Future<Output = Result<HttpResponse, Err>>,
{
type Output = Result<Response<ResBody>, Err>;
type Output = Result<HttpResponse, Err>;

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
match self.project() {
Expand Down Expand Up @@ -206,13 +204,13 @@ where
}
impl<Ser> DefaultMetricsPluginService<Ser>
where
Ser: Service<Request<ReqBody>, Response = Response<ResBody>>,
Ser: Service<HttpRequest, Response = HttpResponse>,
Ser::Future: Send + 'static,
{
/// Gets the default request metrics that can be retrieved from the request object directly
///
/// Assigns None to those that need information from the outer metrics layer to be set
fn get_default_request_metrics(&self, req: &Request<ReqBody>) -> DefaultRequestMetrics {
fn get_default_request_metrics(&self, req: &HttpRequest) -> DefaultRequestMetrics {
DefaultRequestMetrics {
service_name: Some(self.service_name.to_string()),
service_version: self.service_version.map(|n| n.to_string()),
Expand All @@ -226,16 +224,16 @@ where
}
}

impl<Ser> Service<Request<ReqBody>> for DefaultMetricsPluginService<Ser>
impl<Ser> Service<HttpRequest> for DefaultMetricsPluginService<Ser>
where
Ser: Service<Request<ReqBody>, Response = Response<ResBody>>,
Ser: Service<HttpRequest, Response = HttpResponse>,
Ser::Future: Send + 'static,
{
type Response = Ser::Response;
type Error = Ser::Error;
type Future = DefaultMetricsFuture<Ser::Future>;

fn call(&mut self, mut req: Request<ReqBody>) -> Self::Future {
fn call(&mut self, mut req: HttpRequest) -> Self::Future {
let mut stopwatch = Stopwatch::new();
let operation_timer_guard = stopwatch.start_owned();

Expand Down Expand Up @@ -306,7 +304,7 @@ where
}

fn get_default_response_metrics(
res: &Response<ResBody>,
res: &HttpResponse,
operation_time: Option<Duration>,
) -> DefaultResponseMetrics {
let status = res.status();
Expand Down
18 changes: 8 additions & 10 deletions rust-runtime/aws-smithy-http-server-metrics/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ use std::sync::atomic::Ordering;
use std::task::Context;
use std::task::Poll;

use http::Request;
use http::Response;
use pin_project_lite::pin_project;
use tower::Service;

Expand All @@ -22,8 +20,8 @@ use crate::traits::InitMetrics;
use crate::traits::ResponseMetrics;
use crate::traits::ThreadSafeCloseEntry;
use crate::traits::ThreadSafeEntrySink;
use crate::types::ReqBody;
use crate::types::ResBody;
use crate::types::HttpRequest;
use crate::types::HttpResponse;

pin_project! {
/// Future returned by [`MetricsLayerService`].
Expand All @@ -46,12 +44,12 @@ pin_project! {

impl<F, Entry, Sink, Res, Err> Future for MetricsLayerServiceFuture<F, Entry, Sink, Res>
where
F: Future<Output = Result<Response<ResBody>, Err>>,
F: Future<Output = Result<HttpResponse, Err>>,
Entry: ThreadSafeCloseEntry,
Sink: ThreadSafeEntrySink<Entry>,
Res: ResponseMetrics<Entry>,
{
type Output = Result<Response<ResBody>, Err>;
type Output = Result<HttpResponse, Err>;

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
// for safely accessing the pinned inner future
Expand Down Expand Up @@ -95,7 +93,7 @@ where
pub(crate) init_metrics: Init,
pub(crate) response_metrics: Option<Res>,
pub(crate) default_metrics_extension_fn: fn(
&mut Request<ReqBody>,
&mut HttpRequest,
&mut Entry,
DefaultRequestMetricsConfig,
DefaultResponseMetricsConfig,
Expand Down Expand Up @@ -129,10 +127,10 @@ where
}
}
}
impl<Ser, Entry, Sink, Init, Res> Service<Request<ReqBody>>
impl<Ser, Entry, Sink, Init, Res> Service<HttpRequest>
for MetricsLayerService<Ser, Entry, Sink, Init, Res>
where
Ser: Service<Request<ReqBody>, Response = Response<ResBody>> + Clone,
Ser: Service<HttpRequest, Response = HttpResponse> + Clone,
Ser::Future: Send + 'static,
Entry: ThreadSafeCloseEntry,
Sink: ThreadSafeEntrySink<Entry>,
Expand All @@ -147,7 +145,7 @@ where
self.inner.poll_ready(cx)
}

fn call(&mut self, mut req: Request<ReqBody>) -> Self::Future {
fn call(&mut self, mut req: HttpRequest) -> Self::Future {
let mut metrics = (self.init_metrics)(&mut req);

self.default_service_state
Expand Down
Loading
Loading