> ## Documentation Index
> Fetch the complete documentation index at: https://docs.befailproof.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Collector 설치

> AgentEye Collector 설치 문서입니다.

`agenteye-collector` 데몬은 애플리케이션을 차단하지 않고 에이전트의 텔레메트리를 AgentEye로 안정적으로 전송합니다. 코드는 이벤트를 로컬 디렉터리에 기록하고 즉시 다음 작업으로 넘어가며, 이후의 처리는 collector가 담당합니다. collector는 각 파일을 수 밀리초 내에 업로드하며, 재시작·네트워크 장애·일시적인 서버 오류에도 중단 없이 동작합니다. 업로드에 실패한 파일은 지수 백오프(exponential backoff)로 재시도되며, 주기적인 복구 스윕을 통해 크래시나 배포 도중 남겨진 파일도 다시 대기열에 올립니다. 결과적으로 내구성 있는 fire-and-forget 전송이 보장됩니다. 에이전트는 전속력으로 실행되고, collector가 이벤트 유실을 방지합니다.

내부적으로 collector는 경량 데몬으로, Python SDK가 작성하는 `.jsonl` 파일을 `$AGENTEYE_HOME/events/`(기본값: `~/.agenteye/events/`)에서 감시하여 AgentEye 서버에 업로드합니다.

> **이름 변경 안내:** collector 명령어가 \*\*`agenteye-collector`\*\*로 변경되었습니다(이전 이름: `agenteye`). 짧은 이름인 `agenteye`는 이제 AgentEye CLI에서 사용합니다. 기존 설치를 업그레이드하는 경우 [enterprise-docs/collector-migration.md](/ko/agenteye/collector-migration)를 참조하세요.

***

## 사전 요구사항

* `AGENTEYE_TOKEN`: 직접 생성하는 GitHub PAT([enterprise-docs/github-token.md](/ko/agenteye/github-token) 참조)
* 서버 URL 및 collector API 키([enterprise-docs/api-keys.md](/ko/agenteye/api-keys) 참조)

***

## 옵션 A: 바이너리 (권장)

Linux, macOS, Windows(x86\_64 및 arm64)용 사전 빌드된 정적 바이너리를 제공합니다. 최신 `collector/v<version>` 릴리스 태그 아래의 `agenteye-enterprise/releases` 저장소에서 플랫폼에 맞는 바이너리를 직접 다운로드하세요.

사용 가능한 아티팩트 이름:

| 플랫폼             | 아티팩트                                    |
| --------------- | --------------------------------------- |
| Linux x86\_64   | `agenteye-collector-linux-x86_64`       |
| Linux arm64     | `agenteye-collector-linux-arm64`        |
| macOS x86\_64   | `agenteye-collector-darwin-x86_64`      |
| macOS arm64     | `agenteye-collector-darwin-arm64`       |
| Windows x86\_64 | `agenteye-collector-windows-x86_64.exe` |
| Windows arm64   | `agenteye-collector-windows-arm64.exe`  |

**`gh` CLI로 다운로드** (버전을 교체하고 플랫폼에 맞는 아티팩트를 선택하세요):

```bash theme={null}
VERSION=0.0.1-beta.13
GITHUB_TOKEN=$AGENTEYE_TOKEN gh release download "collector/v${VERSION}" \
  --repo agenteye-enterprise/releases \
  --pattern 'agenteye-collector-linux-x86_64'

chmod +x agenteye-collector-linux-x86_64
sudo mv agenteye-collector-linux-x86_64 /usr/local/bin/agenteye-collector
```

**또는 `curl`로 다운로드:**

```bash theme={null}
VERSION=0.0.1-beta.13
ARTIFACT=agenteye-collector-linux-x86_64
curl -fsSL \
  -H "Authorization: token $AGENTEYE_TOKEN" \
  -L "https://github.com/agenteye-enterprise/releases/releases/download/collector%2Fv${VERSION}/${ARTIFACT}" \
  -o agenteye-collector
chmod +x agenteye-collector
sudo mv agenteye-collector /usr/local/bin/agenteye-collector
```

***

## 옵션 B: Docker

```bash theme={null}
echo $AGENTEYE_TOKEN | docker login ghcr.io -u x --password-stdin
docker pull ghcr.io/agenteye-enterprise/collector:beta-latest
```

