Skip to main content
Back to course
Распределенная трассировка: от основ до production
5 / 1828%

Первый проект: инструментация простого приложения

45 минут

Первый проект: инструментация простого приложения

Цель урока

Создадим простое HTTP API и добавим трассировку с OpenTelemetry + Jaeger. Вы увидите:

  • Автоматическую инструментацию (HTTP requests, DB queries)
  • Custom spans для бизнес-логики
  • Атрибуты и events
  • Визуализацию в Jaeger UI

Готовые примеры кода

Все примеры из этого урока доступны в репозитории курса. Вы можете:

  1. Скачать готовые примеры и сразу запустить их
  2. Следовать инструкциям ниже для создания проекта с нуля (рекомендуется для обучения)

Готовые примеры курса

Все примеры доступны по адресу: /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.