Skip to content

Fix: offload of kafka-internal metrics to faststream middleware - #243

Merged
HardMax71 merged 4 commits into
mainfrom
fix/backend-code
Mar 1, 2026
Merged

Fix: offload of kafka-internal metrics to faststream middleware#243
HardMax71 merged 4 commits into
mainfrom
fix/backend-code

Conversation

@HardMax71

@HardMax71 HardMax71 commented Mar 1, 2026

Copy link
Copy Markdown
Owner

Summary by cubic

Offloaded Kafka transport metrics to FastStream KafkaTelemetryMiddleware and introduced KafkaEventTransport for publishing. Simplified EventMetrics to domain-only metrics and updated dashboards to use messaging_* and event_processing_errors_*.

  • Refactors

    • Removed Kafka and event-bus metrics from EventMetrics; keep published, processing duration, and errors.
    • Added KafkaEventTransport; UnifiedProducer now delegates publish after storing (outbox).
    • Updated providers, handlers, and worker to remove direct Kafka metric recording; SSE consumer metrics removed.
    • Grafana: switched to messaging_* metrics, removed Event Bus Queue Size, and retitled errors panels.
    • Marking publish_failed is now best-effort and non-blocking; repository logs if marking fails.
  • Migration

    • Ensure KafkaTelemetryMiddleware is enabled on the FastStream broker to emit messaging_* metrics.
    • Update dashboards/alerts to the new metric names; remove event_bus_queue_size and Kafka-specific metrics.

Written for commit b358cc9. Summary will update on new commits.

Summary by CodeRabbit

  • Monitoring & Observability
    • Simplified metrics to domain-level (publishing, processing duration, errors); removed low-level transport/Kafka metrics and updated dashboards and metric names/labels accordingly.
  • Reliability
    • Publishing failure handling made best-effort: failures are logged and do not propagate; event publish failures are marked without raising.
  • Documentation
    • Updated README badge link for the dead-code workflow.

Copilot AI review requested due to automatic review settings March 1, 2026 22:10
@coderabbitai

coderabbitai Bot commented Mar 1, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Adds a KafkaEventTransport and rewires UnifiedProducer and messaging providers to use it; removes Kafka/transport-level metrics and related methods from EventMetrics and handlers/workers; updates Grafana dashboards and tests; makes mark_publish_failed best-effort; README badge path updated.

Changes

Cohort / File(s) Summary
Transport & exports
backend/app/events/core/transport.py, backend/app/events/core/__init__.py
Add KafkaEventTransport with async publish(event, topic, key) and export it from the events core package.
Producer refactor
backend/app/events/core/producer.py
UnifiedProducer now accepts KafkaEventTransport + EventRepository; replaces direct KafkaBroker use with transport.publish(...); removes logger/metrics usage and related attributes.
Provider wiring
backend/app/core/providers.py
Add get_kafka_event_transport() provider; get_unified_producer() now depends on EventRepository + KafkaEventTransport; remove EventMetrics from Kubernetes worker wiring.
Domain metrics reduction
backend/app/core/metrics/events.py
Remove Kafka/replay/storage/query/queue-size instruments and many EventMetrics methods; retain domain metrics (publish, processing duration, processing errors).
Handlers & worker cleanup
backend/app/events/handlers.py, backend/app/services/k8s_worker/worker.py
Stop recording Kafka-level consumption/production metrics in handlers; remove EventMetrics dependency from KubernetesWorker constructor.
Repository resilience
backend/app/db/repositories/event_repository.py
mark_publish_failed changed to best-effort: exceptions are caught and a warning is logged instead of propagating.
Grafana updates
backend/grafana/provisioning/dashboards/kafka-events-monitoring.json, backend/grafana/provisioning/dashboards/http-middleware.json
Replace Kafka-specific metric names with domain/messaging metric names; update legends/labels; remove Event Bus Queue Size panel and adjust panel queries.
Tests
backend/tests/unit/core/metrics/test_metrics_classes.py, backend/tests/unit/core/metrics/test_execution_and_events_metrics.py
Remove tests/assertions exercising deleted EventMetrics methods (replay/storage/query/Kafka ops/queue setters).
Docs
README.md
Update dead-code workflow badge/link path from vulture.yml to grimp.yml.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant UnifiedProducer
    participant EventRepository
    participant KafkaEventTransport
    participant KafkaBroker

    Client->>UnifiedProducer: produce(event)
    UnifiedProducer->>EventRepository: persist(event)  -- store (outbox)
    EventRepository-->>UnifiedProducer: stored_event(id, metadata)
    UnifiedProducer->>KafkaEventTransport: publish(stored_event, topic=event_type, key)
    KafkaEventTransport->>KafkaBroker: broker.publish(message=event, topic, key.encode())
    KafkaBroker-->>KafkaEventTransport: ack / raise error
    alt publish succeeds
        KafkaEventTransport-->>UnifiedProducer: success
    else publish fails
        KafkaEventTransport-->>UnifiedProducer: exception
        UnifiedProducer->>EventRepository: mark_publish_failed(event_id)  -- best-effort
        UnifiedProducer-->>Client: re-raise exception
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • Fix/keys #200 — Overlaps on removing/renaming EventMetrics methods, adding KafkaEventTransport, and updating UnifiedProducer/provider signatures and dashboards.
  • Feat/dead code #178 — Modifies UnifiedProducer publish flow and transport/metrics handling; touches similar producer/transport code.
  • fix: producer to DI #132 — Refactors UnifiedProducer and DI/provider wiring; overlaps on provider signature changes and producer lifecycle.

Poem

🐰 I stored the carrot, then gave it wings,
Hopped it through transports and tiny strings,
Metrics trimmed to keep the burrow light,
Dashboards hum in the soft moonlight,
A small hop forward — hooray, more springs! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 26.32% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'Fix: offload of kafka-internal metrics to faststream middleware' directly and clearly describes the main architectural change: offloading Kafka metrics from the application code to FastStream's middleware, which aligns with the primary objective of simplifying EventMetrics and removing Kafka-specific instrumentation throughout the codebase.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/backend-code

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.

@codecov-commenter

codecov-commenter commented Mar 1, 2026

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 80.76923% with 5 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
backend/app/db/repositories/event_repository.py 0.00% 4 Missing ⚠️
backend/app/events/core/producer.py 75.00% 1 Missing ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Flag Coverage Δ
backend-e2e 83.15% <80.76%> (+0.03%) ⬆️
backend-unit 67.89% <50.00%> (-0.08%) ⬇️
frontend-unit 86.78% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
backend/app/core/metrics/events.py 100.00% <ø> (ø)
backend/app/core/providers.py 95.00% <100.00%> (+0.07%) ⬆️
backend/app/events/core/__init__.py 100.00% <100.00%> (ø)
backend/app/events/core/transport.py 100.00% <100.00%> (ø)
backend/app/events/handlers.py 48.88% <ø> (-1.65%) ⬇️
backend/app/services/k8s_worker/worker.py 18.70% <100.00%> (+0.13%) ⬆️
backend/app/events/core/producer.py 78.57% <75.00%> (+0.31%) ⬆️
backend/app/db/repositories/event_repository.py 65.38% <0.00%> (-1.95%) ⬇️

... and 1 file with indirect coverage changes

Components Coverage Δ
Backend 90.12% <80.76%> (-0.11%) ⬇️
Frontend 86.78% <ø> (ø)
🚀 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.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No issues found across 12 files

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR shifts Kafka transport-level metrics collection from the application’s EventMetrics implementation to FastStream’s KafkaTelemetryMiddleware, and refactors event publishing to separate “store” vs “transport” responsibilities.

Changes:

  • Remove Kafka-/transport-specific instruments and helper methods from EventMetrics and stop emitting those metrics in handlers/tests.
  • Introduce KafkaEventTransport and refactor UnifiedProducer to delegate Kafka publishing to it.
  • Update Grafana dashboards to query FastStream/OpenTelemetry “messaging_*” metrics instead of the removed custom Kafka metrics.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
