Skip to content

Логи

Логи — это loki-половина L1-стека. Они следуют той же форме плоскости данных, что и метрики: edge'ы пушат напрямую в Loki через HTTPS, manager только запрашивает.

Плоскость данных

text
edge:
  ongrid-edge agent
    └─ plugin: promtail (subprocess)
        ├─ tails /var/log/syslog, /var/log/messages, journald
        └─ remote write HTTPS → loki:3100

                                     ▼ /loki/api/v1/query_range
                              ┌───────────────┐
                              │  manager:     │
                              │   - alert     │
                              │   - LLM tools │
                              └───────────────┘

ADR-015 plugin runtime

promtail запускается как подпроцесс под plugin runtime edge-агента. Агент контролирует lifecycle — рестарт при падении, drain при выключении, логи в тот же systemd-журнал, что и агент. С точки зрения оператора это один systemd-сервис, а не два.

Более ранняя альтернатива («венднор promtail как статически слинкованную Go- библиотеку») была отвергнута, потому что каждый апгрейд клиента Loki заставлял бы делать re-release edge-агента. Подпроцесс их разъединяет.

Конфигурация

Per-edge конфиг promtail рендерится на стороне сервера biz/edge/plugin_config.go и пушится вниз по контрольному туннелю на старте плагина. Он сверяется с system_settings.loki.url, так что изменение URL админом распространяется без пересборки агента.

Дефолтный набор tail:

ИсточникLoki labels
/var/log/syslog, /var/log/messagesjob=node-syslog, host=<edge-name>
systemd journald (все юниты)job=systemd-journal, host=<edge-name>, unit=<svc>

Кастомные tail добавляются через страницу /edges/<id>/logs/sources в SPA — они пишутся в тот же namespace system_settings.loki.*.

Разделение плоскости данных

ADR-014: телеметрия идёт напрямую, control идёт через туннель. Для логов это означает:

  • promtail HTTPS POST → loki:3100/loki/api/v1/push (напрямую).
  • ✅ Loki HTTPS GET ← manager /loki/api/v1/query_range (напрямую).
  • ❌ Логи НЕ путешествуют через контрольный туннель geminio.

Почему: туннель — это in-process multiplexer; перегон лог-всплесков через него душил control RPC (RCA вызовы инструментов, WebSSH I/O), когда ingest скакал. Разделение плоскости данных починило проблему шумного соседа и позволяет nginx владеть публичной поверхностью (TLS, rate limiting, auth) для обеих половин единообразно.

Типы алертов

Два log-driven kind правил — оба Phase-B, оба в evaluators_phaseB.go.

log_match

Срабатывает, когда count_over_time(<stream_selector> |~ <line_filter> [window]) <op> threshold возвращает как минимум одну запись матрицы.

json
{
  "kind": "log_match",
  "scope_type": "global",
  "conditions_json": {
    "stream_selector": "{job=\"systemd-journal\",unit=\"nginx.service\"}",
    "line_filter": "(?i)5\\d{2}",
    "window": "5m",
    "operator": ">=",
    "threshold": 50
  }
}

line_filter опционален — когда пустой, правило считает каждую строку в стриме. Запрос строится per-tick compileLogMatchRule в rules.go:733.

log_volume

Тот же движок, что и log_match в v1 (счёт текущего окна vs абсолютный порог). Исходная семантика spec «отношение vs предыдущее окно» припаркована — нужны два LogQL-запроса + Go-side деление; абсолютная форма уже покрывает обычный use case «логи скакнули за N».

Столбец spec — ratio_op / ratio_threshold (сохранён для forward compat); компилятор мапит их в operator / threshold.

Инструменты

search_logs / query_logql

LLM-обращённый поиск по логам. Два пути регистрации указывают на одного исполнителя:

  • query_logql — сырой проброс LogQL. Используется воркером investigator, когда персона точно знает, какой стрим запрашивать.
  • search_logs — более дружелюбная обёртка, выставленная в Quick Actions чат-UI, принимает свободнотекстовый запрос + имя сервиса.

Схема + исполнитель в query_logql_basetool.go. Базовый клиент: internal/pkg/logquery.

Оба учитывают глобальный env ONGRID_LOG_QUERY_URL (по умолчанию http://loki:3100) и наследуют auth от того же nginx-слоя, который edge'ы используют для пуша.

host_tail_file

Skills-side log-проба — запускается на edge, а не на manager. Используйте это, когда вам нужен сырой файл (например, /var/log/ongrid-edge.log, который не в journald) вместо вьюхи, заинджестированной в Loki. ScopeHost; требует edge_id. См. Skills для модели диспетчеризации.

См. также