feat(integrations): add VictoriaLogs integration#1144
feat(integrations): add VictoriaLogs integration#1144VaibhavUpreti merged 8 commits intoTracer-Cloud:mainfrom
Conversation
Greptile SummaryThis PR adds a complete VictoriaLogs integration: Pydantic config model, catalog wiring (DB-store + env-var paths), verifier, synchronous HTTP client,
Confidence Score: 4/5Safe to review but not ready to merge — one P1 wiring gap makes the tool silently non-functional in production. All the integration plumbing layers (catalog, models, verify, client, evidence type, docs, tests) are well-implemented and address every issue from prior reviews. The single blocker is the missing detect_sources.py block that prevents victoria_logs from ever appearing in available_sources, making is_available() always return False and the tool perpetually unscheduled. Once that one-function addition is made, the PR is ready. app/nodes/plan_actions/detect_sources.py (missing victoria_logs wiring) and app/tools/VictoriaLogsTool/init.py (extract_params query defaulting) Important Files Changed
Sequence DiagramsequenceDiagram
participant ENV as Env / DB Store
participant Catalog as catalog.py
participant DetectSrc as detect_sources.py
participant PlanActions as plan_actions.py
participant Executor as execute_actions.py
participant Tool as VictoriaLogsTool
participant Client as VictoriaLogsClient
ENV->>Catalog: VICTORIA_LOGS_URL / DB record
Catalog->>Catalog: load_env_integrations() / _classify_service_instance()
Catalog->>Catalog: resolve_effective_integrations() → EffectiveIntegrations.victoria_logs ✓
Note over DetectSrc: ⚠️ Missing block for victoria_logs
DetectSrc-->>PlanActions: available_sources (no victoria_logs key)
PlanActions->>Tool: is_available(sources) → False ✗
Note over PlanActions: Tool not scheduled
alt If detect_sources.py is fixed
DetectSrc->>PlanActions: available_sources[victoria_logs] = {base_url, tenant_id}
PlanActions->>Tool: is_available(sources) → True ✓
Executor->>Tool: run(**extract_params(sources))
Tool->>Client: make_victoria_logs_client(base_url, tenant_id)
Client->>Client: GET /select/logsql/query?query=*&limit=50&start=-1h
Client-->>Tool: {success, rows, total}
Tool-->>Executor: {source, available, rows, total}
end
|
There was a problem hiding this comment.
Pull request overview
Adds a first-class VictoriaLogs integration to the integrations/catalog/tooling stack so investigations can query LogsQL and the CLI can verify connectivity.
Changes:
- Introduces VictoriaLogs integration config + catalog wiring (DB-store classification and env var loading).
- Adds VictoriaLogs verifier and a synchronous httpx client for
/select/logsql/query. - Registers a new
victoria_logs_queryinvestigation tool, updates evidence source typing, and adds docs + tests.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
app/integrations/models.py |
Adds VictoriaLogsIntegrationConfig and exposes victoria_logs on EffectiveIntegrations. |
app/integrations/catalog.py |
Adds service key mapping/classification + env loading + direct service resolution for victoria_logs. |
app/integrations/verify.py |
Adds _verify_victoria_logs and wires it into the verify dispatch. |
app/services/victoria_logs/client.py |
Implements VictoriaLogsClient + config normalization + NDJSON parsing. |
app/services/victoria_logs/__init__.py |
Exports the VictoriaLogs client/config factory. |
app/tools/VictoriaLogsTool/__init__.py |
Adds VictoriaLogsTool with extract_params/run executor contract support. |
app/types/evidence.py |
Extends EvidenceSource with "victoria_logs". |
docs/victoria_logs.mdx |
Adds end-user documentation for setup/verify/troubleshooting. |
tests/integrations/test_victoria_logs.py |
Adds unit tests for config normalization, env loading, classification, and verifier status contract. |
tests/tools/test_victoria_logs_tool.py |
Adds tool contract + executor-path regression tests for extract_params/run. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| | Symptom | Fix | | ||
| | --- | --- | | ||
| | **Status: missing** | Set `VICTORIA_LOGS_URL` or add a `victoria_logs` entry to your integrations store | | ||
| | **Connection refused** | Verify the URL is reachable from this host; check firewall rules | | ||
| | **404 on `/select/logsql/query`** | Confirm you are pointing at VictoriaLogs (not VictoriaMetrics for time-series); they expose different endpoints | |
| "tenant_id": { | ||
| "type": "string", | ||
| "default": "", | ||
| "description": "Optional VictoriaLogs tenant ID; sent as the AccountID header.", | ||
| }, | ||
| "query": { | ||
| "type": "string", | ||
| "description": "LogsQL query string (e.g. `_stream_id:* AND error`).", | ||
| }, | ||
| "limit": { | ||
| "type": "integer", | ||
| "default": 50, | ||
| "description": "Maximum number of log entries to return.", | ||
| }, | ||
| "start": { | ||
| "type": "string", | ||
| "default": "-1h", | ||
| "description": "Time range expression accepted by VictoriaLogs (e.g. -1h, -24h).", | ||
| }, | ||
| }, | ||
| "required": ["base_url", "query"], | ||
| } |
| def test_alias_victorialogs_normalizes_to_victoria_logs(self) -> None: | ||
| # The service key map registers both spellings — confirm classification | ||
| # under the canonical key still works when callers feed in a record | ||
| # whose service field reaches this function pre-normalized. | ||
| config, key = _classify_service_instance( | ||
| key="victoria_logs", | ||
| credentials={"base_url": "http://vmlogs:9428", "tenant_id": "team-a"}, | ||
| record_id="vl-team-a", | ||
| ) |
| | Variable | Default | Description | | ||
| | --- | --- | --- | | ||
| | `VICTORIA_LOGS_URL` | — | **Required.** Base URL of your VictoriaLogs instance | | ||
| | `VICTORIA_LOGS_TENANT_ID` | _(unset)_ | Optional. Sent as the `AccountID` header on multi-tenant deployments | | ||
|
|
762b5d7 to
90bc622
Compare
|
Addressed bot review feedback in commit Fixed:
Not changed (false positives):
Quality gates:
|
dacd678 to
124dc30
Compare
|
@yashksaini-coder can you pls share an e2e video demo of the full integration? will be helpful as its the acceptance criteria for most such integration.. |
|
@muddlebee Here's the demo video, sorry it took some time, was shifting OS demo-tests.mp4 |
VaibhavUpreti
left a comment
There was a problem hiding this comment.
Great job @yashksaini-coder !
|
🎊 Achievement unlocked: PR Merged. @yashksaini-coder passed code review, survived CI, and shipped. Respect. 🤝 👋 Join us on Discord - OpenSRE : hang out, contribute, or hunt for features and issues. Everyone's welcome. |