backend/tests/unit/core/metrics/test_metrics_classes.py Removes calls to deleted EventMetrics transport/event-bus methods from smoke tests.
backend/tests/unit/core/metrics/test_execution_and_events_metrics.py Removes calls to deleted EventMetrics transport/event-bus methods from method-level test.
backend/grafana/provisioning/dashboards/kafka-events-monitoring.json Replaces custom kafka_* metric queries with messaging_* metric queries.
backend/grafana/provisioning/dashboards/http-middleware.json Replaces Kafka error queries with event_processing_errors_total aggregations (but leaves event-bus query).
backend/app/services/k8s_worker/worker.py Removes unused EventMetrics dependency from KubernetesWorker.
backend/app/events/handlers.py Stops emitting consumed/consumption-error Kafka metrics; keeps domain-level failure metric emission.
backend/app/events/core/transport.py Adds KafkaEventTransport wrapper over KafkaBroker.publish with debug logging.
backend/app/events/core/producer.py Refactors UnifiedProducer to store then delegate publish to KafkaEventTransport; marks publish failures in DB.
backend/app/events/core/init.py Exports KafkaEventTransport from events core package.
backend/app/core/providers.py Adds DI provider for KafkaEventTransport and rewires UnifiedProducer construction.
backend/app/core/metrics/events.py Removes Kafka/event-bus/replay metrics from EventMetrics, leaving domain-level metrics only.
README.md Updates “dead code check” workflow badge from vulture to grimp.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread backend/grafana/provisioning/dashboards/http-middleware.json
Comment thread backend/app/events/core/producer.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (2)
backend/app/events/core/transport.py (1)

22-23: Use Google-style docstring for publish.

Please document arguments/raises explicitly to match repository docstring conventions.

✍️ Suggested docstring update
-    async def publish(self, event: DomainEvent, topic: str, key: str) -> None:
-        """Publish event to Kafka."""
+    async def publish(self, event: DomainEvent, topic: str, key: str) -> None:
+        """Publish a domain event to Kafka.
+
+        Args:
+            event: Event payload to publish.
+            topic: Kafka topic name.
+            key: Partitioning key for the message.
+
+        Returns:
+            None.
+
+        Raises:
+            Exception: Propagates broker publish failures.
+        """

