X-Ray를 SAM과 Lambda에 내장하고 jest로 조롱

10574 단어 Jestsam람다x-rayAWS
2017년경부터 서버리스에 잠겨 있는 TIS의 코니시 케이스케입니다.



개요



SAM (Serverless Application Model)을 사용한 node.js의 Lambda 프로그램 등에 대해,
퍼포먼스 계측 등을 실시해 X-Ray 기능의 편입에 대해 설명합니다.

또한 X-Ray 기능을 통합하면 aws-sdk-mock을 사용한 단위 테스트에서
통과하지 않기 때문에 aws-xray-sdk의 모의화에 대해서도 설명합니다.

SAM에 X-Ray 추가



API Gateway - Lambda - DynamoDB와 같은 구성으로,
SAM (Serverless Application Model)에 X-Ray를 통합하는 것은
다음과 같이 SAM의 템플릿 속도의 글로벌 섹션Function 대, Tracing: ActiveApiTracingEnabled: True 를 추가하기만 하면 됩니다.

물론 글로벌이 아니라 AWS::Serverless::Function
AWS::Serverless::Api의 Properties에 추가할 수 있습니다.

변경 전 SAM-Template

Globals:
  Function:
    Timeout: 15
  Api:
    # https://github.com/awslabs/serverless-application-model/issues/191
    OpenApiVersion: 3.0.0

변경 후 SAM-Template
Globals:
  Function:
    Timeout: 15
    Tracing: Active # 追加
  Api:
    # https://github.com/awslabs/serverless-application-model/issues/191
    OpenApiVersion: 3.0.0
    TracingEnabled: True # 追加

Lambda 내의 AWS 서비스 호출에 X-Ray 포함



API Gateway에서 Lambda로 전화를 걸면 위의 SAM에 내장하면 충분하지만,
Lambda 내에서 AWS-SDK를 사용하여 AWS 서비스를 호출하는 경우 해당 호출을 추적할 때 코드를 변경해야 합니다.
다만, 코드의 변경이라고 해도, npm i -S aws-xray-sdk-coreaws-xray-sdk (을)를 짜넣고 이하의 코드의 변경을 실시하기만 하면 됩니다.

변경 전 js
const AWS = require('aws-sdk');

변경 후 js
const AWSXRay = require('aws-xray-sdk-core');
const AWS = AWSXRay.captureAWS(require('aws-sdk'));
aws-xray-sdk에는 다음 네 가지 모듈이 포함됩니다.
  • aws-xray-sdk-core
  • aws-xray-sdk-express
  • aws-xray-sdk-mysql
  • aws-xray-sdk-postgres

  • Lambda의 경우 mysql이나 postgres에 연결하지 않으면 aws-xray-sdk-core로 충분하다고 생각합니다.
    Lambda 내에서 AWS Serverless Express을 사용하는 경우 aws-xray-sdk-express가 걱정되지만 EC2 용이므로 사용할 수 없습니다. 그래서 새로 세그먼트를 설정할 수 없기 때문에)

    유닛 테스트(jest)에서의 모형화



    위와 같은 AWS-SDK를 사용하고 있는 프로그램의 유닛 테스트에 편리한 AWS-SDK-Mock 가 있습니다만, AWS-SDK를 랩하고 있는 관계로, 그대로의 코드에서는 움직이지 않게 됩니다.

    AWSXRay가 사용하는 부분 AWS-SDK의 처리를 AWS-SDK-Mock로 쓰면 좋을지도 모릅니다만, 정보가 없어 잘 몰랐습니다.
    ( AWS_XRAY_CONTEXT_MISSING 등의 환경 변수를 설정해도 안됩니다)

    또, Jest용으로 aws-xray-Mock 라고 하는 것이 있습니다만, 위와 같은 호출 방법(captureAWS)에는 대응하고 있지 않고, 개별의 (AWS 서비스마다의) 클라이언트에만 대응하고 있는 것 같습니다 . 풀릭도 나와 있습니다만, 5월부터, 방치되어 버리고 있습니다.
    htps : // 기주 b. 코 m / 엄청나게 l로 ck / 아 ws-x 등 y-도 ck / 푸 l / 4

    따라서 위의 코드를 참조하여 captureAWS에만 해당하는 경우,
    다음의 추가로 aws-sdk-mock을 사용한 테스트가 모두 통과하게 되었습니다.
    beforeAll(async () => {
        jest.mock('aws-xray-sdk-core', () => {
            return { captureAWS: aws => aws };
        });
    });
    

    서브 세그먼트를 추가하거나 AWS 클라이언트 (서비스) 단위를 설정하는 경우,
    다음과 같이 사용하는 메소드를 추가합시다.
    (출처: aws-xray-mockaws-xray-mock의 풀릭 )
    let xRaySegment;
    class MockXraySegment {
        constructor(name) {
            this.name = name;
            xRaySegment = this;
        }
        addNewSubsegment(name) {
            return new MockXraySegment(name);
        }
        addError(error) { }
        close() { }
    }
    beforeAll(async () => {
        // process.env.AWS_XRAY_CONTEXT_MISSING = 'LOG_ERROR';
        jest.mock('aws-xray-sdk-core', () => {
            return {
                captureAWS: aws => aws,
                captureAWSClient: client => client,
                captureHTTPs: http => http,
                captureHTTPsGlobal: httpGlobal => httpGlobal,
                getSegment: () => {
                    if (!xRaySegment) {
                        xRaySegment = new MockXraySegment('Parent Segment');
                        return xRaySegment;
                    }
                    return xRaySegment;
                }
            };
        });
    });
    beforeEach(async () => {
        xRaySegment = null;
    });
    
    

    역시, aws-xray-mock 의 풀릭 병합해 주었으면 좋겠네요.
    ( aws-xray-sdk 뿐만 아니라 aws-xray-sdk-core 도 모형화해 주었으면 합니다만..)



    참고


  • AWS X-Ray를 사용하는 경우 aws-mock에서 `Service.prototype.customizeRequests is not a function`과 화가 난 문제 - Qiita
  • AWS SDK를 사용해도 AWS 환경에 액세스하지 않고 유닛 테스트를 돌리는 방법 - Qiita
  • 좋은 웹페이지 즐겨찾기