Первый проект: инструментация простого приложения
Первый проект: инструментация простого приложения
Цель урока
Создадим простое HTTP API и добавим трассировку с OpenTelemetry + Jaeger. Вы увидите:
- Автоматическую инструментацию (HTTP requests, DB queries)
- Custom spans для бизнес-логики
- Атрибуты и events
- Визуализацию в Jaeger UI
Готовые примеры кода
Все примеры из этого урока доступны в репозитории курса. Вы можете:
- Скачать готовые примеры и сразу запустить их
- Следовать инструкциям ниже для создания проекта с нуля (рекомендуется для обучения)
Готовые примеры курса
Все примеры доступны по адресу: /courses/distributed-tracing/examples/
Для этого урока см. директорию 03-first-project/ с примерами на Node.js, Python и Go.
Быстрый старт:
# Выберите язык: nodejs, python или go
cd 03-first-project/nodejs
docker-compose up -d
curl http://localhost:3000/api/users/1
open http://localhost:16686Подробные инструкции см. в README.md
Архитектура проекта
┌─────────────┐
│ User │
└──────┬──────┘
│ GET /api/users/:id
▼
┌─────────────────┐
│ HTTP Server │ ← Auto-instrumentation создаст HTTP span
└────────┬────────┘
│
▼
┌─────────────────┐
│ Business Logic │ ← Custom span: fetchUser
└────────┬────────┘
│
▼
┌─────────────────┐
│ PostgreSQL │ ← Auto-instrumentation создаст DB span
└─────────────────┘Результат в Jaeger:
├─ GET /api/users/123 [150ms]
├─ fetchUser [140ms]
└─ SELECT * FROM users [80ms]Шаг 1: Инфраструктура (Docker Compose)
Создайте файл docker-compose.yml:
version: "3.8"
services:
# Jaeger All-in-One (для development)
jaeger:
image: jaegertracing/all-in-one:1.53
ports:
- "16686:16686" # Jaeger UI
- "4317:4317" # OTLP gRPC receiver
- "4318:4318" # OTLP HTTP receiver
environment:
- COLLECTOR_OTLP_ENABLED=true
- LOG_LEVEL=debug
# PostgreSQL (для примера с DB)
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: testdb
POSTGRES_USER: user
POSTGRES_PASSWORD: password
ports:
- "5432:5432"
volumes:
- ./init.sql:/docker-entrypoint-initdb.d/init.sqlФайл init.sql (создание тестовых данных):
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO users (name, email) VALUES
('Alice Smith', 'alice@example.com'),
('Bob Johnson', 'bob@example.com'),
('Charlie Brown', 'charlie@example.com');Запуск:
docker-compose up -d
# Проверка
docker ps # Должны быть запущены jaeger и postgres
# Jaeger UI: http://localhost:16686Шаг 2: Инструментация приложения
Шаг 3: Просмотр трейсов в Jaeger UI
Откройте Jaeger UI: http://localhost:16686
Выберите сервис user-api в dropdown
Нажмите Find Traces
Выберите любой трейс из списка
Что вы увидите
Trace Timeline (waterfall):
├─ GET /api/users/1 [150ms] ████████████████████████████
│ ├─ fetchUser [140ms] ██████████████████████████
│ │ └─ SELECT * FROM users [80ms] ████████████Span Details:
- Tags: user.id, http.method, http.status_code, db.system
- Events: Starting user fetch, User fetched successfully
- Process: service.name, service.version, deployment.environment
Горячие клавиши Jaeger UI: - Ctrl+F — поиск по трейсам - Shift+Click —
сравнение двух трейсов - Alt+Click — развернуть/свернуть все спаны
Практическое задание
Задача: Добавьте новый endpoint /api/users (получение списка пользователей) с трассировкой.
Требования:
- Custom span с названием
fetchUserList - Атрибут
users.limit— количество возвращаемых пользователей - Event
Fetched N usersпосле успешного запроса - Обработка ошибок
Ожидаемый результат в Jaeger:
├─ GET /api/users [200ms]
└─ fetchUserList [180ms]
├─ Event: Starting fetch
├─ SELECT * FROM users LIMIT 10 [100ms]
└─ Event: Fetched 3 usersСледующий урок
В следующем уроке мы создадим цепочку из 3 микросервисов и увидим как context propagation работает автоматически.
Поздравляем! Вы создали первое приложение с distributed tracing.