
앞선 3편에서는 보이는 것(메트릭·로그) 을 다듬었다면, 이번 4편은 보이지 않던 요청 흐름(Trace) 을 꺼내는 단계다.
나는 SDK 대신 Java Agent를 택했다. 코드 수정 없이 시작·중단이 가능해서, 실험 → 측정 → 개선 루프를 빠르게 돌리기에 유리했기 때문이다.
처음엔 SDK로 붙여보려 했지만, 배포 주기가 길어지는 게 싫었다.
그래서 JVM 옵션만으로 켜고 끌 수 있는 Agent 방식을 선택했다.

실행 옵션 (내 로컬 예시):
-javaagent:C:/dev/otel-agent/opentelemetry-javaagent.jar ^
-Dotel.service.name=pinup-service ^
-Dotel.exporter.otlp.endpoint=http://localhost:4318 ^
-Dotel.resource.attributes=deployment.environment=local
service.name 으로 서비스 식별 통일UI 성공 확인 포인트 (로그 안 봄):
애플리케이션 실행 직후 콘솔에 opentelemetry-javaagent - version: ... 문구가 보이면 Agent 로딩 성공.

나는 traces는 Tempo로, logs는 Loki로 보냈다. (metrics는 Prometheus 그대로 유지)
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
exporters:
otlphttp/tempo:
endpoint: http://tempo:4319
loki:
endpoint: http://loki:3100/loki/api/v1/push
debug:
verbosity: detailed # 로컬 실험용(필수 아님)
processors:
batch: {}
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlphttp/tempo]
logs:
receivers: [otlp]
processors: [batch]
exporters: [loki]
UI 성공 확인 포인트:
Grafana → Connections → Data sources → Tempo → Save & test → ✅ Success

이제 진짜로 트레이스를 눈으로 본다.
service.name = "pinup-service"
혹은
span.name = "GET /actuator/prometheus"
UI 성공 확인 포인트:


로그에 traceId 를 실어두면, Grafana에서 로그 → 트레이스로 원클릭 이동이 가능하다.
나는 Logback + loki4j 로 JSON 로그에 traceId를 넣었다.
logback-spring.xml (요약):
<appender name="LOKI" class="com.github.loki4j.logback.Loki4jAppender">
<http>
<url>http://localhost:3100/loki/api/v1/push</url>
</http>
<format>
<json>
<field name="timestamp" pattern="%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}" />
<field name="level" pattern="%level" />
<field name="message" pattern="%msg" />
<field name="traceId" pattern="%X{traceId}" />
</json>
</format>
</appender>
Grafana Derived Fields 설정:
traceId"traceId":"([a-f0-9]{32})"${__value.raw}UI 성공 확인 포인트:
{job="pinup-service"} | json

시행착오:
traceId가 대문자/하이픈 포함일 땐 정규식이 안 맞았다.
내 케이스는 소문자 32hex 기준이라 위 정규식이 잘 맞음.
슬로우 쿼리는 두 갈래로 본다.
PostgreSQL 준비:
# postgresql.conf
shared_preload_libraries = 'pg_stat_statements'
최초 1회:
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
Grafana 쿼리 예시 (Table 패널):
SELECT query, total_exec_time, mean_exec_time, calls
FROM pg_stat_statements
ORDER BY mean_exec_time DESC
LIMIT 10;
UI 성공 확인 포인트:
