Enregistreur d’événements de performances et rappel

Télécharger le pilote JDBC

À compter de la version 13.4, Microsoft JDBC Driver pour SQL Server fournit une infrastructure de métriques de performances pour le suivi du minutage des opérations de pilote critiques. Vous pouvez utiliser cette infrastructure pour observer et analyser le comportement d’exécution des connexions et des instructions, ce qui permet d’identifier les goulots d’étranglement de latence dans les interactions de votre application avec SQL Server.

Les métriques sont disponibles via deux mécanismes qui peuvent être utilisés indépendamment ou ensemble :

  • Rappel programmatique : Enregistrez un PerformanceLogCallback pour recevoir des métriques dans votre code d’application.
  • Journalisation Java - Abonnez-vous aux journaliseurs dédiés java.util.logging pour capturer les métriques dans la sortie de log.

Activités suivies

Le pilote effectue le suivi des activités à deux niveaux : la connexion et l’instruction.

Activités au niveau de la connexion

Activité Description
CONNECTION Temps total d’établissement d’une connexion, y compris toutes les sous-activités.
PRELOGIN Temps de négociation de préconnexion TDS avec le serveur.
LOGIN C'est le moment de lancer la connexion TDS et la procédure de poignée de main d'authentification.
TOKEN_ACQUISITION Temps d’acquisition de jetons d’authentification fédérés lors de l’utilisation de l’authentification Microsoft Entra.

Activités au niveau de la déclaration

Activité Description
STATEMENT_REQUEST_BUILD Temps côté client pour générer la requête TDS (liaison de paramètre, traitement SQL, construction de paquets). Mesure du temps uniquement ; ne suit pas les exceptions.
STATEMENT_FIRST_SERVER_RESPONSE Délai d’envoi de la demande à la réception de la première réponse du serveur. Mesure du temps uniquement ; ne suit pas les exceptions.
STATEMENT_PREPARE Temps de sp_prepare quand prepareMethod=prepare.
STATEMENT_PREPEXEC Temps de préparation et d’exécution combinés via sp_prepexec.
STATEMENT_EXECUTE Durée de l’exécution des instructions (sp_executesql, sp_executeSQL direct ou batch).

Activer les métriques de performances

Option 1 : inscrire un rappel

Inscrivez un PerformanceLogCallback pour recevoir des données de performance de manière programmatique :

SQLServerDriver.registerPerformanceLogCallback(new PerformanceLogCallback() {
    @Override
    public void publish(PerformanceActivity activity, int connectionId,
            long durationMs, Exception exception) {
        // Connection-level metrics
        System.out.printf("Activity: %s, Connection: %d, Duration: %d ms%n",
                activity, connectionId, durationMs);
    }

    @Override
    public void publish(PerformanceActivity activity, int connectionId,
            int statementId, long durationMs, Exception exception) {
        // Statement-level metrics
        System.out.printf("Activity: %s, Connection: %d, Statement: %d, Duration: %d ms%n",
                activity, connectionId, statementId, durationMs);
    }
});

Utiliser le timing et le contexte de l’énoncé en nanosecondes

À partir de la version 13.6, un callback peut opter pour un timing en nanosecondes en supplantant useNanoseconds(). Le callback peut également appeler getCurrentUserSql() et getCurrentStatementType() pour établir une corrélation entre un événement au niveau de l’instruction, le texte SQL soumis par l’application et le type d’instruction exécuté. getCurrentStatementType() renvoie STATEMENT, PREPARED_STATEMENT, ou CALLABLE_STATEMENT. Utilisez getCurrentApplicationName() pour identifier la connexion ou le pool qui a produit un événement à partir de sa applicationName propriété de connexion. Si applicationName n’est pas défini, la méthode renvoie le nom d’application par défaut du pilote.

SQLServerDriver.registerPerformanceLogCallback(new PerformanceLogCallback() {
    @Override
    public boolean useNanoseconds() {
        return true;
    }

    @Override
    public void publish(PerformanceActivity activity, int connectionId,
            long durationNs, Exception exception) {
        // Connection-level metrics don't have SQL statement context.
        System.out.printf("Application: %s, Activity: %s, Connection: %d, Duration: %d ns%n",
            getCurrentApplicationName(), activity, connectionId, durationNs);
    }

    @Override
    public void publish(PerformanceActivity activity, int connectionId,
            int statementId, long durationNs, Exception exception) {
        String applicationName = getCurrentApplicationName();
        String userSql = getCurrentUserSql();
        StatementType statementType = getCurrentStatementType();

        System.out.printf("Application: %s, Type: %s, Activity: %s, SQL: %s, Duration: %d ns%n",
            applicationName, statementType, activity, userSql, durationNs);
    }
});

