트레이스-투-로그 상관관계 구성
트레이스-투-로그 상관관계 구성 (Configure trace to logs correlation)
Trace to logs 상관관계는 Tempo의 스팬에서 Loki의 매칭 로그로, 그리고 Loki의 로그 줄에서 Tempo의 트레이스로 바로 이동하게 해줘요. 구성하면 트레이스 뷰에 Logs for this span 링크가 나타나고, 트레이스 ID를 포함한 로그 줄에는 구성된 트레이싱 데이터 소스 링크가 표시됩니다. Tempo 데이터 소스와 Loki 데이터 소스 양쪽을 모두 구성해야 양방향으로 동작해요.
출처: 문서
본문
두 데이터 소스 구성이 필요합니다.
- Tempo 데이터 소스: 스팬 클릭 시 로그를 어떻게 쿼리할지(시간 창, 쿼리, 매칭 태그) 제어
- Loki 데이터 소스: 로그 줄에서 트레이스 ID를 어떻게 추출·링크할지 제어
시작하기 전에
- Grafana에 Tempo 데이터 소스 구성
- Grafana에 Loki 데이터 소스 구성
- 트레이스 ID·서비스 이름 같은 공유 식별자로 트레이스와 로그를 내보내는 애플리케이션
- Grafana Editor 또는 Admin 권한
참고: provisioned 데이터 소스는 Grafana UI에서 수정할 수 없어요. Grafana Cloud Traces(사전 구성 tracing 데이터 소스)의 설정은 읽기 전용입니다. Trace to logs를 구성하려면 데이터 소스 클론으로 편집 가능한 복사본을 만들거나, 자체 관리 인스턴스는 프로비저닝 파일을 업데이트하세요.
Tempo 데이터 소스 구성
트레이스 뷰에서 스팬 클릭 시 Grafana가 로그 데이터 소스를 어떻게 쿼리할지 제어해요. 가이드는 Loki를 쓰지만 Elasticsearch, Splunk, OpenSearch, Falcon LogScale, Google Cloud Logging, VictoriaMetrics Logs도 지원합니다.
- Connections > Data sources로 가서 Tempo 데이터 소스 선택
- Trace to logs 섹션으로 스크롤
- Data source 드롭다운에서 Loki 선택
- Span start time shift와 Span end time shift 구성. 이 필드는 스팬 시작·종료 타임스탬프 주변의 로그 쿼리 시간 창을 확장해요. 기본값
0은 타임스탬프가 정확히 맞지 않으면 로그를 반환하지 않을 수 있어요. 흔한 시작점은 시작-2s, 종료2s이고, 느린/배치 작업 스팬은5s처럼 늘릴 수 있어요. - Tags로 스팬 속성을 Loki 라벨 이름에 매핑. Grafana가 이 태그로 올바른 서비스·Pod·클러스터 로그를 필터링해요. 입력한 Loki 라벨 이름은 Loki 스트림의 라벨 이름과 정확히 일치해야 하며, 불일치하면 오류 없이 조용히 상관관계가 깨집니다. 태그를 구성하지 않으면 기본값으로
cluster,hostname,namespace,pod,service.name(service_name으로 재매핑),service.namespace(service_namespace로 재매핑)를 사용. 자동 점-언더스코어 재매핑은 기본 태그에만 적용되고, 커스텀 태그는 재매핑 이름을 명시해야 해요. Add tag 버튼으로 각 행을 추가하세요.
일반적인 매핑:
| 스팬 속성 | Loki 라벨 |
| --- | --- |
| service.name | service_name |
| service.namespace | service_namespace |
| cluster | cluster |
| namespace | namespace |
| pod | pod |
| hostname | hostname |
낮은 카디널리티 라벨을 선택하세요. Loki에서 라벨 값의 고유 조합마다 별도 스트림이 생성돼요. pod, host, thread, duration, traceId, spanId처럼 많은 고유 값을 갖는 라벨은 수십만~수백만 스트림을 만들어 느린 쿼리·높은 메모리·수집 시 로그 손실을 일으킬 수 있어요. 위 라벨(service_name, namespace, cluster)은 값 집합이 한정적이라 좋은 선택입니다. 트레이스 ID·Pod 이름 같은 고카디널리티 값을 쿼리해야 하면 structured metadata로 저장하세요. 추가 쿼리 가능하면서 스트림은 만들지 않아요. Cardinality 참고.
참고: Loki를 쓸 때 Logs for this span 링크는 구성된 태그 중 하나라도 그 스팬에 존재할 때만 나타나요. 태그가 하나도 매칭되지 않으면 링크가 안 나타나고 오류도 없어요.
- Filter by trace ID와 Filter by span ID 토글 구성.
- Filter by trace ID: Loki 결과를 선택한 스팬뿐 아니라 전체 트레이스의 모든 로그로 필터링. 대부분의 사용 사례에 잘 맞아요.
- Filter by span ID: 단일 스팬의 로그만 필터. 로그에 span ID 필드가 있어야 동작.
이 토글은 Use custom query 활성화 시 비활성화됩니다(커스텀 쿼리가 필터링을 직접 제어). Logs for this span 클릭은 span ID가 아니라 trace ID로 필터링하므로 전체 트레이스의 일치 로그가 모두 포함돼요. 결과가 예상보다 넓어 보이면 정상입니다. 특정 스팬 활동으로 좁히려면 span ID나 스팬 속성으로 필터링하는 커스텀 LogQL 쿼리를 쓰세요(예:
{service_name=\"my-service\"} | json | spanId=\"\"). 이 기능이 동작하려면 애플리케이션이 로그 줄에 트레이스 ID를 주입해야 해요(예: OpenTelemetry SDK 구조화 로깅). 로그에 트레이스 ID가 없으면 쿼리는 시간 범위 필터로 폴백합니다.
- (선택) Use custom query 활성화하고 자동 생성 쿼리를 대체할 LogQL 표현식 작성.
${__tags}로 매핑된 태그 필터를 자동 주입:
{${__tags}} | logfmt | trace_id=`${__trace.traceId}`
pod 같은 태그가 인덱스 라벨이 아닌 structured metadata로 저장되면 스트림 선택기 {}에 나타날 수 없으니 파이프라인 필터로 옮기세요:
{${__tags}} | pod=`${__span.tags["k8s.pod.name"]}` |= `${__trace.traceId}`
사용 가능한 변수 전체 목록은 Custom query variables 참고. 8. Save & test 클릭.
Loki 데이터 소스 구성
Loki 로그 줄에 Tempo 링크를 활성화해 로그 항목에서 트레이스로 이동하게 해줘요.
참고: Tempo 데이터 소스만 구성하고 Loki 데이터 소스를 구성하지 않는 것은 흔한 실수입니다. 이 단계를 건너뛰면 로그 줄 클릭 시 트레이스가 열리지 않아요. 양쪽 모두 필요해요.
- Connections > Data sources에서 Loki 선택
- Additional settings 섹션에서 Derived fields로 스크롤
- Add 클릭으로 새 derived field 추가
- 필드 Name 입력 (예:
TraceID) - Type 선택하고 로그 줄에서 트레이스 ID를 추출할 패턴 입력.
- Regex in log line 선택 시 캡처 그룹이 하나인 정규 표현식 입력. 흔한 패턴:
| 로그 형식 | Regex |
| --- | --- |
|
traceID=<VALUE>|traceID=(\w+)| |trace_id=<VALUE>|trace_id=(\w+)| | JSON 필드"traceId": "<VALUE>"|"traceId":"(\w+)"| - Label 선택 시 라벨 키와 일치하는 정규 표현식 입력. 예:
trace[_]?id→traceid,trace_id둘 다 매칭. 애플리케이션이 서로 다른 트레이스 ID 필드 이름을 쓰면 형식마다 별도 derived field 항목이 필요해요. OpenTelemetry structured metadata로 표준화하면 트레이스 ID가 일관된 라벨로 저장돼 단순해져요.
- Regex in log line 선택 시 캡처 그룹이 하나인 정규 표현식 입력. 흔한 패턴:
| 로그 형식 | Regex |
| --- | --- |
|
- Internal link 토글 활성화하고 드롭다운에서 Tempo 데이터 소스 선택
- Query 필드에
${__value.raw}입력. 이는 링크 클릭 시 추출된 트레이스 ID를 Tempo에 전달해요. 플레이스홀더 텍스트로 보이지만 실제 값으로 입력해야 해요. - Save & test 클릭.
derived field 옵션에 대한 자세한 내용은 Derived fields 참고.
트레이스-투-로그 설정 프로비저닝
데이터 소스 YAML 파일의 tracesToLogsV2 블록으로 구성할 수 있어요. 전체 예시는 Tempo 데이터 소스 프로비저닝, 일반 프로비저닝은 데이터 소스 프로비저닝을 참고하세요.
예시: NGINX 서비스
전제: Kubernetes에서 OpenTelemetry 트레이스를 Tempo로 내보내는 앱, service_name·namespace·pod 라벨로 Loki에 전송되는 로그, trace_id=<VALUE>로 쓰이는 트레이스 ID.
Tempo 데이터 소스 설정:
| 필드 | 값 |
| --- | --- |
| Data source | Loki |
| Span start time shift | -2s |
| Span end time shift | 2s |
| Tags | service.name→service_name, namespace, pod |
| Filter by trace ID | 활성화 |
| Filter by span ID | 비활성화 |
Loki 데이터 소스 derived field 설정:
| 필드 | 값 |
| --- | --- |
| Name | TraceID |
| Type | Regex in log line |
| Regex | trace_id=(\w+) |
| Internal link | 활성화, Tempo 선택 |
| Query | ${__value.raw} |
예상 결과
- Tempo 데이터 소스가 선택된 Explore에서 스팬 클릭 후 Logs for this span 클릭 → 스팬 주변 시간 창 안에서
service_name=nginx와namespace=production으로 필터링된 Loki 열림 - Loki 데이터 소스가 선택된 Explore에서
trace_id=...가 포함된 로그 줄에 Tempo 링크 표시 → 클릭 시 Tempo에서 전체 트레이스 열림
문제 해결
링크가 나타나지 않거나 데이터가 없거나 일부 서비스에서만 동작하면 Trace to logs/metrics/profiles issues 참고. 구성 필드가 회색이면 데이터 소스가 provisioned 상태입니다.
다음 단계
- 트레이스-투-메트릭 상관관계: 스팬을 Prometheus 메트릭 쿼리로 연결
- 트레이스-투-프로파일 상관관계: 스팬을 Grafana Pyroscope 프로파일링 데이터로 연결
- Tempo 데이터 소스 구성