✨ feat(sentry): Ajoute l'intégration de Sentry pour le suivi des erreurs.
This commit is contained in:
1
.env
1
.env
@@ -76,3 +76,4 @@ CLOUDFLARE_TOKEN=4mqx9d7ynvoeCaXonJA07U19rH8gGhctqp7j2Lch
|
||||
MAILCOW_KEY=DF0E7E-0FD059-16226F-8ECFF1-E558B3
|
||||
|
||||
DEV_URL=https://1fc91cb07736.ngrok-free.app
|
||||
SENTRY_BACKEND=https://dcf4ed12f5844686f088838f26082bf0@o4510197735948288.ingest.de.sentry.io/4510197737979984
|
||||
|
||||
@@ -11,6 +11,7 @@ import {SecurityWall} from './class/SecurityWall'
|
||||
import {IpWall} from './class/IpWall'
|
||||
import {ConfirmModal} from './class/ConfirmModal'
|
||||
import preactCustomElement from './functions/preact'
|
||||
import * as Sentry from "@sentry/browser";
|
||||
|
||||
|
||||
function script() {
|
||||
@@ -49,6 +50,26 @@ function full() {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
let metaSentry = document.querySelector('meta[name="sentry"]');
|
||||
if(metaSentry != undefined) {
|
||||
Sentry.init({
|
||||
dsn: "https://f134747cc727471fefb197ab5fd4b1b0@o4510197735948288.ingest.de.sentry.io/4510197772320848",
|
||||
// Setting this option to true will send default PII data to Sentry.
|
||||
// For example, automatic IP address collection on events
|
||||
sendDefaultPii: true,
|
||||
tunnel: "/tunnel",
|
||||
integrations: [
|
||||
Sentry.browserTracingIntegration(),
|
||||
Sentry.replayIntegration()
|
||||
],
|
||||
// Tracing
|
||||
tracesSampleRate: 1.0, // Capture 100% of the transactions
|
||||
// Session Replay
|
||||
replaysSessionSampleRate: 0.1, // This sets the sample rate at 10%. You may want to change it to 100% while in development and then sample at a lower rate in production.
|
||||
replaysOnErrorSampleRate: 1.0 // If you're not already sampling the entire session, change the sample rate to 100% when sampling sessions where errors occur.
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', ()=>{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import './app.scss'
|
||||
import * as Turbo from "@hotwired/turbo"
|
||||
import {PaymentChaque, PaymentPage, PaymentSepa, PaymentVirement} from "./class/PaymentPage.js";
|
||||
import * as Sentry from "@sentry/browser";
|
||||
|
||||
customElements.define('payment-page',PaymentPage,{extends:'button'})
|
||||
customElements.define('payment-cheque',PaymentChaque,{extends:'button'})
|
||||
@@ -9,6 +10,26 @@ customElements.define('payment-virement',PaymentVirement,{extends:'button'})
|
||||
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
let metaSentry = document.querySelector('meta[name="sentry"]');
|
||||
if(metaSentry != undefined) {
|
||||
Sentry.init({
|
||||
dsn: "https://f134747cc727471fefb197ab5fd4b1b0@o4510197735948288.ingest.de.sentry.io/4510197772320848",
|
||||
// Setting this option to true will send default PII data to Sentry.
|
||||
// For example, automatic IP address collection on events
|
||||
sendDefaultPii: true,
|
||||
tunnel: "/tunnel",
|
||||
integrations: [
|
||||
Sentry.browserTracingIntegration(),
|
||||
Sentry.replayIntegration()
|
||||
],
|
||||
// Tracing
|
||||
tracesSampleRate: 1.0, // Capture 100% of the transactions
|
||||
// Session Replay
|
||||
replaysSessionSampleRate: 0.1, // This sets the sample rate at 10%. You may want to change it to 100% while in development and then sample at a lower rate in production.
|
||||
replaysOnErrorSampleRate: 1.0 // If you're not already sampling the entire session, change the sample rate to 100% when sampling sessions where errors occur.
|
||||
});
|
||||
}
|
||||
function createSvgIconPassword(paths, classes) {
|
||||
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
||||
svg.setAttribute("fill", "none");
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"phpoffice/phpspreadsheet": "*",
|
||||
"phpstan/phpdoc-parser": "^2.2",
|
||||
"presta/sitemap-bundle": "^4.1",
|
||||
"sentry/sentry": "*",
|
||||
"sentry/sentry-symfony": "^5.3",
|
||||
"setasign/fpdi": "^2.6",
|
||||
"spatie/mjml-php": "^1.2",
|
||||
|
||||
14
composer.lock
generated
14
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "1daefc9419bbfdfa4b4f286a2a26b1b2",
|
||||
"content-hash": "c30269ac9b27fa9af3a5958c1033684b",
|
||||
"packages": [
|
||||
{
|
||||
"name": "async-aws/core",
|
||||
@@ -7034,16 +7034,16 @@
|
||||
},
|
||||
{
|
||||
"name": "sentry/sentry",
|
||||
"version": "4.15.2",
|
||||
"version": "4.16.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/getsentry/sentry-php.git",
|
||||
"reference": "61a2d918e8424b6de4a2e265c15133a00c17db51"
|
||||
"reference": "c5b086e4235762da175034bc463b0d31cbb38d2e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/getsentry/sentry-php/zipball/61a2d918e8424b6de4a2e265c15133a00c17db51",
|
||||
"reference": "61a2d918e8424b6de4a2e265c15133a00c17db51",
|
||||
"url": "https://api.github.com/repos/getsentry/sentry-php/zipball/c5b086e4235762da175034bc463b0d31cbb38d2e",
|
||||
"reference": "c5b086e4235762da175034bc463b0d31cbb38d2e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -7107,7 +7107,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/getsentry/sentry-php/issues",
|
||||
"source": "https://github.com/getsentry/sentry-php/tree/4.15.2"
|
||||
"source": "https://github.com/getsentry/sentry-php/tree/4.16.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -7119,7 +7119,7 @@
|
||||
"type": "custom"
|
||||
}
|
||||
],
|
||||
"time": "2025-09-03T07:23:48+00:00"
|
||||
"time": "2025-09-22T13:38:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sentry/sentry-symfony",
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
"@grapesjs/studio-sdk-plugins": "^1.0.28",
|
||||
"@hotwired/turbo": "^8.0.13",
|
||||
"@preact/preset-vite": "^2.10.2",
|
||||
"@sentry/browser": "^9.46.0",
|
||||
"@sentry/browser": "^10.20.0",
|
||||
"@tailwindcss/vite": "^4.1.13",
|
||||
"@usewaypoint/email-builder": "^0.0.8",
|
||||
"autoprefixer": "^10.4.21",
|
||||
|
||||
@@ -5,5 +5,17 @@ use App\Kernel;
|
||||
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
|
||||
|
||||
return function (array $context) {
|
||||
|
||||
if($_ENV['APP_ENV'] == "prod") {
|
||||
\Sentry\init([
|
||||
'dsn' => $_ENV['SENTRY_DSN'],
|
||||
// Specify a fixed sample rate
|
||||
'traces_sample_rate' => 1.0,
|
||||
// Set a sampling rate for profiling - this is relative to traces_sample_rate
|
||||
'profiles_sample_rate' => 1.0,
|
||||
// Enable logs to be sent to Sentry
|
||||
'enable_logs' => true,
|
||||
]);
|
||||
}
|
||||
return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
|
||||
};
|
||||
|
||||
@@ -17,7 +17,7 @@ use Vich\UploaderBundle\Templating\Helper\UploaderHelper;
|
||||
class TutoController extends AbstractController
|
||||
{
|
||||
#[Route(path: '/artemis/esyweb/tuto', name: 'artemis_esyweb_tuto', methods: ['GET', 'POST'])]
|
||||
public function tutos(KernelInterface $kernel,Request $request,UploaderHelper $uploaderHelper,LoggerService $loggerService,EsyWebTutoRepository $esyWebTutoRepository,EntityManagerInterface $entityManager)
|
||||
public function tutos()
|
||||
{
|
||||
|
||||
|
||||
|
||||
57
src/Controller/TunnelController.php
Normal file
57
src/Controller/TunnelController.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Repository\CustomerAdvertPaymentRepository;
|
||||
use App\Service\Mailer\Mailer;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
class TunnelController extends AbstractController
|
||||
{
|
||||
#[Route(path: '/tunnel',name: 'tunnels',methods: ['POST'])]
|
||||
public function tunnelSentry(Request $request, HttpClientInterface $httpClient): Response
|
||||
{
|
||||
// Step 1: Get raw request content
|
||||
$content = $request->getContent();
|
||||
|
||||
// Step 2: Parse the first line (DSN) from the request content
|
||||
$piece = explode("\n", $content)[0];
|
||||
$header = json_decode($piece, true); // Decode the JSON into an array
|
||||
|
||||
// Step 3: Parse the DSN to extract project details
|
||||
$dns = parse_url($header['dsn']);
|
||||
$project_id = str_replace("/", "", $dns['path']); // Clean the project ID path
|
||||
|
||||
// Step 4: Construct the Sentry envelope URL
|
||||
$upstream_sentry_url = 'https://' . $dns['host'] . '/api/' . $project_id . '/envelope/';
|
||||
|
||||
try {
|
||||
// Step 5: Forward the request to Sentry's API
|
||||
$httpClient->request('POST', $upstream_sentry_url, [
|
||||
'body' => $content // Forward the exact content of the original request
|
||||
]);
|
||||
|
||||
// Return a successful empty response
|
||||
return $this->json([]);
|
||||
} catch (\Exception $exception) {
|
||||
// Step 6: Handle any general exceptions during the request
|
||||
return $this->json(
|
||||
['error' => 'Error in Sentry tunnel: ' . $exception->getMessage()],
|
||||
Response::HTTP_INTERNAL_SERVER_ERROR
|
||||
);
|
||||
} catch (TransportExceptionInterface $e) {
|
||||
// Step 7: Handle any transport-specific exceptions (e.g., network errors)
|
||||
return $this->json(
|
||||
['error' => 'Error in Sentry tunnel: ' . $e->getMessage()],
|
||||
Response::HTTP_INTERNAL_SERVER_ERROR
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
20
src/EventListener/ErrorSubscriber.php
Normal file
20
src/EventListener/ErrorSubscriber.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\EventListener;
|
||||
use Error;
|
||||
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
|
||||
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
|
||||
|
||||
|
||||
#[AsEventListener(event: ExceptionEvent::class,method: 'onKernelException')]
|
||||
class ErrorSubscriber
|
||||
{
|
||||
public function onKernelException(ExceptionEvent $event)
|
||||
{
|
||||
if($event->getThrowable() instanceof Error) {
|
||||
if($_ENV['APP_ENV'] == "prod") {
|
||||
\Sentry\captureException($event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,15 +6,19 @@
|
||||
<title>{{ websiteTitle }} - {% block title %}{% endblock %}</title>
|
||||
|
||||
{% if noIndex is defined %}
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
{% endif %}
|
||||
<link rel="icon" type="image/png" href="{{ asset('favicon/favicon-96x96.png') }}" sizes="96x96" />
|
||||
<link rel="icon" type="image/svg+xml" href="{{ asset('favicon/favicon.svg') }}" />
|
||||
<link rel="shortcut icon" href="{{ asset('favicon/favicon.ico') }}" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="{{ asset('favicon/apple-touch-icon.png') }}" />
|
||||
<meta name="apple-mobile-web-app-title" content="{{ websiteTitle }}" />
|
||||
<link rel="manifest" href="{{ asset('favicon/site.webmanifest') }}" />
|
||||
<link rel="icon" type="image/png" href="{{ asset('favicon/favicon-96x96.png') }}" sizes="96x96"/>
|
||||
<link rel="icon" type="image/svg+xml" href="{{ asset('favicon/favicon.svg') }}"/>
|
||||
<link rel="shortcut icon" href="{{ asset('favicon/favicon.ico') }}"/>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="{{ asset('favicon/apple-touch-icon.png') }}"/>
|
||||
<meta name="apple-mobile-web-app-title" content="{{ websiteTitle }}"/>
|
||||
<link rel="manifest" href="{{ asset('favicon/site.webmanifest') }}"/>
|
||||
{{ vite_asset('app.js',[]) }}
|
||||
|
||||
{% if app.environment == "prod" %}
|
||||
<meta name="sentry" content="up">
|
||||
{% endif %}
|
||||
</head>
|
||||
{# Changement ici : fond noir, texte blanc #}
|
||||
<body class="bg-gray-900 font-sans antialiased text-gray-100">
|
||||
|
||||
@@ -48,6 +48,10 @@
|
||||
}
|
||||
</style>
|
||||
<script src="https://signature.esy-web.dev/js/form.js"></script>
|
||||
|
||||
{% if app.environment == "prod" %}
|
||||
<meta name="sentry" content="up">
|
||||
{% endif %}
|
||||
</head>
|
||||
<body class="bg-gray-100 dark:bg-gray-900 text-gray-900 dark:text-gray-100">
|
||||
|
||||
|
||||
Reference in New Issue
Block a user