모니터링 & Observability 구성 가이드
이 문서는 Prometheus → AMP, AMG, Langfuse, Bifrost OTel 통합 모니터링의 실전 배포 절차를 다룹니다. 아키텍처 개념과 설계 원칙은 Agent 모니터링 및 LLMOps Observability를 참조하세요.
모니터링 아키텍처 개요
데이터 흐름 요약:
| 데이터 | 경로 | 용도 |
|---|---|---|
| 인프라 메트릭 | vLLM/DCGM/kgateway → Prometheus → AMP → AMG | GPU 활용도, TPS, 지연시간, 에러율 |
| LLM Trace | Bifrost → OTel → Langfuse | 토큰 사용량, 비용, 프롬프트 품질 |
| 게이트웨이 메트릭 | kgateway → Prometheus → AMP | 요청 수, 5xx 에러, 업스트림 상태 |
Prometheus + AMP 구성
2.1 AMP 워크스페이스 생성
# AMP 워크스페이스 생성
aws amp create-workspace \
--alias "vllm-inference-metrics" \
--region ap-northeast-2
# 워크스페이스 ID 확인
export AMP_WORKSPACE_ID=$(aws amp list-workspaces \
--region ap-northeast-2 \
--query 'workspaces[?alias==`vllm-inference-metrics`].workspaceId' \
--output text)
echo "AMP Workspace ID: $AMP_WORKSPACE_ID"
2.2 IAM Role 생성 (Pod Identity용)
# IAM Role 생성
aws iam create-role \
--role-name prometheus-amp-remote-write \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "pods.eks.amazonaws.com"},
"Action": ["sts:AssumeRole", "sts:TagSession"]
}]
}'
# AMP RemoteWrite 권한 부여
aws iam attach-role-policy \
--role-name prometheus-amp-remote-write \
--policy-arn arn:aws:iam::aws:policy/AmazonPrometheusRemoteWriteAccess
2.3 Pod Identity Association 생성
aws eks create-pod-identity-association \
--cluster-name <CLUSTER_NAME> \
--namespace monitoring \
--service-account prometheus-kube-prometheus-prometheus \
--role-arn arn:aws:iam::<ACCOUNT_ID>:role/prometheus-amp-remote-write
위 명령은 앞 단계에서 준비한 IAM Role과 클러스터·namespace·ServiceAccount 사이의 연결을 등록합니다. Pod Identity는 IRSA용 OIDC Provider 설정을 사용하지 않지만, IAM Role의 신뢰 정책과 권한 정책은 준비해야 합니다. 실제 Pod가 자격 증명을 받으려면 노드의 Pod Identity 지원, EKS Auth 접근, 애플리케이션의 지원 SDK와 기본 자격 증명 체인도 확인해야 합니다(설정 조건). 이 문서의 EKS 1.33+는 예시 환경이며, 적용할 클러스터의 지원 조건은 별도로 확인합니다.
2.4 Prometheus Helm values 핵심 설정
# values-eks.yaml
prometheus:
prometheusSpec:
remoteWrite:
- url: "https://aps-workspaces.ap-northeast-2.amazonaws.com/workspaces/${AMP_WORKSPACE_ID}/api/v1/remote_write"
queueConfig:
maxSamplesPerSend: 1000
maxShards: 200
capacity: 2500
sigv4:
region: ap-northeast-2
serviceMonitorSelector: {}
serviceMonitorNamespaceSelector: {}
serviceAccount:
name: prometheus-kube-prometheus-prometheus
# Pod Identity 사용 시 annotations 불필요 (IRSA와 달리)
# scrape 대상
additionalScrapeConfigs:
# vLLM 메트릭
- job_name: 'vllm'
kubernetes_sd_configs:
- role: pod
namespaces:
names: [ai-inference]
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_app]
regex: vllm
action: keep
metrics_path: /metrics
# DCGM Exporter (GPU 메트릭)
- job_name: 'dcgm-exporter'
kubernetes_sd_configs:
- role: pod
namespaces:
names: [monitoring]
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_app]
regex: dcgm-exporter
action: keep
# kgateway 메트릭
- job_name: 'kgateway'
kubernetes_sd_configs:
- role: pod
namespaces:
names: [kgateway-system]
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_app]
regex: kgateway
action: keep
metrics_path: /metrics
2.5 Prometheus Helm 설치
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install prometheus prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace \
-f values-eks.yaml
AMG (Grafana) 구성
3.1 AMG 워크스페이스 생성
aws grafana create-workspace \
--account-access-type CURRENT_ACCOUNT \
--authentication-providers AWS_SSO \
--permission-type SERVICE_MANAGED \
--workspace-name "vllm-monitoring" \
--region ap-northeast-2
export AMG_WORKSPACE_ID=$(aws grafana list-workspaces \
--region ap-northeast-2 \
--query 'workspaces[?name==`vllm-monitoring`].id' \
--output text)
3.2 Service Account + Token 생성
AMG API를 통해 데이터 소스를 추가하려면 Service Account Token이 필요합니다.
# Grafana Service Account 생성 (AMG 콘솔 또는 API)
# AMG 웹 콘솔 → Configuration → Service Accounts → Add Service Account
# Role: Admin
# Token 생성 후 저장
export GRAFANA_TOKEN="<생성된 Token>"
export GRAFANA_ENDPOINT="<AMG 워크스페이스 URL>"
3.3 AMP 데이터 소스 추가
curl -X POST "https://${GRAFANA_ENDPOINT}/api/datasources" \
-H "Authorization: Bearer ${GRAFANA_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"name": "Amazon Managed Prometheus",
"type": "prometheus",
"url": "https://aps-workspaces.ap-northeast-2.amazonaws.com/workspaces/'${AMP_WORKSPACE_ID}'/",
"access": "proxy",
"isDefault": true,
"jsonData": {
"httpMethod": "POST",
"sigV4Auth": true,
"sigV4AuthType": "ec2_iam_role",
"sigV4Region": "ap-northeast-2"
}
}'
sigV4AuthType을 반드시 **ec2_iam_role**로 설정하세요. workspace-iam-role은 유효하지 않은 값으로 502 에러를 반환합니다. AMG workspace IAM Role에 AmazonPrometheusQueryAccess 정책이 연결되어 있어야 합니다.
3.4 IAM Identity Center 사용자 권한 부여
aws grafana update-permissions \
--user-id "<IAM Identity Center user-id>" \
--user-type "SSO_USER" \
--permissions-type "ADMIN" \
--workspace-id $AMG_WORKSPACE_ID \
--region ap-northeast-2
Langfuse EKS 배포
4.1 Helm 설치
# Langfuse Helm 저장소 추가
helm repo add langfuse https://langfuse.github.io/langfuse-helm
helm repo update
# 네임스페이스 생성
kubectl create namespace langfuse
# Langfuse Helm 설치 (PostgreSQL + ClickHouse + Redis 포함)
helm install langfuse langfuse/langfuse \
--namespace langfuse \
--set postgresql.enabled=true \
--set postgresql.auth.password="secure-password" \
--set clickhouse.enabled=true \
--set redis.enabled=true \
--set ingress.enabled=false \
--set replicaCount=2
Langfuse의 PostgreSQL과 ClickHouse는 영구 스토리지가 필요합니다.
# EBS CSI Driver 설치 확인
kubectl get csidriver ebs.csi.aws.com
# default StorageClass 확인
kubectl get storageclass
4.2 Redis 패스워드 주입 (Worker CrashLoopBackOff 방지)
Bitnami Valkey 차트는 Secret key를 valkey-password로 생성하지만, Langfuse Helm 차트가 Worker의 REDIS_CONNECTION_STRING에 패스워드를 자동 포함하지 않습니다.
# Redis 패스워드 확인
REDIS_PW=$(kubectl get secret langfuse-redis -n langfuse \
-o jsonpath='{.data.valkey-password}' | base64 -d)
# Web + Worker 모두 주입
kubectl set env deploy/langfuse-worker deploy/langfuse-web -n langfuse \
REDIS_CONNECTION_STRING="redis://default:${REDIS_PW}@langfuse-redis-primary:6379/0"
langfuse-worker Pod가 CrashLoopBackOff 상태라면 Redis 패스워드 누락이 가장 흔한 원인입니다. 위 명령으로 수동 주입하세요.
4.3 MinIO → S3 + KMS 전환 가이드 (권장)
Langfuse Helm 차트는 기본적으로 MinIO를 내장 S3로 설치하지만, 프로덕션에서는 AWS S3 + KMS를 권장합니다.
| MinIO (기본) | AWS S3 + KMS (권장) | |
|---|---|---|
| 가용성 | 단일 Pod | 99.999999999% (11 nines) |
| 암호화 | 없음 | SSE-KMS (자동 암호화) |
| 인증 | Access Key (환경변수) | Pod Identity (키 불필요) |
| 백업 | 수동 | S3 버전 관리 + Lifecycle |
S3 + KMS 구성 절차
# 1. S3 버킷 + KMS 키 생성
aws s3api create-bucket --bucket langfuse-traces-<ACCOUNT_ID> --region <REGION> \
--create-bucket-configuration LocationConstraint=<REGION>
KMS_KEY=$(aws kms create-key --description "Langfuse trace encryption" \
--query 'KeyMetadata.KeyId' --output text)
# 2. S3 기본 암호화 (KMS)
aws s3api put-bucket-encryption --bucket langfuse-traces-<ACCOUNT_ID> \
--server-side-encryption-configuration \
'{"Rules": [{"ApplyServerSideEncryptionByDefault": {"SSEAlgorithm": "aws:kms", "KMSMasterKeyID": "'$KMS_KEY'"}, "BucketKeyEnabled": true}]}'
# 3. IAM Role + Pod Identity (Access Key 불필요)
aws iam create-role --role-name langfuse-s3-access \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "pods.eks.amazonaws.com"},
"Action": ["sts:AssumeRole", "sts:TagSession"]
}]
}'
aws iam put-role-policy --role-name langfuse-s3-access --policy-name s3-kms \
--policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:PutObject", "s3:GetObject", "s3:DeleteObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::langfuse-traces-<ACCOUNT_ID>",
"arn:aws:s3:::langfuse-traces-<ACCOUNT_ID>/*"
]
},
{
"Effect": "Allow",
"Action": ["kms:GenerateDataKey", "kms:Decrypt"],
"Resource": "arn:aws:kms:<REGION>:<ACCOUNT_ID>:key/'$KMS_KEY'"
}
]
}'
aws eks create-pod-identity-association \
--cluster-name <CLUSTER> --namespace langfuse \
--service-account langfuse \
--role-arn arn:aws:iam::<ACCOUNT_ID>:role/langfuse-s3-access
# 4. Langfuse 환경변수 변경 (MinIO 제거 → S3)
kubectl set env deploy/langfuse-web deploy/langfuse-worker -n langfuse \
LANGFUSE_S3_EVENT_UPLOAD_BUCKET="langfuse-traces-<ACCOUNT_ID>" \
LANGFUSE_S3_EVENT_UPLOAD_REGION="<REGION>" \
LANGFUSE_S3_EVENT_UPLOAD_ENDPOINT- \
LANGFUSE_S3_EVENT_UPLOAD_ACCESS_KEY_ID- \
LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY- \
LANGFUSE_S3_EVENT_UPLOAD_FORCE_PATH_STYLE-
MinIO를 사용할 경우, Helm 차트가 S3 Secret Key를 환경변수에 자동 주입하지 않습니다. 누락 시 OTel trace 수신에서 500 에러가 발생합니다.
MINIO_PW=$(kubectl get secret langfuse-s3 -n langfuse \
-o jsonpath='{.data.root-password}' | base64 -d)
kubectl set env deploy/langfuse-web deploy/langfuse-worker -n langfuse \
LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY="$MINIO_PW" \
LANGFUSE_S3_BATCH_EXPORT_SECRET_ACCESS_KEY="$MINIO_PW" \
LANGFUSE_S3_MEDIA_UPLOAD_SECRET_ACCESS_KEY="$MINIO_PW"
4.4 NEXTAUTH_URL 설정
NEXTAUTH_URL을 실제 접근 가능한 URL로 설정해야 합니다. localhost:3000 (기본값)으로 두면 로그인 시 무한 리다이렉트가 발생합니다.
# kgateway sub-path로 접근하는 경우
kubectl set env deploy/langfuse-web -n langfuse \
NEXTAUTH_URL="http://<NLB_ENDPOINT>/langfuse"
# 별도 도메인으로 접근하는 경우
kubectl set env deploy/langfuse-web -n langfuse \
NEXTAUTH_URL="https://langfuse.example.com"
4.5 kgateway Sub-path 라우팅
Langfuse를 kgateway 통합 NLB의 /langfuse 경로로 서빙하는 설정입니다. 상세한 HTTPRoute YAML은 추론 게이트웨이 배포: 기본 배포를 참조하세요.
필요한 라우팅 규칙:
/langfuse/*→ URLRewrite/+ Langfuse 백엔드/_next/*→ Langfuse (Next.js Static Assets)/api/auth/*→ Langfuse (인증 API)/api/public/*→ Langfuse (Public API + OTel)
5. Bifrost OTel → Langfuse 연동
5.1 Bifrost OTel 플러그인 설정
Bifrost config.json의 OTel 플러그인 설정입니다.
{
"plugins": [{
"enabled": true,
"name": "otel",
"config": {
"service_name": "bifrost",
"trace_type": "genai_extension",
"protocol": "http",
"collector_url": "http://langfuse-web.langfuse.svc.cluster.local:3000/api/public/otel/v1/traces",
"headers": {
"Authorization": "Basic <BASE64(public_key:secret_key)>",
"x-langfuse-ingestion-version": "4"
}
}
}]
}
핵심 주의사항:
| 설정 항목 | 올바른 값 | 잘못된 값 |
|---|---|---|
trace_type | "genai_extension" | "otel" |
collector_url | 전체 OTLP 경로 포함 | base URL만 |
| Authorization | Basic <BASE64(pk:sk)> | Bearer 토큰 |
5.2 kgateway URLRewrite (외부 경유 시)
Bifrost가 kgateway를 경유하여 Langfuse에 OTel trace를 전송하는 경우, URLRewrite가 필요합니다.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: langfuse-otel-route
namespace: observability
spec:
parentRefs:
- name: unified-gateway
namespace: ai-gateway
hostnames:
- "api.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /api/public/otel
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /api/public/otel/v1/traces
backendRefs:
- name: langfuse-web
port: 3000
이 경우 Bifrost config의 collector_url은 kgateway 엔드포인트를 사용합니다:
"collector_url": "http://api.example.com/api/public/otel"
kgateway가 /api/public/otel → /api/public/otel/v1/traces로 리라이트합니다.
| 방식 | collector_url | URLRewrite 필요 |
|---|---|---|
| 내부 직접 | http://langfuse-web.langfuse.svc:3000/api/public/otel/v1/traces | 불필요 |
| kgateway 경유 | http://api.example.com/api/public/otel | 필요 |
클러스터 내부 직접 전송이 더 단순하고 지연이 적습니다. kgateway 경유는 외부 네트워크에서 OTel을 전송하는 경우에 사용합니다.
5.3 OTLP 엔드포인트 정확한 경로
Langfuse의 OTLP 수신 엔드포인트는 다음과 같습니다:
POST /api/public/otel/v1/traces
잘못된 경로 (동작하지 않음):
/api/public/otel (suffix 누락)
/v1/traces (prefix 누락)
/api/public/otel/traces (v1 누락)
6. 추천 PromQL 쿼리 테이블
| 메트릭 | PromQL | 용도 |
|---|---|---|
| GPU 사용률 | avg(DCGM_FI_DEV_GPU_UTIL) | GPU 활성도 |
| GPU 메모리 사용률 | avg(DCGM_FI_DEV_FB_USED / (DCGM_FI_DEV_FB_USED + DCGM_FI_DEV_FB_FREE) * 100) by (gpu) | VRAM 사용률 |
| GPU 온도 | DCGM_FI_DEV_GPU_TEMP | 과열 모니터링 |
| vLLM TPS | rate(vllm:request_success_total[5m]) | 추론 처리량 |
| vLLM TTFT p99 | histogram_quantile(0.99, rate(vllm:time_to_first_token_seconds_bucket[5m])) | 첫 토큰 지연 |
| vLLM E2E p99 | histogram_quantile(0.99, rate(vllm_e2e_request_latency_seconds_bucket[5m])) | 전체 요청 지연 |
| vLLM 배치 크기 | avg(vllm_num_requests_running) | 동시 추론 수 |
| kgateway RPS | sum(rate(envoy_http_downstream_rq_total[5m])) by (route) | 초당 요청 수 |
| kgateway 5xx 에러율 | sum(rate(envoy_cluster_upstream_rq_xx{envoy_response_code_class="5"}[5m])) / sum(rate(envoy_http_downstream_rq_total[5m])) * 100 | 에러율 (%) |
| kgateway p99 지연 | histogram_quantile(0.99, sum(rate(envoy_cluster_upstream_rq_time_bucket[5m])) by (le, route)) | 게이트웨이 지연 |
| Bifrost 요청률 | rate(bifrost_requests_total[5m]) | 게이트웨이 요청률 |
| 활성 연결 수 | sum(envoy_cluster_upstream_cx_active) by (upstream_cluster) | 백엔드별 활성 연결 |
알림 규칙 예시
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: vllm-gpu-alerts
namespace: monitoring
spec:
groups:
- name: gpu-alerts
interval: 30s
rules:
- alert: HighGPUTemperature
expr: DCGM_FI_DEV_GPU_TEMP > 85
for: 5m
labels:
severity: warning
annotations:
summary: "GPU {{ $labels.gpu }} temperature is high"
description: "GPU temperature: {{ $value }} C"
- alert: GPUMemoryFull
expr: (DCGM_FI_DEV_FB_USED / (DCGM_FI_DEV_FB_USED + DCGM_FI_DEV_FB_FREE) * 100) > 95
for: 3m
labels:
severity: critical
annotations:
summary: "GPU {{ $labels.gpu }} memory is nearly full"
- alert: HighVLLMLatency
expr: histogram_quantile(0.99, rate(vllm_e2e_request_latency_seconds_bucket[5m])) > 30
for: 5m
labels:
severity: warning
annotations:
summary: "vLLM P99 latency is above 30s"
- alert: HighGatewayErrorRate
expr: |
sum(rate(envoy_cluster_upstream_rq_xx{envoy_response_code_class="5"}[5m])) /
sum(rate(envoy_cluster_upstream_rq_total[5m])) > 0.05
for: 5m
labels:
severity: critical
annotations:
summary: "Inference Gateway 오류율 5% 초과"
7. 트러블슈팅
7.1 AMP 403 (Pod Identity 누락)
증상: Prometheus 로그에 403 Forbidden remote write 에러
진단:
# Pod Identity Association 확인
aws eks list-pod-identity-associations \
--cluster-name <CLUSTER_NAME> \
--namespace monitoring
# Prometheus ServiceAccount 확인
kubectl get sa prometheus-kube-prometheus-prometheus -n monitoring -o yaml
해결:
# Pod Identity Association 생성
aws eks create-pod-identity-association \
--cluster-name <CLUSTER_NAME> \
--namespace monitoring \
--service-account prometheus-kube-prometheus-prometheus \
--role-arn arn:aws:iam::<ACCOUNT_ID>:role/prometheus-amp-remote-write
# Prometheus Pod 재시작 (Pod Identity 적용)
kubectl rollout restart statefulset prometheus-kube-prometheus-prometheus -n monitoring
7.2 AMG 502 (SigV4 auth type 오류)
증상: AMG에서 AMP 데이터 소스 Test 시 502 Bad Gateway
원인: sigV4AuthType이 workspace-iam-role로 설정됨
해결:
- AMG 콘솔 → Data Sources → AMP 데이터 소스 편집
- SigV4 Auth Details → Auth Type을 **
ec2_iam_role**로 변경 - Save & Test
또는 API로 수정:
curl -X PUT "https://${GRAFANA_ENDPOINT}/api/datasources/<DS_ID>" \
-H "Authorization: Bearer ${GRAFANA_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"jsonData": {
"sigV4Auth": true,
"sigV4AuthType": "ec2_iam_role",
"sigV4Region": "ap-northeast-2"
}
}'
7.3 Langfuse Worker CrashLoopBackOff (Redis)
증상: langfuse-worker Pod가 CrashLoopBackOff 상태
진단:
# Worker 로그 확인
kubectl logs -n langfuse -l app.kubernetes.io/component=worker --tail=30
# Redis 연결 테스트
kubectl run -it --rm redis-test --image=redis:7 --restart=Never -n langfuse -- \
redis-cli -h langfuse-redis-primary -a $(kubectl get secret langfuse-redis -n langfuse -o jsonpath='{.data.valkey-password}' | base64 -d) ping
해결:
REDIS_PW=$(kubectl get secret langfuse-redis -n langfuse \
-o jsonpath='{.data.valkey-password}' | base64 -d)
kubectl set env deploy/langfuse-worker deploy/langfuse-web -n langfuse \
REDIS_CONNECTION_STRING="redis://default:${REDIS_PW}@langfuse-redis-primary:6379/0"
7.4 Langfuse S3 500 (MinIO Secret 누락)
증상: OTel trace 수신 시 Langfuse가 500 에러 반환, 로그에 S3 관련 오류
원인: Langfuse Helm 차트가 MinIO S3 secret key를 환경변수에 자동 주입하지 않음
해결:
MINIO_PW=$(kubectl get secret langfuse-s3 -n langfuse \
-o jsonpath='{.data.root-password}' | base64 -d)
kubectl set env deploy/langfuse-web deploy/langfuse-worker -n langfuse \
LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY="$MINIO_PW" \
LANGFUSE_S3_BATCH_EXPORT_SECRET_ACCESS_KEY="$MINIO_PW" \
LANGFUSE_S3_MEDIA_UPLOAD_SECRET_ACCESS_KEY="$MINIO_PW"
MinIO 관련 이슈를 근본적으로 해결하려면 섹션 4.3의 S3 + KMS 전환을 권장합니다. Pod Identity 기반이므로 Access Key 관리가 불필요하고, 가용성과 암호화가 보장됩니다.
7.5 Langfuse 404 (Sub-path Routing)
증상: /langfuse/ 접속 시 페이지는 로드되지만 CSS/JS가 깨지거나 404
원인: Next.js 정적 자산 경로(/_next/*)와 인증 API(/api/auth/*)가 Langfuse로 라우팅되지 않음
해결: kgateway HTTPRoute에 추가 경로 규칙 필요:
# 추가 필요한 경로들
/_next/* → langfuse-web:3000 (Static Assets)
/api/auth/* → langfuse-web:3000 (NextAuth)
/api/public/* → langfuse-web:3000 (Public API + OTel)
/icon.svg → langfuse-web:3000 (Favicon)
상세 HTTPRoute YAML은 추론 게이트웨이 배포: 기본 배포를 참조하세요.
7.6 Langfuse 무한 리다이렉트 (NEXTAUTH_URL)
증상: Langfuse UI 로그인 시 무한 리다이렉트 루프
원인: NEXTAUTH_URL이 기본값 localhost:3000으로 설정됨
해결:
kubectl set env deploy/langfuse-web -n langfuse \
NEXTAUTH_URL="http://<NLB_ENDPOINT>/langfuse"
참고 자료
- Agent 모니터링 - 모니터링 아키텍처 및 메트릭 설계 상세
- LLMOps Observability - Langfuse/LangSmith/Helicone 비교 및 평가 파이프라인
- Amazon Managed Prometheus
- Amazon Managed Grafana
- Langfuse Helm Chart