From vmkteam-developer
Queries structured JSON logs from Loki for vmkteam appkit Go services via Grafana proxy using LogQL. Details stream labels vs JSON fields, log format, and pcurl commands for errors, RPC methods, slow queries.
npx claudepluginhub vmkteam/claude-plugins --plugin vmkteam-developerThis skill uses the workspace's default tool permissions.
Loki для логов. Доступен через Grafana datasource proxy. Структурированные JSON-логи из Go-сервисов (appkit).
Mandates invoking relevant skills via tools before any response in coding sessions. Covers access, priorities, and adaptations for Claude Code, Copilot CLI, Gemini CLI.
Share bugs, ideas, or general feedback.
Loki для логов. Доступен через Grafana datasource proxy. Структурированные JSON-логи из Go-сервисов (appkit).
Profile: @{grafana_profile} (через datasource proxy)
Datasource UID: {loki_uid}
Два способа доступа:
| Способ | Base URL |
|---|---|
| UID-based (рекомендуется) | https://{grafana_host}/api/datasources/uid/{loki_uid}/resources/ |
| Legacy ID-based | https://{grafana_host}/api/datasources/proxy/{loki_id}/loki/api/v1/ |
ВАЖНО: UID-based путь — /resources/query_range, /resources/labels (без /loki/api/v1/ префикса). Legacy — с /loki/api/v1/.
Stream labels (можно использовать в {...} selector):
service_name — сервис_node — хост/нода_instance — UUID инстанса_version — версия деплояJSON fields (доступны ТОЛЬКО через | json | field=value):
level — INFO, ERROR, WARNmethod — RPC методplatform — desktop, iOS, android, mobiledurationMS — длительность в ms (число)err — текст ошибки (<nil> если нет)msg — тип записи (rpc, http, etc.)ip, country, version, userAgentНЕ ИСПОЛЬЗУЙ level, method, platform в {...} selector — только через | json |.
Правильно: {service_name="{service}"} | json | level="ERROR"
Неправильно: {service_name="{service}",level="ERROR"}
{
"time": "2026-04-03T12:00:28.995Z",
"level": "INFO",
"msg": "rpc",
"method": "lists.episodesunwatched",
"duration": "116.582386ms",
"durationMS": 116,
"err": "<nil>",
"platform": "desktop",
"ip": "128.65.1.139"
}
# Логи сервиса за 5 минут
pcurl @{profile} "https://{grafana_host}/api/datasources/uid/{loki_uid}/resources/query_range" -s -G \
--data-urlencode 'query={service_name="{service}"}' \
--data-urlencode "start=$(date -v-5M +%s)000000000" \
--data-urlencode "end=$(date +%s)000000000" \
--data-urlencode 'limit=50'
# Только ошибки
pcurl @{profile} "https://{grafana_host}/api/datasources/uid/{loki_uid}/resources/query_range" -s -G \
--data-urlencode 'query={service_name="{service}"} | json | level="ERROR"' \
--data-urlencode "start=$(date -v-1H +%s)000000000" \
--data-urlencode "end=$(date +%s)000000000" \
--data-urlencode 'limit=50'
# По RPC методу
pcurl @{profile} "https://{grafana_host}/api/datasources/uid/{loki_uid}/resources/query_range" -s -G \
--data-urlencode 'query={service_name="{service}"} | json | method="{rpc_method}"' \
--data-urlencode "start=$(date -v-1H +%s)000000000" \
--data-urlencode "end=$(date +%s)000000000" \
--data-urlencode 'limit=50'
# Медленные запросы (>500ms)
pcurl @{profile} "https://{grafana_host}/api/datasources/uid/{loki_uid}/resources/query_range" -s -G \
--data-urlencode 'query={service_name="{service}"} | json | durationMS > 500' \
--data-urlencode "start=$(date -v-1H +%s)000000000" \
--data-urlencode "end=$(date +%s)000000000" \
--data-urlencode 'limit=50'
# По тексту (line filter — быстрее)
pcurl @{profile} "https://{grafana_host}/api/datasources/uid/{loki_uid}/resources/query_range" -s -G \
--data-urlencode 'query={service_name="{service}"} |~ "{search_text}"' \
--data-urlencode "start=$(date -v-1H +%s)000000000" \
--data-urlencode "end=$(date +%s)000000000" \
--data-urlencode 'limit=50'
# Ошибки с текстом err (исключая <nil>)
pcurl @{profile} "https://{grafana_host}/api/datasources/uid/{loki_uid}/resources/query_range" -s -G \
--data-urlencode 'query={service_name="{service}"} | json | err!="<nil>"' \
--data-urlencode "start=$(date -v-1H +%s)000000000" \
--data-urlencode "end=$(date +%s)000000000" \
--data-urlencode 'limit=50'
pcurl @{profile} 'https://{grafana_host}/api/datasources/uid/{loki_uid}/resources/labels' -s
pcurl @{profile} 'https://{grafana_host}/api/datasources/uid/{loki_uid}/resources/label/service_name/values' -s
{service_name="{service}"}
{service_name=~"{service1}|{service2}"}
{service_name="{service}",_node="{node}"}
{service_name="{service}"} | json | level="ERROR"
{service_name="{service}"} | json | method="{method}" | durationMS > 500
{service_name="{service}"} | json | err!="<nil>"
{service_name="{service}"} |= "error"
{service_name="{service}"} |~ "timeout|deadline"
{service_name="{service}"} != "healthcheck"
data.result[].stream — stream labelsdata.result[].values[][0] — timestamp в наносекундах (string!)data.result[].values[][1] — JSON string лог-записи