Трек A · Задание A3
Обозреватель поиска по логам
Мини-Kibana, где всё работает на SQL. С её помощью выясните причину сбоя оформления заказов в 11:40.
- 60–120 мин
- Для начинающих
- Любой язык · CLI или веб
- ИИ-инструменты приветствуются
Нужна помощь? Спросите в #dev в Slack Apache Doris. Разработчики и другие участники помогут вам.
Подготовка
Что вы создаёте, почему Doris упрощает задачу и как запустить кластер.
Что вы создадите
Создайте обозреватель логов и разберите с его помощью сбой.
200,000 строк логов, шесть сервисов, одно неудачное утро. Ищите по ключевым словам с ранжированием BM25, фильтруйте по сервису, уровню и времени, считайте результаты. Всё на обычном SQL в одной таблице Doris.
Небольшой обозреватель логов с:
- одним полем поиска (ключевые слова, фразы) с ранжированием по релевантности,
- фильтрами по сервису, уровню и диапазону времени,
- счётчиками фасетов рядом с результатами (совпадения по сервисам и уровням),
- необязательной хронологией числа ошибок за каждые 5 минут.
Затем настоящее испытание: В 11:40 оформление заказов начало сбоить. Какой сервис стал причиной и когда проблема началась на самом деле? Ваш обозреватель должен сделать ответ очевидным.
Эскиз находится в верхней части панели кода
Почему это интересно на Doris
Поиск и аналитика в одной таблице. Инвертированный индекс отвечает на запрос по ключевым словам; то же условие
WHEREподаётся вGROUP BYдля подсчёта фасетов. Не нужно синхронизировать вторую систему.Настоящее ранжирование.
score()сортирует результаты по BM25: первыми идут наиболее релевантные строки, а не просто самые новые.Недорогие фильтры.
serviceиlevelимеют собственные инвертированные индексы; диапазоны времени отсекаются по ключу сортировки.
Панель: строки индексов в определении таблицы
Перед началом
docker pull apache/doris:all-in-one-4.1.3docker run -d --name doris -p 9030:9030 -p 8030:8030 -p 8040:8040 apache/doris:all-in-one-4.1.3docker exec -it doris mysql -uroot -h127.0.0.1 -P9030curl -LO https://github.com/morningman/demo-env/releases/download/for-hackathon/doris-hackathon-glasgow-2026.zip && unzip doris-hackathon-glasgow-2026.zip && cd doris-hackathon-glasgow-2026
- Хост
- 127.0.0.1
- Порт
- 9030
- Пользователь
- rootбез пароля
- База данных
- hackathon
Данные
hackathon.app_logs : одна таблица для всех шести сервисов:
CREATE TABLE app_logs ( ts DATETIME(3) NOT NULL, service VARCHAR(32) NOT NULL, -- api-gateway, auth, catalog, search, checkout, payment level VARCHAR(8) NOT NULL, -- DEBUG / INFO / WARN / ERROR host VARCHAR(32), trace_id VARCHAR(32), status INT, -- HTTP status, when relevant latency_ms INT, message STRING NOT NULL, INDEX idx_msg (message) USING INVERTED PROPERTIES ("parser" = "english", "support_phrase" = "true"), INDEX idx_service (service) USING INVERTED, INDEX idx_level (level) USING INVERTED)DUPLICATE KEY(ts)DISTRIBUTED BY HASH(trace_id) BUCKETS 1PROPERTIES ("replication_num" = "1");seed/a3_app_logs.sql генерирует 200,000 строк за 13 октября 2026 г. одним INSERT … SELECT … FROM numbers("number" = "200000") . Скачивать ничего не нужно. Где-то в этих данных скрыт сбой.
Панель → Таблица: полное определение таблицы
Разработка с ИИ
Работайте вместе с ИИ-агентом для программирования, это приветствуется. Поисковые и ИИ-функции Doris 4.x появились позже обучающих данных большинства моделей. Поэтому перед написанием SQL дайте агенту правильный контекст:
Вставьте контекстный промпт ниже в своего агента.
Укажите ему справочные страницы из этого задания и
AGENTS.mdиз стартового набора. Многие агенты читают этот файл самостоятельно.Перед встраиванием в код пусть агент выполнит каждый SQL-запрос на вашем работающем кластере.
Ещё лучше подключите Doris MCP Server (см. задание A2), чтобы агент сам изучал схему и тестировал запросы.
I'm building a log search explorer on Apache Doris 4.1 for a hackathon.Connection: MySQL protocol, 127.0.0.1:9030, user root, empty password, database `hackathon`.Use a plain MySQL driver and raw SQL.Table `app_logs`: ts DATETIME(3), service, level, host, trace_id, status INT, latency_ms INT,message STRING. Inverted indexes on message (english parser, phrase support), service, level.Doris SQL rules:1. Text search: `message MATCH_ANY 'a b'`, `MATCH_ALL`, `MATCH_PHRASE 'a b'`. Never LIKE.2. BM25: `score()` only with a MATCH_* predicate + `ORDER BY score() DESC LIMIT n`, selected plain (`score() AS relevance`): no ROUND() or JOIN in that SELECT. Bind the user's search text as a driver parameter.3. score() cannot be used with GROUP BY. For facet counts run a second query with the same WHERE clause and GROUP BY service, level.4. Time buckets: `minute_floor(ts, 5)`.Build: search box, service/level/time filters, facet counts, and an error timeline.Run every SQL statement against the live cluster first.Типичные ловушки Doris для ИИ-агента
| Trap | What to do instead |
|---|---|
Использование LIKE '%term%' для текстового поиска | col MATCH_ANY 'a b' (OR), MATCH_ALL (AND), MATCH_PHRASE 'a b' . Они используют инвертированный индекс |
Вызов score() в произвольном запросе | score() требует MATCH_* в качестве предиката в WHERE и ORDER BY score() DESC LIMIT n; иначе Doris отклонит запрос |
Округление, соединение или ранжирование score() в том же запросе | Оставьте score() AS relevance без изменений в запросе к одной таблице. Округляйте, соединяйте или применяйте ROW_NUMBER() во внешнем запросе, используя подзапрос вместо WITH CTE |
score() внутри GROUP BY / агрегатов | Не допускается. Для подсчёта фасетов используйте то же WHERE без score() |
| Использование ORM | Предпочтительны обычный драйвер MySQL и SQL напрямую: ORM могут генерировать неподдерживаемые Doris операторы |
Реализуйте
6 этапов, M0 → M5. Панель следует за текущим шагом.
Сгенерируйте логи
Из папки стартового набора:
M0 · Генерация логовbashdocker exec -i doris mysql -uroot -h127.0.0.1 -P9030 < seed/a3_app_logs.sqlПроверкаЧерез несколько секунд: 200,000 строк логов, с
00:00:00до23:59:5913 октября.Поиск по ключевым словам с BM25
M1 · Поиск по ключевым словам с BM25sqlUSE hackathon;SELECT ts, service, level, message, score() AS relevanceFROM app_logsWHERE message MATCH_ANY 'timeout refused'ORDER BY relevance DESCLIMIT 20;Подключите к полю поиска. Передавайте текст пользователя параметром драйвера (
MATCH_ANY %s);a3/starter.pyиз стартового набора делает именно это.ПроверкаВсе 20 результатов:
connection refusedстроки. BM25 даёт больший вес редким словам: refused встречается в 68 строках, timeout в 347. Выполните поиск только поtimeoutи увидите остальные.Фильтры
M2 · ФильтрыsqlSELECT ts, service, level, message, score() AS relevanceFROM app_logsWHERE message MATCH_ANY 'timeout' AND level = 'ERROR' AND service IN ('checkout', 'payment') AND ts >= '2026-10-13 11:00:00' AND ts < '2026-10-13 12:30:00'ORDER BY relevance DESCLIMIT 20;ПроверкаКаждый результат: строка ERROR с упоминанием timeout. Отображается только один из двух сервисов.
Счётчики фасетов
score()нельзя агрегировать, поэтому для фасетов используйте тот же фильтр без него:M3 · Счётчики фасетовsqlSELECT service, level, COUNT(*) AS hitsFROM app_logsWHERE message MATCH_ANY 'timeout' AND ts >= '2026-10-13 11:00:00' AND ts < '2026-10-13 12:30:00'GROUP BY service, levelORDER BY hits DESC;ПроверкаВ этом интервале 163 совпадающие строки, все
ERROR. Сумма должна совпадать с тем же поиском безGROUP BY: проверьте черезSELECT COUNT(*)и то жеWHERE.Хронология ошибок
M4 · Хронология ошибокsqlSELECT minute_floor(ts, 5) AS bucket, service, COUNT(*) AS errorsFROM app_logsWHERE level = 'ERROR' AND ts >= '2026-10-13 11:00:00' AND ts < '2026-10-13 12:30:00'GROUP BY bucket, serviceORDER BY bucket, service;ПроверкаВ двух сервисах наблюдается всплеск с 11:35 до 12:00. В остальное время ни один сервис не пишет больше 4 ошибок за 5 минут.
Разберите сбой
Ответьте с помощью обозревателя: Какой сервис вызвал сбои оформления заказов и в какую минуту это началось? Запишите в README ответ и подтверждающий его запрос.
Завершите работу
Пройдите проверку, покажите результат и получите значок.
Критерии готовности
Ваш контрольный списокОтправьте работу и получите значок
Участвуйте → отправьте работу → получите значок.
Поместите свою работу в папку с именем вашего GitHub ID: код и README с описанием, инструкцией запуска, одним снимком экрана или GIF и перечнем использованных функций Doris.
Откройте pull request и добавьте её в morningman/demo-env как
doris-hackathon-glasgow-2026/<your-github-id>/. Сделайте fork и push или используйте в GitHub Add file → Upload files. Больше ничего заполнять не нужно.Поделитесь результатом в
#devв Slack Apache Doris: ссылкой на pull request или репозиторий и снимком экрана либо коротким демо. Вопросы, отправка работ и выдача значков происходят там.
Каждый участник задания получает значок участника Apache Doris: принятый pull request в Doris не требуется. Срока нет, работайте столько, сколько нужно. Можно участвовать командой, но это не обязательно. Укажите GitHub ID каждого участника в README.
Дополнительные цели
Фразы и поиск при вводе:
MATCH_PHRASE 'connection refused',MATCH_PHRASE_PREFIXдля поиска по мере ввода.Просмотр трассировки: нажмите строку, чтобы увидеть все логи с тем же
trace_id, в хронологическом порядке.Поиск строкой запроса: попробуйте
SEARCH()DSL (в стиле Lucenefield:term AND …) см. Функция SEARCH.Отслеживание новых логов: вставляйте несколько строк каждую секунду и обновляйте автоматически.
С индексом и без него: сравните
MATCH_ANYвместе сLIKE '%timeout%'по всей таблице и покажите время.
Устранение неполадок и справочные материалы
| Symptom | Fix |
|---|---|
docker: command not found в macOS | Запустите Docker Desktop. Если он уже работает, создайте ссылку на CLI: sudo ln -s /Applications/Docker.app/Contents/Resources/bin/docker /usr/local/bin/docker |
error getting credentials при загрузке образов | Удалите поле credsStore из ~/.docker/config.json (только для локальной разработки) |
port is already allocated | Порты 9030, 8030 или 8040 заняты, часто другим Doris. Проверьте работающие контейнеры (docker ps), либо опубликуйте другие порты хоста, например -p 19030:9030, и подключайтесь к 19030 |
The container name "/doris" is already in use | Вы уже запускали его раньше: docker start doris. Чтобы начать заново, docker rm -f doris (данные будут удалены) |
Контейнер завершается или не переходит в состояние (healthy) | Прочитайте docker logs doris. Обычно причина в памяти: выделите Docker Desktop не менее 6 GB (Settings → Resources). На Apple Silicon не добавляйте --platform linux/amd64 |
permission denied: ./doris.sh | При распаковке потерялось право на выполнение: chmod +x doris.sh, либо выполните bash doris.sh start |
Current database is not set | Выполните USE hackathon; сначала или подключитесь с помощью -Dhackathon |
score() function requires WHERE clause with MATCH function, ORDER BY and LIMIT | Добавьте MATCH_* предикат, ORDER BY score() DESC и LIMIT, и оставьте score() без обёртки (см. ловушки выше) |
| Если не получается больше 10 минут | Напишите в #dev в Slack Apache Doris |
Справочные материалы
Полнотекстовый поискBM25Инвертированный индексФункция SEARCH
Хакатон Apache Doris
Все задания
- A160–120 минПриложение гибридного поискаОткрыть описание задания
- A245–90 минЗадавайте вопросы Doris через MCPОткрыть описание задания
- A360–120 минОбозреватель поиска по логамВы здесь
- A460–120 минОбозреватель трассировок агентовОткрыть описание задания
- B30–60 минТрек B · От документации к демоОткрыть описание задания
