Skip to content

feat(datadog-aws): add per-service interceptor crates for SQS, SNS, and EventBridge#189

Open
Dogbu-cyber wants to merge 16 commits intodavid.ogbureke/ci-integration-msrvfrom
david.ogbureke/aws-sdk-rust
Open

feat(datadog-aws): add per-service interceptor crates for SQS, SNS, and EventBridge#189
Dogbu-cyber wants to merge 16 commits intodavid.ogbureke/ci-integration-msrvfrom
david.ogbureke/aws-sdk-rust

Conversation

@Dogbu-cyber
Copy link
Copy Markdown

@Dogbu-cyber Dogbu-cyber commented Mar 17, 2026

PR Stack: #194 (workspace setup) -> #189 (aws-sdk injection) -> #190 (lambda consumer)

What does this PR do?

Adds trace context injection for the AWS SDK for Rust via three focused interceptor crates. Each crate pulls in only the AWS SDK dependency it needs — users add only what they use.

Crate architecture

instrumentation/
├── datadog-aws-core/       # internal — ServiceHandler trait, generic AwsInterceptor,
│                           #            attribute_keys, limits (not published)
├── datadog-aws-sqs/        # SqsInterceptor
├── datadog-aws-sns/        # SnsInterceptor
└── datadog-aws-eventbridge/ # EventBridgeInterceptor

Usage

// Only pull in the services you use
use datadog_aws_sqs::SqsInterceptor;
use datadog_aws_sns::SnsInterceptor;
use datadog_aws_eventbridge::EventBridgeInterceptor;

let sqs = aws_sdk_sqs::Client::from_conf(
    config.to_builder().interceptor(SqsInterceptor::new()).build()
);

Supported operations

Service Inject operations Tag-only operations Injection point
SQS SendMessage, SendMessageBatch ReceiveMessage, DeleteMessage, DeleteMessageBatch _datadog MessageAttribute (String, JSON)
SNS Publish, PublishBatch GetTopicAttributes, ListSubscriptionsByTopic, Subscribe, CreateTopic, etc. _datadog MessageAttribute (Binary) — avoids subscription filter policy interference
EventBridge PutEvents PutRule, PutTargets, DescribeRule, etc. _datadog key in event detail JSON

Each interceptor also creates a client span (sqs.request, sns.request, eventbridge.request) with standard Datadog tags: aws.service, aws.operation, aws.region, aws.partition, resource.name, operation.name, etc.

Design notes

  • datadog-aws-core exposes a ServiceHandler trait; each service crate implements it and wraps the generic AwsInterceptor in a concrete named type (SqsInterceptor etc.)
  • Injection never fails an AWS call — errors are swallowed and logged at debug level
  • SQS/SNS respect the 10-attribute cap but overwrite a stale _datadog attribute if present
  • EventBridge skips injection if the resulting detail would exceed 1 MB
  • Integration test infrastructure (mock_aws, init_test_tracer, sdk_config, span_attrs) lives in datadog-aws-core behind a test-utils feature flag, so service test files contain only the client builder and test cases

@Dogbu-cyber Dogbu-cyber added the enhancement New feature or request label Mar 17, 2026
@Dogbu-cyber Dogbu-cyber marked this pull request as ready for review March 17, 2026 22:01
@Dogbu-cyber Dogbu-cyber requested a review from a team as a code owner March 17, 2026 22:01
Comment thread integrations/aws/aws-sdk-rust/README.md Outdated
@ygree
Copy link
Copy Markdown

ygree commented Mar 18, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 302fbb5267

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread integrations/aws/aws-sdk-rust/Cargo.toml Outdated
Comment thread integrations/aws/aws-sdk-rust/src/services/sns.rs Outdated
Comment thread integrations/aws/aws-sdk-rust/src/services/sqs.rs Outdated
@Dogbu-cyber Dogbu-cyber changed the base branch from main to david.ogbureke/ci-integration-msrv March 22, 2026 00:54
@Dogbu-cyber Dogbu-cyber force-pushed the david.ogbureke/aws-sdk-rust branch from ee01b82 to 612838b Compare March 22, 2026 00:55
@Dogbu-cyber Dogbu-cyber force-pushed the david.ogbureke/ci-integration-msrv branch 2 times, most recently from 141c5dd to 1184437 Compare March 22, 2026 20:52
@Dogbu-cyber Dogbu-cyber force-pushed the david.ogbureke/aws-sdk-rust branch from 612838b to 4f7442a Compare March 23, 2026 14:54
@Dogbu-cyber Dogbu-cyber changed the title AWS SDK Integration feat(datadog-aws-sdk): add trace context injection for SQS, SNS, and EventBridge Mar 23, 2026
Copy link
Copy Markdown

