Skip to content

docs: write observability setup guide (Prometheus + Grafana) - #545

Merged
AbdulmalikAlayande merged 2 commits into
TegoLabs:mainfrom
omosvico:docs/observability-setup-guide
Aug 2, 2026
Merged

AbdulmalikAlayande merged 2 commits into
TegoLabs:mainfrom
omosvico:docs/observability-setup-guide

Conversation

@omosvico

@omosvico omosvico commented Jul 29, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds a full observability setup guide walking teams through connecting sorokeep's metrics to Prometheus and Grafana.

Changes

  • docs/observability.md — New guide covering:

    • Enabling the metrics server with --metrics-port
    • Minimal prometheus.yml scrape configuration with available metrics reference table
    • Importing the Grafana dashboard (UI and API methods, panel descriptions)
    • Alertmanager rules with example alert configurations (down, high unresolved alerts, cost spike)
    • Docker Compose full-stack example (sorokeep + Prometheus + Grafana + Alertmanager)
    • Troubleshooting section (scrape target down, no metrics data, high latency, dashboard not found)
  • docs/ARCHITECTURE.md — Added cross-link to the observability guide

  • README.md — Updated roadmap item to link to the guide

closes: #340

- Add docs/observability.md covering: enabling the metrics server with --metrics-port,
  minimal prometheus.yml scrape config, importing the Grafana dashboard, Alertmanager rules,
  Docker Compose full-stack example, and a troubleshooting section
- Cross-link from docs/ARCHITECTURE.md
- Cross-link from README.md roadmap section
@coderabbitai

coderabbitai Bot commented Jul 29, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • Documentation
    • Added a comprehensive observability setup guide covering Prometheus metrics, Grafana dashboards, Alertmanager rules, Docker Compose deployment, and troubleshooting.
    • Added architecture documentation guidance for production observability deployment.
    • Updated the roadmap to link directly to the new Observability Setup Guide.

Walkthrough

Added an observability setup guide for Prometheus, Grafana, and Alertmanager. The guide covers metrics endpoints, scraping, dashboards, alerts, Docker Compose deployment, troubleshooting, and repository cross-links.

Changes

Observability Documentation

Layer / File(s) Summary
Metrics and Prometheus setup
docs/observability.md
Documents metrics endpoints, daemon flags, exported metrics, and Prometheus scraping configuration.
Dashboards and alerting
docs/observability.md
Documents Grafana dashboard imports, dashboard panels, Alertmanager rules, and notification routing.
Full-stack deployment and documentation links
docs/observability.md, README.md, docs/ARCHITECTURE.md
Adds a Docker Compose stack, troubleshooting guidance, and links to the observability guide.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related issues

  • #343 — Covers a related Prometheus and Grafana Docker Compose observability setup.
  • #330 — Provides the metrics server and /metrics endpoint documented by this guide.
  • #349 — Covers Alertmanager rules referenced by the guide.
  • #336 — Covers the Grafana dashboard imported in the guide.

Possibly related PRs

Suggested reviewers: abdulmalikalayande

Poem

A rabbit charts metrics by moonlight,
Prometheus keeps each signal right.
Grafana shows the panels clear,
Alerts hop swiftly to the ear.
Compose brings the stack in sight.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely identifies the observability setup guide for Prometheus and Grafana.
Description check ✅ Passed The description accurately summarizes the new guide, cross-links, configuration examples, alerting, deployment, and troubleshooting content.
Linked Issues check ✅ Passed The documentation covers the linked issue objectives, including metrics setup, Prometheus, Grafana, Alertmanager, troubleshooting, and required cross-links [#340].
Out of Scope Changes check ✅ Passed All changes are documentation-only and limited to the three files permitted by the linked issue.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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.

@drips-wave

drips-wave Bot commented Jul 29, 2026

Copy link
Copy Markdown

@omosvico Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

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

🤖 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 `@docs/observability.md`:
- Line 32: Update the fenced code block in the observability documentation
sample to specify a language identifier, using text or console, so the Markdown
lint rule passes.
- Around line 50-55: Update the Metrics Port Reference documentation for
`--metrics-host` so it does not present `0.0.0.0` as an unqualified default;
recommend a private-interface binding or explicitly state the firewall and
reverse-proxy restrictions required before exposing the unauthenticated metrics
endpoint.
- Around line 282-286: Update the “Grafana Dashboard Not Found” troubleshooting
section to remove the unimplemented sorokeep metrics --grafana-dashboard
command. Direct users to import the checked-in resources/grafana/dashboard.json
file, or manually create/import a dashboard in Grafana using the listed metric
names.
- Around line 67-75: Update the Prometheus scrape target in the observability
Docker Compose example from localhost:9464 to the sorokeep Compose service
address sorokeep:9464, while preserving the existing labels and configuration
structure.
- Around line 159-164: Update the SorokeepExtensionCostSpike alert so its
Prometheus expression and notification use consistent units: either multiply
rate(sorokeep_extension_cost_xlm_total[1h]) by 3600 and retain an hourly
threshold/message, or keep the expression unchanged and change the threshold and
description to XLM/second.
- Line 103: Remove all admin/admin defaults from the Grafana setup documentation
and Compose configuration, requiring the Grafana password to come from a secret
or environment variable. Update the API import curl commands to use a token or
environment-provided credential, and revise the referenced Grafana setup
sections consistently.
- Around line 221-229: Add Grafana provisioning configuration alongside the
compose example: create a dashboard provider YAML under provisioning/dashboards
that points to the mounted /etc/grafana/provisioning/dashboards directory, and
add a Prometheus datasource YAML under provisioning/datasources with the compose
service URL. Ensure the existing grafana volume mount exposes these provisioning
files so dashboard.json is imported automatically and Prometheus is available.
🪄 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: ASSERTIVE

Plan: Pro Plus

Run ID: cb193b25-d558-41ae-a8f9-644bc0b386e5

📥 Commits

Reviewing files that changed from the base of the PR and between 35d9237 and 8ea4612.

📒 Files selected for processing (3)
  • README.md
  • docs/ARCHITECTURE.md
  • docs/observability.md
📜 Review details
🧰 Additional context used
🪛 markdownlint-cli2 (0.23.1)
docs/observability.md

[warning] 32-32: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🔇 Additional comments (2)
docs/observability.md (1)

167-172: 🎯 Functional Correctness

No change needed: Alertmanager wiring covers Prometheus alert delivery.

The file includes a separate alertmanager.yml route/receiver configuration, and the full-stack compose is described as including an Alertmanager service.

README.md (1)

664-664: 📐 Maintainability & Code Quality

Resolve the observability support-status mismatch.

The documentation simultaneously presents /metrics as roadmap work and directs production users to configure the observability stack. Confirm the endpoint is implemented and documented as supported; otherwise mark the guide as upcoming/provisional.

  • README.md#L664-L664: align the roadmap wording with the actual endpoint status.
  • docs/ARCHITECTURE.md#L87-L88: avoid unconditional production guidance until the setup is supported.

Comment thread docs/observability.md

Sample output:

```

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Specify the fenced block language.

This sample output triggers MD040; mark it as text (or console) so Markdown lint passes.

🧰 Tools
🪛 markdownlint-cli2 (0.23.1)

[warning] 32-32: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for 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.

In `@docs/observability.md` at line 32, Update the fenced code block in the
observability documentation sample to specify a language identifier, using text
or console, so the Markdown lint rule passes.

Source: Linters/SAST tools

Comment thread docs/observability.md
Comment on lines +50 to +55
### Metrics Port Reference

| Flag | Default | Description |
|------|---------|-------------|
| `--metrics-port` | Disabled | Port for the Prometheus metrics HTTP server |
| `--metrics-host` | `0.0.0.0` | Bind address for the metrics server |

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Do not present 0.0.0.0 as an unqualified default.

The unauthenticated metrics endpoint exposes operational data and is reachable on every interface. Recommend binding to a private interface by default, or explicitly document firewall/reverse-proxy restrictions before exposing this port.

🤖 Prompt for 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.

In `@docs/observability.md` around lines 50 - 55, Update the Metrics Port
Reference documentation for `--metrics-host` so it does not present `0.0.0.0` as
an unqualified default; recommend a private-interface binding or explicitly
state the firewall and reverse-proxy restrictions required before exposing the
unauthenticated metrics endpoint.

Comment thread docs/observability.md
Comment on lines +67 to +75
static_configs:
- targets:
- 'localhost:9464'
labels:
service: sorokeep
network: testnet
```

Replace `localhost` with the sorokeep host address if Prometheus is running on a different machine. If sorokeep runs in a Docker container, use the container name or host's Docker bridge IP.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | rg '(^|/)(prometheus|docker-compose|compose|observability)' || true

echo "== relevant docs slice =="
sed -n '1,260p' docs/observability.md 2>/dev/null | nl -ba | sed -n '1,260p'

echo "== search sorokeep/prometheus compose =="
rg -n "sorokeep|prometheus|9464|statsd|docker-compose|compose" -S . --glob '!node_modules' --glob '!target' | head -n 200

Repository: AbdulmalikAlayande/sorokeep

Length of output: 348


🏁 Script executed:

#!/bin/bash
set -euxo pipefail

echo "== docs/observability.md relevant lines =="
awk '{printf "%6d\t%s\n", NR, $0}' docs/observability.md 2>/dev/null | sed -n '1,280p'

echo "== compose files =="
for f in docker-compose.yaml docker-compose.devnet.yaml; do
  echo "--- $f ($(wc -l < "$f") lines) ---"
  awk '{printf "%6d\t%s\n", NR, $0}' "$f" | sed -n '1,260p'
done

echo "== search for targets and ports =="
rg -n "targets:|localhost:9464|sorokeep:9464|9464|sorokeep|prometheus|statsd|expose:|ports:" -S . --glob '!node_modules' --glob '!target' | head -n 240

Repository: AbdulmalikAlayande/sorokeep

Length of output: 40020


Use the Compose service name for Prometheus scraping.

Section 5 starts an observability Docker Compose stack with separate Prometheus and sorokeep services, so the localhost:9464 target is inside the Prometheus container. Update the Compose example Prometheus config to scrape the sorokeep service instead, e.g. targets: ['sorokeep:9464'].

🤖 Prompt for 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.

In `@docs/observability.md` around lines 67 - 75, Update the Prometheus scrape
target in the observability Docker Compose example from localhost:9464 to the
sorokeep Compose service address sorokeep:9464, while preserving the existing
labels and configuration structure.

Comment thread docs/observability.md

### Via the Grafana UI

1. Open Grafana (`http://localhost:3000`, default login `admin`/`admin`)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Remove the admin/admin deployment path.

The guide documents the default Grafana password, sends it in a curl command, and hard-codes it in Compose. This encourages an immediately compromised Grafana instance. Require a secret/environment-provided password and use a token or environment variable for API imports.

Suggested Compose change
-      - GF_SECURITY_ADMIN_PASSWORD=admin
+      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD:?Set GRAFANA_ADMIN_PASSWORD}