> 현재 베타 빌드는 부동 태그(floating tag)인 `:beta-latest`로 게시됩니다. `:latest`는 안정 릴리스에만 부여됩니다. 재현 가능한 배포를 위해 `:v0.0.1-beta.13`과 같이 특정 버전 태그를 고정해서 사용하는 것을 권장합니다.

**실행:**

```bash theme={null}
docker run -d --restart unless-stopped \
  --name agenteye-collector \
  -e AGENTEYE_URL=https://ingest.example.com/events \
  -e AGENTEYE_KEY="$AGENTEYE_KEY" \
  -e AGENTEYE_HOME=/data \
  -v "$HOME/.agenteye:/data" \
  ghcr.io/agenteye-enterprise/collector:beta-latest \
  start
```

공식 이미지는 비루트(non-root) 사용자로 실행되므로 `AGENTEYE_HOME`을 명시적으로 설정하고 호스트 스풀 디렉터리를 마운트해야 합니다. 볼륨 마운트는 호스트에서 Python SDK가 쓰는 `~/.agenteye/` 디렉터리를 공유합니다. 호스트에서 이미 `AGENTEYE_HOME`을 다른 경로로 설정한 경우, `$HOME/.agenteye` 대신 해당 디렉터리를 마운트하세요.

***

## 설정

모든 옵션은 아래 세 가지 방법으로 설정할 수 있으며, 우선순위는 높은 것부터 낮은 순서입니다:

1. CLI 플래그: `agenteye-collector start --url https://...`
2. 환경 변수: `AGENTEYE_URL=https://...`
3. 설정 파일: `~/.agenteye/config.json`

### 필수 옵션

| 옵션      | CLI 플래그       | 환경 변수          | config.json 키 |
| ------- | ------------- | -------------- | ------------- |
| 백엔드 URL | `--url <URL>` | `AGENTEYE_URL` | `"url"`       |
| API 키   | `--key <KEY>` | `AGENTEYE_KEY` | `"key"`       |

### 선택 옵션 (기본값 포함)

| 옵션             | CLI 플래그                        | 환경 변수                             | config.json 키              | 기본값    |
| -------------- | ------------------------------ | --------------------------------- | -------------------------- | ------ |
| 최대 동시 업로드 수    | `--max-concurrent-uploads <N>` | `AGENTEYE_MAX_CONCURRENT_UPLOADS` | `"max_concurrent_uploads"` | `64`   |
| 스윕 간격(초)       | `--sweep-interval <S>`         | `AGENTEYE_SWEEP_INTERVAL`         | `"sweep_interval_secs"`    | `60`   |
| 스윕 최소 파일 나이(초) | `--sweep-min-age <S>`          | `AGENTEYE_SWEEP_MIN_AGE`          | `"sweep_min_age_secs"`     | `120`  |
| 스윕당 최대 파일 수    | `--sweep-max-files <N>`        | `AGENTEYE_SWEEP_MAX_FILES`        | `"sweep_max_files"`        | `64`   |
| 최대 업로드 시도 횟수   | `--max-retries <N>`            | `AGENTEYE_MAX_RETRIES`            | `"max_retries"`            | `5`    |
| 재시도 기본 지연(ms)  | `--retry-base-delay <MS>`      | `AGENTEYE_RETRY_BASE_DELAY`       | `"retry_base_delay_ms"`    | `1000` |

### mTLS 옵션 (선택)

상호 TLS(mTLS)가 필요한 배포 환경에서 collector는 TLS 핸드셰이크 시 클라이언트 인증서를 제시할 수 있습니다. 이 옵션을 설정하지 않으면 collector는 표준 HTTPS를 사용합니다.

| 옵션              | CLI 플래그             | 환경 변수               | config.json 키 |
| --------------- | ------------------- | ------------------- | ------------- |
| 클라이언트 인증서(PEM)  | `--tls-cert <PATH>` | `AGENTEYE_TLS_CERT` | `"tls_cert"`  |
| 클라이언트 개인 키(PEM) | `--tls-key <PATH>`  | `AGENTEYE_TLS_KEY`  | `"tls_key"`   |
| 커스텀 CA 인증서(PEM) | `--tls-ca <PATH>`   | `AGENTEYE_TLS_CA`   | `"tls_ca"`    |