Le timing en nanoseconde est volontaire. Les rappels qui ne prennent pas useNanoseconds() le dessus continuent de recevoir des durées en millisecondes. Lorsqu’une fonction de rappel enregistrée active cette option, la sortie dédiée du journaliseur de performances utilise également des nanosecondes et indique les durées avec ns ; sinon, elle utilise des millisecondes et ms. Appeler System.nanoTime() peut entraîner plus de surcharge que System.currentTimeMillis() sur certaines plateformes.

Le contexte de rappel n’est disponible que pendant l’invocation correspondante publish() . getCurrentApplicationName() est disponible pour les événements au niveau de la connexion et de l’instruction, et renvoie null en dehors de publish(). Il peut également revenir null lorsque les propriétés de connexion n’ont pas été analysées, par exemple lorsqu’une connexion échoue avant que le nom de l’application ne soit résolu. Les méthodes de contexte SQL retournent null pour les événements au niveau de la connexion, les métriques de sous-activité d’instruction qui n’ont pas de contexte SQL, et les appels effectués en dehors de publish().

Avertissement

Le texte SQL peut contenir des données sensibles en littéraux ou en commentaires. Désinfectez-le et appliquez les exigences de gestion des données de votre organisation avant de les écrire dans les journaux ou la télémétrie.

Option 2 : Configurer la journalisation Java

Configurez java.util.logging pour les enregistreurs de métriques de performances au niveau FINE.

Dans un logging.properties fichier :

com.microsoft.sqlserver.jdbc.PerformanceMetrics.Connection.level = FINE
com.microsoft.sqlserver.jdbc.PerformanceMetrics.Statement.level = FINE
handlers = java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level = FINE

Ou par programmation :

Logger.getLogger("com.microsoft.sqlserver.jdbc.PerformanceMetrics.Connection")
      .setLevel(Level.FINE);
Logger.getLogger("com.microsoft.sqlserver.jdbc.PerformanceMetrics.Statement")
      .setLevel(Level.FINE);

Préparation de l'effet des méthodes sur les activités de déclaration

Les activités suivies pour PreparedStatement dépendent de la propriété de connexion prepareMethod. Pour plus d’informations sur prepareMethod, consultez Définition des propriétés de connexion.

Paramètre prepareMethod Première exécution Deuxième exécution Troisième exécution+
prepexec (valeur par défaut) STATEMENT_EXECUTE (sp_executesql) STATEMENT_PREPEXEC (sp_prepexec) STATEMENT_EXECUTE (sp_execute)
prepare STATEMENT_PREPARE + STATEMENT_EXECUTE STATEMENT_EXECUTE STATEMENT_EXECUTE
none STATEMENT_EXECUTE (SQL directe) STATEMENT_EXECUTE (SQL directe) STATEMENT_EXECUTE (SQL directe)

Note

Avec le paramètre par défaut prepexec , le pilote reporte la préparation en supposant qu’il s’agit d’une utilisation unique. La deuxième exécution utilise sp_prepexec (préparation et exécution combinées). À partir de la troisième exécution, le handle mis en cache est réutilisé via sp_execute. Pour forcer sp_prepexec pour le premier appel, définissez la propriété de connexion enablePrepareOnFirstPreparedStatementCall sur true.

Exemple de sortie de journal

La sortie suivante montre les activités suivies sur trois exécutions consécutives d’un PreparedStatement avec le paramètre par défaut prepexec :

ConnectionID:1, StatementID:1 Request build time, duration: 8ms
ConnectionID:1, StatementID:1 First server response, duration: 17ms
ConnectionID:1, StatementID:1 Statement execute, duration: 75ms        ← 1st call: sp_executesql
ConnectionID:1, StatementID:1 Request build time, duration: 9ms
ConnectionID:1, StatementID:1 First server response, duration: 0ms
ConnectionID:1, StatementID:1 Statement prepexec, duration: 0ms        ← 2nd call: sp_prepexec
ConnectionID:1, StatementID:1 Request build time, duration: 0ms
ConnectionID:1, StatementID:1 First server response, duration: 0ms
ConnectionID:1, StatementID:1 Statement execute, duration: 0ms         ← 3rd call: sp_execute