Skip to content

feat: add CloudWatch Logs service#5

Merged
tyrchen merged 7 commits intomasterfrom
feat/cloudwatch-logs
Mar 18, 2026
Merged

feat: add CloudWatch Logs service#5
tyrchen merged 7 commits intomasterfrom
feat/cloudwatch-logs

Conversation

@tyrchen
Copy link
Owner

@tyrchen tyrchen commented Mar 18, 2026

Summary

  • Add native Rust CloudWatch Logs emulator with awsJson1.1 protocol (X-Amz-Target: Logs_20140328.*)
  • Model crate auto-generated from Smithy (43 operations, 22 shared types, 11 enums, camelCase serde)
  • DashMap-based provider implementing 40 operations across 4 phases
  • Full server integration with feature gate and gateway routing

Operations implemented

Phase Count Operations
0 10 Log group/stream CRUD, PutLogEvents, GetLogEvents, FilterLogEvents
1 11 Retention policies, tags (legacy + ARN), resource policies
2 7 Metric filters, subscription filters (metadata only)
3 12 Destinations, Insights query stubs, query definitions, KMS

Key design decisions

  • Smithy codegen: First service to use the new universal codegen tool (make codegen-logs)
  • camelCase JSON: CloudWatch Logs uses camelCase field naming (unlike most AWS services)
  • Cursor-based pagination: Uses name-based cursors for stable pagination over DashMap
  • Event ordering: Re-sorts stream events after each PutLogEvents to handle cross-batch timestamp overlap
  • AWS-compatible timestamps: endTime is exclusive (< not <=) per AWS docs

Test plan

  • 9 HTTP router unit tests (operation resolution, error cases)
  • 8 Rust integration tests (aws-sdk-cloudwatchlogs)
  • CI workflow (logs-test.yml) with 9 AWS CLI test steps
  • Run logs-test CI job and verify all steps pass
  • Verify existing service CI jobs are unaffected

🤖 Generated with Claude Code

tyrchen and others added 7 commits March 18, 2026 08:01
Implement native Rust CloudWatch Logs emulator with awsJson1.1 protocol.
Model crate auto-generated from Smithy (43 operations, 22 shared types).

New crates:
- ruststack-logs-model: Smithy-generated types with camelCase serde
- ruststack-logs-http: router (Logs_20140328.*), handler, hyper Service
- ruststack-logs-core: DashMap-based provider with all 40 operations

Phase 0 (10 ops): log group/stream CRUD, PutLogEvents, GetLogEvents,
  FilterLogEvents
Phase 1 (11 ops): retention policies, tags (legacy + ARN), resource policies
Phase 2 (7 ops): metric filters, subscription filters (metadata only)
Phase 3 (12 ops): destinations, Insights query stubs, query definitions,
  KMS key association

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add 8 integration tests using aws-sdk-cloudwatchlogs covering log group
CRUD, log stream CRUD, PutLogEvents/GetLogEvents, FilterLogEvents,
retention policies, tagging (modern TagResource API), resource policies,
and metric filters.

Add logs-test.yml CI workflow with AWS CLI-based tests for all
CloudWatch Logs operations.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix GetLogEvents pagination: encode cursor position in tokens
  (f/{index}, b/{index}) instead of random UUIDs
- Fix FilterLogEvents: collect ALL matching events globally before
  sort+truncate instead of breaking per-stream
- Fix end_time to be exclusive (< not <=) per AWS docs
- Fix DescribeLogGroups/Streams pagination: use name-based cursor
  instead of numeric offset for stability across DashMap mutations
- Fix PutLogEvents: re-sort stream events after appending to maintain
  time order across multiple batches

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
AWS CLI --output text returns 'None' for empty/null JMESPath results
instead of empty string. Check for both in assertions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add EVENTS_SKIP_SIGNATURE_VALIDATION and LOGS_SKIP_SIGNATURE_VALIDATION
to the integration workflow. Reduce SQS wait_time_seconds from 1 to 0
in the non-matching event delivery test to avoid unnecessary delays.
Add 10-minute timeout for integration test step.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ence

Replace the per-service skip_signature_validation flags with a simpler
model: signature validation is enabled when a credential provider is
configured (ACCESS_KEY/SECRET_KEY env vars set), disabled otherwise.

Changes:
- Remove skip_signature_validation from all 8 HttpConfig structs
- Remove skip_signature_validation from all 8 service Config structs
- Simplify auth check: `if let Some(cred) = &config.credential_provider`
- Remove all *_SKIP_SIGNATURE_VALIDATION env vars from 10 CI workflows
- Set ACCESS_KEY=test SECRET_KEY=test in all CI server startups
- Test clients already use matching test/test credentials

This ensures signatures are always validated in CI, catching any
auth-related regressions. Local dev without credentials still works
(no credential provider = no validation).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@tyrchen tyrchen merged commit aba20da into master Mar 18, 2026
14 checks passed
@tyrchen tyrchen deleted the feat/cloudwatch-logs branch March 18, 2026 15:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant