Bundle Symfony

Pageviews serveur automatiques via kernel.terminate et configuration sémantique. Compatible Symfony 6.4 et 7, PHP ≥ 8.1.

Installation

composer require quiet-metrics/symfony-metrics

symfony-metrics n'est pas encore sur Packagist. Déclarez son dépôt GitHub (accès requis) ; le package cœur vient de Packagist :

{
    "repositories": [
        { "type": "vcs", "url": "https://github.com/Quiet-Metrics/symfony-metrics" }
    ]
}

Sans Symfony Flex, enregistrez le bundle :

// config/bundles.php
return [
    // …
    QuietMetrics\Symfony\QuietMetricsBundle::class => ['all' => true],
];

Configuration

# config/packages/quiet_metrics.yaml
quiet_metrics:
    public_key: '%env(QUIET_METRICS_PUBLIC_KEY)%'   # clé publique du site (obligatoire)
    secret_key: '%env(QUIET_METRICS_SECRET_KEY)%'   # facultative : signe chaque envoi (HMAC)

    # endpoint: 'https://quietmetrics.dev/api/v1/collect'  # défaut du SDK cœur
    # auto_pageview: false        # désactive la pageview automatique

Par environnement, surchargez dans config/packages/test/quiet_metrics.yaml ou via les variables d'environnement : sans clé publique valide, rien n'est envoyé.

Pageviews automatiques

Le listener écoute kernel.terminate : la réponse est déjà partie chez le visiteur, l'envoi n'ajoute aucune latence perçue. Seules les réponses HTML de requêtes GET réussies sont comptées. Ni XHR, ni erreurs, ni API JSON : vos endpoints REST ne polluent pas les statistiques.

auto_pageview: false coupe le listener : vous gardez le client pour des envois manuels (sites mixtes, tracking sélectif).

Événements

Injectez le client (service public) :

use QuietMetrics\Client;

final class CheckoutController
{
    public function __construct(private readonly Client $quietMetrics) {}

    public function confirm(): Response
    {
        // …
        $this->quietMetrics->event('achat', ['montant' => 49, 'plan' => 'pro']);
    }
}

Depuis une commande console ou un worker Messenger, il n'y a pas de requête courante : passez l'URL explicitement, sinon rien ne part (abandon silencieux) :

$this->quietMetrics->event('import-termine', ['lignes' => 1200], [
    'url' => 'https://monsite.fr/imports',
]);

Cas particuliers

FrankenPHP, RoadRunner, workers persistants. Le listener lit l'objet Request de chaque requête, jamais les superglobales. Rien à configurer.

Reverse proxy / CDN. Le listener utilise Request::getClientIp() : configurez framework.trusted_proxies comme d'habitude et l'IP réelle du visiteur suivra. L'option trust_proxy_headers du SDK ne concerne que les usages hors framework.

Tests. Remplacez le service par un stub pour vérifier vos événements sans réseau :

# config/services_test.yaml
services:
    QuietMetrics\Client:
        class: App\Tests\Double\NullQuietMetricsClient

Contrat de robustesse

Envoi non bloquant (socket fire-and-forget, repli cURL court), échecs silencieux : l'analytics ne casse jamais l'application hôte, même si la plateforme est injoignable.

Vous ne trouvez pas votre réponse ?

Le support répond en français, les jours ouvrés.