← Назад к вопросам

Где сохраняется логирование?

2.3 Middle🔥 121 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Где сохраняется логирование в браузере и на сервере?

Логирование — это очень важная тема для отладки приложений. Рассмотрим все места, где сохраняются логи в фронтенде и бэкенде.

Фронтенд (браузер)

1. Browser Console (консоль браузера)

Самое очевидное место — вкладка Console в DevTools:

// Все эти сообщения идут в консоль браузера
console.log('Information');
console.warn('Warning');
console.error('Error');
console.info('Info');
console.debug('Debug');

Как открыть:

  • Chrome/Firefox: F12 или Ctrl+Shift+J
  • Safari: Cmd+Option+I

ВАЖНО: эти логи удаляются при закрытии страницы!

console.log('This message is temporary');
// Перезагрузи страницу — логи исчезнут

2. localStorage (постоянное хранилище в браузере)

Можно сохранить логи в localStorage для последующего просмотра:

function logToStorage(message, level = 'info') {
  const logs = JSON.parse(localStorage.getItem('app_logs') || '[]');
  logs.push({
    timestamp: new Date().toISOString(),
    level,
    message
  });
  localStorage.setItem('app_logs', JSON.stringify(logs));
}

// Использование
logToStorage('User logged in', 'info');
logToStorage('Payment failed', 'error');

// Просмотр
const logs = JSON.parse(localStorage.getItem('app_logs'));
console.table(logs);

// Очистка
localStorage.removeItem('app_logs');

Ограничения localStorage:

  • Хранит только 5-10 MB
  • Хранит только текст (JSON)
  • Очищается при очистке кэша браузера

3. IndexedDB (объёмное хранилище)

Для большого количества логов используй IndexedDB:

const dbRequest = indexedDB.open('AppLogs', 1);

dbRequest.onupgradeneeded = (event) => {
  const db = event.target.result;
  if (!db.objectStoreNames.contains('logs')) {
    db.createObjectStore('logs', { keyPath: 'id', autoIncrement: true });
  }
};

dbRequest.onsuccess = (event) => {
  const db = event.target.result;
  const transaction = db.transaction('logs', 'readwrite');
  const store = transaction.objectStore('logs');
  
  // Добавить лог
  store.add({
    timestamp: new Date(),
    level: 'error',
    message: 'Something went wrong'
  });
};

Преимущества IndexedDB:

  • Хранит до 50 MB+ (зависит от браузера)
  • Асинхронный API
  • Хорошо структурирован

4. sessionStorage

Времение жизни = время открытия вкладки:

// Сохраняется только во время сессии
sessionStorage.setItem('session_logs', JSON.stringify([
  { message: 'User action 1', time: Date.now() },
  { message: 'User action 2', time: Date.now() }
]));

// При закрытии вкладки — всё удалится

5. Network вкладка (Network tab)

Network вкладка в DevTools сохраняет логи всех HTTP запросов:

// Все эти запросы видны в Network tab
fetch('/api/users');
fetch('/api/posts', { method: 'POST', body: '...' });

Сохранение логов Network:

  • Chrome: Gear icon → "Log XMLHttpRequest"
  • Можно экспортировать как HAR файл

6. Performance вкладка

Performance вкладка логирует:

  • Время загрузки
  • Время рендера
  • Длительность функций (если добавить performance markers)
// Добавить маркер производительности
performance.mark('api-start');
await fetch('/api/data');
performance.mark('api-end');
performance.measure('api-call', 'api-start', 'api-end');

// Просмотр в Performance tab (F12 -> Performance)

Отправка логов на сервер

1. Beacon API (асинхронно)

Отправляет логи без блокирования:

window.addEventListener('beforeunload', () => {
  const logs = JSON.stringify({
    page: window.location.href,
    errors: window.errorLogs || []
  });
  
  navigator.sendBeacon('/api/logs', logs);
});

2. Fetch API

Обычный способ отправить логи:

async function sendLogsToServer(logs) {
  try {
    await fetch('/api/logs', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(logs)
    });
  } catch (error) {
    console.error('Failed to send logs:', error);
  }
}

// Использование
window.addEventListener('error', (event) => {
  sendLogsToServer([{
    type: 'error',
    message: event.message,
    stack: event.error?.stack
  }]);
});

3. Библиотеки логирования

Sentry (самая популярная):

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

Sentry.init({
  dsn: 'https://YOUR-KEY@sentry.io/PROJECT-ID',
  environment: 'production'
});