@joeyzhao2018 joeyzhao2018 left a comment

Choose a reason for hiding this comment

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

LGTM

@Dogbu-cyber Dogbu-cyber force-pushed the david.ogbureke/aws-sdk-rust branch from 3fa3937 to 80424aa Compare March 30, 2026 19:20
@Dogbu-cyber
Copy link
Copy Markdown
Author

@codex review

@Dogbu-cyber Dogbu-cyber force-pushed the david.ogbureke/aws-sdk-rust branch from 80424aa to 80fedd0 Compare March 30, 2026 19:26
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 80424aa3a6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +148 to +150
// EventBridge entries have a 1 MB detail size limit.
if new_detail.len() > ONE_MB {
continue;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Validate full PutEvents entry size before mutating Detail

The size guard only checks new_detail.len(), but EventBridge enforces the 1 MB limit on the entire PutEventsRequestEntry payload, not just the Detail field. If an entry is already near the limit because of Source, DetailType, Resources, etc., adding _datadog can push the total entry size over quota and make PutEvents fail, even though tracing is intended to be non-intrusive. This should use the documented entry-size calculation (or equivalent full-entry check) before writing the mutated detail.

Useful? React with 👍 / 👎.

@Dogbu-cyber Dogbu-cyber force-pushed the david.ogbureke/ci-integration-msrv branch 2 times, most recently from 17f2c7a to 78a6876 Compare March 30, 2026 20:30
@Dogbu-cyber Dogbu-cyber force-pushed the david.ogbureke/aws-sdk-rust branch from 80fedd0 to 18c7914 Compare March 30, 2026 20:48
@Dogbu-cyber Dogbu-cyber force-pushed the david.ogbureke/ci-integration-msrv branch from 78a6876 to bf4ea81 Compare April 2, 2026 14:54
@Dogbu-cyber Dogbu-cyber force-pushed the david.ogbureke/aws-sdk-rust branch 2 times, most recently from 35b2e4f to 7d1fbbe Compare April 2, 2026 15:32
@Dogbu-cyber Dogbu-cyber force-pushed the david.ogbureke/aws-sdk-rust branch from 29211f0 to d999596 Compare April 13, 2026 12:51
Comment on lines +53 to +56
loop {
let Ok((stream, _)) = listener.accept().await else {
break;
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
loop {
let Ok((stream, _)) = listener.accept().await else {
break;
};
while let Ok((stream, _)) = listener.accept().await {

// before extracting trace headers so the injected context points to
// this span, not the caller's span.
let parent_cx = Context::current();
let tracer = global::tracer(TRACER_NAME);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

global::tracer(TRACER_NAME) is called on every AWS SDK invocation, but it acquires an RwLock read guard and boxes a new tracer each time for a constant name. Consider resolving it once in new() and storing it as an Arc<BoxedTracer> field.

@Dogbu-cyber Dogbu-cyber force-pushed the david.ogbureke/aws-sdk-rust branch 2 times, most recently from 7e64f6f to f1e120e Compare April 14, 2026 18:06
};
let span = span_ctx.0.span();

// Re-set response tags to cover cases where read_after_transmit did not run
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

read_after_transmit seems to be redundant

@Dogbu-cyber Dogbu-cyber force-pushed the david.ogbureke/aws-sdk-rust branch from f1e120e to 802625e Compare April 16, 2026 20:38
@Dogbu-cyber Dogbu-cyber changed the title feat(datadog-aws-sdk): add trace context injection for SQS, SNS, and EventBridge feat(datadog-aws): add per-service interceptor crates for SQS, SNS, and EventBridge Apr 16, 2026
…ventBridge

Implements Datadog trace context injection for the AWS SDK for Rust via
three focused interceptor crates, each pulling in only the AWS SDK
dependency it needs:

- datadog-aws-core: shared ServiceHandler trait and generic AwsInterceptor
  (internal, not published)
- datadog-aws-sqs: SqsInterceptor
- datadog-aws-sns: SnsInterceptor
- datadog-aws-eventbridge: EventBridgeInterceptor

Each interceptor creates a client span for the operation and injects
Datadog trace context into the outbound payload:
- SQS: String message attribute (_datadog, JSON)
- SNS: Binary message attribute (_datadog) to avoid filter policy interference
- EventBridge: _datadog key in the PutEvents detail JSON field

Injection respects service limits (SQS/SNS 10-attribute cap, EventBridge
1 MB detail limit) and never fails an AWS call on injection error.
Move mock_aws, init_test_tracer, sdk_config, span_attrs, extract_traceparent,
and split_traceparent into datadog-aws-core behind a test-utils feature flag.

Each service crate's integration test now imports from core rather than
duplicating ~80 lines of infrastructure. Service test dev-dependencies drop
from 9 entries to 4 (core+test-utils, aws-types, serial_test, tokio).
Move ONE_MB and MAX_MESSAGE_ATTRIBUTES out of individual service crates and
into datadog-aws-core/src/limits.rs. Both constants were either duplicated
(MAX_MESSAGE_ATTRIBUTES in SQS and SNS) or service-local despite being
applicable across multiple services.
- Drop PropagatorCarrier newtype: opentelemetry provides impl Injector for
  HashMap<String, String> out of the box, making the wrapper redundant
- Change base_tags visibility from pub to pub(crate): it is an internal
  helper for AwsInterceptor, not part of the public API
- Use serde_json::to_value in inject_into_put_events instead of manually
  mapping trace_headers into serde_json::Value::String entries
@Dogbu-cyber Dogbu-cyber force-pushed the david.ogbureke/ci-integration-msrv branch from d4b18bd to 642bdfd Compare April 16, 2026 21:09
@Dogbu-cyber Dogbu-cyber force-pushed the david.ogbureke/aws-sdk-rust branch from 2cfa3be to 5cf7cc6 Compare April 16, 2026 21:09
@Dogbu-cyber Dogbu-cyber force-pushed the david.ogbureke/aws-sdk-rust branch from 5cf7cc6 to 778b9a8 Compare April 16, 2026 21:38
@Dogbu-cyber Dogbu-cyber requested a review from ygree April 17, 2026 13:16
- Module-level `//!` doc on `interceptor` explaining the 3-hook pipeline
- Field/function docs on `SpanContext`, `extract_trace_headers`,
  `set_response_tags`, `partition_from_region`, `base_tags`, and
  `AwsInterceptor::new`; existing inline comments promoted to `///`
- Per-hook docs on `modify_before_serialization`, `read_before_transmit`,
  and `read_after_execution`
- `#![cfg_attr(not(test), deny(clippy::panic/unwrap_used/expect_used))]`
  so tracing can never crash a customer AWS call
- `SqsOperation` enum and `from_name` doc explaining which ops inject
- `SqsHandler`, `inject`, `service_tags`, `inject_into_send_message`,
  `inject_into_send_message_batch`, `extract_sqs_metadata`, and
  `build_datadog_attribute` all documented
- `should_skip_injection` inline comment promoted to `///` doc
- `#![cfg_attr(not(test), deny(clippy::panic/unwrap_used/expect_used))]`
- `SnsOperation` enum and `from_name` doc explaining which ops inject
- `SnsHandler`, `inject`, `service_tags`, `inject_into_publish`,
  `inject_into_publish_batch`, `HasTopicArn`, `topic_arn_tag`, and
  `arn_resource_name` all documented
- `should_skip_injection` inline comment promoted to `///` doc
- `build_datadog_attribute` inline comment about Binary-vs-String
  promoted to `///` doc (SNS filter policy behaviour)
- `#![cfg_attr(not(test), deny(clippy::panic/unwrap_used/expect_used))]`
- `EventBridgeOperation` enum and `from_name` doc explaining which ops inject
- `EventBridgeHandler`, `inject`, `service_tags`, `extract_rule_name`
  (field name difference between rule-management ops), and
  `inject_into_put_events` (detail merge, start timestamp, size limit,
  and skip conditions) all documented
- `inject` inline comment promoted to `///` doc
- `#![cfg_attr(not(test), deny(clippy::panic/unwrap_used/expect_used))]`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants