Skip to main content
Glama
Suteerth03
by Suteerth03

LogLens

MCP-сервер (Model Context Protocol) для анализа логов. Вместо того чтобы вставлять файл лога в чат и просить LLM разобраться в нем, LogLens предоставляет поиск по логам, получение контекста и сводку инцидентов как инструменты, которые любой MCP-совместимый клиент (Claude Desktop, Claude Code или ваш собственный агент) может вызывать напрямую — с точечным поиском вместо набивания контекста и шагом самопроверки, который отсекает неподтвержденные выводы о корневой причине до того, как они будут возвращены.

Зачем это существует

Это публичная портфолио-версия анализатора логов на базе ИИ, занявшего первое место на внутреннем хакатоне. Если кратко, почему она лучше вставки в чат: производственные логи в контекстное окно; вставленный в чат текст нельзя вызвать из других систем; а в чистом промпте нет механизма проверить, действительно ли ответ модели опирается на данные лога.

Related MCP server: Log Analyzer MCP

Статус

  • Ядро сервера, 3 инструмента — работоспособный end-to-end на примере лога. ✅

  • Генерация первопричин на базе LLM с циклом проверки галлюцинаций: гипотеза проверяется по двум независимым осям и при провале любой из них делается одна повторная попытка. ✅

  • Гибридная архитектура поставок (Groq + Gemini) — верификатор работает в другом семействе моделей, чем генератор, так что проверка не пользуется слепыми зонами генератора. ✅

  • Набор из 8 оценочных сценариев, детерминированная оценка, результат 8/8. ✅

  • Docker-образ, работает как сетевой HTTP-сервер, проверен end-to-end на живом контейнере. ✅

  • Дальше: облачное развёртывание (Azure Container Apps или или подобное), демо-GIF.

Инструменты

Инструмент

Что делает

search_logs

Поиск по ключевым словам в файле лога; возвращает совпадения с окружающим контекстом и идентификатором id строки.

get_error_context

По id строки возвращает более широкое окно строк: полные стек-трейсы, последовательное представление событий.

summarize_incident

Извлекает поисковые термины из вопроса на естественном языке, собирает свидетельства (лексический поиск + временное окно + глобальный анализ аномалий), формирует гипотезу о первопричине, затем независимо проверяет её по двум осям — а если проверка не пройдена,обнажды повторяюет.

Архитектура

Question ──▶ extract search terms (Groq, gpt-oss-20b)
                 │
                 ▼
         search_logs (lexical match)
                 │
                 ▼
    + time-window expansion (asymmetric: 900s before / 180s after —
      causes precede symptoms)
                 │
                 ▼
    + global anomaly scan (all WARN/ERROR lines, not just in-window —
      the explaining line is often itself a warning)
                 │
                 ▼
       generate hypothesis (Groq, gpt-oss-120b)
                 │
                 ▼
    verify: soundness + completeness (Gemini — DIFFERENT provider
    from the generator, on purpose; falls back to same-provider
    Groq if Gemini is unavailable, and reports which happened)
                 │
          unsound/incomplete? ──▶ regenerate once, feeding back
                 │                the lines the first pass overlooked
                 ▼
              answer

Два провайдера — намеренно, а не просто экономия

Groq отвечает за извлечение и генерацию гипотез, Gemini — за верификацию. Просто из-за квот (у Gemini бесплатный тариф ограничен 20 запросами в день; у Groq — гораздо щедрее) это превратилось и в архитектурное улучшение: верификатор, работающий на той же модели, что и генератор утверждения, страдает теми же слепыми зонами. Проверка утверждения через другое семейство моделей делает проверку галлюцинаций действительно независимой, а не вторым мнением одного источника. Verification.independent сообщает, проходил ли ответ кросс-провайдерскую проверку или откатывался на тот же провайдер (Gemini упал/не настроен) — это видно, а не скрыто.

Межсервисный разрыв в поиске — найден тестированием, исправлен на нужном уровне

Ранние тесты вскрыли ограничение: summarize_incident находил непосредственные причины неудачного оформления заказа (исчерпанный пул БД), но упускал первопричину, которую пример журнала содержит — долгий запрос с другого сервиса, который держит соединение. Две структурные проблемы:

  • Поиск был чисто лексическим. Извлечённые термины были ограничены сущностью checkout, поэтому строки inventory-service никогда не попадали в набор улик, как бы хорошо ни были рассуждения. Исправлено расширением временного окна — по признаку асимметрично (900с до / 180с после): причины, появraются выше симптом, часто дольше, чем симметрич короткое окносхватило бы. Плюс глобальное сканирование аномальных (WARN/ERROR) строк независимо от окна, потому что поясняющая запись часто сама является предупреждением («NTP sync failed», «rotation skipped»).

  • Верификатор мог только проштамповать. Раньше он видел только те строки, которые процитировало утверждение, поэтому не мог отловить неполный ответ: объяснение симптома всегда выглядит подкреплённым, если выбирают удобные строки. Теперь он видит весь набор свидетельств и оценивает soundness и completeness независимо; вердикт «обоснованно, но неполно» возвращает пропущенные строки обратно в процесс генерацию.

Набор eval-тестов

npx tsx evals/run-evals.ts          # all 8 cases
npx tsx evals/run-evals.ts 03 08    # a subset, by id substring

8 сценариев покрывают разные архетипы сбоев: конкуренцию между сервисами за ресурсы, OOM из-за неограниченного кэша, усиление retry-шторма, неудачный деплой, две умноженные причины, рассинхронизацию часов на одном сбойном узле, здоровый лог (правильный ответ, «ничего не падало»), а также схему, где громкий симптом маскирует тонкую причину, — специально для испытаний оси полноты. Оценка детерминированная; группы понятий с синонимами плюс обязательные ссылки на улики, без LLM-судей — значит, прогоны воспроизводимы. Отчёт отделяет промахи сбора (улики так и не достиги модели) от промахов рассуждения (улики были, ответ всё равно неверен) — потому что это разные проблемы.

Текущий результат: 8/8 зачётных, 0 сбора, 0 рассужденческих.

Пытки обескура Порой отладка стенда-это сама по себе инженерная историяю: асимметричное время окно и глобальный поиск аномалий — realист брал и чинил незамёдленность; на бесплатной квоте Groq max_tokens — это броня против поминутного бюджета токенов, а не честный потолок оплаты — поэтому завышенное значение даёт 413 независимо от размера промпта; на семейство gpt-oss обязательно поставить reasoning_effort: "low", иначе бюджет уходит на токены рассуждений и вывод обрезается до получения валидного JSON; а сам стенд имел два бага в скоринге (варианты Unicode-пунктуации, плюс вариант клавиатурой с обычным пробелом в том же составном идентификаторе), из-за которых правильные ответы считались провалом. Это предупреждение особенно при создании собственного eval-стенда — он тоже требует отладки.

Docker

docker build -t loglens:local .
docker run -d -p 3000:3000 \
  -e GROQ_API_KEY=your-key \
  -e GEMINI_API_KEY=your-key \
  loglens:local
curl http://localhost:3000/health

Многоступенчатая сборка (компиляция с devDependencies, запуск только с production-зависимыми пакетами, непривилегированный пользователь + контейнерный healthcheck на /health). Контейнер использует HTTP-транспорт (MCP_TRANSPORT=http, по умолчанию в образе), а stdio невыход: у развёрнутого контейнера нет родительского процесса, который запускал бы его локально, как Claude Desktop/Code.

Реальная ошибка, найденная и исправленная при сборке, — важно, если вы делаете свой stateless-мод streamable HTTP MCP: SDK в безсостоятельном режиме требует нового транспорта на каждый запрос: перевозить один транспорт между запросами — и каждый первый же выполненный запрос после первого молча падает с 500, и не выдается никакого исключения. Также одиночныйMcpServer может быть подключён не более к одному транспорту в один момент ("Already connected to a transport"). Исправление (см. createServer() и http-обработчик в src/index.ts) — для кажд reassign запроса создаются fresh McpServer и fresh StreamableHTTPServerTransport; это дёшево, потому что сервер храните лишь определения инструментов и не имеет per-состояния (что возможно) источник, но у всех этих инструментов ничего общего с ним нет. Проверено на живом контейнере: и search_logs, и полный прогон summarize_incident корректно заверцались end-to-end после исправления.

Переменные окружения

| Переменная | Для чего требуется | Примечания | |п--|----|----| | GROQ_API_KEY | summarize_incident (извлечение + гипотеза) | Беспо для на console.groq.com/keys. search_logs и get_error_context работают без него. | | GEMINI_API_KEY | независимая верификация | Free: aistudio.google.com/apikey. Без ключа верификация откатится к тому же провайдеру (Groq) и теряет другим свойством — это отображается через Verification.independent, а не тихо понижается. | | LOGLENS_LOG_FILE | не обязательно | Даёт указать настоящий файл лога, вместо встроенного примерии одновременно. | | MCP_TRANSPORT | не обязательно | http запускает сетевой сервер (для Docker); не задано/другой вариант вызывает расшир dinosaur — stdio (для Claude Desktop/Code). | | PORT | не обязательно | HTTP-порт, по умолчанию 3000. |

Развёртывание

npm install
npm run build

По умолчанию сервер читает fixtures/sample.log, синтетический инцидент (неполняющийся неиндексированный запрос на inventory-service исхушает общий пул БД, дальше по каскаду начинаются сбои checkout-service). Чтобы указать реальный файле:

LOGLENS_LOG_FILE=/path/to/real.log node dist/index.js

Дымовое тестирование (MCP-клиент не требуется)

npx tsx scripts/smoke-test.ts                              # stdio transport
npx tsx scripts/smoke-test-http.ts http://localhost:3000/mcp  # HTTP transport

Запускает (или подключается к) серверу и вызывает все три инструмента — удобно проверить работу до подключения в реальном клиенте. Полный прогон summarize_incident — это 3–4 последовательных LLM-вызова и может забирать 30–90 с; при вызове программно даём щедрый timeout (обе скриптовые программы это делают).

Подключение к Claude Desktop

Переделать %APPDATA%\Claude\claude_desktop_config.json (Windows) и добавьте:

{
  "mcpServers": {
    "loglens": {
      "command": "node",
      "args": ["C:\\Users\\sarve\\OneDrive\\Desktop\\LogLens\\dist\\index.js"],
      "env": {
        "GROQ_API_KEY": "your-groq-key",
        "GEMINI_API_KEY": "your-gemini-key"
      }
    }
  }
}

Блок env — не необход, а обязательно: MCP-клиент запускает сервер с очищенным окружением по умолчанию, а не с вашим shell-профилем, так что без эту запuntu ключи не буду рисун принадлежат summarize_incident, даже если задаются глобально.

Перезапустите Claude Desktop и попросите что-то вроде "поищи в логах for 'pool exhausted'" — он должен автоматически вызвать search_logs.

Подключение к Claude Code

claude mcp add loglens --scope user --env GROQ_API_KEY=your-groq-key --env GEMINI_API_KEY=your-gemini-key -- node C:\Users\sarve\OneDrive\Desktop\LogLens\dist\index.js

(Причина та же: --env передаёт переменные явно, потому что порождённый процесс не наследует окружение вашей оболочки по умолчанию.)

Структура репозитория

src/
  index.ts       MCP server (dual transport: stdio + HTTP) + tool registration
  logParser.ts   log loading, search, time-window expansion, anomaly scan
  summarize.ts   the summarize_incident pipeline: extract -> retrieve -> hypothesize -> verify -> retry
  providers.ts   Groq + Gemini clients, model config, schema-constrained JSON generation
fixtures/
  sample.log     synthetic incident for local testing
evals/
  cases.ts       8 eval case definitions
  run-evals.ts   deterministic scoring harness
  logs/          synthetic logs for eval cases 02-08
scripts/
  smoke-test.ts       stdio transport smoke test
  smoke-test-http.ts  HTTP transport smoke test
Dockerfile       multi-stage build, non-root user, container healthcheck

Related MCP Connectors

Related MCP Servers

  • -
    license
    Not graded
    quality
    Not graded
    maintenance
    Provides comprehensive logging and monitoring capabilities for MCP services with real-time log tailing, advanced search, error analysis, and anomaly detection. Enables centralized log aggregation, correlation tracking, and health monitoring across all MCP ecosystem services.
    -
  • F
    license
    B
    quality
    C
    maintenance
    Enables AI-assisted analysis of log files through advanced searching, filtering, and test execution capabilities. Supports time-based queries, pattern matching, test summarization, and code coverage reporting directly within compatible MCP clients.
    12
    -