Trace ID와 분산 트레이싱

Trace ID와 분산 트레이싱 (Trace IDs & Distributed Tracing)

trace ID는 요청이 시스템을 통해 흐를 때 따라다니는 고유 식별자예요. 분산 시스템에서 trace ID는 여러 서비스에 걸친 작업을 연관짓고 전체 요청 수명주기를 재구성할 수 있게 해줘요. 기본적으로 Langfuse는 무작위 32자리 hex trace ID와 16자리 hex observation ID를 할당해요.

출처: 문서

본문

trace ID는 요청이 시스템을 통해 흐를 때 따라다니는 고유 식별자예요. 분산 시스템에서 trace ID는 여러 서비스에 걸친 작업을 연관짓고 전체 요청 수명주기를 재구성할 수 있게 해줘요.

기본적으로 Langfuse는 무작위 32자리 hex trace ID와 16자리 hex observation ID를 할당해요.

Trace ID 생성 및 접근 (Creating and accessing Trace IDs)

Python SDK

create_trace_id()를 사용해 trace ID를 생성해요. seed가 제공되면 ID는 결정적이에요. 같은 seed를 사용하면 같은 ID를 얻어요. 이는 외부 ID를 Langfuse trace와 상관시키는 데 유용해요.

from langfuse import get_client, Langfuse
langfuse = get_client()

external_request_id = "req_12345"
deterministic_trace_id = langfuse.create_trace_id(seed=external_request_id)

get_current_trace_id()로 현재 trace ID를, get_current_observation_id로 현재 observation ID를 얻을 수 있어요.

또한 observation.trace_idobservation.id를 사용해 LangfuseSpan 또는 LangfuseGeneration 객체에서 trace·observation ID에 직접 접근할 수 있어요.

from langfuse import get_client, Langfuse
langfuse = get_client()

with langfuse.start_as_current_observation(as_type="span", name="my-op") as current_op:
    trace_id = langfuse.get_current_trace_id()
    observation_id = langfuse.get_current_observation_id()
    print(trace_id, observation_id)

JS/TS SDK

createTraceId를 사용해 seed로부터 결정적 trace ID를 생성해요.

import { createTraceId, startObservation } from "@langfuse/tracing";

const externalId = "support-ticket-54321";
const langfuseTraceId = await createTraceId(externalId);

getActiveTraceId로 활성 trace ID를, getActiveSpanId로 현재 observation ID를 얻을 수 있어요.

import { startObservation, getActiveTraceId } from "@langfuse/tracing";

await startObservation("run", async (span) => {
  const traceId = getActiveTraceId();
  console.log(`Current trace ID: ${traceId}`);
});

커스텀 Trace ID 설정 (Setting a custom Trace ID)

Langfuse SDK로 애플리케이션 코드를 감쌀 때 커스텀 trace ID를 설정할 수 있어요.

Python SDK

컨텍스트 매니저 사용:

from langfuse import get_client

langfuse = get_client()

# Use a predefined trace ID with trace_context parameter
with langfuse.start_as_current_observation(
    as_type="span",
    name="my-operation",
    trace_context={
        "trace_id": "abcdef1234567890abcdef1234567890",  # Must be 32 hex chars
        "parent_span_id": "fedcba0987654321"  # Optional, 16 hex chars
    }
) as observation:
    print(f"This observation has trace_id: {observation.trace_id}")
    # YOUR APPLICATION CODE HERE

데코레이터 사용:

from langfuse import observe

@observe()
def my_operation(input):
    # YOUR APPLICATION CODE HERE
    result = call_llm(input)
    return result

process_user_request(
    input="Hello",
    langfuse_trace_id="abcdef1234567890abcdef1234567890" # Must be 32 hex chars
)

JS/TS SDK

결정적 trace ID

미리 정해진 traceId로 새 trace를 시작할 때는 부모 observation에 임의의 parent-spanId도 제공해야 해요. 부모 span은 trace 안에 실제로 존재하지 않고 생성된 observation의 trace ID 상속에만 사용되므로, 부모 span ID 값은 유효한 16-hexchar 문자열이면 무관해요.

createTraceId로 seed 문자열에서 유효하고 결정적인 trace ID를 만들 수 있어요. 이는 Langfuse trace를 지원 티켓 ID 같은 외부 시스템의 ID와 상관시키는 데 유용해요.

import { createTraceId, startObservation } from "@langfuse/tracing";

const externalId = "support-ticket-54321";

// Generate a valid, deterministic traceId from the external ID
const langfuseTraceId = await createTraceId(externalId);

// You can now start a new trace with this ID
const rootSpan = startObservation(
  "process-ticket",
  {},
  {
    parentSpanContext: {
      traceId: langfuseTraceId,
      spanId: "0123456789abcdef", // A valid 16 hexchar string; value is irrelevant as parent span does not exist but only used for inheritance
      traceFlags: 1, // mark trace as sampled
    },
  }
);

// Later, you can regenerate the same traceId to score or retrieve the trace
const scoringTraceId = await createTraceId(externalId);
// scoringTraceId will be the same as langfuseTraceId

parentSpanContext를 설정하면 생성된 span이 더 이상 현재 컨텍스트의 활성 span에서 상속하지 않으므로, 활성 span 컨텍스트에서 분리돼요.

Langfuse SDK instrumentação 문서(trace-ids)에서 자세히 알아보세요.

더 알아보기 (Learn more)