Also applies to: 111-120, 221-226

🤖 Prompt for 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.

In `@docs/observability.md` at line 103, Remove all admin/admin defaults from the
Grafana setup documentation and Compose configuration, requiring the Grafana
password to come from a secret or environment variable. Update the API import
curl commands to use a token or environment-provided credential, and revise the
referenced Grafana setup sections consistently.

Comment thread docs/observability.md
Comment on lines +159 to +164
- alert: SorokeepExtensionCostSpike
expr: rate(sorokeep_extension_cost_xlm_total[1h]) > 1
for: 10m
annotations:
summary: "High extension cost rate detected"
description: "XLM extension cost rate is {{ $value }} XLM/hour — investigate unusual extension activity."

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== File snippet =="
sed -n '140,175p' docs/observability.md | cat -n

echo
echo "== Related counter names =="
rg -n "sorokeep_extension_cost|rate\\(|XLM|cost" docs/observability.md prometheus 2>/dev/null || true

Repository: AbdulmalikAlayande/sorokeep

Length of output: 2479


🌐 Web query:

Prometheus rate counter per second documentation

💡 Result:

The rate function in Prometheus is a primary tool for calculating the per-second average rate of increase of a counter metric over a specified time range [1][2]. Key characteristics and usage: - Functionality: It takes a range vector (e.g., [5m]) and calculates the increase in the counter's value over that window, divided by the duration of the window to produce a per-second rate [1][3][2]. - Counter Resets: It automatically detects and compensates for counter resets (such as when a process restarts), ensuring the rate calculation remains accurate [1][4]. - Extrapolation: The function extrapolates to the ends of the time range, which helps account for missed scrapes or misalignment between scrape cycles and the requested time window [1][2]. - Best Practices: - Use only with counters (or native histograms where components behave like counters) [1][5]. - It is recommended for alerting and graphing slow-moving counters [1][4]. - When combining rate with an aggregation operator (like sum) or an _over_time function, always apply rate first to the raw counter before aggregating [1][5]. Comparison with similar functions: - rate(v range-vector): Calculates the per-second average rate over the entire specified time range, providing a smoothed trend [1][6]. - irate(v range-vector): Calculates an instantaneous rate based only on the last two data points in the range [6][7]. It is more responsive to sudden spikes but significantly noisier, making it less suitable for most alerting [6][7]. - increase(v range-vector): Returns the total absolute increase in a counter over the specified time range, rather than a per-second average [6][7]. Note that rate(v) is mathematically equivalent to increase(v) / range_duration [6][3]. Example query: To get the per-second average rate of HTTP requests over the last 5 minutes: rate(http_requests_total[5m]) [1][8]

