메인 콘텐츠로 건너뛰기
이 가이드는 프로덕션 환경에서 자주 발생하는 증상을 구체적인 진단 방법 및 해결책과 연결하여, 별도의 모니터링 인프라 없이 기존 도구만으로 인시던트를 해결할 수 있도록 합니다. 서버, 수집기, 대시보드, AI 어시스턴트, Python SDK, 헬스/인증서 모니터링, 백업, ClickHouse 기반 분석, 멀티테넌시를 다룹니다. 대시보드 페이지는 /<org-slug>/… 형태의 조직 범위 경로를 사용하며, 이벤트 스트림은 조직 홈(/<org-slug>/)입니다. 이 가이드에서 언급하는 페이지 이름(예: /sessions, /queries)은 해당 조직 범위 경로를 가리킵니다.

로그 확인

AgentEye는 별도의 로깅 또는 모니터링 스택을 포함하지 않습니다. 서버와 대시보드 모두 구조화된 로그를 stdout에 출력하므로, 별도의 로그 수집기 없이 kubectl 또는 docker로 직접 확인할 수 있습니다.

Kubernetes

서버 및 대시보드의 실시간 로그 확인:
유용한 변형 명령어:
목적명령어
마지막 200줄 (실시간 아님)kubectl logs -n agenteye -l app=server --tail=200 --timestamps
이전 크래시 로그kubectl logs -n agenteye <pod-name> --previous
모든 레플리카 동시 tailkubectl logs -n agenteye -l app=server --max-log-requests=10 -f
Postgres (StatefulSet)kubectl logs -n agenteye postgres-0 -f

Docker Compose

대시보드와 서버 간 단일 요청 추적

모든 대시보드 요청에는 request_id가 태그되며, x-request-id 헤더를 통해 서버로 전달됩니다. 서버는 해당 요청에 대한 응답 헤더와 모든 로그 줄에 이 ID를 포함합니다. 단일 요청을 처음부터 끝까지 추적하려면:
  1. 응답 헤더에서 ID를 캡처합니다:
  2. 두 파드의 로그에서 해당 ID를 검색합니다:
동일한 request_id를 공유하는 대시보드의 proxy passthrough, withAuth: authorized, upstream response 로그 줄과 서버의 http request received / http request completed 쌍을 함께 확인할 수 있습니다.

JSON 로그와 jq

대시보드에서 AE_LOG_JSON=1을 설정하면(기본값: NODE_ENV=production일 때 활성화) 한 줄에 하나의 JSON 객체를 출력합니다. 구조적으로 필터링하려면:
Rust 서버는 key=value 형식의 tracing 로그를 출력하므로 jq 없이도 grep이 잘 됩니다:

로그 상세도 높이기

컴포넌트환경 변수예시
서버RUST_LOGRUST_LOG=debug 또는 RUST_LOG=agenteye_server=debug,info
대시보드AE_LOG_LEVELAE_LOG_LEVEL=debug
서버에서 debug를 설정하면 인증마다 api key authenticated 줄이 추가됩니다. 대시보드에서 debug를 설정하면 upstream request, session validated, proxy passthrough 줄이 추가됩니다.

로그 보존

컨테이너 stdout은 휘발성이며, kubelet이 로그 파일을 순환(기본값: 컨테이너당 약 10MiB)하고 디스크에 소수의 파일만 유지합니다. 파드가 삭제되면 로그도 사라집니다. 더 긴 보존 기간이나 파드 간 검색이 필요한 경우, /var/log/containers/를 tail하는 로그 수집기(Loki, CloudWatch, Cloud Logging, Datadog 등)를 클러스터에 연결하세요. AgentEye는 특정 수집기를 요구하거나 권장하지 않습니다.

인증 문제

docker pull이 “unauthorized”로 실패하는 경우

AGENTEYE_TOKEN으로 GHCR에 Docker 인증이 되어 있는지 확인하세요:
토큰은 agenteye-enterprise org의 read:packages 권한이 있어야 합니다. 토큰이 작동하지 않으면 support@exosphere.host에 문의하세요.

gh release download가 404 또는 401을 반환하는 경우

  • 셸에서 AGENTEYE_TOKEN이 export되어 있는지 확인합니다: echo $AGENTEYE_TOKEN
  • GITHUB_TOKEN=$AGENTEYE_TOKEN gh release download ... 형식을 사용하고 있는지 확인합니다(gh CLI는 GITHUB_TOKEN을 읽습니다)
  • 토큰에 agenteye-enterprise/releasescontents:read 권한이 필요합니다

서버 문제

서버가 “invalid port number”로 실패하는 경우