`--tls-cert`와 `--tls-key`는 반드시 함께 설정해야 합니다. 파일은 PEM 형식으로 인코딩되어야 합니다.

`--tls-ca`는 독립적으로 사용할 수 있으며, AgentEye 서버가 공개적으로 신뢰받는 CA가 발급하지 않은 TLS 인증서(예: 실제 DNS 도메인 없이 클러스터 내 `cert-manager` 이슈어가 자체 서명한 인증서)를 사용할 때만 필요합니다. collector는 지정한 CA를 추가 신뢰 앵커로 추가하며, 기존 공개 루트 CA는 계속 신뢰되므로 기존 배포에는 영향이 없습니다. 파일에는 단일 PEM 인증서 또는 전체 체인(여러 PEM 블록을 연결한 형태) 모두 사용할 수 있습니다.

**애플리케이션 파드의 사이드카로 collector를 실행하시나요?** AWS Secrets Manager + Secrets Store CSI Driver + IRSA를 통한 mTLS 번들 전달 및 자동 교체를 포함한 엔드투엔드 EKS 패턴은 [enterprise-docs/single-pod-deployment.md](/ko/agenteye/single-pod-deployment)를 참조하세요.

Secret 핸드오프 패턴으로 Kubernetes에서 실행할 때, 인증서 Secret을 볼륨으로 마운트하고 해당 경로를 지정하세요:

```yaml theme={null}
# 예시: collector Deployment 스니펫
volumes:
  - name: mtls-certs
    secret:
      secretName: agenteye-collector-mtls
containers:
  - name: collector
    env:
      - name: AGENTEYE_TLS_CERT
        value: /etc/agenteye/tls/tls.crt
      - name: AGENTEYE_TLS_KEY
        value: /etc/agenteye/tls/tls.key
      # 서버 인증서가 공개적으로 신뢰받지 않는 경우에만 설정
      # (예: 클러스터 내 자체 서명 CA). 동일한 Secret에
      # tls.crt/tls.key와 함께 ca.crt가 포함되는 경우가 많습니다.
      - name: AGENTEYE_TLS_CA
        value: /etc/agenteye/tls/ca.crt
    volumeMounts:
      - name: mtls-certs
        mountPath: /etc/agenteye/tls
        readOnly: true
```

### `~/.agenteye/config.json` 예시

```json theme={null}
{
  "url": "https://ingest.example.com/events",
  "key": "sk-...",
  "max_concurrent_uploads": 16,
  "sweep_interval_secs": 30
}
```

mTLS 적용 시:

```json theme={null}
{
  "url": "https://ingest.example.com/events",
  "key": "sk-...",
  "tls_cert": "/etc/agenteye/tls/tls.crt",
  "tls_key": "/etc/agenteye/tls/tls.key"
}
```

mTLS + 커스텀 CA(자체 서명 AgentEye 서버) 적용 시:

```json theme={null}
{
  "url": "https://ingest.example.com/events",
  "key": "sk-...",
  "tls_cert": "/etc/agenteye/tls/tls.crt",
  "tls_key": "/etc/agenteye/tls/tls.key",
  "tls_ca": "/etc/agenteye/tls/ca.crt"
}
```

`AGENTEYE_HOME`이 설정된 경우 `~/.agenteye` 대신 해당 디렉터리가 사용됩니다.

***

## 초기 설정

설치 후 서버 URL과 API 키로 collector를 설정합니다:

```bash theme={null}
mkdir -p ~/.agenteye
cat > ~/.agenteye/config.json <<'EOF'
{
  "url": "https://ingest.example.com/events",
  "key": "YOUR_COLLECTOR_KEY"
}
EOF
```

> 신뢰할 수 없는 네트워크를 경유하는 모든 배포 환경에서는 `https`를 사용하여 이벤트가 평문으로 전송되지 않도록 하세요. 평문 형식인 `http://your-server-host:8080/events`는 동일 호스트에서 서버를 대상으로 순수 로컬 테스트를 할 때만 적합합니다.

**연결 테스트** (일회성 플러시, 대기 중인 이벤트를 모두 전송한 후 종료):

```bash theme={null}
agenteye-collector flush
```

