[Elasticsearch] APM: Transaction과 Span으로 성능추적하기

[원본 링크]

Elastic APM stack에서는 단순 모니터링뿐만 아니라 성능 추적 수단을 제공한다.
Go 환경에서 APM을 이용해서 성능 추적을 달성하는 방법은 간략히 정리해둔다.

Elastic APM에서 Transaction은 가장 최상위의 작업 단위고, Span은 세부 작업 단위를 표현할때 사용된다.
예를 들면, 키바나에서는 이런 식으로 표현된다.

저 API 자체가 하나의 트랜잭션이고, 그 내부에 있는 파란색 막대들이 Span인 것이다.
이런걸 보면서 뭐가 병목인지 확인하고 최적화를 하면 된다.




Go echo에서 통합하기

echo 같은 일반적인 서버 프레임워크를 이용한다면 큰 어려움 없이 API 수준의 성능 추적은 달성할 수 있다.

Tracer를 초기화하고, 그걸 미들웨어로 등록해준다.


그럼 API 요청마다 고유한 트랜잭션이 추적될 것이다.




Non-API를 트랜잭션으로 추적하기

저게 API만 되는건 아니고, 직접 트랜잭션을 생성해서 제어하면 다 할 수 있다.

하나의 작업 단위가 생성될때마다 Tracer를 만들고,

StartTransaction을 통해서 트랜잭션을 생성한다.
그리고 그걸 기반으로 Context를 생성해서 저걸 앞으로 사용하면 된다.


그리고 해당 작업이 다 끝났다고 판단되면 End를 해줘야 한다.
이걸 안하면 Elasticsearch에 전송 자체를 하지 않는다.
그래서 가능하면 defer 등으로 걸어주는게 좋다.


그러고 나서 돌려보면, 기대한대로 추적이 될 것이다.




Span 활용하기

근데 저런 트랜잭션 세팅만으로는 뭔가 만족스러운 수준의 추적을 달성하기가 어려울 수도 있다.
별다른 설정을 하지 않는다면 기본 Span은 Network Request, DB Write 같은 I/O 작업에 대해서만 이뤄지기 때문이다.

그래서

이런 식으로 붕 떠있는 그래프가 만들어지곤 한다.

저 빈 공간을 메꾸기 위해서는 직접 Span을 만들어서 주입해줘야 한다.
사용법은 그리 어렵진 않다. 귀찮을 뿐이다.

컨텍스트를 기반으로 트랜잭션을 생성한다. 여기서 컨텍스트는 트랜잭션 기반으로 만들어진 컨텍스트여야 한다. 위에서 했던 것처럼.
그리고 StartSpan으로 새로운 Span을 정의한다. 그리고 해당 단위가 끝날 때 End를 찍어주면 측정 완료다.

그렇게 해서 돌려보면

이제 직접 만든 Span 단위가 시각화되는 것을 확인할 수 있다.

정말 단위 기능 하나하나 다 추적을 하고 싶다면 Span 깎는 노인이 되어서 함수마다 다 달아줘야 한다.