본문 바로가기
자습

AWS EC2 X-Ray Enable

by litaro 2024. 2. 24.

X-Ray 기본 동작 Overview

Application 에서 X-Ray SDK 를 활용하여 Trace 하고자 하는 구간을 작성하면,

X-Ray SDK는 X-Ray daemon 에 해당 구간 메세지를 전달. X-Ray daemon 은 이를 X-Ray API 에 전달. 

X-Ray API 는 다른 client 의 Trace 정보도 취합하여 X-Ray console 에서 보여줌

Lambda의 경우 자동으로 daemon 이 실행되지만, EC2 는 직접 실행 필요

EC2 에서 X-Ray 활성화하기

download daemon

curl https://s3.ap-northeast-2.amazonaws.com/aws-xray-assets.ap-northeast-2/xray-daemon/aws-xray-daemon-3.x.rpm -o /home/commonadm/xray.rpm
sudo apt install alien
sudo alien xray.rpm
sudo dpkg -i xray_3.3.8-2_amd64.deb
 
# 설치 확인
xray -n ap-northeast-2

permission 획득

EC2에서 X-Ray daemon을 통해 X-Ray API에 데이터를 보내기 위해서는 AWSXRayDaemonWriteAccess 권한이 필요

$ xray -n ap-northeast-2
2023-09-21T13:41:00Z [Info] Initializing AWS X-Ray daemon 3.3.8
...
2023-09-21T13:41:03Z [Error] Sending segment batch failed with: AccessDeniedException: User: arn:aws:iam::... is not authorized to perform: xray:PutTraceSegments because no identity-based policy allows the xray:PutTraceSegments action
        status code: 403, request id: cb539924-e6f8-46e0-b6ab-6f817034fc5e

X-Ray SDK 로 원하는 구간 추가

Install x-ray sdk

go get github.com/aws/aws-xray-sdk-go

Incoming Request

참고: https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-go-handler.html

Trace 의 시작 정보는 handler 함수에 추가. echo 서버의 middleware 를 활용

func main() {
...
    e := echo.New()
    e.Use(log.LoggerWrapper(config))
    e.Use(middleware.Recover())
    e.Use(xRay())
...
}
 
func xRay() echo.MiddlewareFunc {
    return echo.WrapMiddleware(func(h http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            xray.Handler(xray.NewFixedSegmentNamer("my-ec2-go"), h).ServeHTTP(w, r)
        })
    })
}

Tracing AWS SDK Call

AWS SDK 를 사용하는 경우 간편하게 Trace 코드 추가 가능

https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-go-awssdkclients.html

  1. xray.AWS() 로 client wrapping 하기
  2.  AWS SDK에서는 trace 를 위해 모든 method의 ...WithContext 버전을 제공. i.e) lambda 의 경우, invoke() 와 invokeWithContext()
func createLambdaClient(endpoint string, region string) *lambda.Lambda {
    sess, err := CreateSession(endpoint, region)
    if err != nil {
        return nil
    }
    client := lambda.New(sess)
    xray.AWS(client.Client)
    return client
}
 
func (l *Lambda) InvokeLambdaWithRole(ctx context.Context, lambdaName string, qualifier string, invokationType string, payload []byte, roleArn string, roleSessionName string) error {
...
 
    sess := session.Must(session.NewSession())
    creds := stscreds.NewCredentials(sess, lambdaName, func(provider *stscreds.AssumeRoleProvider) {
        provider.RoleARN = roleArn
        provider.RoleSessionName = roleSessionName
    })
 
    conf := aws.Config{
        Region:      aws.String(l.region),
        Credentials: creds,
        MaxRetries:  aws.Int(0),
    }
 
    assumedRoleLambdaClient := lambda.New(sess, &conf)
 
    if _, err := assumedRoleLambdaClient.InvokeWithContext(ctx, params); err != nil {
        return err
    }
    return nil
}

Tracing Outgoing HTTP calls

Go 에서 제공하는 org/x/net/context/ctxhttp 를 사용하여 3rd party server로 Rest 요청하는것을 trace 가능

참고: https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-go-httpclients.html

func InitHTTPClient() {
    if httpClient == nil {
        httpClient = xray.Client(createHTTPClient())
    }
}
 
func post(ctx context.Context, url string, body string, headers map[string]string) (*http.Response, error) {
    req, err := http.NewRequest("POST", url, strings.NewReader(body))
...
    return ctxhttp.Do(ctx, httpClient, req)
}

Custom  Subsegments 

별도로 context 저장을 제공하지 않는 경우, 원하는 위치에 subsegments 추가하기 위해서는 xray.BeginSubsegment() 활용

func (m *M) testTrace(a map[string]interface{}) error {
...
    _, subSeg := xray.BeginSubsegment(m.context, fmt.Sprintf("%s %s", "Get", a["b"]))
    cachedData, _ := cache.Get(cacheKey)
    subSeg.Close(nil)
...
}

 

'자습' 카테고리의 다른 글

AWS ASG lifecycle Hook (remotely run shell command on EC2)  (0) 2024.03.29
Go Thread-Safety : sync.Mutex, sync.Map  (0) 2023.08.26
Spring Native  (0) 2022.05.14
go gRPC Server & gRPC Gateway  (0) 2021.09.20
Kong Gateway + Konga  (0) 2021.08.29