POSTGRES_PASSWORD(또는 다른 자격 증명)에 URL 특수 문자(/, +, =)가 포함되어 DATABASE_URL 파싱이 실패합니다. 16진수 인코딩을 사용하여 비밀번호를 재생성하세요:
그런 다음 Kubernetes 시크릿과 Postgres 내부의 비밀번호를 업데이트(또는 Docker Compose용 .env를 재생성)하고 서버를 재시작하세요. 전체 절차는 enterprise-docs/kubernetes-deployment.md § “PostgreSQL credentials”를 참조하세요.

서버가 시작 즉시 종료되는 경우

컨테이너 로그를 확인합니다:
주요 원인:
  • DATABASE_URL이 설정되지 않았거나 잘못된 형식: 서버가 오류를 로그에 기록하고 종료합니다.
  • Postgres에 연결할 수 없음: Postgres 컨테이너 또는 관리형 DB가 실행 중이고 호스트/포트가 올바른지 확인합니다.
  • 마이그레이션 실패: SQL 오류가 있는지 로그를 확인합니다.

GET /health가 non-200을 반환하거나 타임아웃되는 경우

첫 시작 시 서버가 마이그레이션을 실행 중일 수 있습니다. 잠시 기다렸다가 재시도하세요:
문제가 지속되면 docker logs agenteye-server에서 오류를 확인하세요.

GET /ready가 503을 반환하는 경우

/ready는 준비 상태 프로브로, 서버가 Postgres 또는 ClickHouse에 연결할 수 없을 때 503을 반환합니다. 응답 본문에 실패한 의존성이 명시됩니다:
down으로 보고된 의존성을 수정하세요: ClickHouse/Postgres 파드가 Running 상태인가요? CLICKHOUSE_URL / DATABASE_URL이 올바르고 접근 가능한가요? Kubernetes에서 파드는 /ready가 회복될 때까지 NotReady로 표시됩니다. 이는 예상된 동작이며 헬스 모니터링이 경고하는 신호입니다. Redis는 원인이 되지 않습니다: 보고되지만 준비 상태에 영향을 미치지 않습니다.

수집기가 401 Unauthorized를 반환하는 경우

수집기의 API 키에 events:add 권한이 없거나 키가 비활성화되어 있습니다. 올바른 권한으로 새 키를 생성하세요:

인증된 요청이 갑자기 느려진 경우(~5ms 대신 ~200ms)

Redis가 다운되었으나 REDIS_URL은 설정된 상태일 때 나타나는 증상입니다. 모든 캐시 호출이 100ms 후 타임아웃되고 Postgres로 폴스루됩니다. 인증 및 OTP 경로에서는 요청마다 두 번의 폴스루가 발생합니다. 서버 로그에서 확인:
해결 방법:
  1. redis-cli -h <your-redis> ping으로 클러스터 네트워크에서 Redis에 접근 가능한지 확인합니다.
  2. Redis가 잠깐 다운되었다가 복구된 경우, 서버 파드를 재시작하세요. redis::aio::ConnectionManager는 기본 연결이 끊긴 후 안정적으로 재연결하지 못합니다. 파드 재시작 시 새 연결을 깔끔하게 가져옵니다. 대시보드도 마찬가지입니다.
  3. 당장 Redis를 운영하지 않으려면 배포에서 REDIS_URL을 해제하고 재시작하세요. 두 서비스 모두 캐시 없이 실행됩니다(정확성은 유지되며, 지연 시간은 Redis 이전 기준으로 돌아갑니다).

서버 로그에 OTP request rate-limited가 기록되지만 사용자는 한 번만 시도했다고 하는 경우

Redis가 연결 불가 상태였는지 확인하세요. 폴백 경로는 SELECT COUNT(*) FROM otp_codes WHERE created_at > now() - interval '15 minutes'를 사용하는데, 이전에 생성된 OTP 행이 포함됩니다. 사용자가 한 시간 동안 “재전송”을 반복 클릭했다면 15분 창 내에 여전히 5개 이상의 코드가 있을 수 있습니다. 창이 롤오버될 때까지 기다리거나, DELETE FROM otp_codes WHERE user_id = $1 AND created_at > now() - interval '15 minutes'(운영자 콘솔)를 실행하여 해결하세요.

ALLOWED_EMAILS / SESSION_TTL_SECS / OTP_TTL_SECS를 변경하고 재시작했지만 변경이 적용되지 않는 경우

이 환경 변수들은 최초 부팅 시에만 적용되는 시드 값입니다. settings 테이블에 해당 키의 행이 존재하면, 그 행이 진실의 원천이 됩니다. 환경 변수는 최초 부팅 시 한 번만 읽히고 이후 재시작 시에는 무시됩니다. 최초 부팅 이후 변경하려면, 대시보드에 로그인하여 /settings에서 편집하세요. 변경 사항은 모든 레플리카에 수초 내에 적용되며 재시작이 필요 없습니다. 환경 변수에서 강제로 재시드해야 하는 경우(드물며 주로 개발 환경에서만 유용), DELETE FROM settings WHERE key = '<key>' 후 서버를 재시작하면 다음 부팅 시 현재 환경 변수 값을 가져옵니다. 프로덕션에서는 /settings를 통한 편집이 지원되는 방식입니다.