As per coding guidelines backend/**/*.py: "Use Google-style docstrings with Args/Returns/Raises sections".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/app/events/core/transport.py` around lines 22 - 23, The publish
method's docstring is a short description and must be converted to a
Google-style docstring with explicit Args and Raises sections: update the async
def publish(self, event: DomainEvent, topic: str, key: str) -> None: docstring
to include an Args section describing event (DomainEvent), topic (str), key
(str), and a Raises section listing possible exceptions (e.g., KafkaError or
whatever transport errors are raised by this implementation), and keep the
one-line summary and a Returns: None line if your lint rules expect it; ensure
the docstring format matches other backend/**/*.py examples in the repo.
backend/app/events/handlers.py (1)

37-37: Use Google-style docstring for _track_consumed.

Please add explicit Args/Returns/Raises sections for consistency with repo standards.

✍️ Suggested docstring update
-    """Await *coro* and record domain-level failure metric on error."""
+    """Await processing coroutine and record failure metrics on error.
+
+    Args:
+        metrics: Event metrics recorder.
+        event: Consumed domain event.
+        consumer_group: Consumer group name.
+        coro: Processing coroutine to await.
+
+    Returns:
+        None.
+
+    Raises:
+        Exception: Re-raises the original processing exception.
+    """

As per coding guidelines backend/**/*.py: "Use Google-style docstrings with Args/Returns/Raises sections".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/app/events/handlers.py` at line 37, Update the docstring for the
function _track_consumed to use Google-style sections: add an Args section
documenting the coro parameter (a coroutine to await) and any other parameters,
a Returns section describing the awaited result (e.g., the value returned by
coro), and a Raises section describing exceptions propagated (and that a
domain-level failure metric is recorded on error). Keep the one-line summary
"Await *coro* and record domain-level failure metric on error." and ensure the
docstring mentions side effects (recording the metric) in the Raises or a short
Note if appropriate.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@backend/app/events/core/producer.py`:
- Around line 31-33: Catch and save the original publish exception (e.g. as
publish_exc) in the except block around the transport call, then call
self._event_repository.mark_publish_failed(event_to_produce.event_id) inside a
nested try/except; if mark_publish_failed raises, log or swallow that secondary
error but do not overwrite the original—always re-raise the saved publish_exc
(optionally using "raise publish_exc from None" or re-raising to preserve the
original stack). This change should be applied around the existing except
Exception handling where mark_publish_failed is invoked.
- Line 30: The transport is currently forwarding the raw event type through
KafkaEventTransport.publish() to broker.publish() without the required prefix;
modify KafkaEventTransport.publish to build the final topic as
f'{KAFKA_TOPIC_PREFIX}{event_type}' (where KAFKA_TOPIC_PREFIX is loaded from
config/env and defined once for the transport), and pass that composed topic to
broker.publish() instead of the raw event_type; ensure existing callers (e.g.,
producer calling self._transport.publish(event_to_produce,
event_to_produce.event_type, key)) continue to pass the event_type and that only
the transport layer performs the prefix composition.

In `@backend/grafana/provisioning/dashboards/kafka-events-monitoring.json`:
- Around line 657-659: The panel's query groups metrics by
messaging_destination_publish_name (see the expression
"sum(rate(messaging_process_messages_total[1m])) by
(messaging_destination_publish_name)" and the legendFormat
"{{messaging_destination_publish_name}}") but the panel title/description still
says "by consumer group"; update the panel title and any descriptive text to
reference "destination publish name" or similar, or if the intended semantic is
"consumer group" instead, change the PromQL grouping to use the consumer group
label (e.g., by (messaging_consumer_group)) to make title and legend consistent
with the expression and legendFormat.

---

Nitpick comments:
In `@backend/app/events/core/transport.py`:
- Around line 22-23: The publish method's docstring is a short description and
must be converted to a Google-style docstring with explicit Args and Raises
sections: update the async def publish(self, event: DomainEvent, topic: str,
key: str) -> None: docstring to include an Args section describing event
(DomainEvent), topic (str), key (str), and a Raises section listing possible
exceptions (e.g., KafkaError or whatever transport errors are raised by this
implementation), and keep the one-line summary and a Returns: None line if your
lint rules expect it; ensure the docstring format matches other backend/**/*.py
examples in the repo.

In `@backend/app/events/handlers.py`:
- Line 37: Update the docstring for the function _track_consumed to use
Google-style sections: add an Args section documenting the coro parameter (a
coroutine to await) and any other parameters, a Returns section describing the
awaited result (e.g., the value returned by coro), and a Raises section
describing exceptions propagated (and that a domain-level failure metric is
recorded on error). Keep the one-line summary "Await *coro* and record
domain-level failure metric on error." and ensure the docstring mentions side
effects (recording the metric) in the Raises or a short Note if appropriate.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d31dfd3 and a2640ac.

📒 Files selected for processing (12)
  • README.md
  • backend/app/core/metrics/events.py
  • backend/app/core/providers.py
  • backend/app/events/core/__init__.py
  • backend/app/events/core/producer.py
  • backend/app/events/core/transport.py
  • backend/app/events/handlers.py
  • backend/app/services/k8s_worker/worker.py
  • backend/grafana/provisioning/dashboards/http-middleware.json
  • backend/grafana/provisioning/dashboards/kafka-events-monitoring.json
  • backend/tests/unit/core/metrics/test_execution_and_events_metrics.py
  • backend/tests/unit/core/metrics/test_metrics_classes.py
💤 Files with no reviewable changes (2)
  • backend/tests/unit/core/metrics/test_metrics_classes.py
  • backend/tests/unit/core/metrics/test_execution_and_events_metrics.py

Comment thread backend/app/events/core/producer.py
Comment thread backend/app/events/core/producer.py

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

1 issue found across 3 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="backend/app/db/repositories/event_repository.py">

<violation number="1" location="backend/app/db/repositories/event_repository.py:66">
P2: Include exception details in the warning log; otherwise failures are silent and hard to diagnose.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread backend/app/db/repositories/event_repository.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
backend/app/db/repositories/event_repository.py (1)

60-67: Consider logging exception details for debuggability.

The best-effort pattern is appropriate here. However, swallowing the exception without logging any details makes it harder to diagnose issues in production. Consider including the exception info:

♻️ Suggested improvement
     async def mark_publish_failed(self, event_id: str) -> None:
         """Best-effort mark of an event as failed to publish. Never raises."""
         try:
             await EventDocument.find_one(
                 EventDocument.event_id == event_id,
             ).update({"$set": {"publish_failed": True, "publish_failed_at": datetime.now(timezone.utc)}})
-        except Exception:
-            self.logger.warning("Could not mark event as publish-failed", event_id=event_id)
+        except Exception:
+            self.logger.warning("Could not mark event as publish-failed", event_id=event_id, exc_info=True)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/app/db/repositories/event_repository.py` around lines 60 - 67, The
except block in mark_publish_failed swallows errors without details; update the
except in the mark_publish_failed method to capture the exception (e.g., using
"except Exception as exc") and include the exception information in the logger
call (e.g., pass exc or exc_info/str(exc) along with event_id) when handling the
failure from EventDocument.find_one(...).update(...) so failures remain
best-effort but are debuggable.
backend/grafana/provisioning/dashboards/kafka-events-monitoring.json (1)

