aws-samples / aws-samples/sample-agent-assisted-sdlc
feat: add observability (APPLICATION_LOGS + X-Ray + Identity) to AgentCore Gateway
- Dominant language
- Python
- Stars
- 42
- Forks
- 9
- PR merge metrics
- No merged PRs in 30d
Description
## Description
Add observability delivery to the AgentCore Gateway using the existing `RuntimeObservability` construct. The gateway has a different log group pattern than runtimes and does NOT have USAGE_LOGS.
## Context
PRs #80 and #86 deployed observability for the coding assistant and MCP server runtimes respectively. The gateway is the last resource without observability configured.
**Key difference from runtimes:**
- Gateway log group: `/aws/vendedlogs/bedrock-agentcore/gateway/APPLICATION_LOGS/{GatewayID}`
- Runtime log group: `/aws/vendedlogs/bedrock-agentcore/runtime/APPLICATION_LOGS/{runtimeId}`
- Gateway does **NOT** have `USAGE_LOGS` (only runtimes do)
## What to do
### 1. Generalize `RuntimeObservability` construct
Add a `resourceType` prop to `lib/constructs/observability/runtime-observability.ts`:
```typescript
interface RuntimeObservabilityProps {
runtimeArn: string;
runtimeId: string;
resourceType?: "runtime" | "gateway"; // default: "runtime"
logRetentionDays?: number;
enableIdentityLogs?: boolean;
}
```
When `resourceType = "gateway"`:
- APPLICATION_LOGS log group: `/aws/vendedlogs/bedrock-agentcore/gateway/APPLICATION_LOGS/{runtimeId}` (use `gateway` instead of `runtime`)
- Skip USAGE_LOGS entirely (don't create LogGroup, DeliverySource, DeliveryDestination, Delivery for usage)
- X-Ray TRACES: same pattern as runtime (custom resource Lambda)
- Identity: same pattern (shared `/aws/vendedlogs/bedrock-agentcore/workload-identity-directory/APPLICATION_LOGS/default`)
### 2. Add IAM to gateway role
In `lib/constructs/gateway/mcp-gateway.ts`, add to the gateway role:
```typescript
gatewayRole.addToPolicy(new iam.PolicyStatement({
actions: ["bedrock-agentcore:AllowVendedLogDeliveryForResource"],
resources: ["*"],
}));
gatewayRole.addToPolicy(new iam.PolicyStatement({
actions: ["cloudwatch:PutMetricData"],
resources: ["*"],
conditions: { StringEquals: { "cloudwatch:namespace": "bedrock-agentcore" } },
}));
```
### 3. Instantiate in gateway stack
In `lib/nested/gateway-stack.ts`:
```typescript
import { RuntimeObservability } from "../constructs/observability/runtime-observability";
new RuntimeObservability(this, "Observability", {
runtimeArn: this.gateway.gatewayArn,
runtimeId: this.gateway.gatewayId,
resourceType: "gateway",
logRetentionDays: 30,
});
```
## Gateway deliveries (3 total)
| Tab | Log Type | Destination | Log Group |
|-----|----------|-------------|-----------|
| Gateway | `APPLICATION_LOGS` | CWL | `/aws/vendedlogs/bedrock-agentcore/gateway/APPLICATION_LOGS/{gatewayId}` |
| Gateway | `TRACES` | X-Ray | (custom resource) |
| Identity | `APPLICATION_LOGS` | CWL | `/aws/vendedlogs/bedrock-agentcore/workload-identity-directory/APPLICATION_LOGS/default` (shared) |
## Acceptance Criteria
- [ ] `RuntimeObservability` accepts `resourceType?: "runtime" | "gateway"` prop (default: `"runtime"`)
- [ ] When `resourceType = "gateway"`: log group uses `/gateway/APPLICATION_LOGS/` prefix, no USAGE_LOGS created
- [ ] Gateway role has `AllowVendedLogDeliveryForResource` + `cloudwatch:PutMetricData`
- [ ] `RuntimeObservability` instantiated in gateway stack with `resourceType: "gateway"`
- [ ] Existing runtime observability (assistant + MCP servers) unchanged (default `resourceType: "runtime"`)
- [ ] `npx cdk synth --quiet` passes
- [ ] All delivery source/destination names ≤60 chars
- [ ] Post-deploy: Gateway shows APPLICATION_LOGS + TRACES in AgentCore console
## Files to modify
```
lib/constructs/observability/runtime-observability.ts MODIFY — add resourceType prop, conditional USAGE_LOGS
lib/constructs/gateway/mcp-gateway.ts MODIFY — add IAM for observability
lib/nested/gateway-stack.ts MODIFY — instantiate RuntimeObservability
```
## Constraints
- The `gatewayId` is already exposed by `McpGateway` construct (`this.gateway.gatewayId`)
- The `gatewayArn` is already exposed (`this.gateway.gatewayArn`)
- Shared Identity log group is idempotent (custom resource handles it)
- Do NOT break existing runtime/MCP server observability
Contributor guide
Assessment
This issue has not been assessed yet.