수집기 문제

수집기는 시작되지만 이벤트가 대시보드에 나타나지 않는 경우

  1. 수집기가 실행 중인지 확인합니다: systemctl status agenteye-collector(Linux) 또는 프로세스를 확인합니다.
  2. AGENTEYE_URLhttp(s)://your-server-host:8080/events(/events 경로 포함)를 가리키는지 확인합니다.
  3. 즉각적인 출력을 보려면 단발성 플러시를 실행합니다:
  4. Python SDK가 실제로 파일을 기록하고 있는지 확인합니다: ls ${AGENTEYE_HOME:-~/.agenteye}/events/
  5. ${AGENTEYE_HOME:-~/.agenteye}/failed/에 파일이 있다면 업로드가 실패하고 있는 것입니다. 수집기 로그에서 오류를 확인하세요. 4xx 오류(잘못된 키 또는 URL)나 네트워크 문제일 가능성이 높습니다.

$AGENTEYE_HOME/events/에 파일이 쌓이고 업로드되지 않는 경우

  • 수집기가 실행 중이 아닐 수 있습니다. 시작하세요: agenteye-collector start. 시작 시 기존 이벤트를 자동으로 플러시합니다.
  • 수집기 헬스 확인: agenteye-collector health
  • 수집기는 실행 중이지만 서버에 연결할 수 없을 수 있습니다. 수집기와 서버 호스트 간 방화벽 규칙을 확인하세요.

$AGENTEYE_HOME/failed/에 파일이 있는 경우

파일은 모든 재시도가 소진된 후(기본값: 지수 백오프를 적용한 5회) failed/로 이동됩니다. 이는 다음 중 하나를 의미합니다:
  • 서버가 4xx 오류를 반환(잘못된 키, 잘못된 URL, 또는 페이로드 문제)
  • 전체 재시도 창 동안 서버에 연결할 수 없음
근본 원인을 수정한 후 수동으로 재대기열에 추가하세요:

수집기가 모든 업로드에서 network error를 보고하는 경우(TLS 핸드셰이크 실패)

curl -kAGENTEYE_URL에 접근하면 성공하지만 수집기 바이너리가 매번 error sending request for url (...)로 실패한다면, AgentEye 서버가 공개 신뢰 CA에서 서명되지 않은 TLS 인증서를 제공하고 있는 것입니다. 프로덕션 경로deploy/base/certificates/domain.env에 구성된 ACME 수집 호스트명입니다(kubernetes-deployment.md Phase 3.1 / 4.2 참조). INGEST_DOMAIN이 공개 Traefik LB로 해석되고 cert-manager가 Let’s Encrypt 인증서를 발급하면, 수집기는 AGENTEYE_TLS_CA 없이 시스템 신뢰 저장소에 대해 서버 인증서를 검증합니다. 이전에 자체 서명 배포 시 설정했다면 이를 해제하세요. 증상: 수집기가 어제까지 작동했는데 약 90일 후 오늘 실패하는 경우. 배포가 여전히 ingest-tls에 레거시 selfsigned 발급자를 사용하고 있다는 의미입니다. 90일짜리 인증서가 순환되어 고정된 CA 파일이 오래된 것이 됐습니다. 클러스터를 ACME 발급자로 전환하여 영구적으로 수정하세요(배포 가이드 Phase 3.1). 단기 해결책으로, 현재 서버 인증서를 재추출하고 AGENTEYE_TLS_CA를 업데이트하세요:
AGENTEYE_TLS_CA는 추가 신뢰 앵커를 추가합니다. 표준 공개 루트는 계속 신뢰됩니다.

배포 후 ingest-tls 인증서가 Ready: False 상태에서 멈춰 있는 경우

Events와 참조된 Order / Challenge를 확인하세요. 주요 원인:
  • DNS가 공개 LB로 해석되지 않음. HTTP-01 검증자가 INGEST_DOMAIN에 도달하지 못합니다. dig +short INGEST_DOMAIN으로 확인하세요. traefik-public LoadBalancer의 EXTERNAL-IP와 동일한 주소로 해석되어야 합니다. DNS가 전파되면 cert-manager가 자동으로 재시도하므로 Certificate를 삭제할 필요가 없습니다.
  • 로드 밸런서 / 보안 그룹에서 포트 80이 차단됨. HTTP-01은 Let’s Encrypt의 공개 검증자가 포트 80에 접근 가능해야 합니다. 업스트림 WAF나 SG가 :80을 제한하고 있다면 열어주세요(Traefik 설정은 HTTPS로 리디렉션하지만, Boulder는 리디렉션을 따르고 응답을 수락합니다).
  • dnsNames가 치환되지 않음. kubectl get certificate ingest-tls -n agenteye -o jsonpath='{.spec.dnsNames}'INGEST_DOMAIN_PLACEHOLDER를 표시한다면 domain.env 단계를 건너뛴 것입니다. domain.env.example에서 생성하고 재적용하세요.
  • Let’s Encrypt 속도 제한. 동일 호스트명에 대한 반복 실패한 주문은 중복 인증서 또는 유효성 검사 실패 한도를 초과합니다. 재시도 전 최소 한 시간 기다리세요. 정확한 속도 제한 메시지는 Order 상태를 확인하세요.

