feat: Victoria Logs Integration#663
feat: Victoria Logs Integration#663aniruddhaadak80 wants to merge 18 commits intoTracer-Cloud:mainfrom
Conversation
…d routing precedence
There was a problem hiding this comment.
Pull request overview
Adds first-class VictoriaLogs support to the investigation toolchain (Issue #126), alongside a broad formatting pass and several prompt/routing refinements to improve RCA correctness and avoid speculative diagnoses.
Changes:
- Introduces
VictoriaLogsClient+VictoriaLogsToolto query VictoriaLogs via LogsQL. - Adds VictoriaLogs integration config model and updates RCA / routing prompts for stricter evidence-first behavior.
- Applies repo-wide formatting/line-wrapping refactors across tools, integrations, services, and CLI modules.
Reviewed changes
Copilot reviewed 231 out of 232 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| app/webapp.py | Formatting-only change for health status assignment. |
| app/utils/ingest_delivery.py | Formatting-only change for payload construction. |
| app/utils/discord_delivery.py | Formatting-only change for function signatures. |
| app/utils/config.py | Formatting-only change for env parsing helpers and signatures. |
| app/tools/utils/data_validation.py | Formatting-only change (line wrap). |
| app/tools/utils/compaction.py | Formatting-only change (signature + multiline condition). |
| app/tools/tool_decorator.py | Formatting-only change; adds blank line before wrapper. |
| app/tools/registry.py | Formatting-only change for function signature. |
| app/tools/registered_tool.py | Formatting-only change for exception and dict construction. |
| app/tools/investigation_registry/docstring_parser.py | Formatting-only change for list comprehension and regex call. |
| app/tools/base.py | Formatting-only change (wrap outputs + metadata dict). |
| app/tools/VictoriaLogsTool/init.py | New tool to query VictoriaLogs (currently has execution/registration issues). |
| app/tools/VercelLogsTool/init.py | Formatting-only changes. |
| app/tools/VercelDeploymentStatusTool/init.py | Formatting-only changes. |
| app/tools/TracerTasksTool/init.py | Formatting-only change in schema. |
| app/tools/TracerFailedRunTool/init.py | Formatting-only changes. |
| app/tools/TracerFailedJobsTool/init.py | Formatting-only changes (multiline calls + dict literal). |
| app/tools/TracerErrorLogsTool/init.py | Formatting-only changes. |
| app/tools/SentrySearchIssuesTool/init.py | Formatting-only changes (dict literals). |
| app/tools/SentryIssueEventsTool/init.py | Formatting-only changes (availability + error payload). |
| app/tools/SentryIssueDetailsTool/init.py | Formatting-only changes (availability + error payload). |
| app/tools/SREGuidanceTool/knowledge_base.py | Formatting-only changes (keyword lists). |
| app/tools/S3MarkerTool/init.py | Formatting-only changes (error payload + signature). |
| app/tools/S3ListTool/init.py | Formatting-only changes (error payload). |
| app/tools/S3InspectTool/init.py | Formatting-only changes (availability + error payloads). |
| app/tools/S3GetObjectTool/init.py | Formatting-only changes (availability + error payloads). |
| app/tools/PrefectWorkerHealthTool/init.py | Formatting-only changes. |
| app/tools/PrefectFlowRunsTool/init.py | Formatting-only changes. |
| app/tools/PostgreSQLReplicationStatusTool/init.py | Formatting-only change (import grouping). |
| app/tools/OpsGenieAlertsTool/init.py | Formatting-only changes. |
| app/tools/OpsGenieAlertDetailTool/init.py | Formatting-only changes. |
| app/tools/OpenClawMCPTool/init.py | Formatting-only changes. |
| app/tools/MongoDBAtlasMetricsTool/init.py | Formatting-only changes. |
| app/tools/MariaDBStatusTool/init.py | Formatting-only changes. |
| app/tools/MariaDBSlowQueriesTool/init.py | Formatting-only changes. |
| app/tools/MariaDBReplicationTool/init.py | Formatting-only changes. |
| app/tools/MariaDBProcessListTool/init.py | Formatting-only changes. |
| app/tools/MariaDBInnoDBStatusTool/init.py | Formatting-only changes. |
| app/tools/LambdaInvocationLogsTool/init.py | Formatting-only changes. |
| app/tools/LambdaInspectTool/init.py | Formatting-only changes. |
| app/tools/LambdaErrorsTool/init.py | Formatting-only changes. |
| app/tools/LambdaConfigTool/init.py | Formatting-only changes. |
| app/tools/JiraSearchIssuesTool/init.py | Formatting-only changes. |
| app/tools/JiraIssueDetailTool/init.py | Formatting-only changes. |
| app/tools/JiraCreateIssueTool/init.py | Formatting-only changes. |
| app/tools/JiraAddCommentTool/init.py | Formatting-only changes. |
| app/tools/HoneycombTracesTool/init.py | Formatting-only changes. |
| app/tools/GrafanaTracesTool/init.py | Formatting-only changes. |
| app/tools/GrafanaServiceNamesTool/init.py | Formatting-only changes. |
| app/tools/GrafanaMetricsTool/init.py | Formatting-only changes. |
| app/tools/GrafanaLogsTool/init.py | Formatting-only changes. |
| app/tools/GrafanaAlertRulesTool/init.py | Formatting-only changes. |
| app/tools/GitLabPipelinesTool/init.py | Formatting-only changes. |
| app/tools/GitLabMRsTool/init.py | Formatting-only changes. |
| app/tools/GitLabFileTool/init.py | Formatting-only changes. |
| app/tools/GitLabCommitsTool/init.py | Formatting-only + trailing comma fix. |
| app/tools/GitHubSearchCodeTool/init.py | Formatting-only changes. |
| app/tools/GitHubRepositoryTreeTool/init.py | Formatting-only changes. |
| app/tools/GitHubFileContentsTool/init.py | Formatting-only changes. |
| app/tools/GitHubCommitsTool/init.py | Formatting-only changes. |
| app/tools/ElasticsearchLogsTool/_client.py | Formatting-only changes (helper + dict literal). |
| app/tools/ElasticsearchLogsTool/init.py | Formatting-only changes. |
| app/tools/EKSPodLogsTool/init.py | Formatting-only changes (logging + payload dict). |
| app/tools/EKSNodegroupHealthTool/init.py | Formatting-only changes (payload dict). |
| app/tools/EKSNodeHealthTool/init.py | Formatting-only changes (payload dict). |
| app/tools/EKSListNamespacesTool/init.py | Formatting-only changes (list/dict construction). |
| app/tools/EKSListDeploymentsTool/init.py | Formatting-only changes (payload dict + conditional). |
| app/tools/EKSEventsTool/init.py | Formatting-only changes (payload dict + conditional). |
| app/tools/EKSDescribeClusterTool/init.py | Formatting-only changes (payload dict). |
| app/tools/EKSDescribeAddonTool/init.py | Formatting-only changes (payload dict). |
| app/tools/EKSDeploymentStatusTool/init.py | Formatting-only changes (logging + payload dict). |
| app/tools/DataDogNodePodsTool/init.py | Formatting-only changes. |
| app/tools/DataDogMonitorsTool/init.py | Formatting-only changes. |
| app/tools/DataDogMetricsTool/init.py | Formatting-only changes. |
| app/tools/DataDogLogsTool/_client.py | Formatting-only changes (helper + dict literal). |
| app/tools/DataDogLogsTool/init.py | Formatting-only changes (call + list comprehension wrap). |
| app/tools/DataDogEventsTool/init.py | Formatting-only changes. |
| app/tools/DataDogContextTool/init.py | Formatting-only changes. |
| app/tools/CoralogixLogsTool/init.py | Formatting-only changes. |
| app/tools/CloudWatchLogsTool/init.py | Formatting-only changes (schema + boto args). |
| app/tools/CloudWatchBatchMetricsTool/init.py | Formatting-only changes (schema + helper calls). |
| app/tools/ClickHouseSystemHealthTool/init.py | Formatting-only changes (import grouping). |
| app/tools/BitbucketSearchCodeTool/init.py | Formatting-only changes. |
| app/tools/BitbucketFileContentsTool/init.py | Formatting-only changes. |
| app/tools/BitbucketCommitsTool/init.py | Formatting-only changes. |
| app/tools/AlertmanagerAlertsTool/init.py | Formatting-only changes. |
| app/tools/AWSOperationTool/init.py | Formatting-only changes. |
| app/state/factory.py | Formatting-only changes (dict comprehension + cast wrapping). |
| app/state/agent_state.py | Formatting-only changes (ConfigDict wrapping). |
| app/services/victoria_logs/client.py | New VictoriaLogs HTTP client (NDJSON parsing + tenant header logic). |
| app/services/victoria_logs/init.py | New service factory/export for VictoriaLogs. |
| app/services/tracer_client/tracer_integrations.py | Formatting-only changes (signature + logging wrap). |
| app/services/tracer_client/aws_batch_jobs.py | Formatting-only changes (ternary + comprehension wrap). |
| app/services/s3_client.py | Formatting-only changes (payload dict + expression wrap). |
| app/services/lambda_client.py | Formatting-only changes (credential checks + conditional wrap). |
| app/services/honeycomb/client.py | Formatting-only changes (payload extraction + error payloads). |
| app/services/grafana/config.py | Formatting-only changes (boolean expressions wrap). |
| app/services/grafana/base.py | Formatting-only changes (list/dict construction + debug log). |
| app/services/google_docs/client.py | Minor logic fix for 403/404 error messaging + formatting. |
| app/services/env.py | Formatting-only changes (helper signature + string wrap). |
| app/services/eks/eks_k8s_client.py | Formatting-only changes (logging + signature wrap). |
| app/services/eks/eks_client.py | Formatting-only changes (kwargs dict + indexing wrap). |
| app/services/coralogix/client.py | Formatting-only changes. |
| app/services/cloudwatch_client.py | Formatting-only changes (credential checks). |
| app/services/aws_sdk_client.py | Formatting-only changes (tuple return + list truncation wrap). |
| app/services/alertmanager/client.py | Formatting-only changes (payload dict construction). |
| app/sandbox/runner.py | Formatting-only changes (NamedTemporaryFile call). |
| app/remote/stream.py | Formatting-only changes (slice spacing). |
| app/remote/slack_context.py | Formatting-only changes (ValueError + warning wrap). |
| app/remote/renderer.py | Formatting-only changes (frozenset literals). |
| app/remote/ops.py | Formatting-only changes (exceptions + signature wrap). |
| app/pipeline/runners.py | Formatting-only changes (ternary expression + imports + calls). |
| app/pipeline/routing.py | Formatting-only changes (logger.exception wrap). |
| app/pipeline/graph.py | Formatting-only changes (conditional edges call formatting). |
| app/nodes/root_cause_diagnosis/evidence_checker.py | Formatting-only changes (constants + conditionals wrap). |
| app/nodes/resolve_integrations/node.py | Formatting-only changes (tracker message wrap). |
| app/nodes/publish_findings/urls/aws.py | Formatting-only change (single-line return). |
| app/nodes/publish_findings/renderers/terminal.py | Formatting-only changes (slices + function signatures + print wrap). |
| app/nodes/publish_findings/formatters/report.py | Formatting-only changes (regex + string assembly + comprehension wrap). |
| app/nodes/publish_findings/formatters/lineage.py | Formatting-only changes (helpers + string wrap). |
| app/nodes/plan_actions/plan_actions.py | Formatting-only changes (signature + calls + conditionals wrap). |
| app/nodes/investigate/node.py | Formatting-only changes (casts + calls wrap). |
| app/nodes/investigate/models.py | Formatting-only changes (field wraps + helpers). |
| app/nodes/extract_alert/models.py | Updates alert source description (adds more sources) + formatting. |
| app/nodes/extract_alert/extract_node.py | Formatting-only changes (logging, tracker fields, reaction calls). |
| app/nodes/extract_alert/extract.py | Tightens LLM extraction instructions to reduce misrouting/speculation; formatting. |
| app/nodes/chat.py | Formatting-only changes (blank line + bind_tools wrap). |
| app/masking/detectors.py | Formatting-only changes (ternary + generator wrap). |
| app/masking/context.py | Formatting-only changes (compiled patterns + signature wrap). |
| app/integrations/trello.py | Formatting-only changes. |
| app/integrations/store.py | Formatting-only changes (warning wrap). |
| app/integrations/sentry.py | Formatting-only changes. |
| app/integrations/posthog.py | Formatting-only changes. |
| app/integrations/postgresql.py | Formatting-only changes (config dict + messages). |
| app/integrations/models.py | Adds VictoriaLogsIntegrationConfig model + formatting changes. |
| app/integrations/mariadb.py | Formatting-only changes. |
| app/integrations/kafka.py | Formatting-only changes. |
| app/integrations/gitlab.py | Formatting-only changes + minor quoting consistency. |
| app/integrations/github_issue_comments.py | Formatting-only changes (string wrap + exception wrap). |
| app/integrations/clients/prefect/client.py | Formatting-only changes (payload dicts + logging wrap). |
| app/integrations/clients/notion/client.py | Formatting-only changes (payload dicts + logging wrap). |
| app/integrations/clickhouse.py | Formatting-only changes (config parsing + error payload). |
| app/integrations/bitbucket.py | Formatting-only changes. |
| app/integrations/azure_sql.py | Formatting-only changes (builder + error payload). |
| app/integrations/main.py | Formatting-only change (print wrap). |
| app/guardrails/rules.py | Formatting-only changes (warning wrap). |
| app/guardrails/engine.py | Formatting-only changes (super call + matches append + slicing). |
| app/guardrails/cli.py | Formatting-only changes (redaction wrap). |
| app/guardrails/audit.py | Formatting-only changes (preview wrap). |
| app/entrypoints/mcp.py | Formatting-only changes (Field wraps). |
| app/dockerfile_test.py | Formatting-only changes (assert formatting). |
| app/deployment/provider_config.py | Formatting-only changes (function signatures + error strings). |
| app/deployment/ec2_config.py | Formatting-only changes (write_text wrap). |
| app/constants/prompts.py | Adds stricter evidence-first + anti-speculation requirements; updates router prompt. |
| app/cli/wizard/prompts.py | Formatting-only changes (prompt tokens + signature wrap). |
| app/cli/wizard/init.py | Formatting-only change (blank line). |
| app/cli/update.py | Formatting-only changes (constants + exception messages + prompt). |
| app/cli/tests/runner.py | Formatting-only change (call wrap). |
| app/cli/tests/catalog.py | Formatting-only changes (signature + any() wrap). |
| app/cli/tests/init.py | Formatting-only changes (import grouping). |
| app/cli/prompt_support.py | Formatting-only changes (signature wrap). |
| app/cli/payload.py | Formatting-only change (print wrap). |
| app/cli/local_llm/ollama.py | Formatting-only changes (print wrap + subprocess call). |
| app/cli/local_llm/hardware.py | Formatting-only changes (exception tuple + returns). |
| app/cli/local_llm/command.py | Formatting-only changes (print wrap). |
| app/cli/layout.py | Formatting-only changes (Text assembly wrap). |
| app/cli/investigate_input.py | Formatting-only change (list comprehension wrap). |
| app/cli/investigate.py | Formatting-only changes (tuple assignment wrap). |
| app/cli/health_view.py | Formatting-only changes (Panel + json.dumps wrap). |
| app/cli/errors.py | Formatting-only changes (click.echo wrap). |
| app/cli/deploy.py | Formatting-only changes (subprocess run wrap + logging wrap). |
| app/cli/commands/tests.py | Formatting-only changes (option formatting + signature wrap). |
| app/cli/commands/remote_health.py | Formatting-only changes (rich panel composition wrap). |
| app/cli/commands/onboard.py | Formatting-only changes (signature wrap). |
| app/cli/commands/integrations.py | Formatting-only changes (import grouping + click args/options). |
| app/cli/commands/general.py | Formatting-only changes (options + json.dumps wrap). |
| app/cli/commands/doctor.py | Formatting-only changes (list comp + dict literal wrap). |
| app/cli/commands/deploy.py | Formatting-only changes (signature wrap + imports + option wrap). |
| app/cli/args.py | Formatting-only changes (argument wrap). |
| app/cli/main.py | Formatting-only changes (click option wrap + blank line). |
| app/auth/jwt_auth.py | Formatting-only changes (blank lines + exception tuple + error wrap). |
| app/analytics/provider.py | Formatting-only change (Thread init wrap). |
| app/analytics/cli.py | Formatting-only changes (env parsing + capture call wrap). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| class VictoriaLogsTool(BaseTool): | ||
| name = "victoria_logs_query" | ||
| source = "victoria_logs" | ||
| description = "Query structured logs from VictoriaLogs using LogsQL to investigate application errors or anomalies." |
There was a problem hiding this comment.
source = "victoria_logs" is not a valid EvidenceSource value (see app/types/evidence.py). Because BaseTool.__init_subclass__() validates metadata at import time, this will raise during module import and prevent the tool registry from loading. Add "victoria_logs" to the EvidenceSource Literal (or change this tool's source to an existing value if that's intended).
| def extract_params(self, sources: dict) -> dict[str, Any]: | ||
| return {} | ||
|
|
||
| def run( | ||
| self, query: str, limit: int = 50, start: str = "-1h", **kwargs: Any | ||
| ) -> dict[str, Any]: | ||
| vl_conf = kwargs.get("sources", {}).get("victoria_logs", {}) | ||
| config = VictoriaLogsIntegrationConfig( | ||
| base_url=vl_conf.get("base_url", ""), | ||
| tenant_id=vl_conf.get("tenant_id", "0"), | ||
| ) | ||
|
|
||
| if not config.base_url: | ||
| return { | ||
| "source": "victoria_logs", | ||
| "available": False, | ||
| "error": "VictoriaLogs base_url is required.", | ||
| } | ||
|
|
||
| client = VictoriaLogsClient(config) | ||
| result = client.query_logs(query=query, limit=limit, start=start) | ||
|
|
There was a problem hiding this comment.
extract_params() returns {}, but the investigation executor calls action.run(**action.extract_params(...)). That means run() will be invoked without the required query argument and will raise a TypeError. Implement extract_params() to supply at least query/limit/start (and any needed connection params), and update run() to accept those explicitly rather than relying on kwargs["sources"] which will never be passed by the executor.
| params = {"query": query, "limit": limit, "start": start} | ||
| headers = {} | ||
| if self.config.tenant_id: | ||
| headers["AccountID"] = self.config.tenant_id | ||
|
|
There was a problem hiding this comment.
tenant_id defaults to the string "0", which is truthy, so this client will always send an AccountID: 0 header. If "0" is intended to mean “no tenant scoping” (as implied elsewhere in the codebase), consider only setting this header when tenant_id is non-empty and not "0" to avoid unintended scoping or auth failures.
| rows = [] | ||
| for line in resp.text.splitlines(): | ||
| if not line.strip(): | ||
| continue | ||
| try: | ||
| rows.append(json.loads(line)) | ||
| except Exception: | ||
| pass | ||
|
|
There was a problem hiding this comment.
The NDJSON parsing loop silently ignores JSON decoding failures (except Exception: pass). This can turn partial/invalid responses into “success” with missing rows and no signal to callers. Catch json.JSONDecodeError explicitly and return a warning/error (e.g., include a parse_errors count or fail the request if any non-empty line is invalid).
Fix formatting and typing issues previously caught by the CI pipelines, and constrain formatting strictly to the modified files.
8858ebc to
bdfbfe4
Compare
Greptile SummaryThis PR adds a
Confidence Score: 3/5Not safe to merge — the VictoriaLogsTool is permanently non-functional due to missing catalog wiring, and two issues flagged in prior threads remain unresolved. A P1 defect means the primary deliverable of this PR (a working VictoriaLogs query tool) cannot function at all at runtime. Combined with two open prior-thread P1s (EffectiveIntegrations missing field, integration_id injection), the integration has no usable path to production. app/integrations/catalog.py (missing direct_services entry + load_env_integrations block), app/integrations/models.py (EffectiveIntegrations missing victoria_logs field) Important Files Changed
|
| victoria_logs_config = VictoriaLogsIntegrationConfig.model_validate( | ||
| { | ||
| "base_url": credentials.get("base_url", ""), | ||
| "tenant_id": credentials.get("tenant_id", "0"), | ||
| "integration_id": integration.get("id", ""), | ||
| } | ||
| ) |
There was a problem hiding this comment.
Extra field
integration_id breaks DB-configured Victoria Logs
VictoriaLogsIntegrationConfig extends StrictConfigModel which sets extra="forbid". Passing integration_id to model_validate() will always raise a ValidationError, which is silently swallowed by the surrounding except Exception: continue. This means any Victoria Logs integration stored in the database will be permanently skipped — only env-var-backed (VICTORIA_LOGS_BASE_URL) configurations will work.
| victoria_logs_config = VictoriaLogsIntegrationConfig.model_validate( | |
| { | |
| "base_url": credentials.get("base_url", ""), | |
| "tenant_id": credentials.get("tenant_id", "0"), | |
| "integration_id": integration.get("id", ""), | |
| } | |
| ) | |
| victoria_logs_config = VictoriaLogsIntegrationConfig.model_validate( | |
| { | |
| "base_url": credentials.get("base_url", ""), | |
| "tenant_id": credentials.get("tenant_id", "0"), | |
| } | |
| ) |
Prompt To Fix With AI
This is a comment left during a code review.
Path: app/integrations/catalog.py
Line: 190-196
Comment:
**Extra field `integration_id` breaks DB-configured Victoria Logs**
`VictoriaLogsIntegrationConfig` extends `StrictConfigModel` which sets `extra="forbid"`. Passing `integration_id` to `model_validate()` will always raise a `ValidationError`, which is silently swallowed by the surrounding `except Exception: continue`. This means any Victoria Logs integration stored in the database will be permanently skipped — only env-var-backed (`VICTORIA_LOGS_BASE_URL`) configurations will work.
```suggestion
victoria_logs_config = VictoriaLogsIntegrationConfig.model_validate(
{
"base_url": credentials.get("base_url", ""),
"tenant_id": credentials.get("tenant_id", "0"),
}
)
```
How can I resolve this? If you propose a fix, please make it concise.| openclaw: EffectiveIntegrationEntry | None = None | ||
| mysql: EffectiveIntegrationEntry | None = None | ||
| alertmanager: EffectiveIntegrationEntry | None = None |
There was a problem hiding this comment.
victoria_logs missing from EffectiveIntegrations
EffectiveIntegrations also extends StrictConfigModel (extra="forbid"). Any code that hydrates this model from the resolved integrations dict will raise a ValidationError if victoria_logs is present. All other integrations (grafana, datadog, coralogix, alertmanager, etc.) have a corresponding field here; victoria_logs needs one too.
| openclaw: EffectiveIntegrationEntry | None = None | |
| mysql: EffectiveIntegrationEntry | None = None | |
| alertmanager: EffectiveIntegrationEntry | None = None | |
| alertmanager: EffectiveIntegrationEntry | None = None | |
| victoria_logs: EffectiveIntegrationEntry | None = None |
Prompt To Fix With AI
This is a comment left during a code review.
Path: app/integrations/models.py
Line: 508-510
Comment:
**`victoria_logs` missing from `EffectiveIntegrations`**
`EffectiveIntegrations` also extends `StrictConfigModel` (`extra="forbid"`). Any code that hydrates this model from the resolved integrations dict will raise a `ValidationError` if `victoria_logs` is present. All other integrations (grafana, datadog, coralogix, alertmanager, etc.) have a corresponding field here; `victoria_logs` needs one too.
```suggestion
alertmanager: EffectiveIntegrationEntry | None = None
victoria_logs: EffectiveIntegrationEntry | None = None
```
How can I resolve this? If you propose a fix, please make it concise.| import contextlib | ||
| with contextlib.suppress(Exception): | ||
| rows.append(json.loads(line)) |
There was a problem hiding this comment.
import contextlib inside the loop
Module imports should be at the top of the file, not inside a for loop. Python caches them so it won't crash, but it's non-idiomatic and obscures intent. Move the import to the module level alongside the other imports.
| import contextlib | |
| with contextlib.suppress(Exception): | |
| rows.append(json.loads(line)) | |
| import contextlib | |
| import json | |
| from typing import Any | |
| import httpx |
Then remove the in-loop import and keep only with contextlib.suppress(Exception):.
Prompt To Fix With AI
This is a comment left during a code review.
Path: app/services/victoria_logs/client.py
Line: 36-38
Comment:
**`import contextlib` inside the loop**
Module imports should be at the top of the file, not inside a `for` loop. Python caches them so it won't crash, but it's non-idiomatic and obscures intent. Move the import to the module level alongside the other imports.
```suggestion
import contextlib
import json
from typing import Any
import httpx
```
Then remove the in-loop import and keep only `with contextlib.suppress(Exception):`.
How can I resolve this? If you propose a fix, please make it concise.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| alert_source: str | None = Field( | ||
| default=None, | ||
| description=( | ||
| "Platform that fired the alert: 'grafana', 'datadog', 'honeycomb', " | ||
| "'coralogix', 'cloudwatch', or None if unknown" | ||
| "'coralogix', 'cloudwatch', 'eks', 'alertmanager', or None if unknown" | ||
| ), | ||
| ) |
There was a problem hiding this comment.
alert_source description omits victoria_logs
All other log/observability integrations added to the platform are listed in this field's description to guide the LLM. The extract prompt in extract.py also enumerates them explicitly. If VictoriaLogs can be the origin of an alert (e.g. alerting rules inside VictoriaLogs), the LLM will have no hint to set alert_source = "victoria_logs". Consider adding it to the allowed set if applicable.
Prompt To Fix With AI
This is a comment left during a code review.
Path: app/nodes/extract_alert/models.py
Line: 23-29
Comment:
**`alert_source` description omits `victoria_logs`**
All other log/observability integrations added to the platform are listed in this field's description to guide the LLM. The extract prompt in `extract.py` also enumerates them explicitly. If VictoriaLogs can be the origin of an alert (e.g. alerting rules inside VictoriaLogs), the LLM will have no hint to set `alert_source = "victoria_logs"`. Consider adding it to the allowed set if applicable.
How can I resolve this? If you propose a fix, please make it concise.- Remove forbidden extra field integration_id passed to VictoriaLogsIntegrationConfig - Add �ictoria_logs to EffectiveIntegrations model - Move import contextlib to top of module in VictoriaLogsClient
VaibhavUpreti
left a comment
There was a problem hiding this comment.
Hi @aniruddhaadak80, Could you please add a demo image or video showcasing the feature? Also, kindly update the documentation with any relevant setup instructions.
Once that’s done, please tag @yashksaini-coder and @Devesh36 for an initial review.
Thank you!
yashksaini-coder
left a comment
There was a problem hiding this comment.
A few things need to be fixed before this can move forward — detailed inline comments below on each file.
| You can query connected systems (e.g., Tracer run/task data, logs, metrics, failed jobs/tools) and developer tooling (e.g., GitHub and Sentry) using available tools. | ||
|
|
||
| CRITICAL RCA BEHAVIORS: | ||
| - Evidence First: Clearly separate direct observations from inferences. Do not make premature root-cause claims before sufficient evidence is gathered. |
There was a problem hiding this comment.
These prompt changes (CRITICAL RCA BEHAVIORS block and the general chat rewrite) have nothing to do with Victoria Logs. Please remove them from this PR. If you think they're worth making, open a separate PR for them.
| @classmethod | ||
| def _normalize_dataset(cls, value: object) -> str: | ||
| return str(value or DEFAULT_HONEYCOMB_DATASET).strip() or DEFAULT_HONEYCOMB_DATASET | ||
| return ( |
There was a problem hiding this comment.
VictoriaLogsIntegrationConfig is imported in verify.py, the service init, and the tool — but it's never actually defined anywhere in this PR or in main. This will throw an ImportError the moment any of those modules are loaded. You need to add the Pydantic model class here, something like:\n\npython\nclass VictoriaLogsIntegrationConfig(StrictConfigModel):\n base_url: str = ""\n tenant_id: str = "0"\n integration_id: str = ""\n
| from typing import Any | ||
|
|
||
| from app.integrations.models import VictoriaLogsIntegrationConfig | ||
| from app.services.victoria_logs.client import VictoriaLogsClient |
There was a problem hiding this comment.
This import will crash at load time because VictoriaLogsIntegrationConfig doesn't exist in models.py. Fix the model definition first (see comment on models.py).
| @@ -276,13 +300,33 @@ def _build_sts_client(config: dict[str, Any]) -> tuple[Any, str, str]: | |||
| region_name=region, | |||
| aws_access_key_id=credentials.access_key_id if credentials else "", | |||
| aws_secret_access_key=credentials.secret_access_key if credentials else "", | |||
There was a problem hiding this comment.
The verify function itself looks fine, but it won't actually get called. For victoria_logs to appear in effective_integrations, catalog.py needs a classification block for it (similar to how other services are handled in _classify_service_instance). Without that, the config will never reach here. Please also add load_env_integrations() support with env vars like VICTORIA_LOGS_URL and VICTORIA_LOGS_TENANT_ID.
| is_noise=false (default) for: any alert, error, failure, incident, warning, monitoring notification (including health checks and informational states). | ||
| When in doubt, set is_noise=false. | ||
|
|
||
| CRITICAL INSTRUCTIONS FOR RCA CAPABILITY: |
There was a problem hiding this comment.
These changes to alert_source routing and the new CRITICAL INSTRUCTIONS block are not related to Victoria Logs at all. Please remove them from this PR — they change core routing behaviour and would need their own review and tests.
…try and VictoriaLogsTool
yashksaini-coder
left a comment
There was a problem hiding this comment.
Great progress — all the P1 blockers from prior rounds are fixed (EvidenceSource, catalog wiring, EffectiveIntegrations, integration_id injection). Thank you for working through those. One critical runtime bug remains before this can merge.
🔴 Critical — extract_params() returns {} → TypeError on every real invocation
File: app/tools/VictoriaLogsTool/__init__.py lines 40–50
The investigation executor calls:
kwargs = action.extract_params(available_sources) # → {}
data = action.run(**kwargs) # → run() with no argsBut run(self, query: str, ...) declares query as a required positional argument with no default. Python raises TypeError: run() missing 1 required positional argument: 'query' every time the tool fires. The tool will never successfully execute in an investigation.
Fix — implement extract_params following the same pattern as CoralogixLogsTool / ElasticsearchLogsTool:
def extract_params(self, sources: dict) -> dict[str, Any]:
vl = sources.get("victoria_logs", {})
return {
"query": vl.get("default_query", "*"),
"limit": vl.get("limit", 50),
"start": vl.get("start", "-1h"),
"sources": sources, # so run() can pull credentials from kwargs
}🟡 Major — tenant_id = "0" always truthy → AccountID: 0 sent on every request
bool("0") is True, so the if self.config.tenant_id: guard in client.py always fires and adds AccountID: 0 to every HTTP request — even when no multi-tenancy is configured. Non-multi-tenant VictoriaLogs deployments may reject or misroute this header.
Fix: Change to tenant_id: str | None = None in the config model and update the guard to if self.config.tenant_id is not None:. Update catalog.py line 1544 accordingly.
🟠 Minor — 'victorialogs' vs 'victoria_logs' inconsistency
extract.py and models.py tell the LLM to output "victorialogs" (no underscore) as alert_source, but EvidenceSource, tool.source, and all catalog keys use "victoria_logs" (underscore). Please standardize on "victoria_logs" throughout — catalog.py already has the alias.
🟠 Minor — No VictoriaLogsTool unit tests
The 3 existing tests cover integration plumbing (env load, classification, verify). There are no tests for VictoriaLogsTool.is_available(), extract_params(), or run() happy/error paths. Please add tests/tools/test_victoria_logs_tool.py.
🟠 Minor — Missing integration docs
The contributor checklist in CONTRIBUTING.md requires a docs/<integration>.mdx page. Please add docs/victoria_logs.mdx with setup, env vars, and verification steps.
Once those are addressed this will be in good shape to merge. The core integration work is solid.
fix: VictoriaLogsTool extract_params implementation fix: VictoriaLogs tenant_id truthiness bug and multi-tenancy guards refactor: Standardize victoria_logs naming and support env vars revert: Out-of-scope changes in extract_alert/extract.py
|
@aniruddhaadak80 CI is still red. |
Resolves #126 by adding a complete Victoria Logs integration. This implements a VictoriaLogsClient and a new VictoriaLogsTool that queries using LogsQL.