Agent skill
query-victorialogs
Query and analyze logs from VictoriaLogs using LogsQL via HTTP API. Use when the user asks to "query logs", "search logs", "check VictoriaLogs", "find errors in logs", "tail logs", "get log stats", "search VictoriaLogs", "check dev/prod logs", or any log investigation task involving VictoriaLogs. Also triggers on mentions of LogsQL, VictoriaLogs, or log troubleshooting.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/devops/query-victorialogs-varfolomejev-query-victorialogs-13
SKILL.md
Query VictoriaLogs
Environment Setup
Read the project CLAUDE.md for VL_DEV_URL and VL_PROD_URL values. Default to DEV unless user specifies production.
CRITICAL: Time Range Limits
NEVER query more than 3 hours without explicit _time filter. The server will crash on wide time ranges.
- Default: use
_time:5mto_time:1hfor recent logs - Max safe range: 3 hours. NEVER exceed 3 days under any circumstances.
- Always include
_timefilter in every query — no exceptions.
When User Knows Only a Date (Not Exact Time)
If the user says "check logs from March 20" but doesn't know the exact time, use a two-step approach:
Step 1: Find the time range using /select/logsql/hits — lightweight, returns only counts:
curl -s "$VL_URL/select/logsql/hits" \
-H 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8' \
--data-urlencode "query=SEARCH_TERM" \
-d 'step=3600000ms' \
-d 'start=2026-03-20T00:00:00Z' \
-d 'end=2026-03-20T23:59:59Z' \
--insecure
This returns hit counts per hour — find which hours have data.
Step 2: Query only the narrow time range identified from Step 1:
curl -s "$VL_URL/select/logsql/query" \
-H 'Accept: application/stream+json' \
-H 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8' \
--data-urlencode "query=SEARCH_TERM" \
-d 'limit=500' \
-d 'start=2026-03-20T14:00:00Z' \
-d 'end=2026-03-20T15:00:00Z' \
--insecure
Always follow this pattern: hits first to locate, then query to fetch.
How to Query
Use curl directly via Bash tool. Always use --insecure flag and POST with application/x-www-form-urlencoded;charset=UTF-8.
Query Logs
curl -s "$VL_URL/select/logsql/query" \
-H 'Accept: application/stream+json' \
-H 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8' \
--data-urlencode "query=_time:5m error" \
-d 'limit=500' \
--insecure
Hit Counts (histogram) — use to locate time ranges
curl -s "$VL_URL/select/logsql/hits" \
-H 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8' \
--data-urlencode "query=_time:1h error" \
-d 'step=60000ms' \
--insecure
Stats Query
curl -s "$VL_URL/select/logsql/stats_query" \
-H 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8' \
--data-urlencode "query=_time:5m error | stats count() as errors" \
--insecure
Discover Fields/Streams
# Field names
curl -s "$VL_URL/select/logsql/field_names" --data-urlencode "query=_time:5m *" --insecure
# Field values
curl -s "$VL_URL/select/logsql/field_values" --data-urlencode "query=_time:5m *" -d 'field=level' --insecure
# Streams
curl -s "$VL_URL/select/logsql/streams" --data-urlencode "query=_time:5m *" --insecure
LogsQL Quick Reference
Filters
error # word in _msg
"connection refused" # phrase
{app="nginx"} # stream filter
_time:5m # last 5 minutes
field:value # field filter
field:re("pattern") # regexp
q1 AND q2 / q1 OR q2 / NOT q # logical
Pipes
| fields f1, f2 # keep fields
| unpack_json # parse JSON
| stats by (field) count() as c # aggregate
| sort by (field desc) # sort
| limit 10 # limit
| filter field > 100 # post-filter
| top 10 by (path) # top N
| extract_regexp "(?P<ip>...)" # extract via regex
Stats Functions
count(), sum(f), avg(f), min(f), max(f), median(f), quantile(0.95, f), rate(), count_uniq(f), uniq_values(f)
For full LogsQL syntax: read references/logsql-reference.md
For full HTTP API details: read references/http-api.md
Best Practices
- ALWAYS include
_timefilter — server crashes without it. Default to_time:5mor_time:1h. - Max 3 hours per query. If broader search needed, use hits endpoint first to locate the right window.
- Unknown time? Hits first, query second. Use
/select/logsql/hitswith 1h step to scan a day, then query only the relevant hours. - Place fastest filters (word, phrase) first, slowest (regexp) last
- Use
limitto avoid overwhelming output — start with 100-500 - Use
| unpack_jsonwhen logs are JSON-structured - Use
| collapse_numsto group similar error messages - Use
| stats by (_stream) count()to find noisiest services - Pipe output through
jqfor readability when needed
Didn't find tool you were looking for?