본문으로 바로가기 본문 바로가기
WIKI 기술 지식 베이스

프로그래밍 방식 접근을 위한 로그 API 옵션

원문 보기 위키 갱신

Fly.io 앱은 Firecracker 마이크로VM(저희가 Machine이라고 부르는 것)에서 실행돼요. 각 Machine은 stdout/stderr를 캡처하고, 그 로그를 NATS를 통해 보내며, 일정 기간 동안 VictoriaLogs 기반 검색 인덱스에 저장합니다. 대부분의 사용자는 fly logs로 로그를 소비하거나 외부 저장소로 로그 전송을 설정합니다. 이 문서는 CLI나 익스포터 없이 로그를 직접 가져오는 프로그래밍 방식의 옵션들을 안내합니다.

출처: 문서

본문

개요 (Overview)

Fly.io 앱은 저희가 Machine이라고 부르는 Firecracker 마이크로VM에서 실행됩니다. 각 Machine은 stdout/stderr를 캡처하고, 그 로그를 NATS를 통해 보내며, 일정 기간 동안 VictoriaLogs 기반 검색 인덱스에 저장해요. 대부분의 사용자는 fly logs로 로그를 소비하거나 외부 저장소(sink)로 로그 전송을 설정합니다.

하지만 때로는 CLI나 익스포터를 설정하지 않고 로그를 직접 가져오고 싶을 때가 있어요. 도구를 구축하고 있거나, 무언가를 자동화하고 있거나, 로그를 자체 시스템으로 파이프하고 싶기 때문이죠.


프로그래밍 방식으로 로그를 가져오는 옵션

프로그래밍 방식으로 로그를 얻을 수 있는 방법은 다음과 같습니다:

  • 문서화되지 않은 HTTP API: fly logs가 내부적으로 사용하는 것입니다.
  • NATS 프록시: 메시지 수준에서 실시간 로그를 구독합니다.
  • 외부 저장소로의 로그 전송: 로그를 다른 곳으로 수집한 다음 그 시스템으로 쿼리합니다.

각각 트레이드오프가 있어요. 영구 검색을 원하면 로그를 내보내세요. 저지연 푸시를 원하면 NATS를 사용하세요. 지금 curl로 뭔가 하고 싶다면 HTTP API를 사용하세요.

1. HTTP API (fly logs와 동일)

Fly CLI는 내부 API에 접근해 로그를 스트리밍합니다. 여러분도 사용할 수 있어요:

GET /api/v1/apps/:app_name/logs
Authorization: ***

응답은 로그 항목의 data 배열과 페이지네이션을 위한 meta.next_token 커서가 있는 JSON:API 문서입니다. 기본적으로 지난 24시간의 가장 최근 로그 100개가 반환됩니다. 다음 쿼리 매개변수를 전달해 로그를 필터링하거나 시작 타임스탬프를 설정할 수 있어요:

  • region: 세 글자 리전 코드. 이 리전의 로그만 반환합니다.
  • instance: Machine ID. 이 인스턴스의 로그만 반환합니다.
  • next_token: 나노초 단위 Unix 타임스탬프(예: 1779235200000000000). 이 시간 이후의 로그를 반환하며, 페이지네이션 커서로 사용하거나 특정 순간부터 역추적(backfill)하는 데 사용됩니다. 각 응답에는 다음 요청에 전달해 앞으로 페이지를 넘길 수 있는 meta.next_token이 포함됩니다.
    • next_token은 이전에 문서화된 start_time(ISO 8601) 매개변수를 대체합니다.

이 엔드포인트는 외부 사용을 위해 공식적으로 지원되지 않지만, 대부분 안정적입니다. flyctl이 이에 의존하기 때문이에요.

빠른 가져오기나 단순 폴링 스크립트에 사용하세요. 속도 제한이나 인증 문제가 발생하면 토큰에 앱에 대한 read 접근 권한이 있는지 확인하세요.

