GCP

Agent Platform Model Monitoring Dashboard 구축 – Cloud Monitoring으로 여러 프로젝트의 Gemini 트래픽, 이상치, 에러, Batch 작업까지 한 화면에서 보기

안녕하세요. GS Neotek 김민형 입니다.
Vertex AI(Agent Platform)에서 지원되는 Gemini 같은 모델을 여러 프로젝트에서 쓰다 보면, 사용량과 성능, 안정성을 한 곳에서 보고 싶어집니다.
이번 글에서는 Cloud Monitoring 커스텀 대시보드로 모델별, 프로젝트별 트래픽부터 누적 사용량, 사용량 이상치, 에러와 지연, Batch 작업까지 쉽게 모니터링할 수 있는 대시보드를 구축하는 방법을 소개합니다.
글에 나오는 설정값과 쿼리는 실제로 운영 중인 대시보드 JSON에서 가져온 것이라 그대로 적용해 보실 수 있습니다.

한눈에 보기

항목내용
대상 환경여러 GCP 프로젝트에서 Vertex AI(Agent Platform) 기반 Gemini를 호출하는 환경
사용하는 도구1. Cloud Monitoring 커스텀 대시보드(JSON 편집)
2. Monitoring 필터 기반 쿼리
3. PromQL
4. 로그 기반 메트릭
핵심 메트릭1. publisher/online_serving/model_invocation_count
2. publisher/online_serving/token_count
3. publisher/online_serving/model_invocation_latencies
4. 감사 로그로 만든 Batch Job 생성 건수
대시보드 구성1. 트래픽 현황
2. 누적 사용량
3. 사용량 이상치 감지
4. 에러/지연
5. Batch 작업 모니터링
상단 필터model_user_id, location, resource_container(프로젝트 ID)

대시보드가 답해야 하는 질문

위젯을 배치하기 전에, 운영하면서 자주 묻게 되는 질문을 먼저 정리하는 것을 권장드립니다.
대시보드는 아래 다섯 가지에 바로 답할 수 있어야 합니다.

  • 프로젝트가 여러 개일 때, 프로젝트별로 나눠 보면서도 전체를 한 번에 볼 수 있는가
  • “지난주 피크 QPS가 얼마였나”처럼 평균과 피크를 숫자로 바로 읽을 수 있는가
  • 특정 모델의 호출량이 갑자기 튀는 것을 사람이 차트를 지켜보지 않아도 알 수 있는가
  • 장애가 났을 때 5XX 비율과 429 비율을 모델별로 보고 SLA 보상 요청 여부를 판단할 근거가 있는가
  • 온라인 호출 메트릭에 잡히지 않는 Batch Prediction이 얼마나 돌고 있는지 볼 수 있는가

전체 구조

먼저 모니터링 전용 프로젝트를 하나 두고, Gemini를 쓰는 프로젝트들을 그 프로젝트의 Metrics Scope에 묶습니다.
이렇게 하면 대시보드 하나에서 모든 프로젝트의 메트릭이 보이고, 메트릭의 resource_container 값이 곧 프로젝트 ID가 됩니다.
대시보드 상단에는 리소스 라벨 필터 세 개를 둡니다.

"dashboardFilters": [
  { "filterType": "RESOURCE_LABEL", "labelKey": "model_user_id", "valueType": "STRING" },
  { "filterType": "RESOURCE_LABEL", "labelKey": "location", "valueType": "STRING" },
  { "filterType": "RESOURCE_LABEL", "labelKey": "resource_container", "valueType": "STRING" }
]
JSON

필터를 비워 두면 전체 프로젝트가 각각 표시되고, resource_container에 프로젝트 ID를 넣으면 그 프로젝트만 보입니다.
위젯은 다섯 개의 collapsibleGroup으로 묶고, 맨 위에는 Markdown 텍스트 위젯으로 사용 안내를 넣습니다.
조회 기간 선택기를 바꾸면 모든 차트와 테이블이 그 기간 기준으로 다시 계산되므로, 같은 대시보드를 일간 리포트와 주간 리포트에 그대로 쓸 수 있습니다.

Vertex AI가 기본으로 제공하는 대시보드는 모든 값을 /s 같은 비율 단위로만 보여 주기 때문에, 총량이나 평균을 보려면 대시보드 JSON을 직접 고쳐야 합니다.
위젯을 만들 때 공통으로 쓰는 설정은 세 가지입니다.
Vertex AI의 호출 수와 토큰 메트릭은 구간 변화량(DELTA) 종류라서, perSeriesAligner를 ALIGN_RATE로 두면 초당 값이 나오고 ALIGN_DELTA로 두면 정렬 구간의 합계가 나옵니다.
outputFullDuration을 true로 두면 조회 기간 전체가 하나의 구간이 되어 기간 총합이나 평균이 숫자 하나로 나옵니다.
unitOverride를 “1”로 두면 자동으로 붙는 /s 단위 없이 숫자만 표시됩니다.