Citations:


Correct the extension-cost alert units.

rate(sorokeep_extension_cost_xlm_total[1h]) returns XLM/second, but the threshold is 1 XLM/second and the notification says XLM/hour. Either compare rate(...) * 3600 against an hourly threshold, or change the annotation to XLM/second so the alert and message match.

🤖 Prompt for 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.

In `@docs/observability.md` around lines 159 - 164, Update the
SorokeepExtensionCostSpike alert so its Prometheus expression and notification
use consistent units: either multiply
rate(sorokeep_extension_cost_xlm_total[1h]) by 3600 and retain an hourly
threshold/message, or keep the expression unchanged and change the threshold and
description to XLM/second.

Comment thread docs/observability.md
Comment on lines +221 to +229
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana-data:/var/lib/grafana
- ./resources/grafana:/etc/grafana/provisioning/dashboards:ro

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== repo files matching grafana/dashboard/prometheus =="
git ls-files | rg -i '(^|/)(grafana|dashboard|prometheus).*|^docs/observability\.md$|^compose|docker-compose|docker-compose\.yml|docker-compose\.yaml|docker-compose.*\.ya?ml$' || true

echo
echo "== docs/observability.md around relevant section =="
if [ -f docs/observability.md ]; then
  nl -ba docs/observability.md | sed -n '180,260p'
fi

echo
echo "== search for grafana provisioning references =="
rg -n "grafana|provisioning|promotion|provider|datasource|dashboard\.json|Prometheus|metrics" docs compose . -g '!**/node_modules/**' -g '!**/.git/**' 2>/dev/null | head -200 || true

Repository: AbdulmalikAlayande/sorokeep

Length of output: 419


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== docs/observability.md around relevant section =="
python3 - <<'PY'
from pathlib import Path
p=Path("docs/observability.md")
lines=p.read_text(errors="replace").splitlines()
for i,line in enumerate(lines[179:259], start=180):
    print(f"{i:4}: {line}")
PY

echo
echo "== Compose grafana/config sections =="
python3 - <<'PY'
from pathlib import Path
for path in ["docker-compose.yaml","docker-compose.devnet.yaml"]:
    p=Path(path)
    if not p.exists():
        continue
    lines=p.read_text(errors="replace").splitlines()
    seen=[]
    for i,line in enumerate(lines,1):
        if "grafana" in line.lower() or "dashboard" in line.lower() or "prometheus" in line.lower() or "provisioning" in line.lower() or "datasource" in line.lower() or "GF_" in line:
            seen.append((i,line))
    print(f"--- {path} ({len(lines)} lines) ---")
    for i,line in seen[:80]:
        print(f"{i}: {line}")
PY