중요하게도, 현재 보존 기간(약 7일)까지 거슬러 올라가는 과거 로그에 접근할 수 있는 유일한 옵션이 이것입니다. 다른 옵션은 연결된 순간부터만 스트리밍을 시작합니다.

2. NATS로 로그 구독 (실험적)

로그는 다음과 같은 주제(subject)로 NATS를 통해 스트리밍됩니다:

logs.<app>.<region>.<instance>

프록시 URL을 통해 연결하고 org 슬러그와 개인 액세스 토큰으로 인증하여 NATS 클라이언트를 사용해 직접 구독할 수 있어요.

NATS 주제 예시:

logs.my-app.lhr.*

이렇게 하면 실시간으로 구조화된 JSON 로그 메시지를 얻을 수 있습니다.

**참고:** NATS 프록시는 버전이 있는 API나 안정성 보장이 없는 내부 전송입니다. 동작은 하지만, 저희가 로깅 인프라를 발전시키면서 변경될 수 있어요. 진지한 무언가를 구축한다면 로그 전송(shipper)을 통해 로그를 내보내는 것을 권장합니다.

알아두어야 할 사항:

  • 재연결 처리가 필요해요. 네트워크가 끊기거나 프록시가 다시 시작되면 구독자가 재연결하고 메시지를 잃지 않고 재개해야 합니다.
  • 백프레셔 처리가 필요합니다. 앱이 로그를 충분히 빨리 처리하지 못하면 메시지가 쌓여서 버려질 수 있어요. 소비자를 따라잡거나 정상적으로 실패하도록 설계하세요.
  • 구독자 간에 중복 제거를 원한다면 NATS 큐 그룹을 사용하세요.
  • NATS는 연결하는 순간부터만 로그를 스트리밍합니다. 처음부터 구독하지 않았다면 어떤 기록도 얻지 못해요.

Fly의 NATS 로그 스트림 연결(인증, 주제 패턴, 예제 클라이언트)에 대한 자세한 내용은 사용자 앱을 위한 관찰 가능성 가이드를 참고하세요.

3. 외부 저장소로의 로그 전송 (Log Shipper)

영구적이고 쿼리 가능한 로그를 원한다면 그것들을 내보내세요. 저희는 NATS를 수신하고 Loki, Datadog, Elastic, Honeycomb 또는 S3 같은 저장소로 로그를 전달하는 Fly Log Shipper라는 작은 앱을 유지 관리합니다.

로그 전송기는 Vector를 실행하는 프리빌트 Fly 앱으로, TOML을 통해 사용자 지정할 수 있는 구성을 갖추고 있어요. 로그 주제를 구독하고 원하는 곳 어디든 데이터를 스트리밍합니다.

예제 구성:

[sinks.loki]
type = "loki"
inputs = ["fly_logs"]
endpoint = "https://my-loki-instance.example"
encoding.codec = "json"

어떤 로그가 전달될지 제어하려면 배포 시 SUBJECT 환경 변수를 설정하세요:

SUBJECT="logs.my-app.*.*"

NATS와 마찬가지로 로그 전송기도 연결하는 순간부터의 로그만 봅니다. 오늘 배포하면 어제의 로그는 볼 수 없어요.

로그 전송기는 내부적으로 NATS를 사용합니다. Fly가 유지 관리하기 때문에 사용자 지정 NATS 클라이언트보다 인프라 변경 사항과 호환될 가능성이 더 높아요. 장기 보존, 전문 검색, 알림 또는 기존 관찰 가능성 스택과의 통합을 원한다면 가장 견고한 옵션입니다.

자세한 내용:


요약: 그래서 뭘 사용해야 하나요?

  • 스크립트에서 로그를 grep하고 싶나요? HTTP API를 사용해 보세요.
  • 자체 시스템으로 실시간 스트림을 원하나요? NATS(주의 사항 있음).
  • 안정적인 검색과 대시보드를 원하나요? 전송기로 로그를 내보내세요.

더 알아보기 (Learn more)