Логирование переходов

Universal Router — это легковесная и гибкая библиотека маршрутизации для JavaScript, которая позволяет строить маршруты на основе объектов и асинхронных функций. Одной из важных возможностей при построении сложных приложений является логирование переходов, которое помогает отслеживать навигацию, отлаживать маршруты и анализировать поведение пользователя.


Основные подходы к логированию

В Universal Router логирование можно реализовать несколькими способами:

  1. Через обработку результата маршрута Каждый маршрут может возвращать значение или промис. После вызова router.resolve(context) результат можно использовать для записи информации в лог:
import UniversalRouter from 'universal-router';

const routes = [
  { path: '/', action: () => 'Главная' },
  { path: '/about', action: () => 'О сайте' },
];

const router = new UniversalRouter(routes);

async function navigate(path) {
  const result = await router.resolve({ pathname: path });
  console.log(`[LOG] Переход на ${path}: результат = ${result}`);
}

navigate('/');
navigate('/about');

В этом примере лог фиксирует не только путь, но и результат действия маршрута.

  1. Через middleware-подобные функции Universal Router позволяет использовать функции-обработчики для каждого маршрута или для всей маршрутизируемой структуры. Это удобно для централизованного логирования:
const logger = async (context, next) => {
  console.log(`[LOG] Начало обработки пути: ${context.pathname}`);
  const result = await next();
  console.log(`[LOG] Конец обработки пути: ${context.pathname}`);
  return result;
};

const routes = [
  { path: '/', action: () => 'Главная' },
  { path: '/profile', action: () => 'Профиль' },
];

const router = new UniversalRouter(routes, { context: {}, resolveRoute: logger });

router.resolve({ pathname: '/profile' });

Здесь logger действует как промежуточный слой, позволяя логировать до и после выполнения маршрута. Такой подход особенно полезен для отладки цепочек маршрутов и асинхронных переходов.

  1. Логирование ошибок маршрутизации Ошибки при разрешении маршрутов можно перехватывать через блоки try/catch или через глобальные обработчики промисов. Это позволяет отслеживать невалидные переходы:
async function navigate(path) {
  try {
    const result = await router.resolve({ pathname: path });
    console.log(`[LOG] Успешный переход на ${path}: ${result}`);
  } catch (error) {
    console.error(`[ERROR] Ошибка перехода на ${path}: ${error.message}`);
  }
}

navigate('/nonexistent');

Использование такого подхода обеспечивает комплексное логирование как успешных переходов, так и ошибок.


Контекст для расширенного логирования

Universal Router поддерживает передачу объекта context, который доступен на всех этапах маршрутизации. С его помощью можно хранить данные о переходах, пользователях, параметрах URL и времени перехода:

const routes = [
  {
    path: '/dashboard',
    action: ({ context }) => {
      context.logs.push(`Переход на /dashboard в ${new Date().toISOString()}`);
      return 'Панель управления';
    },
  },
];

const context = { logs: [] };
const router = new UniversalRouter(routes);

router.resolve({ pathname: '/dashboard', context }).then(result => {
  console.log('Результат:', result);
  console.log('Логи переходов:', context.logs);
});

Такой подход позволяет аккумулировать историю навигации внутри одного контекста и использовать её для аналитики или отладки.


Логирование динамических маршрутов и параметров

Universal Router поддерживает динамические сегменты URL, что делает логирование параметров особенно важным:

const routes = [
  { path: '/user/:id', action: ({ params }) => `Профиль пользователя ${params.id}` },
];

const router = new UniversalRouter(routes);

router.resolve({ pathname: '/user/42' }).then(result => {
  console.log(`[LOG] Переход на /user/:id, params:`, { id: 42, result });
});

Выделение параметров в лог позволяет не только видеть путь, но и конкретные значения, передаваемые в маршрут.


Использование сторонних библиотек для централизованного логирования

Для крупных приложений логирование через console.log может быть недостаточно. Universal Router легко интегрируется с такими инструментами, как:

  • Sentry для отслеживания ошибок и событий.
  • LogRocket для записи действий пользователя.
  • Winston или Pino для сервера Node.js.

Пример интеграции с Sentry:

import * as Sentry from '@sentry/browser';

const routes = [
  { path: '/checkout', action: () => 'Страница оплаты' },
];

const router = new UniversalRouter(routes);

router.resolve({ pathname: '/checkout' }).catch(error => {
  Sentry.captureException(error);
});

Такой подход обеспечивает централизованное хранение логов и ошибок, что критично для production-окружений.


Рекомендации по организации логирования

  • Разделять логи навигации и логи ошибок. Первые используются для аналитики, вторые — для отладки и мониторинга.
  • Использовать middleware-подход для единообразного логирования всех маршрутов.
  • Хранить параметры и контекст переходов для последующего анализа поведения пользователей.
  • При работе с динамическими маршрутами всегда фиксировать params, чтобы логи были информативными.
  • Для серверных приложений интегрировать логирование с системой мониторинга и хранения логов, чтобы избежать потери данных при сбоях.

Логирование переходов в Universal Router является мощным инструментом для контроля работы приложения, отладки маршрутов и анализа пользовательской активности. Правильная организация логов повышает прозрачность навигации и облегчает сопровождение сложных SPA и серверных приложений.