`flush`는 진행 상황을 stdout에 출력합니다. 스풀이 비어 있으면 `No pending files.`를 출력하고 `0`으로 종료합니다. 그렇지 않으면 파일별로 한 줄씩(`[UPLOADED] <file>` 또는 `[FAILED] <file> (<reason>)`) 출력한 후, `Done: <uploaded>/<total> uploaded, <failed> failed.` 요약을 출력합니다. 이를 통해 데몬을 시작하기 전에 URL, 키, TLS 설정이 올바른지 편리하게 확인할 수 있습니다.

***

## 데몬으로 실행

### 직접 실행

```bash theme={null}
agenteye-collector start
```

### 컨테이너 / Docker

collector와 애플리케이션이 같은 컨테이너를 공유하는 경우, 프로세스 슈퍼바이저 아래에서 실행하세요. 가장 간단한 옵션은 `supervisord`입니다. 주요 배포판에 모두 포함되어 있으며, 크래시된 프로세스를 재시작하고, 시그널을 전달하며, 우아한 종료를 기다립니다.

**`Dockerfile`:**

```Dockerfile theme={null}
FROM python:3.11-slim

RUN apt-get update && apt-get install -y --no-install-recommends supervisor \
 && rm -rf /var/lib/apt/lists/*

# 공식 이미지에서 agenteye-collector 바이너리를 가져옵니다.
# 특정 태그를 고정하세요 (현재 베타는 :beta-latest, 또는 :v<version> 태그).
# :latest는 안정 릴리스에만 게시됩니다.
COPY --from=ghcr.io/agenteye-enterprise/collector:beta-latest \
     /usr/local/bin/agenteye-collector /usr/local/bin/agenteye-collector

COPY supervisord.conf /etc/supervisor/conf.d/agenteye.conf
COPY my_agent.py      /app/my_agent.py

CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"]
```

**`supervisord.conf`:**

```ini theme={null}
[supervisord]
nodaemon=true
user=root

[program:agenteye-collector]
command=/usr/local/bin/agenteye-collector start
autorestart=true
stopwaitsecs=30
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

[program:app]
command=python /app/my_agent.py
autorestart=unexpected
stopwaitsecs=30
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
```

각 설정의 이유:

* agenteye-collector의 `autorestart=true`: 어떤 이유로든 종료 시 재시작(크래시, 패닉, OOM 포함).
* 앱의 `autorestart=unexpected`: 비정상 종료 시에만 재시작하므로, 0으로 종료하는 일회성 에이전트가 반복 실행되지 않습니다.
* `stopwaitsecs=30`: SIGTERM 수신 후 supervisord가 SIGKILL로 에스컬레이션하기 전에 collector가 대기 중인 업로드를 처리할 시간을 줍니다.
* `stdout_logfile=/dev/stdout`, `*_maxbytes=0`: 두 프로그램의 출력을 컨테이너 stdout으로 스트리밍하며, 컨테이너 내부에 로그 파일을 생성하지 않습니다.

`AGENTEYE_URL` / `AGENTEYE_KEY`(및 TLS 환경 변수)는 기존과 동일하게 `docker run -e`로 전달하세요. supervisord는 환경 변수를 상속합니다.

> **컨테이너를 분리해서 실행하시나요?** collector를 별도 컨테이너(Docker Compose 서비스, Kubernetes 사이드카 등)로 실행하는 경우 supervisord를 사용하지 마세요. 컨테이너 런타임의 재시작 정책이 이미 그 역할을 담당합니다. EKS 사이드카 패턴은 [enterprise-docs/single-pod-deployment.md](/ko/agenteye/single-pod-deployment)를 참조하세요.

**Kubernetes 활성 프로브(liveness probe)** (collector가 단독 또는 supervisord 아래에서 실행되는 경우 모두 적용):

```yaml theme={null}
livenessProbe:
  exec:
    command: ["agenteye-collector", "health"]
  initialDelaySeconds: 10
  periodSeconds: 30
```

실행 중인 데몬은 30초마다 `$AGENTEYE_HOME/health.json`에 하트비트를 기록합니다. `agenteye-collector health`는 해당 파일을 읽어, 하트비트가 최신 상태이고 업로드 태스크가 정상적으로 실행 중일 때만 `0`(정상)으로 종료합니다. 하트비트가 90초보다 오래된 경우(예: 데몬이 중지됨) 또는 예기치 않은 종료 후 watcher와 sweeper가 재시작 중인 경우에는 `1`(비정상)로 종료합니다. 하트비트는 `start`에서만 기록되므로, 일회성 `flush` 명령이 아닌 장시간 실행되는 데몬에 대해 프로브를 실행하세요.

