Registrador de rendimiento y devolución de llamada

Descargar controlador JDBC

A partir de la versión 13.4, Microsoft JDBC Driver for SQL Server proporciona un marco de métricas de rendimiento para realizar un seguimiento del tiempo de las operaciones críticas del controlador. Puede usar este marco para observar y analizar el comportamiento de ejecución de conexiones y instrucciones, lo que ayuda a identificar cuellos de botella de latencia en las interacciones de la aplicación con SQL Server.

Las métricas están disponibles a través de dos mecanismos que se pueden usar de forma independiente o conjunta:

  • Callback programático: registra un PerformanceLogCallback para recibir métricas en el código de tu aplicación.
  • Registro en Java: suscríbete a java.util.logging registradores específicos para capturar métricas en la salida de registro.

Actividades con seguimiento

El controlador realiza un seguimiento de las actividades en dos niveles: conexión y instrucción.

Actividades de nivel de conexión

Actividad Descripción
CONNECTION Tiempo total para establecer una conexión, incluidas todas las subactividades.
PRELOGIN Tiempo de negociación previa al inicio de sesión de TDS con el servidor.
LOGIN Tiempo dedicado al proceso de inicio de sesión y autenticación de TDS.
TOKEN_ACQUISITION Tiempo dedicado a la obtención de tokens de autenticación federada al utilizar la autenticación de Microsoft Entra.

Actividades en el nivel de instrucción

Actividad Descripción
STATEMENT_REQUEST_BUILD Tiempo del lado cliente para compilar la solicitud TDS (enlace de parámetros, procesamiento de SQL, construcción de paquetes). Solo temporización; no registra las excepciones.
STATEMENT_FIRST_SERVER_RESPONSE Tiempo desde el envío de la solicitud para recibir la primera respuesta del servidor. Solo temporización; no registra las excepciones.
STATEMENT_PREPARE Hora de sp_prepare cuando prepareMethod=prepare.
STATEMENT_PREPEXEC Tiempo de preparación y ejecución combinados a través de sp_prepexec.
STATEMENT_EXECUTE Tiempo de ejecución de declaraciones (sp_executesql, sp_execute, SQL directo o lote).

Habilitación de métricas de rendimiento

Opción 1: Programar una llamada de retorno

Registre un PerformanceLogCallback para recibir datos de rendimiento mediante programación:

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);
    }
});

Utiliza el tiempo de nanosegundos y el contexto de la sentencia

A partir de la versión 13.6, un callback puede habilitar la temporización con precisión de nanosegundos sobrescribiendo useNanoseconds(). La callback también puede llamar getCurrentUserSql() y getCurrentStatementType() correlacionar un evento a nivel de instrucción con el texto SQL enviado por la aplicación y el tipo de instrucción que se ejecutó. getCurrentStatementType() devuelve STATEMENT, PREPARED_STATEMENT, o CALLABLE_STATEMENT. Usa getCurrentApplicationName() para identificar la conexión o el pool que produjo un evento mediante su propiedad de conexión applicationName. Si applicationName no está activado, el método devuelve el nombre de la aplicación por defecto del controlador.

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);
    }
});

El tiempo de nanosegundos es opcional. Las llamadas de regreso que no anulan useNanoseconds() siguen recibiendo duraciones en milisegundos. Cuando una callback registrada opta por participar, la salida dedicada del registrador de rendimiento también utiliza nanosegundos y etiqueta duraciones con ns; de lo contrario, utiliza milisegundos y ms. Llamar System.nanoTime() puede tener más costes generales que System.currentTimeMillis() en algunas plataformas.

El contexto de callback solo está disponible durante la invocación correspondiente publish() . getCurrentApplicationName() está disponible para eventos de nivel de conexión y de instrucción, y devuelve null fuera de publish(). También puede devolverse null cuando las propiedades de la conexión no se han analizado, como cuando una conexión falla antes de que se resuelva el nombre de la aplicación. Los métodos de contexto SQL devuelven null para eventos a nivel de conexión, métricas de subactividad de instrucciones que no tienen contexto SQL y llamadas realizadas fuera de publish().

Caution

El texto SQL puede contener datos sensibles en literales o comentarios. Sanéalo y aplica los requisitos de tratamiento de datos de su organización antes de escribirlo en los registros o en la telemetría.

Opción 2: Configuración del registro de Java

Configurar java.util.logging para los registradores de métricas de rendimiento en el nivel FINE.

En un logging.properties archivo:

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

O mediante programación:

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

Preparar el efecto del método en las actividades de instrucción

Las actividades cuyo seguimiento se realiza para PreparedStatement dependen de la propiedad de conexión de prepareMethod. Para obtener más información sobre prepareMethod, vea Establecimiento de las propiedades de conexión.

Configuración de prepareMethod Primera ejecución Segunda ejecución Tercera ejecución y siguientes
prepexec (valor predeterminado) 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 directo) STATEMENT_EXECUTE (SQL directo) STATEMENT_EXECUTE (SQL directo)

Nota:

Con la configuración predeterminada prepexec , el controlador aplaza la preparación suponiendo un único uso. La segunda ejecución usa sp_prepexec (preparación y ejecución combinadas). A partir de la tercera ejecución en adelante, el identificador almacenado en caché se reutiliza a través de sp_execute. Para forzar sp_prepexec en la primera llamada, establezca la propiedad de conexión enablePrepareOnFirstPreparedStatementCall en true.

Salida de registro de ejemplo

La siguiente salida muestra las actividades registradas a lo largo de tres ejecuciones consecutivas de un PreparedStatement con la configuración predeterminada de 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