1. 트래픽 현황 (QPS/TPS, 평균/피크)

첫 번째 그룹은 평상시 상시 모니터링용입니다.
프로젝트별 QPS는 model_invocation_count를, TPS는 token_count를 60초 단위 ALIGN_RATE로 정렬하고 project_id로 묶어 합산한 라인 차트입니다.

프로젝트별 QPS와 TPS 라인 차트, 그리고 프로젝트별 평균 QPS와 피크 QPS 테이블

이 그룹의 핵심은 평균과 피크 테이블입니다.
1차 집계로 1분 단위 초당 값을 만들고, secondaryAggregation에서 ALIGN_MEAN 또는 ALIGN_MAX를 적용한 뒤 outputFullDuration을 true로 두면 조회 기간 전체의 평균 또는 피크가 한 숫자로 나옵니다.
아래는 피크 QPS 테이블의 쿼리 부분입니다.

"timeSeriesQuery": {
  "outputFullDuration": true,
  "timeSeriesFilter": {
    "filter": "metric.type=\"aiplatform.googleapis.com/publisher/online_serving/model_invocation_count\" resource.type=\"aiplatform.googleapis.com/PublisherModel\"",
    "aggregation": {
      "alignmentPeriod": "60s",
      "perSeriesAligner": "ALIGN_RATE",
      "crossSeriesReducer": "REDUCE_SUM",
      "groupByFields": ["resource.label.\"project_id\""]
    },
    "secondaryAggregation": {
      "alignmentPeriod": "86400s",
      "perSeriesAligner": "ALIGN_MAX"
    }
  },
  "unitOverride": "1"
}
JSON

평균 테이블은 ALIGN_MAX 자리만 ALIGN_MEAN으로 바꾸면 됩니다.
조회 기간을 1주일로 바꾸면 “그 주의 프로젝트별 평균 QPS와 피크 QPS”가 바로 표로 나오니, 주간 리포트에 숫자를 옮겨 적기만 하면 됩니다.

프로젝트별 평균 TPS와 피크 TPS 테이블, 모델별 QPS와 TPM 라인 차트

모델 축에서는 QPS 외에 TPM(Tokens Per Minute)과 RPM(Requests Per Minute)을 같이 둡니다.
Gemini 쿼터가 분당 단위로 정해지기 때문에, 분당 값은 ALIGN_DELTA 60초로 만들면 쿼터와 바로 비교할 수 있습니다.
모델 수가 많아 차트가 읽기 어려워지지 않도록 pickTimeSeriesFilter로 평균 기준 상위 30개 시계열만 그리는 것을 권장드립니다.

2. 누적 사용량

두 번째 그룹은 일간, 주간 사용량 리포트용입니다.
총 호출 횟수와 총 토큰 테이블을 두되, 호출 횟수는 모델과 location으로, 토큰은 모델과 type 라벨로 나눕니다.
alignmentPeriod를 86400초로 두고 ALIGN_DELTA에 outputFullDuration을 true로 하면 선택 기간의 총합이 한 줄로 나옵니다.

모델별 RPM 라인 차트와 누적 사용량 그룹의 총 호출 횟수, 총 토큰 사용량 테이블

token_count의 type 라벨에는 input, output 외에 cache_read_input, cache_write_input도 있어서, 캐시 토큰을 따로 보면 컨텍스트 캐싱이 실제로 얼마나 쓰이고 있는지 확인할 수 있습니다.

3. 사용량 이상치 감지

세 번째 그룹은 하루에 한두 번 점검하는 용도이며, 여기서부터는 PromQL을 씁니다.
“직전 3시간 평균 + 3σ” 같은 통계 계산은 Monitoring 필터 방식으로 표현하기 번거롭지만, Cloud Monitoring 대시보드가 PromQL을 지원하므로 쿼리 하나로 끝낼 수 있습니다.
첫 번째 위젯은 전체 토큰 사용량의 실제 TPS와 정상 상한선을 겹쳐 그립니다.

# 실제 TPS (전체)
sum(rate(aiplatform_googleapis_com:publisher_online_serving_token_count{monitored_resource="aiplatform.googleapis.com/PublisherModel"}[5m]))

# 정상 상한선 (3h 평균 + 3σ)
avg_over_time(sum(rate(aiplatform_googleapis_com:publisher_online_serving_token_count{monitored_resource="aiplatform.googleapis.com/PublisherModel"}[5m]))[3h:10m])
+ 3 * stddev_over_time(sum(rate(aiplatform_googleapis_com:publisher_online_serving_token_count{monitored_resource="aiplatform.googleapis.com/PublisherModel"}[5m]))[3h:10m])
Bash

