Логирование в Fresh

Логирование является важной частью разработки веб-приложений, обеспечивая контроль за выполнением кода и диагностику ошибок. В фреймворке Fresh для JavaScript оно организуется с учетом особенностей серверного рендеринга и использования Deno. Рассмотрим основные подходы и практики логирования в Fresh.


Основы логирования

Fresh работает на платформе Deno, поэтому стандартные методы логирования включают:

  • console.log() – вывод информации в консоль;
  • console.error() – вывод ошибок;
  • console.warn() – вывод предупреждений;
  • console.info() – информационные сообщения.

Эти методы подходят для базового логирования, однако для крупномасштабных приложений рекомендуется использовать специализированные библиотеки или встроенные механизмы Deno, такие как std/log.

import * as log from "https://deno.land/std@0.203.0/log/mod.ts";

await log.setup({
  handlers: {
    console: new log.handlers.ConsoleHandler("DEBUG"),
  },
  loggers: {
    default: {
      level: "DEBUG",
      handlers: ["console"],
    },
  },
});

log.info("Сервер Fresh запущен");
log.warning("Это предупреждение");
log.error("Произошла ошибка");

Логирование запросов

В Fresh серверная часть основана на Handlers. Для логирования HTTP-запросов часто используют middleware-подобные функции, оборачивая обработчики:

export const handler = {
  async GET(req, ctx) {
    console.log(`[GET] ${req.url} - Запрос обработан`);
    return ctx.render({});
  },

  async POST(req, ctx) {
    console.log(`[POST] ${req.url} - Данные получены`);
    return ctx.render({});
  },
};

Такой подход позволяет фиксировать метод запроса, URL и дополнительные параметры, что критично для отладки API и анализа трафика.


Логирование ошибок

Fresh поддерживает обработку ошибок через try/catch и глобальные обработчики. Для централизованного логирования ошибок можно использовать кастомный middleware:

export async function errorMiddleware(req, ctx, next) {
  try {
    return await next();
  } catch (err) {
    console.error("Ошибка сервера:", err);
    return new Response("Внутренняя ошибка сервера", { status: 500 });
  }
}

Важно фиксировать стек вызовов и контекст запроса, чтобы быстро локализовать проблему.


Асинхронное логирование и производительность

В высоконагруженных приложениях прямой вызов console.log может влиять на производительность. Для минимизации задержек используют асинхронное логирование:

import { writeFileStr } from "https://deno.land/std@0.203.0/fs/mod.ts";

async function asyncLog(message) {
  await writeFileStr("./logs/app.log", `${new Date().toISOString()} - ${message}\n`, { append: true });
}

asyncLog("Приложение стартовало");

Такой подход позволяет сохранять логи на диск без блокировки основного потока обработки запросов.


Структурированное логирование

Для удобного анализа и интеграции с системами мониторинга рекомендуется использовать JSON-формат логов:

const logEntry = {
  timestamp: new Date().toISOString(),
  level: "INFO",
  message: "Пользователь авторизован",
  userId: 1234,
  path: "/login"
};

console.log(JSON.stringify(logEntry));

Структурированные логи легко фильтровать и отправлять в внешние системы аналитики.


Настройка уровней логирования

Уровни логирования помогают контролировать объем информации, выводимой в продакшене и в разработке:

  • DEBUG – подробная информация для отладки;
  • INFO – стандартные события приложения;
  • WARN – потенциальные проблемы;
  • ERROR – критические ошибки;
  • CRITICAL – сбои, требующие немедленного внимания.

Использование уровней позволяет гибко управлять логами без изменения кода обработчиков.


Интеграция с внешними системами

Fresh может работать с внешними сервисами логирования, такими как Logstash, Datadog или Sentry. Для интеграции достаточно отправлять структурированные события через HTTP или WebSocket:

async function sendToSentry(error) {
  await fetch("https://sentry.io/api/events", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      message: error.message,
      stack: error.stack,
      timestamp: new Date().toISOString(),
    }),
  });
}

Такой подход обеспечивает централизованное хранение и анализ ошибок.


Практические рекомендации

  • Использовать асинхронное и структурированное логирование для производительных приложений.
  • Разделять логи по уровням критичности и средам (development, production).
  • Логировать контекст запроса, включая метод, URL и параметры.
  • Обеспечивать централизованное управление ошибками через middleware.
  • При необходимости интегрировать логи с внешними аналитическими сервисами.

Логирование в Fresh является сочетанием возможностей Deno и особенностей серверного рендеринга. Его грамотная организация повышает надежность, удобство отладки и позволяет масштабировать приложения без потери контроля над процессами.