BigQuery에 수집된 데이터 액세스 감사 로그에서 자주 사용되는 쿼리 5개

나는 주식회사에서 데이터를 전송하는 엔지니어인 태전이다.
BigQuery Advent Calendar 2021 15일째 보도다.
https://qiita.com/advent-calendar/2021/bigquery
당초'VPC Service Controls 및 BigQuery'라는 주제로 기사를 썼으나 내용에 오류가 있어 주제를 변경해 보내드립니다.
나는 먼저 내용을 정리한 다음에 당초 주제의 보도를 따로 공개하고 싶다.
갑자기 주제를 변경해서 아주 얇은 내용으로 바뀌었으니 advent 달력 보도로 공개가 늦어진 것을 용서해 주십시오🙏
그럼 이번에는 제가 빅큐리의 감사 로그를 읽을 때 자주 사용하는 조회를 소개하고 싶습니다.
개인적으로는 최근 몇 년 동안 분석실 겸 데이터 엔지니어에서 데이터 엔지니어 전공으로 바뀌면서 조회할 기회가 줄어들었다.
올해 가장 많은 분들의 보살핌을 받은 표는 조직적으로 동기화된 데이터 방문 감사 일지표입니다. 감사한 마음으로 기사에 남기고 싶습니다.

전제 조건

  • 조직 산하의 모든 BigQuery를 사용하는 프로젝트에서 수집된 데이터 액세스 감사 로그
  • 수집된 감사 로그를 특정 프로젝트의 BigQuery에 기록
  • BigQuery의 숙박 방법에 대해 설명하지 않음
  • BigQuery audit logs overview #Cloud Logging exports
  • 당사는 Terraform을 통해 GCP 프로젝트(조직)를 관리하고 프로젝트를 시작할 때부터 BigQuery를 포함한 모든 서비스에서 감사 로그를 수집했습니다.
    resource "google_project_iam_audit_config" "default" {
      project = google_project.project.project_id
      service = "allServices"
      audit_log_config {
        log_type = "DATA_READ"
      }
      audit_log_config {
        log_type = "DATA_WRITE"
      }
      audit_log_config {
        log_type = "ADMIN_READ"
      }
    }
    

    일반 질의


    1. 특정 표를 인용한 조회 목록 가져오기


    #standardSQL
    SELECT
      protopayload_auditlog.authenticationInfo.principalEmail,
      timestamp,
      protopayload_auditlog.servicedata_v1_bigquery.jobGetQueryResultsResponse.job.jobConfiguration.query.query,
    FROM
      `audit_sink_project.cloud_audit_logs.cloudaudit_googleapis_com_data_access_202111*`,
      UNNEST(protopayload_auditlog.servicedata_v1_bigquery.jobGetQueryResultsResponse.job.jobStatistics.referencedTables) AS t
    WHERE
      1 = 1
      AND t.projectId = "project"
      AND t.datasetId = "dataset"
      AND t.tableId = "table"
    
    protopayload_auditlog.servicedata_v1_bigquery.jobGetQueryResultsResponse.job.jobStatistics.referencedViews로도 참고할 수 있는 보기입니다.

    2. 자주 사용하는 데이터 세트 목록 가져오기


    #standardSQL
    SELECT
      REGEXP_EXTRACT(protopayload_auditlog.resourceName, '^projects/[^/]+/datasets/([^/]+)/tables') AS dataset_ref,
      COUNT(DISTINCT REGEXP_EXTRACT(protopayload_auditlog.resourceName, '^projects/[^/]+/datasets/[^/]+/tables/(.*)$')) AS active_tables,
      COUNTIF(JSON_EXTRACT(protopayload_auditlog.metadataJson, "$.tableDataRead") IS NOT NULL) AS read_events,
      COUNTIF(JSON_EXTRACT(protopayload_auditlog.metadataJson, "$.tableDataChange") IS NOT NULL) AS change_events,
    FROM
      `audit_sink_project.cloud_audit_logs.cloudaudit_googleapis_com_data_access_202111*`
    WHERE
      1 = 1
      AND (
        JSON_EXTRACT(protopayload_auditlog.metadataJson, "$.tableDataRead") IS NOT NULL
        OR JSON_EXTRACT(protopayload_auditlog.metadataJson, "$.tableDataChange") IS NOT NULL
      )
    GROUP BY
      dataset_ref
    ORDER BY
      read_events DESC
    

    3. 각 테이블의 최종 방문(참고) 시간 얻기


    #standardSQL
    SELECT
      protopayload_auditlog.authenticationInfo.principalEmail,
      REGEXP_EXTRACT(protopayload_auditlog.resourceName, '^projects/[^/]+/datasets/([^/]+)/tables') AS dataset_ref,
      SPLIT(REGEXP_EXTRACT(protopayload_auditlog.resourceName, '^projects/[^/]+/datasets/[^/]+/tables/(.*)$'), '$')[OFFSET(0)] AS table_ref,
      MAX(timestamp) AS last_accessed_at,
    FROM
      `audit_sink_project.cloud_audit_logs.cloudaudit_googleapis_com_data_access_202111*`
    WHERE
      1 = 1
      AND JSON_EXTRACT(protopayload_auditlog.metadataJson, "$.tableDataRead") IS NOT NULL
    GROUP BY
      principalEmail, dataset_ref, table_ref
    ORDER BY
      last_accessed_at DESC
    

    4. 매달 사용자별 조회 원가 확인


    #standardSQL
    SELECT
      TIMESTAMP_TRUNC(TIMESTAMP(JSON_EXTRACT_SCALAR(protopayload_auditlog.metadataJson, "$.jobChange.job.jobStats.endTime")), MONTH) AS month,
      protopayload_auditlog.authenticationInfo.principalEmail,
      5.0 * (SUM(CAST(JSON_EXTRACT_SCALAR(protopayload_auditlog.metadataJson, "$.jobChange.job.jobStats.queryStats.totalBilledBytes") AS INT64)) / POWER(2, 40)) AS USD
    FROM
      `audit_sink_project.cloud_audit_logs.cloudaudit_googleapis_com_data_access_202112*`
    WHERE
      1 = 1
      AND JSON_EXTRACT_SCALAR(protopayload_auditlog.metadataJson, "$.jobChange.job.jobConfig.type") = "QUERY"
    GROUP BY
      month,
      principalEmail
    ORDER BY
      USD DESC
    

    5. 오류 발생 쿼리 확인


    SELECT
      protopayload_auditlog.authenticationInfo.principalEmail,
      resource.labels.project_id,
      timestamp,
      protopayload_auditlog.servicedata_v1_bigquery.jobCompletedEvent.job.jobConfiguration.query.query,
      protopayload_auditlog.servicedata_v1_bigquery.jobCompletedEvent.job.jobStatus.error.message,
    FROM
      `audit_sink_project.cloud_audit_logs.cloudaudit_googleapis_com_data_access_202112*`
    WHERE
      1 = 1
      AND protopayload_auditlog.methodName = 'jobservice.jobcompleted'
      AND severity = "ERROR"
    ORDER BY
      timestamp DESC
    


    정부BigQuery Audit Log Dashboard 추천.

    좋은 웹페이지 즐겨찾기