실제 TPS 선이 상한선을 넘으면 평소 패턴에서 벗어난 것입니다.
범례에 쿼리 대신 이름이 보이게 하려면 label_replace로 name 라벨을 붙입니다.
두 번째 위젯은 모델별 토큰 급증 배율입니다.

# 모델별 토큰 급증 배율 (최근 5분 / 직전 1시간)
sum by (model_user_id) (rate(aiplatform_googleapis_com:publisher_online_serving_token_count{monitored_resource="aiplatform.googleapis.com/PublisherModel"}[5m]))
/ clamp_min(sum by (model_user_id) (rate(aiplatform_googleapis_com:publisher_online_serving_token_count{monitored_resource="aiplatform.googleapis.com/PublisherModel"}[1h])), 1)
Bash

최근 5분 사용량을 직전 1시간 평균으로 나눈 값이라 평소와 같으면 1 근처에 머물고, 갑자기 늘면 배율이 튑니다.
분모가 0이 되지 않도록 clamp_min으로 최솟값을 1로 막고, 위젯 thresholds에 3배 기준선을 그려 둡니다.

전체 토큰 사용량 이상치 차트와 모델별 토큰 급증 배율 차트, 그 아래 에러 발생 추이와 모델별 5XX 에러 총 건수

이상치는 사고가 아니라 “확인할 가치가 있는 변화”로 보는 것을 권장드립니다.
신규 배포나 이벤트로 인한 정상적인 급증도 똑같이 잡히므로, 기준선을 넘었다고 바로 장애로 보지 않고 원인을 확인하는 신호로 씁니다.

4. 에러/지연

네 번째 그룹은 장애 대응과 SLA 판단용입니다.
에러 발생 추이는 response_code 라벨이 2XX가 아닌 호출만 모델과 응답 코드별로 쌓은 막대 차트이고, 5XX 총 건수 테이블은 5XX만 모델별로 합산한 것입니다.
비율 위젯은 timeSeriesFilterRatio로 분자와 분모를 따로 정의합니다.

"timeSeriesFilterRatio": {
  "numerator": {
    "filter": "metric.type=\"aiplatform.googleapis.com/publisher/online_serving/model_invocation_count\" resource.type=\"aiplatform.googleapis.com/PublisherModel\" metric.label.\"response_code\"=monitoring.regex.full_match(\"5[0-9][0-9]\")",
    "aggregation": { "alignmentPeriod": "60s", "perSeriesAligner": "ALIGN_DELTA", "crossSeriesReducer": "REDUCE_SUM", "groupByFields": ["resource.label.\"model_user_id\""] }
  },
  "denominator": {
    "filter": "metric.type=\"aiplatform.googleapis.com/publisher/online_serving/model_invocation_count\" resource.type=\"aiplatform.googleapis.com/PublisherModel\"",
    "aggregation": { "alignmentPeriod": "60s", "perSeriesAligner": "ALIGN_DELTA", "crossSeriesReducer": "REDUCE_SUM", "groupByFields": ["resource.label.\"model_user_id\""] }
  }
}
JSON

같은 구조에서 분자 필터만 response_code=”429″로 바꾸면 Throttle Error Rate가 됩니다.
5XX는 서비스 쪽 문제, 429는 쿼터 초과라서 성격이 다르기 때문에 두 비율을 따로 두고, 기간 평균 테이블도 각각 붙이는 것을 권장드립니다.

모델별 Server Error Rate와 Throttle Error Rate 차트, 기간 평균 테이블, 모델별 호출 Latency p50 p99 차트

Latency는 model_invocation_latencies가 DISTRIBUTION 타입이라 crossSeriesReducer를 REDUCE_PERCENTILE_50과 REDUCE_PERCENTILE_99로 두 번 그려 p50과 p99를 한 차트에 겹칩니다.
장애 시에는 이 그룹에서 5XX 비율이 얼마나 오래, 어느 모델에서 올라갔는지 보고 SLA 보상 요청 여부를 판단합니다.

5. Batch 작업 모니터링

Batch Prediction은 온라인 호출이 아니라서 online_serving 메트릭에 토큰과 호출 수가 잡히지 않습니다.
대신 Batch Prediction Job을 만들 때 Admin Activity 감사 로그에 batchPredictionJobs.create 항목이 남고, 이 로그는 기본으로 켜져 있어 따로 설정할 것이 없습니다.
그래서 감사 로그를 로그 기반 카운터 메트릭으로 만들고 model 라벨을 추출해 대시보드에 올립니다.
아래는 로그 기반 메트릭을 만들 때 쓰는 필터의 예시이며, 실제 methodName 값과 라벨 추출 경로는 환경의 로그 탐색기에서 확인한 값을 쓰시면 됩니다.