### systemd (Linux, 프로덕션 권장)

```ini theme={null}
# /etc/systemd/system/agenteye-collector.service
[Unit]
Description=AgentEye Collector
After=network.target

[Service]
ExecStart=/usr/local/bin/agenteye-collector start
Restart=on-failure
RestartSec=5
EnvironmentFile=/etc/agenteye/env

[Install]
WantedBy=multi-user.target
```

`/etc/agenteye/env` 생성:

```
AGENTEYE_URL=https://ingest.example.com/events
AGENTEYE_KEY=YOUR_COLLECTOR_KEY
```

```bash theme={null}
sudo systemctl daemon-reload
sudo systemctl enable --now agenteye-collector
sudo systemctl status agenteye-collector
```

### launchd (macOS)

```xml theme={null}
<!-- ~/Library/LaunchAgents/ai.befailproof.agenteye-collector.plist -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>ai.befailproof.agenteye-collector</string>
  <key>ProgramArguments</key>
  <array>
    <string>/usr/local/bin/agenteye-collector</string>
    <string>start</string>
  </array>
  <key>EnvironmentVariables</key>
  <dict>
    <key>AGENTEYE_URL</key>
    <string>https://ingest.example.com/events</string>
    <key>AGENTEYE_KEY</key>
    <string>YOUR_COLLECTOR_KEY</string>
  </dict>
  <key>RunAtLoad</key>
  <true/>
  <key>KeepAlive</key>
  <true/>
</dict>
</plist>
```

```bash theme={null}
launchctl load ~/Library/LaunchAgents/ai.befailproof.agenteye-collector.plist
```

***

## Collector 업그레이드

collector는 자동으로 업데이트되지 않습니다. 업그레이드 방법:

* **바이너리:** 최신 `collector/v<version>` 릴리스에서 새 `agenteye-collector-<os>-<arch>` 아티팩트를 다운로드하고([옵션 A](#option-a-binary-recommended) 참조), `/usr/local/bin/agenteye-collector`를 교체한 후 서비스를 재시작합니다(`sudo systemctl restart agenteye-collector`, `launchctl load` 재실행, 또는 슈퍼바이저 재시작).
* **Docker:** `docker pull ghcr.io/agenteye-enterprise/collector:beta-latest`(또는 고정된 `:v<version>` 태그; `:latest`는 안정 릴리스에만 존재)를 실행하고 컨테이너를 재생성합니다.

`AGENTEYE_TOKEN`은 비공개 릴리스 저장소에서 새 바이너리/이미지를 다운로드할 때 필요하지만, 실행 중인 데몬에는 **필요하지 않습니다**.

***

## 서브커맨드

| 명령어                         | 설명                                                                                                                                                                               |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `agenteye-collector start`  | 장시간 실행 데몬을 시작합니다. 시작 시 이전 실행에서 남은 이벤트를 플러시한 후, 새 파일을 감시하며 업로드합니다. watcher와 sweeper는 예기치 않은 종료 시 자동 재시작되며, 30초마다 `health.json`에 하트비트를 기록합니다.                                      |
| `agenteye-collector flush`  | 일회성 실행: 대기 중인 모든 파일을 업로드하고 종료합니다. 스풀이 비어 있으면 `No pending files.`를 출력하고, 그렇지 않으면 파일별 `[UPLOADED]`/`[FAILED]` 로그와 `Done: <uploaded>/<total> uploaded, <failed> failed.` 요약을 출력합니다. |
| `agenteye-collector health` | 데몬의 `health.json` 하트비트를 읽습니다. 최신 상태이고 정상이면 `0`으로 종료하고, 하트비트가 오래되었거나(90초 초과) 태스크가 재시작 중이면 `1`로 종료합니다.                                                                             |

***

## 디렉터리 구조

```
~/.agenteye/
├── config.json       <- 선택적 설정 파일
├── events/           <- SDK가 작성하는 .jsonl 파일, collector가 처리
└── failed/           <- 모든 업로드 시도에 실패한 파일
```

`failed/`의 파일은 자동으로 재시도되지 않습니다. 수동으로 재대기열에 넣으려면 해당 파일을 `events/`로 이동한 후 `agenteye-collector flush`를 실행하세요.
