Skip to content
Merged
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
83 changes: 83 additions & 0 deletions docs/transaction_search.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Transaction Search

The AgentCore CLI automatically enables
[CloudWatch Transaction Search](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Transaction-Search.html)
as a post-deploy step whenever agents are deployed. This gives you full trace visibility for agent invocations without
any manual setup.

> Transaction search takes ~10 minutes to become fully active after being enabled. Traces from invocations made before
> that window may not be indexed.

## What happens by default

When you run `agentcore deploy` and the project contains at least one agent, the CLI performs the following steps after
the CloudFormation deployment succeeds:

1. **Enable Application Signals** — Calls `StartDiscovery` to create the required service-linked role (idempotent).
2. **Create CloudWatch Logs resource policy** — Adds a `TransactionSearchXRayAccess` resource policy that grants X-Ray
permission to write to the `aws/spans` and `/aws/application-signals/data` log groups. Skipped if the policy already
exists.
3. **Set trace segment destination** — Configures X-Ray to send trace segments to CloudWatch Logs (skipped if already
set).
4. **Set indexing to 100%** — Updates the X-Ray `Default` indexing rule to 100% probabilistic sampling so all traces are
indexed.

All operations are **idempotent** and safe to run on every deploy. Transaction search setup is **non-blocking** — if any
step fails (e.g., due to insufficient permissions), the deploy still succeeds and a warning is logged.

## Overriding defaults

You can customize transaction search behavior via the global CLI config file at `~/.agentcore/config.json`.

### Disable transaction search entirely

```json
{
"disableTransactionSearch": true
}
```

When disabled, the CLI skips all transaction search setup steps during deploy.

### Change the indexing percentage

By default, 100% of traces are indexed. To lower the sampling rate:

```json
{
"transactionSearchIndexPercentage": 50
}
```

The value must be a number between 0 and 100.

### Configuration reference

| Key | Type | Default | Description |
| ---------------------------------- | --------- | ------- | ----------------------------------------------- |
| `disableTransactionSearch` | `boolean` | `false` | Skip transaction search setup on deploy |
| `transactionSearchIndexPercentage` | `number` | `100` | X-Ray indexing rule sampling percentage (0–100) |

## Required IAM permissions

The following permissions are needed for the transaction search setup. If the caller lacks any of these, a warning is
logged but the deploy still succeeds.

- `application-signals:StartDiscovery`
- `logs:DescribeResourcePolicies`
- `logs:PutResourcePolicy`
- `xray:GetTraceSegmentDestination`
- `xray:UpdateTraceSegmentDestination`
- `xray:UpdateIndexingRule`

## Viewing traces

After transaction search is fully active (~10 minutes), you can view traces for your deployed agents:

```bash
# List recent traces
agentcore traces

# Get a specific trace
agentcore traces --trace-id <trace-id>
```
883 changes: 506 additions & 377 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
"aws-cdk-lib": "^2.240.0",
"constructs": "^10.4.4",
"esbuild": "^0.27.2",
"eslint": "^10.0.3",
"eslint": "^9.39.4",
"eslint-config-prettier": "^10.1.8",
"eslint-import-resolver-typescript": "^4.4.4",
"eslint-plugin-import": "^2.32.0",
Expand Down
6 changes: 6 additions & 0 deletions src/cli/commands/deploy/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -418,11 +418,16 @@ export async function handleDeploy(options: ValidatedDeployOptions): Promise<Dep

