프로파일 및 모니터링

프로파일 및 모니터링 (Profile and Monitor, Go)

개요 (Overview)

Go 클라이언트는 쿼리 실행을 관찰할 수 있어요. 쿼리 실행 후 연산자별 프로파일링 메트릭을 검색할 수 있고, DuckDB의 로그 메시지를 받는 로그 저장소를 등록할 수 있어요. 둘 다 아래에 설명해요.

출처: 문서

본문

프로파일링 (Profiling)

프로파일링 정보는 연결-로컬이므로 db.Conn()으로 체크아웃한 *sql.Conn에서 읽어요. [enable_profilingprofiling_mode PRAGMA]({% link docs/current/dev/profiling.md %})로 그 연결에서 프로파일링을 활성화하고, 프로파일링할 쿼리를 실행한 다음, duckdb.GetProfilingInfo()로 결과를 읽어요:

db, err := sql.Open("duckdb", "")
check(err)
defer db.Close()

conn, err := db.Conn(context.Background())
check(err)
defer conn.Close()

// 각 쿼리 후 프로파일링 출력을 stdout으로 출력하지 않도록 함.
_, err = conn.ExecContext(context.Background(), `PRAGMA enable_profiling = 'no_output'`)
check(err)
// 각 연산자에 대한 포괄적인 메트릭 집합을 수집.
_, err = conn.ExecContext(context.Background(), `PRAGMA profiling_mode = 'detailed'`)
check(err)

// 프로파일링할 쿼리 실행.
res, err := conn.QueryContext(context.Background(), `SELECT 42`)
check(err)
res.Close()

// 그 쿼리에 대해 수집된 메트릭 검색.
info, err := duckdb.GetProfilingInfo(conn)
check(err)

// 선택적으로, 다시 프로파일링 끄기.
_, err = conn.ExecContext(context.Background(), `PRAGMA disable_profiling`)
check(err)

GetProfilingInfo()는 DuckDB의 쿼리 플랜을 그대로 반영한 트리인 duckdb.ProfilingInfo를 반환해요. 각 노드는 메트릭 이름을 값으로 매핑하는 Metrics 맵과 자식 노드의 Children 슬라이스를 가져요. 루트 노드(QUERY_ROOT)는 전체 쿼리에 걸쳐 측정된 메트릭을 보유하고, 각 하위는 자체 메트릭을 가진 플랜 연산자예요. 트리를 순회해 읽어요:

log.Printf("query latency: %s", info.Metrics["LATENCY"])
for _, child := range info.Children {
    log.Printf("operator: %s", child.Metrics["OPERATOR_NAME"])
}

수집되는 메트릭은 연결에 설정된 profiling_mode에 따라 달라져요. 사용 가능한 모드와 메트릭 이름은 [Profiling 페이지]({% link docs/current/dev/profiling.md %})를 참고해요.

로그 저장소 (Log Storage)

DuckDB는 [로그 메시지]({% link docs/current/operations_manual/logging/overview.md %})를 Go에서 등록한 커스텀 저장소로 전달할 수 있어요. duckdb.RegisterLogStorage()Connector에 등록하고, 이름과 각 항목의 레벨, 타입, 메시지를 받는 DefaultLoggerCallback을 가진 duckdb.LoggerCallbacks를 전달해요:

connector, err := duckdb.NewConnector("", nil)
check(err)
defer connector.Close()

err = duckdb.RegisterLogStorage(connector, "my_log_storage", duckdb.LoggerCallbacks{
    DefaultLoggerCallback: func(level, logType, logMsg string) {
        log.Printf("[%s] %s: %s", level, logType, logMsg)
    },
})
check(err)

// 로깅을 활성화한 다음, 등록된 저장소를 가리키도록 함.
db := sql.OpenDB(connector)
_, err = db.Exec(`CALL enable_logging(level = 'info')`)
check(err)
_, err = db.Exec(`SET logging_storage = 'my_log_storage'`)
check(err)

로깅은 기본적으로 꺼져 있으므로 SET logging_storage로 저장소를 선택하는 것 외에도 CALL enable_logging()으로 활성화해야 해요. 둘 다 설정되면 DuckDB는 모든 로그 호출을 콜백으로 전달해요.

더 알아보기 (Learn more)

  • [Profiling]({% link docs/current/dev/profiling.md %}) — DuckDB의 쿼리 프로파일링 출력과 enable_profilingprofiling_mode PRAGMA.
  • [Logging]({% link docs/current/operations_manual/logging/overview.md %}) — enable_logging으로 로깅 활성화하고 duckdb_logs로 로그 항목 쿼리하기.
  • [Run Queries]({% link docs/current/clients/go/querying.md %}) — 이 페이지가 메트릭을 읽는 쿼리 실행하기.
  • [Connect]({% link docs/current/clients/go/connecting.md %}) — 프로파일링이 동작하는 연결 체크아웃과 로그 저장소가 등록되는 커넥터.