959-961: Missing aggregation may cause noisy visualization.

This query uses rate(messaging_publish_messages_total[1m]) without sum() by (messaging_destination_name). If multiple application instances publish to the same topic, each instance will produce a separate series with the same legend label, making the panel cluttered and potentially misleading.

Consider adding aggregation to match the "Producer Rate by Topic" panel pattern:

♻️ Suggested fix
-          "expr": "rate(messaging_publish_messages_total[1m]) or vector(0)",
+          "expr": "sum(rate(messaging_publish_messages_total[1m])) by (messaging_destination_name) or vector(0)",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/grafana/provisioning/dashboards/kafka-events-monitoring.json` around
lines 959 - 961, The panel query is using
rate(messaging_publish_messages_total[1m]) which can produce one time series per
instance and clutter the panel; modify the expression to aggregate instances per
topic like sum by (messaging_destination_name) (e.g., replace rate(...) or
vector(0) with sum by (messaging_destination_name)
(rate(messaging_publish_messages_total[1m])) or vector(0)) so the series are
grouped by messaging_destination_name while keeping the existing legendFormat
"{{messaging_destination_name}}".
backend/grafana/provisioning/dashboards/http-middleware.json (1)

225-226: Remove or vector(0) from grouped aggregations to prevent noisy unlabeled {} line.

These queries use or vector(0) with by (...) grouping. The vector(0) has no labels, so it doesn't match the grouped label set and creates a separate, unlabeled {} series with zero value, cluttering legends.

For dashboards, this fallback is unnecessary. Simply removing it produces cleaner output.

♻️ Proposed query cleanup
-          "expr": "sum(rate(event_processing_errors_total[5m])) by (error_type) or vector(0)",
+          "expr": "sum(rate(event_processing_errors_total[5m])) by (error_type)",
           "legendFormat": "{{error_type}}",
...
-          "expr": "sum(rate(event_processing_errors_total[5m])) by (consumer_group) or vector(0)",
+          "expr": "sum(rate(event_processing_errors_total[5m])) by (consumer_group)",
           "legendFormat": "{{consumer_group}}",

Also applies to: lines 231–232

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/grafana/provisioning/dashboards/http-middleware.json` around lines
225 - 226, The grouped aggregation expressions like
"sum(rate(event_processing_errors_total[5m])) by (error_type) or vector(0)"
produce an unlabeled `{}` zero series; remove the "or vector(0)" suffix from
these queries (e.g., the expr used with legendFormat "{{error_type}}") so the
aggregation by (error_type) only returns labeled series; apply the same removal
to the other affected expression at the indicated occurrence (lines 231–232) to
avoid the noisy unlabeled legend entry.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@backend/grafana/provisioning/dashboards/kafka-events-monitoring.json`:
- Around line 657-664: Update the "Consumer Rate by Topic" panel so its PromQL
expression uses the non-deprecated label messaging_destination_name instead of
messaging_destination_publish_name: locate the panel titled "Consumer Rate by
Topic" (the query that references
sum(rate(messaging_process_messages_total[1m])) by
(messaging_destination_publish_name)) and replace the group-by label
messaging_destination_publish_name with messaging_destination_name to match the
producer panel and FastStream semantics.

---

Nitpick comments:
In `@backend/app/db/repositories/event_repository.py`:
- Around line 60-67: The except block in mark_publish_failed swallows errors
without details; update the except in the mark_publish_failed method to capture
the exception (e.g., using "except Exception as exc") and include the exception
information in the logger call (e.g., pass exc or exc_info/str(exc) along with
event_id) when handling the failure from EventDocument.find_one(...).update(...)
so failures remain best-effort but are debuggable.

In `@backend/grafana/provisioning/dashboards/http-middleware.json`:
- Around line 225-226: The grouped aggregation expressions like
"sum(rate(event_processing_errors_total[5m])) by (error_type) or vector(0)"
produce an unlabeled `{}` zero series; remove the "or vector(0)" suffix from
these queries (e.g., the expr used with legendFormat "{{error_type}}") so the
aggregation by (error_type) only returns labeled series; apply the same removal
to the other affected expression at the indicated occurrence (lines 231–232) to
avoid the noisy unlabeled legend entry.

In `@backend/grafana/provisioning/dashboards/kafka-events-monitoring.json`:
- Around line 959-961: The panel query is using
rate(messaging_publish_messages_total[1m]) which can produce one time series per
instance and clutter the panel; modify the expression to aggregate instances per
topic like sum by (messaging_destination_name) (e.g., replace rate(...) or
vector(0) with sum by (messaging_destination_name)
(rate(messaging_publish_messages_total[1m])) or vector(0)) so the series are
grouped by messaging_destination_name while keeping the existing legendFormat
"{{messaging_destination_name}}".

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a2640ac and ca1508c.

📒 Files selected for processing (3)
  • backend/app/db/repositories/event_repository.py
  • backend/grafana/provisioning/dashboards/http-middleware.json
  • backend/grafana/provisioning/dashboards/kafka-events-monitoring.json

@sonarqubecloud

sonarqubecloud Bot commented Mar 1, 2026

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
backend/app/db/repositories/event_repository.py (1)

66-67: Include traceback context in the swallowed-error warning log.

Line 67 logs only str(exc). Since this path intentionally suppresses exceptions, include exc_info for actionable diagnostics.

Proposed logging improvement
         except Exception as exc:
-            self.logger.warning("Could not mark event as publish-failed", event_id=event_id, error=str(exc))
+            self.logger.warning(
+                "Could not mark event as publish-failed",
+                event_id=event_id,
+                error=str(exc),
+                exc_info=exc,
+            )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/app/db/repositories/event_repository.py` around lines 66 - 67, The
except block that calls self.logger.warning("Could not mark event as
publish-failed", event_id=event_id, error=str(exc)) should include traceback
context so the swallowed exception is actionable; update the call to pass
exc_info (e.g., exc_info=True or exc_info=exc) to the self.logger.warning
invocation and preserve event_id and error metadata so the warning logs the full
traceback along with the existing event_id and error=str(exc).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@backend/app/db/repositories/event_repository.py`:
- Line 61: The docstring for mark_publish_failed in event_repository.py must be
converted to a Google-style docstring including Args, Returns, and Raises
sections; update the triple-quoted string for the mark_publish_failed function
to explain what the method does, document parameters (if any) under Args, state
the return value under Returns (e.g., None or bool) and explicitly note under
Raises that it never raises (or that exceptions are caught and handled), keeping
the intent "Best-effort mark of an event as failed to publish. Never raises." in
the description.

---

Nitpick comments:
In `@backend/app/db/repositories/event_repository.py`:
- Around line 66-67: The except block that calls self.logger.warning("Could not
mark event as publish-failed", event_id=event_id, error=str(exc)) should include
traceback context so the swallowed exception is actionable; update the call to
pass exc_info (e.g., exc_info=True or exc_info=exc) to the self.logger.warning
invocation and preserve event_id and error metadata so the warning logs the full
traceback along with the existing event_id and error=str(exc).

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ca1508c and b358cc9.

📒 Files selected for processing (1)
  • backend/app/db/repositories/event_repository.py

Comment thread backend/app/db/repositories/event_repository.py
@HardMax71
HardMax71 merged commit 2454249 into main Mar 1, 2026
16 checks passed
@HardMax71
HardMax71 deleted the fix/backend-code branch March 1, 2026 22:49
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.

3 participants