Skip to content

feat: add shared observability abstractions and wire to runtime log handler - #2169

Merged
jariy17 merged 1 commit into
refactorfrom
logs-scaffold
Sep 2, 2026
Merged

feat: add shared observability abstractions and wire to runtime log handler#2169
jariy17 merged 1 commit into
refactorfrom
logs-scaffold

Conversation

@nborges-aws

@nborges-aws nborges-aws commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Description

This PR adds reusable observability infrastructure and wires the imperative agentcore runtime logs command to it. Remaining wiring, as well as traces and project based observability are planned as follow ups to this PR.

Each primitive handler resolves its own log source, while the shared observability client handles provider-independent log operations. CloudWatch-specific mechanics remain isolated behind a dedicated client.

Original PR and discussion: PR #2147

  • Adds a reusable, logs-only ObservabilityClient as the shared API entry point
  • Adds a CloudWatchClient responsible for CloudWatch request handling and event normalization
  • Adds a shared logs handler for common observability flags and behavior. Resource specific logic is set up per primitive handler.
  • Wires the imperative agentcore runtime logs command to the shared infrastructure
  • Preserves legacy trace and project behavior without duplicating the logs implementation

Note: legacy observability.ts client still exists to support project resolution methods and trace methods. As those are OOS for this PR. Follow ups to this PR will contain logic scaffolding project based & trace infra, at which point legacy client will be removed and logic shifted.

Architecture

primitive logs handler
 → shared logs handler
 → ObservabilityClient
 → CloudWatchClient
 → CloudWatch Logs

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Other (please describe):

Testing

How have you tested the change?

  • bun run test (2764 pass, 0 fail)
  • I ran npm run test:unit and npm run test:integ
  • I ran npm run typecheck
  • I ran npm run lint
  • If I modified src/assets/, I ran npm run test:update-snapshots and committed the updated snapshots

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the
terms of your choice.


Stack created with GitHub Stacks CLIGive Feedback 💬

@github-actions github-actions Bot added the size/xl PR size: XL label Sep 2, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added agentcore-harness-reviewing AgentCore Harness review in progress claude-security-reviewing Claude Code /security-review in progress labels Sep 2, 2026
@github-actions github-actions Bot added size/xl PR size: XL and removed size/xl PR size: XL labels Sep 2, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Sep 2, 2026
@codecov-commenter

codecov-commenter commented Sep 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.03722% with 20 lines in your changes missing coverage. Please review.
✅ Project coverage is 97.12%. Comparing base (89d302b) to head (956414f).

Files with missing lines Patch % Lines
src/core/observability/client.ts 40.00% 15 Missing ⚠️
src/core/observability/insights.ts 91.80% 5 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##           refactor    #2169      +/-   ##
============================================
- Coverage     97.16%   97.12%   -0.05%     
============================================
  Files           519      525       +6     
  Lines         35506    35698     +192     
============================================
+ Hits          34500    34672     +172     
- Misses         1006     1026      +20     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@agentcore-devx-automation agentcore-devx-automation Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AgentCore Harness Review

Verdict: Looks good

Scanned the new src/core/observability/* and src/handlers/observability/* modules and their tests. The abstractions look clean and I didn't find any serious issues that need to change before merging:

  • The ObservabilityClientSourceReader → resolver split is well-scoped, and the barrel import path (core/observability/index) is intentionally used until the legacy src/core/observability.ts is migrated (per the in-file comments).
  • Mocking is kept at proper boundaries — SourceReader and CloudWatchLogsClient fakes in unit tests, and the fixture test drives the whole handler stack through recorded SDK responses via fixtureFactories. No excessive mocking.
  • CloudWatchSourceReader.searchLogs correctly clamps per-page limit to 10 000, guards against nextToken cycles, and translates ResourceNotFoundException into a customer-facing ResourceNotFoundError for all three operations.
  • Live Tail loop handles both the streamed SessionTimeoutException event and the thrown-exception form, respects AbortSignal inside the inner loop, and strips the legacy :* ARN suffix that StartLiveTail rejects.
  • resolveTimeWindow pins now() to a single reference so --since 1h and --until 30m compute against the same instant, and validates window ordering.
  • Telemetry is emitted centrally via the router's cli.command_run wrapper, so no per-handler instrumentation is required here.

Minor nits I intentionally didn't flag (not blocking):

  • runInsightsQuery re-fetches page 0 after polling completes rather than reusing the results from the final poll response — extra API call, but harmless.
  • sanitizeQueryValue is exported but not yet used inside this PR; presumably picked up by a follow-up caller.

Ship it.

@agentcore-devx-automation agentcore-devx-automation Bot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Sep 2, 2026
@github-actions github-actions Bot added size/xl PR size: XL and removed size/xl PR size: XL labels Sep 2, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Sep 2, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Sep 2, 2026
@github-actions github-actions Bot added size/xl PR size: XL and removed size/xl PR size: XL labels Sep 2, 2026
@nborges-aws nborges-aws changed the title feat: add shared observability abstractions feat: add shared observability abstractions and wire to runtime log handler Sep 2, 2026
@github-actions github-actions Bot added size/xl PR size: XL and removed size/xl PR size: XL labels Sep 2, 2026
@github-actions github-actions Bot added size/xl PR size: XL and removed size/xl PR size: XL labels Sep 2, 2026
options: CoreOptions,
signal?: AbortSignal,
): AsyncGenerator<CloudWatchLogEvent, void> {
if (query.limit !== undefined && query.limit <= 0) return;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is there a reason why we aren't throwing an InputValidationError? I think we should rather than silently returning.

let nextToken: string | undefined;
let yielded = 0;

do {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

OOS: We should use create a paginator helper in the future.

@jariy17
jariy17 merged commit ff62e76 into refactor Sep 2, 2026
32 of 34 checks passed
@jariy17
jariy17 deleted the logs-scaffold branch September 2, 2026 21:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/xl PR size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants