metricscloudwatchembedded

Crates.io version shield Crates.io license shield

The interface is not stable

Purpose

Provide a backend for the metrics facade crate, to emit metrics in CloudWatch Embedded Metrics Format

Simple Example

```rust let metrics = metricscloudwatchembedded::Builder::new() .cloudwatch_namespace("MyApplication") .init() .unwrap();

metrics::increment_counter!("requests", "Method" => "Default");

metrics .set_property("RequestId", "ABC123") .flush(std::io::stdout()); ```

AWS Lambda Example

The Lambda Runtime intergration feature handles flushing metrics after each invoke via either run() alternatives or MetricService which inplements the tower::Service trait.

It also provides optional helpers for: * emiting a metric on cold starts * wrapping cold starts in a tracing span * decorating metric documents with request id and/or x-ray trace id

In your Cargo.toml add: toml metrics = "0.21" metrics_cloudwatch_embedded = { version = "0.4.0", features = ["lambda"] } tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "env-filter", "json"] }

main.rs: ```rust use lambdaruntime::{Error, LambdaEvent}; use metricscloudwatch_embedded::lambda::handler::run; use serde::{Deserialize, Serialize}; use tracing::{info, span, Level};

[derive(Deserialize)]

struct Request {}

[derive(Serialize)]

struct Response { req_id: String, }

async fn functionhandler(event: LambdaEvent) -> Result { let resp = Response { reqid: event.context.request_id.clone(), };

info!("Hello from function_handler");

metrics::increment_counter!("requests", "Method" => "Default");

Ok(resp)

}

[tokio::main]

async fn main() -> Result<(), Error> { tracingsubscriber::fmt() .json() .withenvfilter(tracingsubscriber::filter::EnvFilter::fromdefaultenv()) .withtarget(false) .withcurrentspan(false) .withouttime() .init();

let metrics = metrics_cloudwatch_embedded::Builder::new()
    .cloudwatch_namespace("MetricsTest")
    .with_dimension("Function", std::env::var("AWS_LAMBDA_FUNCTION_NAME").unwrap())
    .lambda_cold_start_span(span!(Level::INFO, "cold start").entered())
    .lambda_cold_start_metric("ColdStart")
    .with_lambda_request_id("RequestId")
    .init()
    .unwrap();

info!("Hello from main");

run(metrics, function_handler).await

} CloudWatch log after a single invoke (cold start): plaintext INITSTART Runtime Version: provided:al2.v19 Runtime Version ARN: arn:aws:lambda:us-west-2::runtime:d1007133cb0d993d9a42f9fc10442cede0efec65d732c7943b51ebb979b8f3f8 {"level":"INFO","fields":{"message":"Hello from main"},"spans":[{"name":"cold start"}]} START RequestId: fce53486-160d-41e8-b8c3-8ef0fd0f4051 Version: $LATEST {"aws":{"Timestamp":1688294472338,"CloudWatchMetrics":[{"Namespace":"MetricsTest","Dimensions":[["Function"]],"Metrics":[{"Name":"ColdStart","Unit":"Count"}]}]},"Function":"MetricsTest","RequestId":"fce53486-160d-41e8-b8c3-8ef0fd0f4051","ColdStart":1} {"level":"INFO","fields":{"message":"Hello from functionhandler"},"spans":[{"name":"cold start"},{"requestId":"fce53486-160d-41e8-b8c3-8ef0fd0f4051","xrayTraceId":"Root=1-64a15448-4aa914a00d66aa066325d7e3;Parent=60a7d0c22fb2f001;Sampled=0;Lineage=16f3a795:0","name":"Lambda runtime invoke"}]} {"aws":{"Timestamp":1688294472338,"CloudWatchMetrics":[{"Namespace":"MetricsTest","Dimensions":[["Function","Method"]],"Metrics":[{"Name":"requests"}]}]},"Function":"MetricsTest","Method":"Default","RequestId":"fce53486-160d-41e8-b8c3-8ef0fd0f4051","requests":1} END RequestId: fce53486-160d-41e8-b8c3-8ef0fd0f4051 REPORT RequestId: fce53486-160d-41e8-b8c3-8ef0fd0f4051 Duration: 1.22 ms Billed Duration: 11 ms Memory Size: 128 MB Max Memory Used: 13 MB Init Duration: 8.99 ms ```

Limitations

Supported Rust Versions (MSRV)

The AWS Lambda Rust Runtime requires a minimum of Rust 1.62, and is not guaranteed to build on compiler versions earlier than that.

This may change when async traits are released to stable depending on the ripple effects to the ecosystem.

License

This project is licensed under the Apache-2.0 License. Apache-2.0 was chosen to match the Lambda Runtime

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be licensed as above, without any additional terms or conditions.

Thanks