Conversation
d4c73a9 to
d159f07
Compare
WalkthroughAdds 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 Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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. Comment |
d159f07 to
4a97119
Compare
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 inAWSCloudwatchMixin.
This repeats a prior review note about_events_buffer,_logs_buffer, and_metrics_bufferbeing unused.src/draive/aws/observability.py (1)
14-17: Importctxfromdraiveinstead ofhaiway.context.
This violates the project import guideline for src/draive/**/*.py. As per coding guidelines, importctxfromdraivewhile keepingObservabilityMetricKindfromhaiway.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 AWSCloudwatchTo verify that
ctxis exported fromdraive, you can run:#!/bin/bash rg -n "ctx" src/draive/__init__.py rg -n "from draive import .*ctx" --type=py
4a97119 to
95ebb38
Compare
No description provided.