Blob 스토리지로 내보내기(Export to blob storage)
Blob 스토리지로 내보내기(Export to blob storage)
20분, 매시간, 매일, 매주 단위로 Amazon S3, S3 호환 스토리지, Google Cloud Storage, 또는 Azure Blob Storage로 내보내기를 예약할 수 있습니다. 이 문서는 엑스포트 통합을 구성하는 방법, 매니페스트 기반으로 엑스포트를 처리하는 방법, 그리고 legacy 엑스포트를 enriched observations로 업그레이드하는 방법을 다룹니다.
출처: 문서
본문
이 기능은 어디에서 쓸 수 있나요?
| 플랜 | 사용 가능 여부 |
|---|---|
| Hobby | 사용 불가 |
| Core | 사용 불가 |
| Pro | Teams Add-on 필요 |
| Enterprise | 사용 가능 |
| Self Hosted | 사용 가능 |
개요(Overview)
Amazon S3, S3 호환 스토리지, Google Cloud Storage, 또는 Azure Blob Storage로 20분, 매시간, 매일, 매주 단위로 내보내기를 예약할 수 있습니다.
엑스포트 구성
통합 만들기
- Project Settings > Integrations > Blob Storage를 엽니다.
- 제공자를 선택하고 버킷, 경로, 자격 증명을 입력합니다. 셀프 호스터는 blob storage 배포 페이지 에서 벤더별 버킷/자격 증명 설정을 참고하세요.
- 파일 형식, 스케줄, 내보내기 모드, 필드 그룹을 선택합니다.
- 통합을 활성화하고 저장합니다. 첫 실행이 곧 시작됩니다.
| 설정 | 선택 및 동작 |
|---|---|
| Provider and access | AWS S3, S3 Compatible Storage, 또는 Azure Blob Storage. Google Cloud Storage는 S3 Compatible Storage를 통해 연결됩니다: 엔드포인트를 https://storage.googleapis.com으로 설정하고 서비스 계정 대신 HMAC 키 쌍으로 인증 |
| Format | Parquet(기본), CSV, JSON, 또는 JSONL. 텍스트 형식은 gzip 압축 가능. Parquet는 자체 인코딩과 압축 사용 |
| Schedule | 20분마다, 매시간, 매일, 매주. 각 실행은 하나의 시간 창을 내보냄 |
| Export Mode | Full history는 프로젝트의 가장 오래된 데이터에서 시작. From setup date는 통합이 활성화된 시점에 시작. From custom date는 선택한 날짜에서 시작. 이 설정을 변경하면 동기화 위치가 재설정되고 그 지점부터 다시 스캔 |
통합 설정 페이지는 상태 배지를 보여줍니다:
| 배지 | 의미 |
|---|---|
| Active | 활성화되어 동기화됨. 다음 실행이 예약됨 |
| Running | 실행 진행 중 |
| Queued | 실행 예정이며 대기 중 |
| Pending | 활성화됐지만 아직 실행되지 않음 |
| Disabled | 꺼짐 |
| Error | 마지막 실행 실패. 메시지와 타임스탬프가 표시됨 |
Parquet 참고 사항
- observation 파일은
input_price,output_price,total_price를 생략합니다.cost_details와total_cost를 사용하세요. trace와 score 필드는 영향 없음. - 25.11보다 오래된 셀프 호스팅 ClickHouse에서는 ClickHouse를 업그레이드하거나 CSV, JSON, JSONL을 사용하세요. 불완전한 Parquet 출력이 보고되지 않을 수 있기 때문입니다.
저장 전에 Validate를 사용해 Langfuse가 제공된 자격 증명으로 대상을 접근할 수 있는지 확인하세요. 통합은 버킷의 다른 객체를 바꾸지 않고 구성된 프리픽스 아래의 모든 출력을 씁니다.
Langfuse는 내 버킷에 다음 구조로 엑스포트를 씁니다:
{prefix}{project-id}/
├── observations_v2/
│ └── {timestamp}.{parquet|json|jsonl|csv}[.gz]
├── scores/
│ └── {timestamp}.{parquet|json|jsonl|csv}[.gz]
└── manifests/
└── {timestamp}.json
필드 선택
Observation 컬럼은 구성할 수 있고, score 컬럼은 고정입니다.
새 통합은 11개 필드 그룹을 모두 선택합니다. core는 필수입니다. 파일 크기를 줄이거나 민감한 데이터를 생략하려면 다른 그룹을 비활성화하세요.
| 그룹 | 필드 |
|---|---|
core |
end_time, id, parent_observation_id, project_id, start_time, trace_id, type |
basic |
bookmarked, environment, is_root_observation, level, name, public, session_id, status_message, user_id, version |
time |
completion_start_time, created_at, updated_at |
io |
input, output |
metadata |
metadata |
model |
input_price, model_id, model_parameters, output_price, provided_model_name, total_price |
usage |
cost_details, total_cost, usage_details, usage_pricing_tier_id, usage_pricing_tier_name |
prompt |
prompt_id, prompt_name, prompt_version |
metrics |
latency, time_to_first_token |
trace_context |
release, tags, trace_name |
tools |
tool_call_names, tool_calls, tool_definitions |
변경 사항은 향후 엑스포트에만 적용됩니다. 타입과 설명은 observation field reference 를 참고하세요.
Scores는 항상 내보내지며 필드를 선택할 수 없습니다.
| 카테고리 | 필드 |
|---|---|
| Identity | id, project_id, timestamp, created_at, updated_at |
| Context and links | trace_id, observation_id, session_id, dataset_run_id, environment |
| Score | name, data_type, value, string_value, source, comment |
score field reference 에서 타입과 설명을 참고하세요.
API로 구성
공개 엔드포인트로 통합을 읽거나 업데이트할 수 있습니다:
GET /api/public/integrations/blob-storage
PUT /api/public/integrations/blob-storage
PUT에서 exportFieldGroups는 core를 포함해야 합니다. 속성을 생략하면 현재 선택을 유지합니다. compressed는 CSV, JSON, JSONL에만 적용됩니다.
인증, 제공자 설정, 전체 스키마는 REST API reference 를 참고하세요.
엑스포트 처리(Process exports)
각 실행의 매니페스트를 작업 단위로 사용하세요.
엑스포트 완료 시점 알기
실행은 매니페스트가 {prefix}{project-id}/manifests/{timestamp}.json에 존재할 때만 완료됩니다. Langfuse는 모든 데이터 파일이 성공적으로 업로드된 후에 이를 씁니다.
업로드가 실패하면 매니페스트가 쓰이지 않습니다. 실행이 재시도되고 같은 키 아래의 데이터 객체는 덮어써집니다.
매니페스트가 나타나면:
files[]를 읽으세요.files[].key의 모든 전체 객체 키를 가져오세요. 파일 이름을 유도하거나 테이블 디렉토리를 나열하지 마세요.- 인접한 엑스포트 창이 포함 경계(inclusive boundary)를 공유하므로 ID로 레코드를 중복 제거하세요.
| 필드 | 용도 |
|---|---|
window |
실행에 대한 포함하는 minTimestamp와 maxTimestamp |
exportSource, tables |
포함된 엑스포트 소스와 테이블 |
files[] |
각 데이터 파일의 객체 키, 테이블, 형식, 압축, 업로드 크기, 행 수 |
Parquet의 경우 files[].rowCount는 null입니다. 개수가 필요하면 파일 메타데이터를 검사하세요. 알 수 없는 매니페스트 필드는 무시하세요. 추가 변경이 파서를 깨뜨리지 않도록 하기 위함입니다.
파이프라인 트리거
{prefix}{project-id}/manifests/로 필터링된 object-created 이벤트를 구독한 뒤 매니페스트를 가져와 각 files[].key를 처리하세요.
- Amazon S3: S3 Event Notifications 또는 EventBridge
- Google Cloud Storage:
OBJECT_FINALIZE용 Pub/Sub notifications - Azure Blob Storage:
Microsoft.Storage.BlobCreated용 Event Grid - MinIO: bucket notifications
- Backblaze B2: event notifications
내 S3 호환 제공자에 object-created 이벤트가 없다면 매니페스트 프리픽스를 폴링하고 마지막으로 처리한 키를 체크포인트하세요. 매니페스트 이름은 엑스포트 타임스탬프 순으로 정렬됩니다.
매니페스트 처리를 멱등적(idempotent)으로 만드세요. 제공자 이벤트는 두 번 이상 전달될 수 있고, 따라잡기(catch-up)는 몇 개의 매니페스트를 가까이 생성할 수 있습니다.
legacy 엑스포트 업그레이드
내 통합이 Traces and observations (legacy) 를 사용하거나 버킷이 traces/와 observations/ 파일을 받는다면 이 업그레이드를 완료하세요. Langfuse Cloud에서 남은 legacy 엑스포트는 2026년 11월 16일(2026-11-16)에 전환됩니다. 셀프 호스팅 v4에서 legacy 소스는 서버가 events_only로 전환된 후 데이터 생산을 중단합니다.
엑스포트 데이터의 변경 사항
Legacy 소스는 observation 데이터를 observations/에, trace 컨텍스트를 별도 traces/ 파일에 쓰며, 소비자가 trace_id로 조인합니다. Enriched 소스는 각 observation 행이 이미 trace 컨텍스트를 담은 단일 observations_v2/ 파일을 씁니다.
필드 그룹 은 두 observation 파일의 컬럼을 선택합니다. 세 그룹은 legacy observations/ 파일에서 필드가 더 적고 나머지는 동일합니다:
| 그룹 | observations_v2/ |
observations/ |
|---|---|---|
basic |
bookmarked, environment, is_root_observation, level, name, public, session_id, status_message, user_id, version |
environment, level, name, status_message, version |
usage |
cost_details, total_cost, usage_details, usage_pricing_tier_id, usage_pricing_tier_name |
동일, usage_pricing_tier_id 없음 |
trace_context |
release, tags, trace_name |
효과 없음. 이 필드들은 traces/ 파일에 있음(trace_name은 name) |
traces/ 파일 자체는 필드 그룹이 적용되지 않는 고정 스키마를 가집니다. trace 수준의 input, output, metadata, timestamp, version은 observations_v2/에 직접 대응물이 없습니다. 거기서 같은 이름의 필드는 observation 수준 데이터를 담습니다.
각 파일의 모든 컬럼은 legacy field reference 를 참고하세요.
Enriched observations로 전환
소비자가 enriched 레이아웃을 지원하면 대부분의 통합은 바로 전환할 수 있습니다:
- 셀프 호스팅 Langfuse v4는 먼저 서버를
dual쓰기 모드로 전환 하고 과거 데이터 마이그레이션을 완료 하세요. - Enriched 엑스포트 소스는 배포가 v4 이벤트 테이블을 쓰는 것을 요구하므로
legacy쓰기 모드에서만 사용할 수 없습니다. Legacy 엑스포트 소스는 기본값인events_only에서는 사용할 수 없습니다. 서버의events_only컷오버 전에 통합을 전환하세요. - 새 소비자를 준비합니다. 각 매니페스트의
files[].key에서observations_v2/와scores/를 처리합니다. enriched field reference 를 사용하세요. - 엑스포트를 전환합니다. Enriched observations (recommended) 를 선택합니다.
- 검증하고 legacy를 폐기합니다. 새 소비자로 다음 완료된 엑스포트를 처리합니다. 성공하면
traces/와observations/를 읽는 소비자를 폐기합니다.
선택: 컷오버 동안 두 레이아웃 모두 유지.
파이프라인이 컷오버 공백을 견딜 수 없다면 1단계 후 일시적으로 Traces and observations (legacy) and enriched observations를 선택하세요. 이는 이후 창에 대해서만 observations/와 observations_v2/를 씁니다. 이전 엑스포트를 backfill하지는 않습니다. 새 것이 검증될 때까지 두 소비자를 모두 실행한 뒤 2단계로 계속하세요.
두 observation 레이아웃을 같은 프로덕션 데이터셋에 로드하지 마세요. 이 옵션을 사용할 수 없으면 export compatibility matrix 를 확인하세요.
컷오버 체크
- 모든 배포: 전환 후
traces/와observations/는 빈 파일 포함해 파일을 더 이상 받지 않습니다. 실행 완료 신호로manifests/를 사용하세요. - Langfuse Cloud: 엑스포트를 처리할 때
DEPRECATION_NOTICE.txt는 무시하세요. 실행의 일부가 아닙니다. - 셀프 호스팅 Langfuse v4:
dual이 두 레이아웃 모두 선택 가능한 유일한 쓰기 모드이므로 위의 선택적 이중 레이아웃 검증은 이를 요구합니다.
엑스포트 필드 참조(Export field reference)
각 엑스포트 파일의 필드 이름과 타입입니다. 타입은 JSON과 JSONL 출력과 일치합니다. 타임스탬프는 UTC의 YYYY-MM-DD HH:MM:SS.ffffff를 사용합니다. 각 스키마는 아래에 있을 때 축약됩니다.
| 파일 | 내보내지는 시점 | 스키마 |
|---|---|---|
observations_v2/ |
현재 enriched 엑스포트 | Enriched observations |
scores/ |
모든 엑스포트 | Scores |
traces/ |
deprecated legacy 엑스포트 | Legacy exports |
observations/ |
deprecated legacy 엑스포트 | Legacy exports |
Enriched observations — observations_v2/
각 행은 하나의 observation을 나타내며 trace 컨텍스트를 포함합니다. 선택한 필드 그룹 만 나타납니다. core는 항상 포함됩니다.
| 필드 | 타입 | 설명 |
|---|---|---|
id |
string | 고유 observation 식별자 |
trace_id |
string | 관련 observations와 scores가 공유하는 trace 식별자 |
project_id |
string | Langfuse 프로젝트 식별자 |
environment |
string | 환경 라벨 |
type |
string | observation 타입: SPAN, GENERATION, EVENT, AGENT, TOOL, CHAIN, RETRIEVER, EVALUATOR, EMBEDDING, 또는 GUARDRAIL |
parent_observation_id |
string | 부모 observation 식별자. 루트 observation이면 빈 값 |
is_root_observation |
boolean | observation이 논리적 루트인지 여부 |
start_time |
string (timestamp) | observation 시작 시점 |
end_time |
string (timestamp) 또는 null | observation 종료 시점 |
name |
string | 사용자 정의 observation 이름 |
metadata |
object | 사용자 제공 observation 메타데이터 |
level |
string | DEBUG, DEFAULT, WARNING, 또는 ERROR |
status_message |
string | 상태 또는 오류 메시지 |
version |
string | 사용자 정의 버전 |
input |
string | observation 입력. 일반 텍스트 또는 JSON일 수 있음 |
output |
string | observation 출력. 일반 텍스트 또는 JSON일 수 있음 |
provided_model_name |
string | SDK 또는 사용자가 제공한 모델 이름 |
model_parameters |
string | JSON으로 인코딩된 모델 매개변수 |
usage_details |
object (string → integer) | input, output, total 같은 카테고리별 토큰 사용량 |
cost_details |
object (string → number) | 카테고리별 USD 비용 |
completion_start_time |
string (timestamp) 또는 null | 첫 스트리밍 토큰이 생성된 시점 |
prompt_name |
string | Langfuse 프롬프트 이름 |
prompt_version |
integer 또는 null | Langfuse 프롬프트 버전 |
total_cost |
number | USD 총 observation 비용. 비용이 기록되지 않으면 0 |
latency |
number 또는 null | 초 단위 지속 시간 |
time_to_first_token |
number 또는 null | 첫 토큰까지의 시간(초) |
model_id |
string | 매칭된 Langfuse 모델 정의 식별자 |
created_at |
string (timestamp) | 행 생성 시각 |
updated_at |
string (timestamp) | 마지막 행 업데이트 시각 |
prompt_id |
string | Langfuse 프롬프트 식별자 |
tool_calls |
array of strings | JSON 문자열로 인코딩된 툴 호출 |
tool_call_names |
array of strings | 호출된 툴 이름 |
tool_definitions |
object | 모델에 제공된 툴 또는 함수 스키마 |
usage_pricing_tier_id |
string 또는 null | 비용 계산에 사용된 가격 티어 식별자 |
usage_pricing_tier_name |
string 또는 null | 비용 계산에 사용된 가격 티어 이름 |
input_price |
string 또는 null | 매칭된 단위당 입력 가격. Parquet에서 생략 |
output_price |
string 또는 null | 매칭된 단위당 출력 가격. Parquet에서 생략 |
total_price |
string 또는 null | 매칭된 호출당 고정 가격. Parquet에서 생략 |
user_id |
string | trace의 최종 사용자 식별자 |
session_id |
string | trace의 세션 식별자 |
trace_name |
string | trace 이름 |
tags |
array of strings | trace 태그 |
release |
string | trace 릴리스 |
bookmarked |
boolean | trace가 북마크됐는지 여부 |
public |
boolean | trace가 공개인지 여부 |
2026-04-01 이후 생성된 통합은 latency와 time_to_first_token을 초 단위로 내보냅니다. 이전 통합은 역호환성을 위해 이 필드를 밀리초로 내보냅니다.
Scores — scores/
Scores는 항상 내보내집니다. 필드는 구성할 수 없습니다. 데이터 타입이 NUMERIC, BOOLEAN, CATEGORICAL, 또는 TEXT인 점수가 포함됩니다. corrections(데이터 타입 CORRECTION)는 포함되지 않습니다.
| 필드 | 타입 | 설명 |
|---|---|---|
id |
string | 고유 점수 식별자 |
timestamp |
string (timestamp) | 점수 생성 시각 |
project_id |
string | Langfuse 프로젝트 식별자 |
environment |
string | 환경 라벨 |
trace_id |
string 또는 null | 연결된 trace 식별자 |
observation_id |
string 또는 null | 연결된 observation 식별자 |
session_id |
string 또는 null | 연결된 세션 식별자 |
dataset_run_id |
string 또는 null | 연결된 데이터셋 run 식별자 |
name |
string | 점수 이름 |
value |
number | 숫자 값. TEXT 점수는 0 사용 |
source |
string | API, ANNOTATION, 또는 EVAL |
comment |
string 또는 null | 선택적 코멘트 또는 평가자 근거 |
data_type |
string | NUMERIC, BOOLEAN, CATEGORICAL, 또는 TEXT |
string_value |
string 또는 null | 카테고리 라벨 또는 텍스트 값. 숫자 점수는 null |
created_at |
string (timestamp) | 행 생성 시각 |
updated_at |
string (timestamp) | 마지막 행 업데이트 시각 |
Legacy exports — traces/ and observations/
Legacy 엑스포트는 deprecated입니다. trace 컨텍스트를 traces/로, observation 데이터를 observations/로 나누며 소비자가 trace_id로 조인합니다. 소비자를 바꾸기 전에 legacy 엑스포트 업그레이드 를 확인하세요.
Traces (traces/)
trace 파일은 고정 스키마를 가지며 필드 그룹이 적용되지 않습니다.
주요 필드: id(string, 고유 trace 식별자), timestamp(string timestamp, trace 생성 시각), name(string, 사용자 정의 trace 이름), environment(string), project_id(string), metadata(object, trace 메타데이터), user_id(string|null), session_id(string|null), release(string|null, 애플리케이션 릴리스), version(string|null), public(boolean), bookmarked(boolean), tags(array of strings), input(string|null), output(string|null), created_at(string timestamp), updated_at(string timestamp).
Legacy trace 수준의 input, output, metadata, timestamp, version은 observations_v2/에 직접 대응물이 없습니다. 같은 이름의 observation 필드는 observation 수준 데이터를 담습니다. trace 파일은 total_cost, latency, observations, scores, html_path를 포함하지 않습니다.
Observations (observations/)
각 행은 trace 컨텍스트 없이 하나의 observation을 나타냅니다. trace_id를 traces/ 파일에 조인해 추가하세요. 선택한 필드 그룹 만 나타납니다. core는 항상 포함됩니다.
주요 필드(enriched와 같은 의미를 가짐): id, trace_id, project_id, environment, type, parent_observation_id, start_time, end_time, name, metadata, level, status_message, version, input, output, provided_model_name, model_parameters, usage_details, cost_details, completion_start_time, prompt_name, prompt_version, total_cost, latency, time_to_first_token, model_id, created_at, updated_at, prompt_id, tool_calls, tool_call_names, tool_definitions, usage_pricing_tier_name, input_price, output_price, total_price. (input_price, output_price, total_price는 Parquet에서 생략.)
필드가 두 observation 파일 모두에 나타나면 같은 의미를 지닙니다. 단, 설정되지 않은 값은 다르게 인코딩됩니다. 위에서 null인 필드는 observations_v2/ JSON/JSONL 출력에서 세 값 중 하나로 매핑됩니다.
observations_v2/의 값 |
필드 |
|---|---|
"" (빈 문자열) |
input, model_id, model_parameters, output, parent_observation_id, prompt_id, prompt_name, provided_model_name, status_message, version |
null |
completion_start_time, end_time, input_price, latency, output_price, prompt_version, time_to_first_token, total_price, usage_pricing_tier_name |
0 |
total_cost |
빈 문자열은 v4 이벤트 테이블이 컬럼을 non-nullable로 저장하는 곳에 나타납니다. total_cost는 cost_details['total']에서 읽으므로 거기의 0은 진짜 0 비용과 구분할 수 없습니다.
이 컬럼들을 선택하는 필드 그룹과 enriched 엑스포트와의 차이는 what changes in the exported data 를 참고하세요.
Parquet 차이점
Parquet는 내부 인코딩과 압축을 사용하므로 gzip이 적용되지 않습니다. observation 파일은 input_price, output_price, total_price를 생략합니다. 비용 데이터에는 cost_details와 total_cost를 사용하세요. trace와 score 필드는 모든 형식에서 동일합니다.
경로, 파일 이름, 매니페스트 워크플로우는 엑스포트 처리 를 참고하세요.
FAQ
- Blob 스토리지 엑스포트 타이밍과 재시도는 어떻게 동작하나요?
- Blob storage 구성 변경 — 왜 재내보내지 않고 여전히 오류가 보이나요?
- Blob storage 엑스포트에 빈 파일이 보이는 이유는 뭔가요?