dashboard-tls 인증서가 Ready: False 상태이거나 브라우저에서 여전히 경고가 표시되는 경우

위의 ingest-tls와 동일한 진단 절차를 따르세요(kubectl describe certificate dashboard-tls -n agenteye). DNS, 포트 80, 플레이스홀더, 속도 제한 원인이 모두 적용되며, 대시보드에만 해당하는 두 가지 추가 원인이 있습니다:
  • DASHBOARD_DOMAIN이 잘못된 LoadBalancer를 가리킴. 공개 수집용 Traefik LB가 아닌 대시보드 Traefik LB를 가리켜야 합니다. 호스트명을 dig +short로 확인하고 대시보드 LB 주소와 비교하세요.
  • 대시보드 Traefik 인스턴스가 챌린지를 처리하지 못함. cert-manager의 HTTP-01 솔버를 위한 범위 지정 Ingress 공급자를 활성화하는 번들 대시보드 값 파일과 함께 설치되어야 합니다. 없으면 솔버가 라우팅 불가능하여 Order가 영구적으로 pending 상태가 됩니다. 제공된 값으로 인스턴스를 업그레이드하면 대기 중인 챌린지가 자동으로 완료됩니다.
  • LoadBalancer에 IP 제한이 걸려 있음. 소스 범위는 포트 80에도 적용되어 Let’s Encrypt의 검증자를 차단합니다. 최초 발급과 약 75일마다의 갱신 시 모두 영향을 받습니다. LB를 다시 열거나, 잠그기 전에 지원팀과 DNS-01 솔버를 조율하세요.
발급이 실패하는 동안 대시보드는 이전 인증서(또는 신규 설치의 경우 ingress 기본값)로 계속 서비스됩니다. 브라우저 경고로 접근이 불편해질 뿐, 서비스가 중단되지는 않습니다.

대시보드에 신뢰할 수 있는 인증서가 적용된 후에도 CLI가 TLS 검증을 건너뛰는 경우

--insecure는 로그인 시 cli.json에 저장됩니다. 대시보드가 공개 신뢰 인증서를 제공하면, agenteye --base-url https://<your-dashboard-domain> --secure login으로 다시 로그인하세요. 검증이 다시 활성화되어 저장되고 시작 경고가 사라집니다.

대시보드 문제

ADMIN_EMAIL 사용자를 비활성화하거나 편집할 수 없는 경우

이는 의도된 동작입니다. ADMIN_EMAIL과 일치하는 사용자는 서버 시작 시마다 보호됨으로 표시됩니다. 대시보드는 해당 행의 비활성화 버튼을 숨기며, API는 해당 사용자에 대한 DELETE /users/:idPUT /users/:id 요청을 403 Forbidden으로 거부합니다. 데이터베이스 트리거도 보호된 행을 비활성화하는 직접 UPDATE 문을 거부합니다. 부트스트랩 관리자를 교체하려면, 환경에서 ADMIN_EMAIL을 변경하고 서버를 재시작하세요. 새 이메일이 보호됨으로 업서트됩니다. 이전 관리자는 데이터베이스에서 명시적으로 제거할 때까지 보호 플래그를 유지합니다(이전 이메일이 여전히 유효한 관리자이므로 일반적으로 무방합니다).

대시보드에 이벤트가 표시되지 않는 경우

  1. 대시보드 환경 변수(AGENTEYE_SERVER_URL, AGENTEYE_API_KEY)에서 서버 URL과 API 키가 올바른지 확인합니다.
  2. 대시보드 API 키에 events:read 권한이 필요합니다.
  3. 이벤트가 실제로 수집되었는지 확인합니다: curl http://your-server:8080/events -H "Authorization: Bearer $ADMIN_KEY"

/errors는 비어 있는데 /events에는 빨간색 행이 표시되는 경우