// Post-deploy: Enable CloudWatch Transaction Search (non-blocking, silent)
const nextSteps = agentNames.length > 0 ? [...AGENT_NEXT_STEPS] : [...MEMORY_ONLY_NEXT_STEPS];
const notes: string[] = [];
if (agentNames.length > 0) {
try {
const tsResult = await setupTransactionSearch({ region: target.region, accountId: target.account, agentNames });
if (tsResult.error) {
logger.log(`Transaction search setup warning: ${tsResult.error}`, 'warn');
} else {
notes.push(
'Transaction search enabled. It takes ~10 minutes for transaction search to be fully active and for traces from invocations to be indexed.'
);
}
} catch (err: unknown) {
logger.log(`Transaction search setup failed: ${getErrorMessage(err)}`, 'warn');
Expand All @@ -438,6 +443,7 @@ export async function handleDeploy(options: ValidatedDeployOptions): Promise<Dep
outputs,
logPath: logger.getRelativeLogPath(),
nextSteps,
notes,
};
} catch (err: unknown) {
logger.log(getErrorMessage(err), 'error');
Expand Down
6 changes: 6 additions & 0 deletions src/cli/commands/deploy/command.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ async function handleDeployCLI(options: DeployOptions): Promise<void> {
}
}

if (result.notes && result.notes.length > 0) {
for (const note of result.notes) {
console.log(`\nNote: ${note}`);
}
}

if (result.nextSteps && result.nextSteps.length > 0) {
console.log(`Next: ${result.nextSteps.join(' | ')}`);
}
Expand Down
1 change: 1 addition & 0 deletions src/cli/commands/deploy/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface DeployResult {
outputs?: Record<string, string>;
logPath?: string;
nextSteps?: string[];
notes?: string[];
error?: string;
}

Expand Down
11 changes: 11 additions & 0 deletions src/cli/tui/screens/deploy/DeployScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export function DeployScreen({
deployMessages,
diffSummaries,
numStacksWithChanges,
deployNotes,
isDiffLoading,
requestDiff,
hasError,
Expand Down Expand Up @@ -355,6 +356,16 @@ export function DeployScreen({
</Box>
)}

{allSuccess && deployNotes.length > 0 && (
<Box flexDirection="column" marginTop={1}>
{deployNotes.map((note, i) => (
<Text key={i} dimColor>
Note: {note}
</Text>
))}
</Box>
)}

{allSuccess && targetStatuses.length > 0 && (
<Box flexDirection="column" marginTop={1}>
<Text bold>Gateway Targets:</Text>
Expand Down
9 changes: 9 additions & 0 deletions src/cli/tui/screens/deploy/useDeployFlow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ interface DeployFlowState {
diffSummaries: StackDiffSummary[];
/** Number of stacks with changes (from overall diff result) */
numStacksWithChanges?: number;
/** Notes to display after successful deploy (e.g., transaction search info) */
deployNotes: string[];
/** Whether an on-demand diff is currently running */
isDiffLoading: boolean;
/** Request an on-demand diff (lazy: runs once, caches result) */
Expand Down Expand Up @@ -122,6 +124,7 @@ export function useDeployFlow(options: DeployFlowOptions = {}): DeployFlowState
const [diffSummaries, setDiffSummaries] = useState<StackDiffSummary[]>([]);
const [numStacksWithChanges, setNumStacksWithChanges] = useState<number | undefined>();
const [isDiffLoading, setIsDiffLoading] = useState(false);
const [deployNotes, setDeployNotes] = useState<string[]>([]);
const isDiffRunningRef = useRef(false);
const [deployOutput, setDeployOutput] = useState<string | null>(null);
const [deployMessages, setDeployMessages] = useState<DeployMessage[]>([]);
Expand Down Expand Up @@ -386,6 +389,11 @@ export function useDeployFlow(options: DeployFlowOptions = {}): DeployFlowState
});
if (tsResult.error) {
logger.log(`Transaction search setup warning: ${tsResult.error}`, 'warn');
} else {
setDeployNotes(prev => [
...prev,
'Transaction search enabled. It takes ~10 minutes for transaction search to be fully active and for traces from invocations to be indexed.',
]);
}
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error';
Expand Down Expand Up @@ -601,6 +609,7 @@ export function useDeployFlow(options: DeployFlowOptions = {}): DeployFlowState
deployMessages,
diffSummaries,
numStacksWithChanges,
deployNotes,
isDiffLoading,
requestDiff,
stackOutputs,
Expand Down
Loading