Настройка Error Tracking (Sentry) для веб-приложения
Sentry — стандарт de facto для отслеживания ошибок в веб-приложениях. Фиксирует исключения с полным стеком вызовов, контекстом запроса, переменными окружения и breadcrumbs — цепочкой событий, предшествовавших ошибке. Отличие от логов: Sentry группирует идентичные ошибки, показывает частоту и первое вхождение, умеет назначать ответственных.
Варианты использования
Sentry SaaS (sentry.io) — нет инфраструктуры, есть бесплатный tier (5000 ошибок/месяц). Self-hosted — Docker-based, требует ~4 GB RAM, подходит для команд с требованиями к данным или большим объёмом ошибок.
Установка SDK
PHP / Laravel:
composer require sentry/sentry-laravel
php artisan sentry:publish --dsn=https://[email protected]/project-id
config/sentry.php создаётся автоматически. В .env:
SENTRY_LARAVEL_DSN=https://[email protected]/project-id
SENTRY_TRACES_SAMPLE_RATE=0.1
SENTRY_PROFILES_SAMPLE_RATE=0.1
В bootstrap/app.php (Laravel 11) или app/Exceptions/Handler.php (Laravel 9-10) — SDK регистрирует себя автоматически через service provider.
Ручная отправка с контекстом:
use Sentry\State\Scope;
\Sentry\withScope(function (Scope $scope) use ($user, $order): void {
$scope->setUser(['id' => $user->id, 'email' => $user->email]);
$scope->setContext('order', [
'id' => $order->id,
'amount' => $order->total,
'status' => $order->status,
]);
$scope->setTag('payment_provider', 'stripe');
\Sentry\captureException(new \RuntimeException('Payment gateway timeout'));
});
JavaScript / React:
npm install @sentry/react
// src/main.tsx
import * as Sentry from '@sentry/react';
Sentry.init({
dsn: import.meta.env.VITE_SENTRY_DSN,
environment: import.meta.env.MODE,
release: import.meta.env.VITE_APP_VERSION,
integrations: [
Sentry.browserTracingIntegration(),
Sentry.replayIntegration({
maskAllText: false,
blockAllMedia: false,
}),
],
tracesSampleRate: 0.1,
replaysSessionSampleRate: 0.05,
replaysOnErrorSampleRate: 1.0, // 100% при ошибке
});
Error Boundary для React:
import * as Sentry from '@sentry/react';
const App = () => (
<Sentry.ErrorBoundary
fallback={({ error, resetError }) => (
<div>
<p>Что-то пошло не так</p>
<button onClick={resetError}>Попробовать снова</button>
</div>
)}
onError={(error, componentStack) => {
console.error('React error boundary caught:', error);
}}
>
<Router />
</Sentry.ErrorBoundary>
);
Source Maps для JavaScript
Без source maps стек вызовов в Sentry показывает минифицированный код. Настройка через Sentry Vite Plugin:
npm install @sentry/vite-plugin --save-dev
// vite.config.ts
import { sentryVitePlugin } from '@sentry/vite-plugin';
export default defineConfig({
build: { sourcemap: true },
plugins: [
react(),
sentryVitePlugin({
org: 'your-org',
project: 'your-project',
authToken: process.env.SENTRY_AUTH_TOKEN,
sourcemaps: {
assets: './dist/**',
ignore: ['node_modules'],
filesToDeleteAfterUpload: ['./dist/**/*.map'],
},
}),
],
});
Source maps загружаются в Sentry при сборке и удаляются из публичной директории — в браузере пользователя они недоступны.
Настройка окружений и release tracking
В CI/CD при деплое:
# Создание release и привязка коммитов
sentry-cli releases new "$VERSION"
sentry-cli releases set-commits "$VERSION" --auto
sentry-cli releases finalize "$VERSION"
sentry-cli releases deploys "$VERSION" new -e production
Это позволяет видеть в Sentry: какой коммит впервые вызвал ошибку, в каком релизе она появилась, была ли она в предыдущих версиях.
Фильтрация шума
По умолчанию Sentry будет ловить всё — включая ожидаемые 404, ботов, краши из расширений браузера. Фильтрация:
// config/sentry.php
'before_send' => function (\Sentry\Event $event, ?\Sentry\EventHint $hint): ?\Sentry\Event {
$exception = $hint?->exception;
// Игнорировать ожидаемые исключения
if ($exception instanceof \Illuminate\Auth\AuthenticationException) {
return null;
}
if ($exception instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException) {
return null;
}
// Игнорировать ошибки от ботов
$userAgent = request()->header('User-Agent', '');
if (str_contains(strtolower($userAgent), 'bot')) {
return null;
}
return $event;
},
// JavaScript: игнорировать ошибки расширений браузера
Sentry.init({
denyUrls: [
/extensions\//i,
/^chrome:\/\//i,
/^chrome-extension:\/\//i,
],
ignoreErrors: [
'ResizeObserver loop limit exceeded',
'Non-Error promise rejection captured',
],
});
Алерты и уведомления
В Sentry: Settings → Alerts → Create Alert Rule:
- New issue — немедленно при первом вхождении нового типа ошибки
- Error frequency — если ошибка происходит > 100 раз за 1 час
- Regression — ошибка вернулась после того, как была отмечена resolved
Интеграции: Slack, Telegram (через webhook), PagerDuty, Jira (автосоздание задач).
Сроки
Установка и базовая настройка SDK для backend + frontend, настройка source maps, первичная фильтрация шума, alert-правила: 2-4 часа.







