-
이전 토스팅을 통해 LGTM + OTel 스택을 설치했다.
NCP(Naver Cloud Platform)에서 LGTM + Otel Collector 을 사용한 모니터링 설치 - dev :: Daramu
NCP(Naver Cloud Platform)에서 LGTM + Otel Collector 을 사용한 모니터링 설치 - dev
LGTM 스택 사용을 통한 모니터링 구축을 진행할 것이다. 본 포스팅은 각 컴포넌트를 간소화 하여 설치한 버전을 할 것이며, Prod용을 원한다면 해당 포스팅 참고 바란다. LGTM은 Loki, Grafana, Tempo, Mimir
daramu.tistory.com
이제는 스프링 부트에서 마무리 설정을 통해 앱 로그까지 보내볼 것인데,
설치 단계에서 함께 했다면 "opentelemetry-operator" 가 설치되어 있을 것이므로 코드 수정 없이 간단하게 로그를 수집할 수있다.
오퍼레이터는 java agent를 자동으로 주입해 주지만, 트리거가 필요하다.
순서는 operator 설치 → Instrumentation 리소스 생성 → 앱 Pod에 annotation 추가 이며, 이때 annotation 추가를 트리거로 agent를 자동으로 주입해준다.(init container 로 주입해준다.)
그럼 default namespace에 있는 spring boot 어플리케이션에 자동으로 주입되는지 바로 테스트를 진행하겠다.
# instrumentation.yaml apiVersion: opentelemetry.io/v1alpha1 kind: Instrumentation metadata: name: otel-instrumentation namespace: default spec: exporter: endpoint: http://otel-daemonset-collector.monitoring.svc:4317 propagators: - tracecontext - baggage sampler: type: parentbased_traceidratio argument: "1.0" java: image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-java:latest env: - name: OTEL_EXPORTER_OTLP_PROTOCOL value: grpckubectl apply -f instrumentation.yaml그리고 deployment에 annotation을 추가해준다.
kubectl patch deployment <앱이름> -n default -p '{ "spec": { "template": { "metadata": { "annotations": { "instrumentation.opentelemetry.io/inject-java": "otel-instrumentation" } } } } }'앱 이름이 "cicd-demo-backend" 라면 <앱이름> 대신 그것을 집어 넣으면 된다.
그럼 deployment에 이렇게 추가된다.

물론 직접 spec.template.metadata.annotations.instrumentation.opentelemetry.io/inject-java: otel-instrumentation 을 넣어도 상관없다. 오히려 이게 더 좋아보이나, 현재 CI/CD 구조가 여러개를 테스트 중에 꼬여있어서 수정 전 kubectl로 임시 테스트 해보겠다.
참고로 namepsace에 따라 Instrumentation 와 deployment에 주입되는 값은 달라져야 한다.
가령 backend네임스페이스에 배포 했다면, Instrumentation의 namespace: Instrumentation이고,
deployment의 annotation은 backend/otel-instrumentation 이다.
그럼 화면처럼 Explore -> Tempo에서 트레이스를 확인할 수 있다.
현재는 간단한 스프링부트앱이라 / GET 요청밖에 없지만 복잡한 API나 DB연결이 있다면 해당 정보까지 한번에 볼 수 있다.

그런데 트레이스만 보는 것이 아닌, 해당 트레이스에 연계된 로그까지 볼 수 있는 방법이 있다.
이전 otel operator으로 트레이스는 자동으로 수집했지만,
트레이스와 연계하기 위해서 로그에 Logback이 JSON 형식으로 로그를 출력해야한다. 이 설정을 진행할 것이다.
스프링부트 버전에 따라 다른데, 만약 사용하는 스프링 부트 버전이 3.4 이상이라면 별도의 설정 없이 application.yaml을 수정하여 로그 설정을 진행하면 된다.
스프링 부트 3.4이후부터는 structured logging이 내장되어 있기에 그냥 로그 설정만 하면 된다.
#application.yaml logging: structured: format: console: ecs그럼 이제 어플리케이션이 올라올때 "kubectl get pod" 로 pod 네임 확인 후 "kubectl logs {pod_name}" 을 입력하면 아래처럼 span_id와 trace_id정상적으로 달고 나오는걸 알 수 있다.
참고로 Trace_id 는 시작부터 끝까지 동작하는 모든 작업의 관리 단위이다.
가령 누군가의 요청으로 스프링 부트가Controller 에서 요청을 받고 DB를 조회한다면, 이 일련의 모든 작업에는 동일한 Trace_id 가 있는거다.
그리고 span_id는 각 작업마다 붙는 식별자로, Controller에 요청을 보내는 span_id 한개, DB를 조회하는 다른 span_id한개 이런식으로 구성되며, 결과적으로 span_id는 trace_id의 하위에 존재하게 된다.

설정이 되었다면 다시 Grafana로 돌아가서 Tempo나 Loki로 들어간다. TraceID 기준이라 상관 없다.
그리고 Search에서 원하는 트래픽의 Trace ID를 누르면 트레이스를 확인할 수 있다. 단순 GET 요청이라 한개의 span밖에 없지만, 만약 여러개의 복잡한 span으로 이루어진 trace라면 그렇게 뜰 것이다.

그리고 오른쪽에 Logs for this span을 누른다면, Loki에서 바로 로그를 확인할 수 있다.

위의 로그는 GET요청밖에 없기에 모니터링 테스트를 위해 임의로 LoggerFactory로 생성한 콘솔 로그다.

이처럼 트레이스, 로그, 매트릭 여러 종류의 로그를 한번에 볼 수 있는 LGTM + OTEL 스택을 마무리 하겠다.
'Monitoring > LGTM + Otel' 카테고리의 다른 글
NCP(Naver Cloud Platform)에서 LGTM + Otel Collector 을 사용한 모니터링 설치 - prod용 (0) 2026.05.28 NCP(Naver Cloud Platform)에서 LGTM + Otel Collector 을 사용한 모니터링 설치 - dev (0) 2026.05.28 댓글