echo
echo "== provision resource files =="
for f in $(git ls-files | rg -i 'resources/grafana|grafana.*ya?ml|datasource|dashboard\.json'; true); do
  echo "--- $f ($(wc -l < "$f") lines) ---"
  sed -n '1,160p' "$f"
done

Repository: AbdulmalikAlayande/sorokeep

Length of output: 3057


🌐 Web query:

Grafana provisioning documentation dashboard providers datasource provisioning dashboards directory YAML provider

💡 Result:

Grafana provides a system for automated configuration known as provisioning, which allows you to define data sources and dashboards using YAML files [1][2]. These files are processed by Grafana upon startup and can be continuously managed, supporting GitOps workflows [1][2]. Provisioning Directories The provisioning system typically looks for configuration files in directories defined by your Grafana installation. By default, these are structured as follows [2]: provisioning/ datasources/ dashboards/ Data Source Provisioning Data source configuration files are placed in the provisioning/datasources directory [1]. Each file contains a list of data sources under the datasources key [1][3]. If a data source with the same name already exists, Grafana will update it to match the provided configuration [1]. Dashboard Provisioning Dashboard configuration files are placed in the provisioning/dashboards directory [1][4]. Each file specifies a list of providers that instruct Grafana on where to load dashboard files from the local filesystem [1][4]. An example dashboard provider YAML configuration looks like this [1][4]: apiVersion: 1 providers: - name: 'My Dashboard Provider' orgId: 1 folder: '' type: file disableDeletion: false updateIntervalSeconds: 10 allowUiUpdates: false options: path: /var/lib/grafana/dashboards foldersFromFilesStructure: true Key Configuration Options: - name: A unique name for the provider [1][4]. - type: The provider type, which defaults to file [1][4]. - options.path: The filesystem path where your dashboard JSON files are located [1][4]. - foldersFromFilesStructure: When set to true, Grafana maps the filesystem directory structure to folders within the Grafana UI [1][4]. To use this, you must leave the folder and folderUid options unset [4]. Security and Paths For security, Grafana restricts the paths that can be used for provisioning [5]. You must configure allowed paths in your grafana.ini or custom.ini file using the permitted_provisioning_paths option under the [paths] section [5][6]. This option defines which directories Grafana is allowed to access for provisioning resources [5].

Citations:


Add Grafana dashboard and data-source provisioning configs.

Mounting resources/grafana into dashboards/ only makes dashboard files visible; Grafana still needs a provisioning/dashboards/<provider>.yaml pointing to the mounted path and a provisioning/datasources/prometheus.yaml datasource. Without these, the full-stack compose example starts Grafana but does not automatically import dashboard.json or make Prometheus available.

🤖 Prompt for 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.

In `@docs/observability.md` around lines 221 - 229, Add Grafana provisioning
configuration alongside the compose example: create a dashboard provider YAML
under provisioning/dashboards that points to the mounted
/etc/grafana/provisioning/dashboards directory, and add a Prometheus datasource
YAML under provisioning/datasources with the compose service URL. Ensure the
existing grafana volume mount exposes these provisioning files so dashboard.json
is imported automatically and Prometheus is available.

Comment thread docs/observability.md
Comment on lines +282 to +286
### Grafana Dashboard Not Found

**Symptom:** The import screen says "Dashboard not found."

Ensure you're importing the correct file from `resources/grafana/dashboard.json`. If the file doesn't exist, generate it by running `sorokeep metrics --grafana-dashboard` (requires implementation of the dashboard export feature), or manually create a dashboard in the Grafana UI using the metric names listed above.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Do not recommend an unimplemented dashboard-export command.

The troubleshooting step explicitly says sorokeep metrics --grafana-dashboard requires an unimplemented feature, so users following the recovery path will receive a command failure. Remove that command and point users to the checked-in dashboard file or manual import.

🤖 Prompt for 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.

In `@docs/observability.md` around lines 282 - 286, Update the “Grafana Dashboard
Not Found” troubleshooting section to remove the unimplemented sorokeep metrics
--grafana-dashboard command. Direct users to import the checked-in
resources/grafana/dashboard.json file, or manually create/import a dashboard in
Grafana using the listed metric names.

@gitguardian

