Skip to content

Comments

Add CloudWatch Observability#482

Merged
KaQuMiQ merged 1 commit intomainfrom
feature/cloudwatch
Jan 20, 2026
Merged

Add CloudWatch Observability#482
KaQuMiQ merged 1 commit intomainfrom
feature/cloudwatch

Conversation

@KaQuMiQ
Copy link
Collaborator

@KaQuMiQ KaQuMiQ commented Jan 20, 2026

No description provided.

@KaQuMiQ KaQuMiQ force-pushed the feature/cloudwatch branch from d4c73a9 to d159f07 Compare January 20, 2026 08:45
@coderabbitai
Copy link

coderabbitai bot commented Jan 20, 2026

Walkthrough

Adds CloudWatch observability to the Draive AWS package: new AWSCloudwatch state, AWSCloudwatchMixin (with put_log/put_event/put_metric and SDK error translation), CloudwatchObservability factory and ScopeStore-based span/attribute/metric/event plumbing, new CloudWatch-related Protocols in types, AWSAPI client initialization for CloudWatch clients, AWS client feature wiring, public exports updated, tests for CloudWatch helpers and ScopeStore, and a Makefile change removing .env include and bumping UV_VERSION. Also minor isinstance-to-union syntax updates in ollama and resources modules.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.89% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive No pull request description was provided, making it impossible to assess whether it relates to the changeset. Add a pull request description explaining the CloudWatch observability feature, its purpose, and how it integrates with the existing AWS module.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add CloudWatch Observability' directly and specifically describes the main purpose of the changeset—introducing CloudWatch observability integration to the draive.aws module.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@KaQuMiQ KaQuMiQ force-pushed the feature/cloudwatch branch from d159f07 to 4a97119 Compare January 20, 2026 08:47
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🤖 Fix all issues with AI agents
In `@src/draive/aws/cloudwatch.py`:
- Around line 197-216: The Sequence isinstance check in _render_dimension_value
can match str, but the prior isinstance(value, str) returns early; add a short
clarifying comment above the Sequence branch (inside _render_dimension_value)
explaining that strings are handled first to avoid the Sequence path because str
is a Sequence, so the ordering is intentional and required for correct behavior
(reference ObservabilityAttribute and the Sequence branch in
_render_dimension_value).
- Around line 219-239: The _sanitize_attributes function contains redundant type
branches that all assign the value to sanitized[key] except for None/MISSING and
empty sequences; simplify by iterating attributes.items(), skip values that are
None or MISSING, if isinstance(value, Sequence) and not value then continue,
otherwise assign sanitized[key] = value; keep references to
ObservabilityAttribute, MISSING, and the sanitized dict so behavior and typing
remain the same.
- Around line 19-36: The __slots__ on AWSCloudwatchMixin declare _events_buffer,
_logs_buffer, and _metrics_buffer but these attributes are never initialized or
used; either remove those names from __slots__ if no buffering is intended, or
implement buffering by initializing these attributes in
AWSCloudwatchMixin.__init__ (e.g., set self._events_buffer, self._logs_buffer,
self._metrics_buffer to appropriate container types) and add methods that
push/flush items to them (referencing AWSCloudwatchMixin, __slots__, and the
three buffer names to locate the exact changes).

In `@src/draive/aws/observability.py`:
- Around line 58-70: The code swallows exceptions during message formatting
(formatted_message = message % args) without any diagnostics; update the except
Exception block so that when formatting fails you emit a warning that includes
the failed message, the args and the exception details (e.g., via
scopes[scope.scope_id].record_log or the module logger) before falling back to
the original message so misconfigured log calls can be diagnosed; reference
formatted_message, args and scopes[scope.scope_id].record_log when adding the
warning.
- Around line 14-17: Update the imports so that ctx is imported from draive
while ObservabilityMetricKind remains imported from haiway.context: replace
"from haiway.context import ObservabilityMetricKind, ctx" with two imports —
"from haiway.context import ObservabilityMetricKind" and "from draive import
ctx" — leaving the existing references to MISSING and AWSCloudwatch unchanged;
ensure any usages of ctx still reference the same symbol.