최신 SDK 버전은 실패를 전용 event_type: "error" 행 대신 페이로드에 outcome: "error"가 포함된 agent_end / tool_result / hook_completed 이벤트로 보냅니다. /errors 페이지는 이제 두 가지 모두를 매칭합니다: /events 스트림에서 빨간색으로 표시되는 모든 행(명시적 event_type='error', 페이로드의 outcome/status가 실패 집합에 속하는 경우, is_error: true, 또는 truthy error 필드)이 /errors에 표시됩니다. 이전에 /events에 빨간색 행이 있었는데 “이 창에 오류 없음”이 표시됐다면, 대시보드와 서버를 함께 업그레이드하세요(GET /events의 확장된 필터 errored=true). 그러면 두 뷰가 일치하게 됩니다.

넓은 시간 범위에서 /models, /tools, /hooks가 느리거나 로드 실패하는 경우

증상: 대규모 이벤트 테이블(수백만 행)에서 /models, /tools, /hooks를 열거나 시간 범위를 7d, 30d, all로 넓히면 차트가 로딩되다가 오류가 표시됩니다. 서버 로그에 latency_aggregate 요청에 대한 ClickHouse MEMORY_LIMIT_EXCEEDED(Code 241) 또는 쿼리 타임아웃이 기록됩니다. 원인: 이전 빌드에서는 이 페이지들의 지연 시간 및 분포 롤업을 전체 원시 이벤트 payload를 읽고 인메모리 정렬-조인으로 요청/응답 이벤트를 쌍으로 맞추는 쿼리로 계산했습니다. 이로 인해 쿼리 최대 메모리가 창의 크기에 비례하여 증가했고, 바쁜 테넌트에서는 ClickHouse의 쿼리당 메모리 한계를 초과할 수 있었습니다. 해결 방법: 이 수정을 포함하는 빌드로 업그레이드하세요. 롤업은 이제 압축된 승격 컬럼만 읽고 스트리밍 집계로 이벤트를 쌍으로 맞추므로, 최대 메모리가 더 이상 원시 페이로드와 함께 확장되지 않습니다. 넓은 창도 메모리 한계 내에서 빠르게 반환됩니다. 개선은 전적으로 쿼리 측에서 이루어집니다. 기존 데이터에 즉시 적용되며, 재수집이나 백필이 필요 없습니다.

대시보드가 로드되지 않거나 빈 페이지가 표시되는 경우

대시보드 컨테이너 로그를 확인합니다:
가장 흔한 원인은 AGENTEYE_SERVER_URL 또는 AGENTEYE_API_KEY가 누락되거나 연결할 수 없는 서버를 가리키는 경우입니다.

대시보드 분석 / 텔레메트리

