공부/ELK
[ELK] apm agent - go
떤뚜
2019. 7. 10. 10:10
== ''Apm은 insights를 제공합니다. 그리고 이러한 insights를 위하여 어플리케이션의 코드를 변경하여 instrument하는 과정이 필요합니다. '' ==
== ''golang은 자동화된 instrumentation에 적합하지 않은 원시 기계어 코드로 컴파일이 되며, go 프로그램은 goroutine와 같이 일반적이지 않은 스레딩 모델을 가지고 있습니다. '' ==
예제 프로젝트 : http://192.168.10.20:58888/go_test
- Project
- go-ApmExam1 (서버)
- go-ApmExam2 (서버)
- go-ApmExam3 (서버)
- go-ApmCommon
- 위 소스들 형상관리시에 govendor를 사용한다면 ApmExam프로젝트들의 vendor에 go-ApmCommon이 들어가지 않게 해주어야 합니다.
- (각각 다른 위치에 두고 사용하는 경우는 제외)
- 실행방법
- 아래 처럼 서버정보 및 기타 정보를 Configuration으로 등록해 줍니다.
{{{
export ELASTIC_APM_SERVER_URL="http://192.168.10.16:8200"
export ELASTIC_APM_SERVICE_NAME="go-ApmExam1"
}}} - Exam프로젝트들의 config폴더 속 사용할 phase를 선택 또는 생성하여 해당 phase이름의 폴더속에 toml파일을 자신에게 맞게 설정합니다.
- 설정 후 아래 처럼 빌드 후 Run Args를 넣어 실행시킵니다.
{{{
go build && ./go-ApmExam1 local
}}}
- call api
- postman등을 이용하여 아래와 같이 get으로 요청합니다.
- ex) http://192.168.0.126:7001/userInfo/kss
코드 작성
- apm agent module 설치
go get -u go.elastic.co/apm
- go의 프레임워크 별 가본 사용방법
[https://www.elastic.co/guide/en/apm/agent/go/1.x/instrumenting-source.html]
- 위 링크를 참조하여 해당하는 프레임워크의 사용법을 따라 agent module을 적용합니다.
- 예제 프로젝트에서는 module/apmgorilla를 참조했습니다.
- 핵심 자료
go-apm-agent의 기능
- Tracing
- Web requests
- 기능 : 서버로 들어오는 요청과 같은 동작에 대한 tracing, api transaction
- 적용방법 : 위 프레임워크 별 기본사용 방법 참조하여 apm agent middleware로 등록, 서버정보 및 연결 정보 export
{{{
//export ELASTIC_APM_SERVER_URL="http://192.168.10.141:8200"
//export ELASTIC_APM_SERVICE_NAME="go-ApmExample3"
r.Use(apmgorilla.Middleware())
}}} - SQL queries
- 기능 : 위 web requests 부분의 api transaction에 sql query에 대한 내용을 포함시켜 줍니다.
- 적용방법 : sql module을 해당 모듈의 apm instrumented version으로 교체하여 사용합니다. [[BR]]위 미들웨어 처럼 postgre, oracle등 각 sql module에 해당하는 버전을 apm agent package에서는 제공합니다.
{{{
//before
import _ “github.com/mattn/go-sqlite3” // registers the “sqlite3” driver
//after
import _ "go.elastic.co/apm/module/apmsql/sqlite3"
}}} - Custom spans
- 기능 : 위 sql 부분에 추가된 내용과 비슷합니다. 하지만 저러한 tracing을 custom하게 사용하게 해줍니다. 예를 들어 function 마다 custom span을 적용해주면 각 function이 실행 되는 status를 추적할 수 있습니다.
- 적용방법 : request의 context에 apm package가 제공해주는 function에 따라 일종의 context value를 추가해주면 됩니다.
{{{
func updateRequestCount(ctx context.Context, name string) (int, error) {
span, ctx := apm.StartSpan(ctx, “updateRequestCount”, “custom”)
defer span.End()
...
} }}} - Outgoing HTTP requests
- 기능 : 나가는 http requests에 대한 정보를 확인 할 수 있게 해줍니다. 해당 서버의 apm agent의 context를 주고 받기에 각 app들의 요청들을 연결되게 확인 할 수 있습니다.
- 적용방법 : http.Client를 이용하여 WithContext를 이용해 apm의 context 정보를 함께 보내줍니다.
{{{
// apmhttp.WrapClient instruments the given http.Client
client := apmhttp.WrapClient(http.DefaultClient)
// If “ctx” contains a reference to an in-progress transaction, then the call below will start a new span.
resp, err := client.Do(req.WithContext(ctx))
… resp.Body.Close() // the span is ended when the response body is consumed or closed
}}} - Panic & Error tracking
- 기능 : panic 이나 error 발생의 조사를 쉽게 할 수 있게 panic이나 error를 capture하여 에러를 APM UI에서 별도로 확인 가능하게 하며, 해당 에러의 Exception trace를 남겨줍니다.
- 적용방법 :
- Panic은 agent middleware에서 알아서 tracking 해줍니다.
- Error는 아래와 같이 소스만 등록해주면 Panic처럼 tracking 됩니다.
{{{
if err != nil {
apm.CaptureError(req.Context(), err).Send()
return err
} }}}
- Logging intgration
- 기능 : 해당 transaction들의 traceID등을 log에 추가시켜 application logs을 apm 추적데이터들과 통합시켜 줍니다. error log발생시 위 Error tracker에 추가 할 수도 있습니다.
- 상세 : logrus를 이용한 ECS(elastic common schema)의 해당 로그 필드에 매핑 또는 기본값을 filebeat 프로세서를 사용하여 변환합니다.
- ECS에 대한 설명[https://www.elastic.co/kr/blog/introducing-the-elastic-common-schema]
- 적용방법 :
- handler function에 아래의 코드를 추가시켜 줍니다.
{{{
log := log.WithFields(apmlogrus.TraceContext(req.Context()))
}}} - Error tracking
{{{
func init() {
// apmlogrus.Hook will send "error", "panic", and "fatal" log messages to Elastic APM.
log.AddHook(&apmlogrus.Hook{})
} }}}
- handler function에 아래의 코드를 추가시켜 줍니다.
- Infrastructure and application metrics
- 기능 : 30초 단위 metric 전송(agent를 실행중인 서비스의 'allocated memory, execute path, go version 등)[[BR]] [http://192.168.10.16:443/app/kibana#/discover?_g=(refreshInterval:(pause:!t,value:0),time:(from:now-15m,to:now))&_a=(columns:!(_source),index:'apm-*',interval:auto,query:(language:kuery,query:''),sort:!('@timestamp',desc))]
- 적용방법 : middleware 자체 기능, metricbeat 설치시 더 상세