gitguardian Bot commented Jul 29, 2026 •

Copy link
Copy Markdown

️✅ There are no secrets present in this pull request anymore.

If these secrets were true positive and are still valid, we highly recommend you to revoke them.
While these secrets were previously flagged, we no longer have a reference to the
specific commits where they were detected. Once a secret has been leaked into a git
repository, you should consider it compromised, even if it was deleted immediately.
Find here more information about risks.


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

@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

🤖 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 `@README.md`:
- Line 680: Remove the Prometheus `/metrics` bullet from the Roadmap section in
README.md, leaving the existing observability documentation reference and other
roadmap entries unchanged.
🪄 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: ASSERTIVE

Plan: Pro Plus

Run ID: 9e472a0d-f27f-4563-9e02-04e34e626390

📥 Commits

Reviewing files that changed from the base of the PR and between 8ea4612 and 6100d80.

📒 Files selected for processing (1)
  • README.md
📜 Review details
🔇 Additional comments (1)
README.md (1)

3-5: LGTM!

Also applies to: 28-28, 72-77, 674-678

Comment thread README.md

- Plugin interface for alert channels — so a new channel (Matrix, MS Teams, email) doesn't require touching core dispatch code or the DB schema
- Prometheus `/metrics` endpoint for teams with existing observability stacks
- Prometheus `/metrics` endpoint for teams with existing observability stacks — see [Observability Setup Guide](docs/observability.md)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate files =="
git ls-files | rg '(^|/)README\.md$|docs/observability\.md$|observability' || true

echo "== README relevant lines =="
if [ -f README.md ]; then
  sed -n '660,690p' README.md | nl -ba -v660
fi

echo "== observability guide occurrences =="
if [ -f docs/observability.md ]; then
  rg -n "(/metrics|metrics-port|--metrics-port|built-in|Roadmap|future|observability)" docs/observability.md -C 2 || true
  wc -l docs/observability.md
fi

echo "== code occurrences for /metrics and metrics-port =="
rg -n "(/metrics|--metrics-port|metrics-port|metricsPort|metrics)" --glob '!node_modules' --glob '!dist' --glob '!build' . -C 2 || true

Repository: AbdulmalikAlayande/sorokeep

Length of output: 413


🏁 Script executed:

#!/bin/bash
set -u

echo "== README relevant lines =="
if [ -f README.md ]; then
  sed -n '660,690p' README.md | awk '{printf "%6d  %s\n", NR+659, $0}'
fi

echo "== observability guide occurrences =="
if [ -f docs/observability.md ]; then
  rg -n "(/metrics|metrics-port|--metrics-port|built-in|Roadmap|future|observability)" docs/observability.md -C 2 || true
  wc -l docs/observability.md
fi

echo "== code occurrences for /metrics and metrics-port =="
rg -n "(/metrics|--metrics-port|metrics-port|metricsPort|metrics)" --glob '!node_modules' --glob '!dist' --glob '!build' . -C 2 || true

Repository: AbdulmalikAlayande/sorokeep

Length of output: 24419


Remove the /metrics entry from the Roadmap.

docs/observability.md documents the /metrics endpoint as a built-in feature enabled with --metrics-port, so keeping it under “Roadmap” in README.md mislabels existing work as future work.

🤖 Prompt for 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.

In `@README.md` at line 680, Remove the Prometheus `/metrics` bullet from the
Roadmap section in README.md, leaving the existing observability documentation
reference and other roadmap entries unchanged.