대시보드는 기본적으로 익명의 제품 사용 분석을 PostHog에 전송하며, 대시보드 자체의 /ingest 경로(퍼스트 파티 https://us.i.posthog.com 리버스 프록시)를 통해 라우팅됩니다. 브라우저 광고 차단기가 차단하지 않도록 퍼스트 파티로 전송됩니다. 이는 대시보드의 핵심 기능과 독립적입니다:
  • 대시보드 컨테이너(브라우저가 아님)가 PostHog에 연결합니다. https://us.i.posthog.com에 대한 아웃바운드 접근이 차단되면 텔레메트리는 무음으로 비활성화되며, 대시보드는 정상적으로 작동하고 사용자에게 오류가 표시되지 않습니다.
  • 에이전트, 세션, 이벤트 데이터는 포함되지 않으며 대시보드 UI 사용 데이터만 전송됩니다.
  • 텔레메트리를 완전히 비활성화하려면 대시보드 컨테이너에 AE_ANALYTICS_DISABLED=1을 설정하고 재시작하세요. 배포 가이드의 Telemetry & privacy를 참조하세요.

CLI 분석 / 텔레메트리

agenteye CLI는 기본적으로 익명의 사용 분석(실행된 명령어, 성공/종료 상태, 실행 시간)을 PostHog에 전송합니다. 이는 CLI 기능과 독립적입니다:
  • CLI를 실행하는 머신https://us.i.posthog.com에 직접 연결합니다. 아웃바운드 접근이 차단되면 텔레메트리는 무음으로 비활성화되며(전송에 시간 제한이 있어 명령어 실행이 지연되지 않습니다) CLI는 정상적으로 작동합니다.
  • 에이전트, 세션, 이벤트 데이터는 포함되지 않습니다. 명령어 인수 및 플래그 값(대시보드 URL, 토큰, 이메일, 세션 ID, 쿼리 필터)은 전송되지 않습니다.
  • 비활성화하려면 CLI 환경에서 AGENTEYE_ANALYTICS_DISABLED=1(또는 크로스 도구 DO_NOT_TRACK=1)을 설정하세요. CLI 가이드의 Telemetry & privacy를 참조하세요.

AI 어시스턴트 문제

전체 설정은 enterprise-docs/assistant.md를 참조하세요.

어시스턴트 버블이 표시되지 않는 경우

다음 조건이 모두 충족될 때만 버블이 표시됩니다:
  • 로그인한 사용자에게 agent:use 권한이 있어야 합니다.
  • 대시보드에 AGENTEYE_AGENT_URL이 설정되어 있고 agent 서비스에 접근 가능해야 합니다.
  • agent 서비스에 LLM 엔드포인트가 구성되어 있어야 합니다(ANTHROPIC_API_KEY, ANTHROPIC_BASE_URL을 통한 게이트웨이, 또는 Bedrock/Vertex). 아무것도 설정되지 않으면 에이전트가 “구성되지 않음”을 보고하고 버블이 숨겨집니다.
대시보드 호스트에서 에이전트 헬스를 확인하세요: curl http://agent:9100/health{"status":"ok","llm_configured":true,...}를 반환해야 합니다.

어시스턴트가 특정 데이터를 읽을 수 없다고 하는 경우

도구는 사용자별로 제한됩니다. 사용자에게 evaluations:read(또는 events:read, dashboards:read) 권한이 없으면 해당 도구가 제공되지 않으며, 어시스턴트는 해당 데이터를 읽을 수 없다고 말합니다. 관련 읽기 권한을 부여하세요.

메시지 전송 시 “assistant not configured” (HTTP 503)가 발생하는 경우

agent 컨테이너에 LLM 엔드포인트가 구성되지 않았거나, 대시보드의 AGENTEYE_AGENT_TOKEN이 에이전트의 토큰과 일치하지 않습니다. 두 값을 모두 설정하고 재시작하세요.

agent 컨테이너가 부하 시 재시작되거나 OOM이 발생하는 경우

각 대화는 단기적인 자식 프로세스를 생성합니다. 컨테이너가 init 프로세스로 실행되는지 확인하세요(이미지가 tini를 사용하며, Compose에서는 init: true 설정). 적절한 메모리 한도를 설정하고, 필요시 AGENTEYE_AGENT_MAX_STEPS를 줄이세요.

CLI 문제

agenteyeModuleNotFoundError: No module named 'click'으로 시작 실패하는 경우

0.1.6 버전의 agenteye CLI를 새로 설치하면 시작 시 다음 오류가 발생할 수 있습니다:
0.1.6은 typerclick을 간접적으로 설치하는 것에 의존했습니다. 현재 typer 릴리스는 더 이상 이를 포함하지 않아, 깨끗한 환경에서 패키지가 누락됩니다. click에 직접 의존하는 0.1.7 이상으로 업그레이드하세요:
설치 안내는 enterprise-docs/cli.md를 참조하세요.

Python SDK 문제

$AGENTEYE_HOME/events/에 파일이 생성되지 않는 경우

SDK는 이벤트를 버퍼링하고 기본적으로 500ms마다 플러시합니다. 플러시 전에 프로세스가 종료되면 이벤트가 손실될 수 있습니다. 단기 실행 스크립트에서는 agenteye.configure(flush_interval=0.1)로 더 빠른 플러시를 설정하거나, 플러시 사이클이 완료될 때까지 프로세스가 실행되도록 하세요. AGENTEYE_HOME이 설정되어 있다면, SDK가 ~/.agenteye/events/가 아닌 $AGENTEYE_HOME/events/에 기록하는지 확인하세요(SDK ≥ 0.0.1b5 필요).

ValueError: Reserved field names cannot be used as custom fields

timestamp, type, environment는 예약된 이름으로 커스텀 필드로 사용할 수 없습니다. 이 중 하나를 전달하면 다음 오류가 발생합니다:
문제가 되는 커스텀 필드의 이름을 변경하세요. session_idagent_id는 이벤트 호출의 명시적 파라미터이며 커스텀 필드가 아닙니다. 이를 다시 커스텀 필드로 전달하면 TypeError가 발생합니다.

헬스 모니터링 문제

Slack으로 경고가 오지 않는 경우(Robusta)

Robusta 헬스 경고는 옵트인 방식입니다. 설치하고 Slack 채널을 지정할 때까지 아무것도 전송하지 않습니다. 릴리스와 싱크를 확인하세요:
주요 원인: Slack api_key / slack_channel이 설정되지 않았거나(또는 토큰이 취소됨); api_key가 Robusta 클라우드 릴레이 토큰(robusta integrations slack)인데 번들된 disableCloudRouting: true는 셀프 호스팅 Slack 봇 토큰(xoxb-…)이 필요하거나 disableCloudRouting: false로 설정해야 함; 싱크 scope가 파드가 실행 중인 네임스페이스를 제외함(번들 값은 agenteye로 범위 지정); 또는 아직 실패가 발생하지 않음. 파드를 종료하여 테스트 경고를 강제 발생시키세요:
설치 및 구성은 enterprise-docs/health-monitoring.md를 참조하세요.

서버가 지속적으로 NotReady 상태를 반복하는 경우

준비 상태 프로브가 /ready를 호출하며, Postgres 또는 ClickHouse에 연결할 수 없을 때 실패합니다. 서버가 NotReady를 반복한다면 의존성이 간헐적으로 사용 불가능한 것입니다. ClickHouse와 Postgres 파드, 그리고 서버의 CLICKHOUSE_URL / DATABASE_URL을 확인하세요. /ready가 보고하는 내용을 확인합니다:
이 프로브는 의도적으로 허용적입니다(관대한 실패 임계값). 따라서 지속적인 반복은 프로브가 너무 엄격한 것이 아니라 실제 의존성 문제를 나타냅니다. 활성 프로브는 /health에 남아 있으므로, 준비 상태 반복이 파드를 재시작하지는 않습니다.

인증서 모니터링 문제

CronJob이 Slack 알림을 보내지 않는 경우

cert-renewal-check CronJob은 시크릿에 저장된 Slack 웹훅 URL이 필요합니다. 존재 여부를 확인하세요:
없으면 생성하세요:
시크릿이 없어도 CronJob은 실행되어 stdout에 결과를 기록합니다. 로그 확인:

알림을 받기 전에 클라이언트 인증서가 만료된 경우

CronJob은 12시간마다 실행됩니다. 실행되지 않고 있다면 상태를 확인하세요:
수동 확인을 트리거합니다:
만료된 인증서를 즉시 재발급하려면:
그런 다음 수집기를 실행하는 클러스터에 재생성된 collector-mtls-secret.yaml을 적용하고 재시작하세요:

백업 문제

agenteye-backup이 “No space left on device”로 실패하는 경우

agenteye-backup CronJob은 Postgres + ClickHouse를 backup-tmp emptyDir 임시 볼륨(기본값 30Gi)에 덤프한 다음, tar 아카이브를 S3에 스트리밍합니다. 압축된 아카이브는 임시 저장소에 기록되지 않으므로, 임시 저장소는 원시 덤프만 보관하면 됩니다. 파드 퇴거 / No space left on device원시 덤프가 임시 저장소 크기를 초과함을 의미합니다(ClickHouse events 덤프가 주된 원인이며 시간이 지날수록 증가합니다). 실패한 작업의 로그를 확인하세요:
해결 방법: 오버레이에서 CronJob의 backup-tmp emptyDir sizeLimit을 원시 덤프 총 크기보다 높이고, 노드의 임시 저장소가 실제로 이를 수용할 수 있는지 확인하세요(sizeLimit은 상한이지 예약이 아닙니다). 덤프가 단일 노드의 디스크를 초과하면 backup-tmp를 PVC(EBS/PD)로 교체하거나, 소스에서 덤프를 압축하세요.
이전 릴리스에서는 .tar.gz를 덤프와 동일한 20Gi 임시 저장소에 기록하여 덤프 + 아카이브가 초과되어 업로드 전에 파드가 퇴거됐습니다. 이는 S3 오류처럼 보이지만 실제로는 디스크 문제입니다. 업로드 스트리밍으로 이 두 배 문제가 해결됩니다.

agenteye-backupcurl 설치 실패로 실패하는 경우

작업이 postgres:16 이미지에서 실행되며 ClickHouse HTTP 덤프를 위해 시작 시 curl을 설치합니다. Debian 패키지 미러에 대한 이그레스가 없는 클러스터에서는 apt-get 단계가 실패합니다. 백업 파드의 이그레스를 허용하거나, curl이 포함된 미러링/커스텀 백업 이미지를 빌드하여 오버레이에서 참조하세요.

agenteye-backup은 실행되지만 오브젝트 스토리지에 아무것도 저장되지 않는 경우

기본 구성은 실제 BACKUP_BUCKET(ts-prod-agenteye/backups)과 agenteye-backup ServiceAccount를 포함합니다. 작업은 아카이브를 S3에 스트리밍합니다(tar cz … | aws s3 cp - s3://…). 백업 파드가 버킷에 대한 쓰기 권한이 없으면 업로드 오류가 발생합니다. 스크립트가 set -euo pipefail 하에 실행되므로, 파이프 어느 곳에서든 실패하면 전체 작업이 upload 단계에서 실패합니다(파드의 EXIT 트랩이 backup FAILED during step: upload를 기록합니다). 임시 저장소 퇴거를 수정한 후에도 이 단계에 도달하므로, 이제 업로드가 정상적으로 저장되는지 확인하세요. 실패한 작업의 로그에서 S3 접근 오류를 검색하세요:
해결 방법: 오버레이에서 BACKUP_BUCKET을 소유한 버킷으로 설정하고, 기존 agenteye-backup ServiceAccount에 쓰기 권한을 주석으로 추가하세요(IRSA / Workload Identity / Pod Identity). enterprise-docs/kubernetes-deployment.mdBackups 섹션을 참조하세요.

ClickHouse 기반 평가 / 세션 / 쿼리

업그레이드 후 /queries 페이지 사이드바가 비어 있는 경우

세 개의 테이블(events, evaluations, agent_sessions)이 있어야 합니다. 업그레이드 후 SchemaBrowser 사이드바가 비어 있다면, 서버가 시작 시 ClickHouse DDL 적용에 실패한 것입니다. failed to apply CH DDL statement가 있는지 서버 로그를 확인하세요:
가장 흔한 원인은 마이그레이션 실행 중 ClickHouse에 연결할 수 없는 경우입니다. 서버는 CH에 연결할 수 없으면 시작을 거부하므로, 멈춘 파드는 일반적으로 쿼리 페이지가 조용히 고장나는 것보다 CrashLoopBackOff 상태가 됩니다. 그러나 부분적인 DDL 적용(하나는 성공, 다음 5개는 5xx)은 스키마를 절반만 적용된 상태로 남깁니다. CH가 연결 가능함을 확인한 후 서버 파드를 재시작하세요:

새 평가가 /sessions 또는 /queries에 나타나지 않는 경우

업그레이드 후 새 평가는 Postgres가 아닌 ClickHouse에 기록되며, /sessions(evaluations:read 권한 필요)와 /queries에 표시됩니다. 표시되지 않는다면:
  1. 평가자 파이프라인이 활성화되어 있고(EVALUATOR_ENDPOINT가 서버에 설정됨) 최종 결과를 생성하고 있는지 확인합니다. evaluation_finalized 로그 줄을 확인하세요.
  2. 서버에서 CH에 연결 가능한지 확인합니다: kubectl exec -n agenteye deploy/server -- curl -fsS http://clickhouse:8123/ping.
  3. CH 테이블을 직접 확인합니다: kubectl exec -n agenteye clickhouse-0 -- clickhouse-client -q 'SELECT count() FROM agenteye.evaluations'.

부하 시 쿼리가 “Memory limit exceeded”로 실패하거나 ClickHouse가 OOMKilled되는 경우

증상: 대시보드/쿼리 부하가 높을 때 분석 페이지(이벤트 스트림, /sessions, 모델/지연 시간 뷰, SQL 편집기)가 실패하거나 타임아웃됩니다. 서버가 잠깐 NotReady 상태가 되고 ClickHouse 파드의 재시작 횟수가 증가합니다. 거의 항상 메모리 문제이며 CPU나 디스크 문제가 아닙니다. 메모리 문제 확인 (복제로 해결할 처리량 문제가 아님을 확인):
  1. OOM 킬 여부를 파드에서 확인합니다:
    재시작 횟수가 증가하면서 Reason: OOMKilled / Exit Code: 137이 나타나면 이것이 원인입니다.
  2. ClickHouse가 거부하고 있는 것을 확인합니다:
    MEMORY_LIMIT_EXCEEDED 횟수가 많으면 해당 증상입니다. 메시지에 *“maximum: N GiB”*가 표시되는데, 이 N은 파드 메모리 한도의 0.9배입니다(deploy/base/clickhouse/configmap.yamlmax_server_memory_usage_to_ram_ratio). 대용량 읽기가 N을 초과하면 거부됩니다.
  3. 문제가 아닌 것들을 배제합니다. CPU, 파트 수, 디스크가 모두 낮다면 레플리카/샤딩 추가는 낭비입니다:
원인: ClickHouse 파드의 메모리 한도가 분석 작업 집합에 비해 너무 작습니다. 가장 무거운 읽기는 원시 JSON payload 컬럼을 가져와 JSONExtract*를 실행하고 FINAL을 사용하며, 각각 수 GiB가 필요할 수 있습니다. 구성된 캐시(mark_cache_size + uncompressed_cache_size)가 파드보다 크면 동일한 예산을 소비하여 쿼리 메모리를 압박합니다. 해결 방법 — ClickHouse 메모리 확장:
  1. 오버레이에서 clickhouse StatefulSet의 컨테이너 resources를 패치하여 ClickHouse 메모리 한도를 높이세요(다른 컴포넌트의 resources에 사용하는 오버레이 메커니즘과 동일). 사용 가능한 서버 예산은 0.9 × 한도입니다. 6Gi 한도는 약 5.4GiB, 16Gi 한도는 약 14GiB입니다. requests.memory도 실제 최솟값으로 설정하여 스케줄러가 이를 예약하도록 하세요. 이를 적용하면 CH 파드가 재생성됩니다(단일 레플리카 → 약 30~60초의 분석 다운타임). 트래픽이 적은 시간에 수행하세요.
  2. `deploy/base/clickhouse/configmap