# 예시: Batch Prediction Job 생성 감사 로그만 고르는 필터
resource.type="audited_resource"
protoPayload.serviceName="aiplatform.googleapis.com"
protoPayload.methodName=~"CreateBatchPredictionJob"
Bash

대시보드에서는 이 메트릭을 logging.googleapis.com/user/vertex_batch_job_created 라는 이름으로 불러 프로젝트별, 모델별 생성 추이와 총 건수를 그립니다.
작업을 청크 단위로 나눠 제출하는 구조라면 생성 건수가 처리량의 대리 지표가 되므로, 대량 생성 시에는 알림 정책으로 메일을 받도록 설정하는 것을 권장드립니다.

프로젝트별, 모델별 Batch Job 생성 추이 막대 차트와 총 건수 테이블

정확한 비용은 Billing에서 확인해야 하고, Billing은 실시간 집계가 아니라 사용 발생 후 반영되므로 사후 확인 용도로만 씁니다.

대시보드 맨 위에 적어 두면 좋은 사용 규칙

위젯이 많아지면 보는 사람마다 해석이 달라지기 쉬우므로, 맨 위 텍스트 위젯에 아래와 같은 사용 규칙을 적는 것을 권장드립니다.

그룹언제 보는가
1. 트래픽 현황평상시 상시 모니터링
2. 누적 사용량일간, 주간 사용량 리포트를 만들 때
3. 사용량 이상치 감지하루 1~2회 점검. 상한선 초과 또는 3배 기준선 초과 시 원인 확인
4. 에러/지연장애, 응답 이상 대응과 SLA 판단 시
5. Batch 작업 모니터링Batch Job 생성 추이 점검

3번과 5번 그룹은 각각 PromQL과 로그 기반 메트릭 특성상 상단 프로젝트 필터가 적용되지 않는다는 점도 같이 적어 둡니다.

이 구성의 장점

  • 1. 설정 몇 가지로 평균, 피크, 총합 테이블을 모두 만들 수 있습니다.
    perSeriesAligner, secondaryAggregation, outputFullDuration 세 가지 조합만으로 리포트에 필요한 숫자가 대시보드에서 바로 나옵니다.
  • 2. 통계 기반 이상치 감지를 별도 시스템 없이 대시보드 안에서 끝낼 수 있습니다.
    PromQL의 avg_over_time과 stddev_over_time, 그리고 rate 비율만으로 상한선과 급증 배율을 그릴 수 있습니다.
  • 3. 메트릭이 없는 Batch 작업도 같은 화면에 올릴 수 있습니다.
    기본으로 켜져 있는 감사 로그를 로그 기반 메트릭으로 바꾸는 것만으로 충분합니다.
  • 4. 사용 안내를 대시보드 안에 넣어 두면 대시보드만 열어도 보는 법을 알 수 있습니다.
    텍스트 위젯이 Markdown을 지원해서 표와 목록으로 규칙을 정리할 수 있습니다.

주의할 점

  • 1. PromQL 위젯과 로그 기반 위젯에는 상단 프로젝트 필터가 적용되지 않습니다.
    그룹 안의 위젯을 프로젝트별로 나눠 그리는 것으로 보완할 수 있지만, 필터 하나로 전체가 같이 움직이지는 않는다는 점을 사용자에게 안내해야 합니다.
  • 2. Batch Prediction은 실시간 토큰, 호출 메트릭이 없습니다.
    생성 건수는 대리 지표일 뿐이므로, 정확한 사용량과 비용은 Billing에서 사후에 확인해야 합니다.
  • 3. 차트는 시계열 상위 30개까지만 그리도록 제한하는 것이 좋습니다.
    모델과 프로젝트 조합이 그보다 많아지면 차트에서는 빠지므로, 전체 목록은 테이블에서 확인하도록 안내합니다.
  • 4. 이상치 기준값은 환경에 맞춰 조정해야 합니다.
    3시간 창과 3σ, 3배 기준선은 출발점일 뿐이며, 워크로드의 트래픽 패턴에 따라 값을 조정하는 것을 권장드립니다.

마무리

대시보드 JSON을 직접 다루면 Cloud Monitoring만으로도 여러 프로젝트의 Gemini 트래픽, 이상치, 에러, Batch 작업을 운영 기준에 맞춰 한 화면에서 볼 수 있습니다.
기본 대시보드를 그대로 쓰고 계시다면 평균, 피크 테이블과 이상치 감지 그룹부터 추가해 보시는 것을 권장드립니다.
더 좋은 구성 아이디어나 질문이 있으면 댓글로 남겨 주세요.

5/5 - (평가 개수 : 1)

궁금한 점이 있으신가요?

자세한 문의는 GS Neotek 홈페이지를 이용해 주세요.

문의하기

필자: 민형 김

전체 게시물수 : 2

전체 조회수 : 28

게시물 공유하기