// Все ошибки отправляются на Sentry
try {
  riskyOperation();
} catch (error) {
  Sentry.captureException(error);
}

Pino.js (для Node.js):

const logger = require('pino')({
  transport: {
    target: 'pino-http'
  }
});

logger.info({ user: 'John' }, 'User logged in');

Бэкенд (сервер)

1. Файлы логов

На Linux/Mac сервере логи обычно хранятся в:

# Node.js приложения
/var/log/app.log          # Обычные логи
/var/log/app-error.log    # Только ошибки
/var/log/app-access.log   # HTTP запросы

# Python приложения
/var/log/flask_app.log
/var/log/django.log

# Системные логи
/var/log/syslog
/var/log/messages

2. Express.js пример

const fs = require('fs');
const path = require('path');

const logDir = path.join(__dirname, 'logs');
if (!fs.existsSync(logDir)) {
  fs.mkdirSync(logDir);
}

function logError(error) {
  const logFile = path.join(logDir, `${new Date().toISOString().split('T')[0]}.log`);
  const message = `[${new Date().toISOString()}] ${error.message}\n${error.stack}\n\n`;
  
  fs.appendFileSync(logFile, message);
}

app.use((error, req, res, next) => {
  logError(error);
  res.status(500).json({ error: error.message });
});

3. Docker/Контейнеры

Логи контейнера доступны через:

# Просмотр логов контейнера
docker logs my-container

# Последние 100 строк
docker logs --tail 100 my-container

# В реальном времени
docker logs -f my-container

4. Системы логирования

ELK Stack (Elasticsearch, Logstash, Kibana):

const elasticsearch = require('@elastic/elasticsearch');
const client = new elasticsearch.Client({ node: 'http://localhost:9200' });

app.use((req, res, next) => {
  // Логирование HTTP запросов
  client.index({
    index: 'logs',
    body: {
      timestamp: new Date(),
      method: req.method,
      url: req.url,
      status: res.statusCode
    }
  });
  next();
});

Datadog/New Relic (облачные системы мониторинга):

const datadog = require('dd-trace').init();
const logger = require('pino')();

logger.info({ user: 'John' }, 'User action');
// Автоматически отправляется в Datadog

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

Хорошее логирование:

{
  "timestamp": "2024-01-15T10:30:45.123Z",
  "level": "error",
  "service": "auth-service",
  "userId": "user_123",
  "message": "Failed to authenticate user",
  "error": {
    "type": "AuthenticationError",
    "message": "Invalid credentials",
    "stack": "...."
  },
  "metadata": {
    "ip": "192.168.1.1",
    "userAgent": "Mozilla/5.0...",
    "duration": 1234
  }
}

Уровни логирования

console.debug('Debug info'); // 0 - самый детальный
console.info('Information'); // 1
console.warn('Warning');     // 2
console.error('Error');      // 3 - только критичные

Таблица: где хранятся логи

МестоПостоянное?ОбъёмДоступПримеры
ConsoleНетМалоеDevToolslog, warn, error
localStorageДа5-10 MBJS, DevToolsПользовательские логи
IndexedDBДа50 MB+JSИстория действий
sessionStorageНет*5-10 MBJSВременные логи
Network tabНет*Все запросыDevToolsHTTP логи
Файлы сервераДаНеограниченноSSH, Logs/var/log/*.log
ELK/DatadogДаНеограниченноWeb UIОблачное хранилище
Docker logsЗависитЗависитdocker logsЛоги контейнера

*Удаляются при закрытии вкладки/браузера

Best practices

  1. Использование уровней логирования:
logger.error('Critical error'); // Отправляй на сервер
logger.warn('Warning');         // Отправляй на сервер
logger.info('Info');            // Сохраняй локально
logger.debug('Debug');          // Только при разработке
  1. Не логируй чувствительные данные:
// ПЛОХО
logger.info(`User ${user.password} logged in`);

// ХОРОШО
logger.info(`User ${user.id} logged in`, {
  userId: user.id,
  email: user.email // без пароля!
});
  1. Включай контекст:
logger.error('Request failed', {
  url: request.url,
  method: request.method,
  status: response.status,
  duration: response.time
});
  1. Ротация файлов логов (на сервере):
const rfs = require('rotating-file-stream');
const accessLogStream = rfs.createStream('access.log', {
  interval: '1d',    // Ротация каждый день
  maxSize: '100M'    // Или максимум 100MB
});
Где сохраняется логирование? | PrepBro