Централизованное логирование является ключевым аспектом при построении масштабируемых приложений на Fresh. Оно позволяет отслеживать работу серверных обработчиков, состояние компонентов, ошибки и производительность приложения в единой системе, упрощая анализ и отладку. Fresh, будучи современным фреймворком на основе Deno, предоставляет гибкие возможности интеграции логирования через стандартные средства JavaScript и дополнительные библиотеки.
Единообразие формата логов Логи должны иметь структурированный формат: timestamp, уровень (info, warn, error, debug), источник события (middleware, route handler, component), сообщение. Это упрощает фильтрацию и агрегацию данных в централизованных системах вроде Loki, Elasticsearch или Grafana.
Разделение уровней логирования
debug — подробная информация для разработчиков,
выводится только в локальной среде.info — ключевые события работы приложения: успешные
запросы, статус обработки данных.warn — потенциальные проблемы, которые не нарушают
работу приложения.error — критические ошибки, исключения, которые требуют
вмешательства.Асинхронность логирования В Fresh серверные обработчики часто работают с асинхронными функциями. Логи должны записываться без блокировки основного потока, чтобы не влиять на производительность. Используются асинхронные функции записи в файл или отправки данных в удалённые хранилища.
Fresh основан на Deno, поэтому можно использовать встроенный модуль
std/log:
import * as log from "https://deno.land/std@0.201.0/log/mod.ts";
await log.setup({
handlers: {
console: new log.handlers.ConsoleHandler("DEBUG", {
formatter: "{datetime} [{levelName}] {msg}",
}),
file: new log.handlers.FileHandler("INFO", {
filename: "./logs/app.log",
formatter: "{datetime} [{levelName}] {msg}",
}),
},
loggers: {
default: {
level: "DEBUG",
handlers: ["console", "file"],
},
},
});
const logger = log.getLogger();
logger.info("Сервер запущен");
Для контроля запросов и отклика полезно внедрять middleware, которое перехватывает все входящие HTTP-запросы:
import { MiddlewareHandlerContext } from "$fresh/server.ts";
export const logRequests = async (req: Request, ctx: MiddlewareHandlerContext) => {
const start = performance.now();
const response = await ctx.next();
const duration = (performance.now() - start).toFixed(2);
logger.info(`${req.method} ${req.url} - ${response.status} (${duration}ms)`);
return response;
};
Особенности данного подхода:
Middleware можно подключать глобально в main.ts, чтобы
каждое событие HTTP автоматически логировалось.
Fresh поддерживает обработку ошибок на уровне серверного рендеринга и API-роутеров. Для централизованного логирования ошибок рекомендуется создавать глобальный обработчик:
import { ErrorHandler } from "$fresh/server.ts";
export const errorHandler: ErrorHandler = (err, ctx) => {
logger.error(`Ошибка в ${ctx.url}: ${err.message}`);
return new Response("Произошла ошибка на сервере", { status: 500 });
};
Для крупных проектов рекомендуется отправлять логи в централизованные хранилища:
Пример отправки логов через HTTP:
async function sendLogToRemote(logEntry: Record<string, unknown>) {
await fetch("https://logging.example.com/ingest", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(logEntry),
});
}
logger.info = async (msg: string) => {
const logEntry = { timestamp: new Date().toISOString(), level: "INFO", message: msg };
console.info(msg);
await sendLogToRemote(logEntry);
};
Централизованное логирование в Fresh обеспечивает прозрачность работы приложения, позволяет быстро выявлять ошибки и оптимизировать производительность. Правильная организация логов и интеграция с внешними системами значительно упрощает сопровождение крупных проектов.