Skip to content

feat(zulip): add Prometheus topic autoresolve#2099

Open
oguertler wants to merge 7 commits into
robusta-dev:masterfrom
oguertler:zulip-topic-autoresolve
Open

feat(zulip): add Prometheus topic autoresolve#2099
oguertler wants to merge 7 commits into
robusta-dev:masterfrom
oguertler:zulip-topic-autoresolve

Conversation

@oguertler

Copy link
Copy Markdown
Contributor
  • Add opt-in topic_autoresolve support for the Zulip sink
  • Use Prometheus alert titles as Zulip topics and resolve matching topics with Zulip’s resolved-topic prefix
  • Document the new Zulip sink option

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fdf5c0ad-60e1-443f-831b-bd1c4552717b

📥 Commits

Reviewing files that changed from the base of the PR and between c51de1b and 5064b9e.

📒 Files selected for processing (1)
  • src/robusta/integrations/zulip/sender.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/robusta/integrations/zulip/sender.py

Walkthrough

Adds an optional topic_autoresolve setting to the Zulip sink; the sink passes stream_name to ZulipSender, which now precomputes stream metadata, caches topics, centralizes payload building, and can resolve/patch existing Zulip topics for Prometheus findings when enabled.

Changes

Zulip topic autoresolve feature

Layer / File(s) Summary
Topic autoresolve configuration parameter
src/robusta/core/sinks/zulip/zulip_sink_params.py
topic_autoresolve: bool = False field added to ZulipSinkParams.
Sink configuration and wiring
src/robusta/core/sinks/zulip/zulip_sink.py
ZulipSink captures stream_name from configuration and passes it to ZulipSender during construction.
ZulipSender refactoring and topic resolution
src/robusta/integrations/zulip/sender.py
ZulipSender now accepts stream_name, fetches max_message_len and stream_id, caches topics, centralizes message payload creation, and conditionally resolves/patches existing messages when topic_autoresolve is enabled for Prometheus findings.
Feature documentation
docs/configuration/sinks/zulip.rst
Documentation added for topic_autoresolve (default false), Prometheus alert title mapping and resolve behavior, required bot permissions, interaction with topic_name/topic_override, and updated generated values example.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main feature addition: opt-in Prometheus topic autoresolve for the Zulip sink, which is the primary change across all modified files.
Description check ✅ Passed The description relates directly to the changeset, explaining the opt-in topic_autoresolve feature, its functionality with Prometheus alert titles, and documentation updates.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@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: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/robusta/integrations/zulip/sender.py`:
- Line 93: The log statement currently emits the full topics list at warning
level via logging.warning(f"topics: {topics}"), which should be reduced to
debug-level noise; locate that call in src/robusta/integrations/zulip/sender.py
(the logging call that references the topics variable) and change it to
logging.debug(f"topics: {topics}") (ensure the logging module is
imported/available where used).
- Around line 100-117: The __find_msg_id_for_topic_title method currently uses
substring matching in its nested find_msg_id (if title in topic["name"]) which
can pick wrong topics; change the comparison to exact equality (e.g.,
topic["name"] == title) and also accept the resolved prefixed form (e.g., "✔ " +
title) to handle resolved messages, then keep the rest of the logic (refreshing
topic_cache via __load_topics(self.stream_id), warnings, and returning msg_id[0]
or None) unchanged so only the matching logic in find_msg_id is updated.
- Around line 219-234: The PATCH call after posting reuses the full `data` from
__build_msg_data (which includes the new `content`), so
r.patch(f".../messages/{msg_id}", data=data) overwrites the original message
text; instead construct a minimal patch payload (e.g., only the topic field set
to channel_topic plus "propagate_mode":"change_all") and use that for the PATCH
to update only the topic; update the code paths around __build_msg_data, the
POST call, and the subsequent r = self.zclient.patch(...) to send this minimal
patch when msg_id is present.
- Around line 73-82: The two Zulip helper methods __get_stream_id and
__find_msg_id_for_topic_title currently can return an int or None on
errors/not-found; update their function signatures to explicitly annotate the
return type as "-> int | None" (Python 3.10 union syntax) so the contract is
clear, and ensure any callers accept a possible None return; locate the methods
by name in sender.py and change their definitions to include the new return type
annotation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 583a78d2-e949-404c-9af3-7d42da1e659e

📥 Commits

Reviewing files that changed from the base of the PR and between bbb7481 and e66cec5.

📒 Files selected for processing (4)
  • docs/configuration/sinks/zulip.rst
  • src/robusta/core/sinks/zulip/zulip_sink.py
  • src/robusta/core/sinks/zulip/zulip_sink_params.py
  • src/robusta/integrations/zulip/sender.py

Comment thread src/robusta/integrations/zulip/sender.py Outdated
Comment thread src/robusta/integrations/zulip/sender.py Outdated
Comment thread src/robusta/integrations/zulip/sender.py
Comment thread src/robusta/integrations/zulip/sender.py
@tt-kkaiser

Copy link
Copy Markdown

I would approve 👍

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.

2 participants