Closes #126.
Adds a first-class VictoriaLogs integration: config model, catalog wiring (DB-store + env-var paths), verifier, sync HTTP client, LangGraph tool, docs, and tests.
Scope
Strictly limited to the integration. No edits to
app/nodes/extract_alert/or any prompt files — this PR scopes to integration plumbing only.What's in
app/integrations/models.py(VictoriaLogsIntegrationConfig,EffectiveIntegrations.victoria_logs)app/integrations/catalog.py(service key map, classifier, env loader,direct_services)app/integrations/verify.py(_verify_victoria_logs,SUPPORTED_VERIFY_SERVICES, dispatch)app/services/victoria_logs/{__init__.py, client.py}app/tools/VictoriaLogsTool/__init__.pyapp/types/evidence.pydocs/victoria_logs.mdxtests/integrations/test_victoria_logs.py,tests/tools/test_victoria_logs_tool.pyHow prior P1/P2 review feedback is addressed
This PR was rebuilt from
mainafter PRs #663 and #1060 were closed. Each issue raised on those PRs is addressed below.extract_params/runexecutor-contract mismatch (P1, #663 + #1060)Prior PRs read credentials from
kwargs["sources"]insiderun(), but the executor calls tools astool.run(**tool.extract_params(sources))with nosourceskwarg, sobase_urlwas always empty. Fixed by mirroringAlertmanagerAlertsTool:extract_params()returns every kwargrun()declares, andrun()accepts them as explicit parameters. A unit testTestExecutorPathContract::test_run_via_extract_params_succeedsinvokes the tool exactly as the executor does, so any future drift fails at unit-test time.Verifier returned
status=\"verified\"instead of\"passed\"(P1, #1060)verification_exit_code()checksstatus == \"passed\"._verify_victoria_logsnow returns\"passed\"/\"missing\"/\"failed\"consistent with every other verifier inverify.py.victoria_logsmissing fromEffectiveIntegrations(P1, #663 + #1060)EffectiveIntegrationsusesextra=\"forbid\".victoria_logs: EffectiveIntegrationEntry | None = Nonedeclared. A test (test_effective_integrations_field_exists) re-validates the dump shape to guard against regression.victoria_logsabsent fromdirect_servicesandload_env_integrations()(P1, #663)Both added in
catalog.py._classify_service_instancehandles the DB-store path;load_env_integrationsreadsVICTORIA_LOGS_URLand optionalVICTORIA_LOGS_TENANT_ID.tenant_iddefaulted to\"0\"and always sentAccountID(P2, #1060)tenant_id: str | None = Nonewith a validator collapsingNone,\"\", and whitespace toNone. TheAccountIDheader is sent only whentenant_idis explicitly configured. Docs reflect this — noVICTORIA_LOGS_TENANT_ID=\"0\"example.import contextlibinside the loop (P2, #1060)Moved to module level in
client.py.\"victoria_logs\"not inEvidenceSourceLiteral (P1, #1060)Added.
BaseTool.__init_subclass__()validates this at import time.Unrelated extraction-prompt edits (P1, #1060)
Not touched in this PR.
Configuration
Quality gates
ruff check— clean on all 9 changed filesruff format --check— cleanmypy— no issues on changed filespytest tests/integrations/test_victoria_logs.py tests/tools/test_victoria_logs_tool.py— 38/38 passedpytest tests/integrations/ tests/tools/ tests/types/— 1972 passed, 1 xfailed (no regressions)