@onreza/bunny-logger
v1.1.2
Published
Высокопроизводительная библиотека логирования для Bun и Node.js с красивым форматированием
Maintainers
Readme
@onreza/bunny-logger
Современный, типобезопасный и расширяемый логгер для Node.js и TypeScript-приложений.
🌟 Особенности
- Типобезопасность: полная поддержка TypeScript с дженериками для метаданных
- Транспорты: консоль, файл, Grafana Loki и возможность создавать свои
- Форматирование: настраиваемые форматы вывода и цветовые темы
- Производительность: асинхронные транспорты и буферизация для минимального влияния на работу приложения
- Гибкие метаданные: добавление контекстной информации к логам
- Структурированное логирование: поддержка вложенной структуры данных
- Визуальные функции: баннер в консоли для мониторинга приложения
📦 Установка
npm install @onreza/bunny-loggerили
yarn add @onreza/bunny-loggerили
bun add @onreza/bunny-logger🚀 Базовое использование
import { BunnyLogger } from '@onreza/bunny-logger';
// Создание простого логгера
const logger = new BunnyLogger({
name: 'app',
level: 'info',
prettify: true,
});
// Логирование
logger.info('Приложение запущено');
logger.warn('Внимание: %s слишком высокая', 'нагрузка');
logger.error(new Error('Произошла ошибка!'));
// Логирование с метаданными
logger.info('Пользователь авторизован', { userId: 123, role: 'admin' });
// Логирование объектов
const user = { id: 1, name: 'John', roles: ['admin', 'user'] };
logger.object(user, 'Данные пользователя');🧩 Расширенные возможности
Типизированные метаданные
// Определяем тип метаданных
interface AppMetadata {
appName: string;
version: string;
environment: 'dev' | 'test' | 'prod';
}
// Создаем типизированный логгер
const appLogger = new BunnyLogger<AppMetadata>({
name: 'app',
metadata: {
appName: 'MyApp',
version: '1.0.0',
environment: 'dev',
},
});
// Автодополнение метаданных в IDE
appLogger.info('Запуск приложения', { environment: 'prod' }); // Ошибка! Только 'dev', 'test' или 'prod'Дочерние логгеры с наследованием метаданных
// Типы пользовательских метаданных
interface UserMetadata {
userId: number;
username: string;
}
// Создаем дочерний логгер с дополнительными метаданными
const userLogger = appLogger.with<UserMetadata>({
userId: 123,
username: 'john_doe',
});
// userLogger теперь имеет комбинированный тип метаданных: AppMetadata & UserMetadata
userLogger.info('Действие пользователя');Несколько транспортов
import { BunnyLogger, TransportRegistry } from '@onreza/bunny-logger';
const logger = new BunnyLogger({
name: 'multi-logger',
transports: [
// Логи уровня info и выше в консоль
TransportRegistry.create('console', {
level: 'info',
prettify: true,
}),
// Все логи в файл
TransportRegistry.create('file', {
level: 'debug',
filePath: './logs/app.log',
format: 'json',
maxSize: 10 * 1024 * 1024, // 10MB
maxFiles: 5,
}),
// Ошибки в Loki для анализа
TransportRegistry.create('loki', {
level: 'error',
url: 'http://loki:3100',
labels: { app: 'my-service' },
}),
],
});Контексты логирования
async function processRequest(req, res) {
// Создаем контекст логирования для запроса
const ctx = logger.createContext(`${req.method} ${req.path}`);
const requestLogger = ctx.getLogger();
try {
requestLogger.info('Начало обработки запроса');
// Бизнес-логика...
requestLogger.info('Запрос успешно обработан');
ctx.end('Успешно');
} catch (error) {
requestLogger.exception(error);
ctx.error(error);
throw error;
}
}Баннер для мониторинга
import { BannerManager } from '@onreza/bunny-logger';
// Инициализация баннера
BannerManager.init({
active: true,
content: 'Сервер работает на порту 3000',
updateIntervalMs: 1000,
});
// Добавление статусных элементов
BannerManager.addStatusItem('Память', () => {
const used = process.memoryUsage().heapUsed / 1024 / 1024;
return `${Math.round(used * 100) / 100} MB`;
});
BannerManager.addStatusItem('Запросы', () => `${requestCounter}`);📋 API Reference
Основные классы
BunnyLogger- основной класс логгераTransportRegistry- реестр транспортовFormatterRegistry- реестр форматтеровBannerManager- управление консольным баннером
Транспорты
ConsoleTransport- вывод в консольFileTransport- запись в файл с ротациейLokiTransport- отправка в Grafana LokiMultiTransport- комбинированный транспорт
Уровни логирования
trace- детальная трассировка для разработкиdebug- отладочная информацияinfo- информационные сообщенияwarn- предупрежденияerror- ошибкиfatal- критические ошибкиsilent- отключение логирования
Стили форматирования
minimal- максимально компактный выводcompact- однострочный компактный выводdetailed- подробный вывод с дополнительной информациейfancy- красивый вывод с рамками и иконками
Темы
default- стандартная тема с яркими цветамиdark- тема для темных терминаловlight- тема для светлых терминаловpastel- пастельные цвета
🛠️ Расширение функциональности
Создание собственного транспорта
import { BaseTransport, TransportOptions, TransportRegistry } from '@onreza/bunny-logger';
// Расширение интерфейса опций
interface MyTransportOptions extends TransportOptions {
customOption?: string;
}
// Создание класса транспорта
class MyTransport extends BaseTransport<MyTransportOptions> {
constructor(options: MyTransportOptions) {
super('my-transport', {
level: options.level ?? 'info',
customOption: options.customOption,
...options,
});
}
async log<TMeta extends Record<string, any>>(message: LogMessage<TMeta>): Promise<void> {
// Логика записи лога
console.log(`Custom transport: ${message.message}`);
}
async close(): Promise<void> {
// Освобождение ресурсов
}
}
// Регистрация транспорта
TransportRegistry.register('my-transport', MyTransport);Создание собственного форматтера
import { BaseFormatter, FormatterRegistry } from '@onreza/bunny-logger';
class MyFormatter extends BaseFormatter {
constructor() {
super('my-formatter', 'detailed', true);
}
format<TMeta extends Record<string, any>>(
message: LogMessage<TMeta>,
theme: ConsoleTheme,
useColors: boolean,
): string {
// Логика форматирования
return `[${message.level}] ${message.message}`;
}
}
// Регистрация форматтера
FormatterRegistry.register('my-formatter', MyFormatter);📝 Примеры использования
Express.js
import express from 'express';
import { BunnyLogger } from '@onreza/bunny-logger';
const app = express();
const logger = new BunnyLogger({ name: 'express-app' });
// Миддлвар для логирования запросов
app.use((req, res, next) => {
const requestId = crypto.randomUUID();
const requestLogger = logger.with({
requestId,
method: req.method,
path: req.path,
ip: req.ip,
});
requestLogger.info('Получен запрос');
const start = Date.now();
res.on('finish', () => {
const duration = Date.now() - start;
requestLogger.info(`Запрос обработан за ${duration}ms`, {
statusCode: res.statusCode,
contentLength: res.get('Content-Length'),
});
});
req.logger = requestLogger;
next();
});
app.get('/', (req, res) => {
req.logger.debug('Обработка запроса главной страницы');
res.send('Hello World!');
});
app.listen(3000, () => {
logger.info('Сервер запущен на порту 3000');
// Вывод информации о запуске
logger.logServerStart(
{},
{
hostname: 'localhost',
port: 3000,
environment: 'development',
routes: [
{ method: 'GET', path: '/' },
{ method: 'POST', path: '/api/users' },
],
},
);
});📈 Производительность
BunnyLogger разработан с учетом производительности:
- Проверка уровня логирования перед форматированием
- Асинхронная запись в файл
- Буферизация и пакетная отправка в Loki
- Ленивая инициализация ресурсоемких функций
