성능 로거 및 콜백

JDBC 드라이버 다운로드

버전 13.4부터 Microsoft JDBC Driver for SQL Server는 중요한 드라이버 작업의 타이밍을 추적하기 위한 성능 메트릭 프레임워크를 제공합니다. 이 프레임워크를 사용하여 연결 및 문 실행 동작을 관찰하고 분석하여 애플리케이션과 SQL Server의 상호 작용에서 대기 시간 병목 상태를 식별할 수 있습니다.

메트릭은 독립적으로 또는 함께 사용할 수 있는 두 가지 메커니즘을 통해 사용할 수 있습니다.

  • 프로그래밍 방식 콜백 - 애플리케이션 코드에서 메트릭을 수신하도록 PerformanceLogCallback를 등록합니다.
  • Java 로깅 - 전용 java.util.logging 로거를 구독하여 로그 출력에서 메트릭을 캡처합니다.

추적된 활동

드라이버는 연결 및 문의 두 가지 수준에서 활동을 추적합니다.

연결 수준 활동

Activity 설명
CONNECTION 모든 하위 활동을 포함하여 연결을 설정하는 총 시간입니다.
PRELOGIN 서버와 TDS 사전 로그인 협상 시간입니다.
LOGIN TDS 로그인 및 인증 핸드셰이크에 대한 시간입니다.
TOKEN_ACQUISITION Microsoft Entra 인증을 사용할 때 페더레이션 인증 토큰을 획득하는 시간입니다.

문장 수준 활동

Activity 설명
STATEMENT_REQUEST_BUILD TDS 요청(매개 변수 바인딩, SQL 처리, 패킷 생성)을 빌드하는 클라이언트 쪽 시간입니다. 타이밍 전용, 예외를 추적하지 않습니다.
STATEMENT_FIRST_SERVER_RESPONSE 요청을 보내는 시간부터 첫 번째 서버 응답 수신까지의 시간입니다. 타이밍 전용, 예외를 추적하지 않습니다.
STATEMENT_PREPARE 시간을 지정합니다 sp_prepareprepareMethod=prepare.
STATEMENT_PREPEXEC sp_prepexec을 통해 결합된 준비 및 실행의 시간입니다.
STATEMENT_EXECUTE 문 실행 시간(sp_executesql, sp_execute, 직접 SQL, 또는 일괄 처리).

성능 메트릭 사용

옵션 1: 콜백 등록

PerformanceLogCallback 프로그래밍 방식으로 성능 데이터를 수신하도록 등록합니다.

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

나노초 타이밍과 문장 맥락을 활용하세요

버전 13.6부터 콜백은 useNanoseconds()를 재정의하여 나노초 타이밍을 사용하도록 설정할 수 있습니다. 콜백은 또한 문장 수준의 이벤트를 애플리케이션 getCurrentUserSql()getCurrentStatementType() 이 제출한 SQL 텍스트와 실행된 문장 유형과 연관시키는 데 사용할 수 있습니다. getCurrentStatementType()은 STATEMENT, PREPARED_STATEMENT 또는 CALLABLE_STATEMENT를 반환합니다. getCurrentApplicationName() 연결 속성을 사용하여 이벤트를 생성한 연결 또는 풀을 식별하려면 applicationName를 사용하세요. applicationName 설정이 안 되면 메서드는 드라이버의 기본 애플리케이션 이름을 반환합니다.

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

나노초 타이밍은 선택적으로 결정됩니다. 오버라이드 useNanoseconds() 되지 않는 콜백은 계속 밀리초 단위로 지속 시간을 받습니다. 등록된 콜백이 옵트인할 때, 전용 성능 로거 출력도 나노초 단위를 사용하며 지속 시간을 ns다음과 같이 표시합니다; 그렇지 않으면 밀리초 및 ms를 사용합니다. 일부 플랫폼에서는 System.nanoTime() 호출이 System.currentTimeMillis()보다 오버헤드가 더 클 수 있습니다.

콜백 컨텍스트는 해당 publish() 호출 시에만 제공됩니다. getCurrentApplicationName()는 연결 수준 및 문 수준 이벤트에 사용할 수 있으며, null 외부에서는 publish()을 반환합니다. 또한 연결 속성이 파싱되지 않은 경우, 예를 들어 애플리케이션 이름이 해결되기 전에 연결이 실패할 때도 반환 null 할 수 있습니다. SQL 컨텍스트 메서드는 연결 수준 이벤트, SQL 컨텍스트가 없는 문 하위 활동 메트릭, 그리고 publish() 외부에서 이루어진 호출에 대해 null를 반환합니다.

Caution

SQL 텍스트는 리터럴이나 주석으로 민감한 데이터를 포함할 수 있습니다. 로그나 텔레메트리에 기록하기 전에 데이터를 정제하고 조직의 데이터 처리 요구사항을 적용하세요.

옵션 2: Java 로깅 구성

java.util.logging의 성능 메트릭 로거를 FINE 수준으로 구성합니다.

logging.properties 파일에서:

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

또는 프로그래밍 방식으로 다음을 수행합니다.

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

명령문 활동에 대한 메서드 효과 준비

PreparedStatement의 추적되는 활동은 prepareMethod 연결 속성에 따라 달라집니다. 자세한 prepareMethod내용은 연결 속성 설정을 참조하세요.

prepareMethod 설정 첫 번째 실행 두 번째 실행 세 번째+ 실행
prepexec(기본값) 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) STATEMENT_EXECUTE (직접 SQL) STATEMENT_EXECUTE (직접 SQL)

메모

기본 prepexec 설정을 사용하면 드라이버가 단일 사용을 가정하여 준비를 연기합니다. 두 번째 실행은 (결합된 준비 및 실행)을 사용합니다 sp_prepexec . 세 번째 실행 이후부터 캐시된 핸들은 .를 통해 sp_execute다시 사용됩니다. 첫 번째 호출을 강제로 sp_prepexec 실행하려면 연결 속성을 enablePrepareOnFirstPreparedStatementCalltrue.로 설정합니다.

샘플 로그 출력

다음 출력은 기본 PreparedStatement 설정을 사용하여 세 번의 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