AbdulmalikAlayande added a commit that referenced this pull request Aug 2, 2026
…oints (#545, #340)

PR #545's docs/observability.md was written and submitted without
actually being run against sorokeep, despite the issue's own
acceptance criteria requiring every step to be verified end-to-end:
- every metric name in the guide (sorokeep_contracts_total,
  sorokeep_contract_entries_total, sorokeep_alerts_fired_total,
  sorokeep_alerts_unresolved_total, sorokeep_channel_accounts_total)
  is wrong — none of these exist; the real names are
  sorokeep_contracts_tracked, sorokeep_entries_tracked, etc.
- documented a /healthz endpoint and a --metrics-host flag, neither
  of which exist yet
- referenced resources/grafana/dashboard.json and a
  `sorokeep metrics --grafana-dashboard` CLI flag, neither of which
  exist — the PR's own text admitted the flag "requires
  implementation"

Verified every metric name and the sample /metrics output directly
against the real registry (collectAllMetrics + register.metrics()) and
corrected the guide throughout: fixed the metrics table and sample
output, removed the nonexistent /healthz and --metrics-host
references (added the real SOROKEEP_METRICS_TOKEN auth doc instead),
replaced the fabricated dashboard-import section with accurate
"no bundled dashboard yet, build panels manually" guidance plus real
PromQL examples against the actual metric names, fixed the Alertmanager
example rule that referenced a nonexistent metric, and removed a
docker-compose volume mount pointing at a directory that doesn't
exist. Kept the well-structured parts (Prometheus scrape config,
Alertmanager wiring, docker-compose stack, troubleshooting table) as-is
— those were sound.

Verified: tsc clean, full suite 1300/1300 (including README/docs
parity tests), npm audit clean, build succeeds, and every metric name
and sample output in the corrected guide was checked directly against
a live collectAllMetrics()/register.metrics() call.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@AbdulmalikAlayande
AbdulmalikAlayande merged commit 8b018de into TegoLabs:main Aug 2, 2026
2 checks passed
@AbdulmalikAlayande

Copy link
Copy Markdown
Collaborator

Merged into main (43ad363) after local verification (tsc, lint, full suite 1300/1300 including README/docs parity tests, npm audit, build).

Good structure and coverage overall, but the acceptance criteria required every step to be verified end-to-end, and several things didn't match reality when I checked: every metric name in the guide was wrong (e.g. sorokeep_contracts_total vs the real sorokeep_contracts_tracked), it documented a /healthz endpoint and --metrics-host flag that don't exist, and referenced a Grafana dashboard file and CLI flag that aren't implemented yet. Verified every metric name and sample output directly against a live collectAllMetrics()/register.metrics() call and corrected the guide throughout — kept the well-structured Prometheus/Alertmanager/docker-compose/troubleshooting sections as-is since those were sound.

Thanks for the solid overall structure — good foundation, just needed a pass against the real running system.

AbdulmalikAlayande added a commit that referenced this pull request Aug 2, 2026
…oints (#545, #340)

PR #545's docs/observability.md was written and submitted without
actually being run against sorokeep, despite the issue's own
acceptance criteria requiring every step to be verified end-to-end:
- every metric name in the guide (sorokeep_contracts_total,
  sorokeep_contract_entries_total, sorokeep_alerts_fired_total,
  sorokeep_alerts_unresolved_total, sorokeep_channel_accounts_total)
  is wrong — none of these exist; the real names are
  sorokeep_contracts_tracked, sorokeep_entries_tracked, etc.
- documented a /healthz endpoint and a --metrics-host flag, neither
  of which exist yet
- referenced resources/grafana/dashboard.json and a
  `sorokeep metrics --grafana-dashboard` CLI flag, neither of which
  exist — the PR's own text admitted the flag "requires
  implementation"

Verified every metric name and the sample /metrics output directly
against the real registry (collectAllMetrics + register.metrics()) and
corrected the guide throughout: fixed the metrics table and sample
output, removed the nonexistent /healthz and --metrics-host
references (added the real SOROKEEP_METRICS_TOKEN auth doc instead),
replaced the fabricated dashboard-import section with accurate
"no bundled dashboard yet, build panels manually" guidance plus real
PromQL examples against the actual metric names, fixed the Alertmanager
example rule that referenced a nonexistent metric, and removed a
docker-compose volume mount pointing at a directory that doesn't
exist. Kept the well-structured parts (Prometheus scrape config,
Alertmanager wiring, docker-compose stack, troubleshooting table) as-is
— those were sound.

Verified: tsc clean, full suite 1300/1300 (including README/docs
parity tests), npm audit clean, build succeeds, and every metric name
and sample output in the corrected guide was checked directly against
a live collectAllMetrics()/register.metrics() call.
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.

docs: write observability setup guide (Prometheus + Grafana)

2 participants