In `@tests/test_aws_cloudwatch_observability.py`:
- Around line 9-34: Extract the helper function _load_cloudwatch_module into a
pytest fixture (e.g., named cloudwatch_module) with scope="module" or "session",
accept the builtin monkeypatch fixture, perform the same fake boto3/botocore
setup and importlib.import_module + importlib.reload of "draive.aws.cloudwatch",
and return the reloaded module; then update tests to accept the
cloudwatch_module fixture (replace explicit calls to
_load_cloudwatch_module(monkeypatch) with the fixture parameter) so the setup is
centralized and reused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In `@src/draive/aws/observability.py`:
- Around line 22-30: Add a NumPy-style docstring to the public factory/function
CloudwatchObservability documenting its parameters, return value, and possible
errors: list each parameter (log_level: ObservabilityLevel, log_group: str,
log_stream: str, event_bus: str, event_source: str, metrics_namespace: str)
under a "Parameters" section with types and brief purpose, add a "Returns"
section describing the Observability instance produced, and a "Raises" section
for any exceptions this function can propagate; place the docstring immediately
under the def CloudwatchObservability(...) signature and follow the project's
NumPy-style formatting conventions.

In `@src/draive/aws/state.py`:
- Around line 102-258: Add a NumPy-style class docstring to the AWSCloudwatch
class (place immediately below "class AWSCloudwatch(State):") describing the
class purpose and listing its public parameters/attributes (e.g., log_putting:
AWSCloudwatchLogPutting, metric_putting: AWSCloudwatchMetricPutting,
event_putting: AWSCloudwatchEventPutting), and include standard NumPy-style
sections such as Parameters, Attributes and Raises/Returns as appropriate; keep
the text concise and focused on what the class encapsulates and the types of its
injected collaborators so the docstring satisfies the project's docstring
guidelines.

In `@src/draive/aws/types.py`:
- Around line 99-132: Add NumPy-style docstrings to the three public Protocols
AWSCloudwatchLogPutting, AWSCloudwatchMetricPutting, and
AWSCloudwatchEventPutting: for each Protocol add a docstring describing the
purpose, a Parameters section listing each keyword-only parameter (name, type,
short description) and a Returns section (None), and include any notes about
expected formats (e.g., metric units, JSON detail string) if relevant; place the
docstrings immediately below each class definition so the public symbols are
documented per guidelines.

In `@tests/test_aws_state_observability.py`:
- Around line 28-186: Tests directly instantiate ScopeStore and call methods
(e.g., ScopeStore(...), record_scope_start, record_scope_end, record_attributes,
record_metric) which leaks global state; change both tests to create an isolated
scope via the context manager ctx.scope(...) (use "async with ctx.scope(...)"
passing the same
identifier/trace_id/log_group/log_stream/event_bus/event_source/metrics_namespace),
run the scope interactions (record_scope_start/record_scope_end or
record_attributes/record_metric) inside that async-with block, then await
asyncio.gather(*tasks) after exiting the block so background tasks are scoped
and state is isolated.
♻️ Duplicate comments (2)
src/draive/aws/cloudwatch.py (1)

20-24: Duplicate: unused buffer slots in AWSCloudwatchMixin.
This repeats a prior review note about _events_buffer, _logs_buffer, and _metrics_buffer being unused.

src/draive/aws/observability.py (1)

14-17: Import ctx from draive instead of haiway.context.
This violates the project import guideline for src/draive/**/*.py. As per coding guidelines, import ctx from draive while keeping ObservabilityMetricKind from haiway.context.

♻️ Suggested fix
-from haiway.context import ObservabilityMetricKind, ctx
+from haiway.context import ObservabilityMetricKind
+
+from draive import MISSING, ctx
-from draive import MISSING
-from draive.aws.state import AWSCloudwatch
+from draive.aws.state import AWSCloudwatch

To verify that ctx is exported from draive, you can run:

#!/bin/bash
rg -n "ctx" src/draive/__init__.py
rg -n "from draive import .*ctx" --type=py

@KaQuMiQ KaQuMiQ force-pushed the feature/cloudwatch branch from 4a97119 to 95ebb38 Compare January 20, 2026 09:28
@KaQuMiQ KaQuMiQ merged commit 3273156 into main Jan 20, 2026
2 checks passed
@KaQuMiQ KaQuMiQ deleted the feature/cloudwatch branch January 20, 2026 09:37
This was referenced Jan 21, 2026
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