Во фреймворке Fresh логирование является ключевым инструментом для отслеживания поведения приложений на этапе разработки и диагностики ошибок в продакшене. Fresh, основанный на Deno и использовании стандартов современного JavaScript/TypeScript, предоставляет гибкие возможности для ведения логов.
В Fresh логирование реализуется с помощью стандартного объекта
console (console.log,
console.error, console.warn,
console.info, console.debug) и
специализированных библиотек, совместимых с Deno, таких как
std/log. Эти инструменты позволяют различать уровни
логирования и направлять вывод в разные потоки, например, stdout или
файлы.
import { log } from "https://deno.land/std@0.203.0/log/mod.ts";
await log.setup({
handlers: {
console: new log.handlers.ConsoleHandler("DEBUG"),
file: new log.handlers.FileHandler("INFO", {
filename: "./logs/app.log",
formatter: "{levelName} {msg}",
}),
},
loggers: {
default: {
level: "DEBUG",
handlers: ["console", "file"],
},
},
});
const logger = log.getLogger();
logger.info("Приложение запущено");
logger.debug("Отладочная информация");
logger.error("Произошла ошибка");
В этом примере показано, как настроить разные обработчики логов, чтобы отдельные сообщения выводились в консоль, а более важные — сохранялись в файл.
Fresh и Deno поддерживают следующие стандартные уровни логов:
Использование уровней позволяет фильтровать сообщения и сосредоточиться на наиболее значимых событиях.
В Fresh каждый маршрут и обработчик запросов может включать логирование для отслеживания запросов и ответов. Для HTTP-запросов удобно логировать метод, URL и статус ответа:
import { HandlerContext } from "$fresh/server.ts";
export async function handler(req: Request, ctx: HandlerContext) {
const start = performance.now();
try {
const resp = await ctx.next();
const duration = (performance.now() - start).toFixed(2);
console.info(`[${req.method}] ${req.url} - ${resp.status} (${duration}ms)`);
return resp;
} catch (err) {
console.error(`Ошибка обработки запроса ${req.url}:`, err);
throw err;
}
}
Такой подход помогает отслеживать производительность каждого запроса и выявлять узкие места в приложении.
Для сложных приложений важно логировать внутреннее состояние, например, данные, получаемые из базы, или результаты вычислений:
const users = await db.query("SELECT * FROM users");
console.debug("Полученные пользователи:", users);
Использование console.debug позволяет выводить объемные
структуры данных только на этапе разработки, без загрязнения логов
продакшена.
Для улучшения читаемости и последующего анализа рекомендуется использовать структурированные логи в формате JSON:
console.log(JSON.stringify({
level: "INFO",
message: "Пользователь авторизовался",
userId: 123,
timestamp: new Date().toISOString()
}));
Структурированные логи удобно парсить внешними инструментами мониторинга и визуализации.
В продакшене важно отключать детальное логирование и оставлять только критические сообщения. Можно использовать переменные окружения для контроля уровня логов:
const LOG_LEVEL = Deno.env.get("LOG_LEVEL") || "INFO";
if (LOG_LEVEL === "DEBUG") {
console.debug("Подробная отладочная информация");
}
console.info("Основные события приложения");
Такой подход обеспечивает баланс между информативностью логов и производительностью.
Fresh позволяет интегрировать логирование с внешними системами мониторинга, например, Loki, ELK или Sentry. Для этого структурированные JSON-логи отправляются через HTTP или TCP:
const logData = JSON.stringify({
level: "ERROR",
message: "Не удалось подключиться к базе",
timestamp: new Date().toISOString(),
});
await fetch("https://loki.example.com/loki/api/v1/push", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: logData,
});
Такой подход обеспечивает централизованное хранение и анализ логов большого приложения.
Logging в Fresh — это не просто вывод сообщений, а важный инструмент для отладки, мониторинга и поддержки приложения на всех этапах жизненного цикла.