동일한 동전의 양면: 가상 모니터링을 통한 테스팅과 모니터링의 통합

digital-experience-monitoring.jpg

역사적으로, 소프트웨어 개발과 SRE는 서로 다른 문화적 관점과 우선순위를 가진 사일로에서 작업해 왔습니다. DevOps의 목표는 소프트웨어 개발 및 운영 전반에 걸쳐 공통적이고 상호 보완적인 관행을 확립하는 것입니다. 그러나 일부 조직에서는 진정한 협업이 드물고 효과적인 DevOps 파트너십을 구축하기 위해 아직도 여러 가지 작업을 해야 합니다.

문화적인 문제 외에도, 이러한 단절의 가장 일반적인 이유 중 하나는 유사한 목표를 달성하기 위해 다양한 도구를 사용하는 것입니다. 구체적인 예를 위해, 엔드 투 엔드(e2e) 테스팅과 가상 모니터링을 비교해 보겠습니다

이 블로그에서는 이러한 기술에 대한 개요를 공유해 드립니다. 예제 리포지토리 carlyrichmond/synthetics-replicator를 사용하여, Playwright, @elastic/synthetics 및 GitHub Actions가 Elastic Synthetics 및 레코더와 힘을 합하여 개발 및 SRE 팀을 통합하고 Netlify와 같은 서비스 제공자에서 호스팅되는 간단한 웹 애플리케이션에 대한 사용자 경험을 검증 및 모니터링할 수 있는 방법에 대해서도 보여드리겠습니다.

Elastic은 최근 가상 모니터링을 도입했으며, 이전 블로그에서 소개드렸듯이 가상 모니터링은 e2e 테스트를 모두 대체할 수 있습니다. 사용자 워크플로우를 조기에 검증하기 위해 단일 도구로 통합하면 수정 사항을 검증하기 위해 사용자 문제를 다시 생성할 수 있는 공통 언어가 제공됩니다.

가상 모니터링과 e2e 테스트 비교

개발 도구와 운영 도구가 대치 중인 경우, 각각의 서로 다른 문화를 함께 통합하는 것은 어렵습니다. 이러한 접근 방식의 정의를 고려하면, 실제로 개발 도구와 운영 도구는 동일한 목표를 달성하는 것을 목표로 한다는 것을 알 수 있습니다.

e2e 테스트는 클릭, 사용자 텍스트 입력 및 탐색을 포함하여 사용자 경로를 다시 만드는 일련의 테스트입니다. e2e 테스트가 소프트웨어 애플리케이션 계층의 통합을 테스트하기 위한 것이라고 주장하는 사람들도 많지만, e2e 테스트가 에뮬레이트하는 것은 사용자의 워크플로우입니다. 한편, 가상 모니터링(특히 브라우저 모니터링이라고 알려진 하위 집합)은 애플리케이션을 통해 사용자 경로를 에뮬레이트하는 애플리케이션 성능 모니터링 관행입니다. 

이 두 가지 기술은 모두 사용자 경로를 에뮬레이트합니다. 단절된 개발자와 운영 사이를 넘나드는 도구를 사용하면, 함께 협력하여 웹 애플리케이션에서 프로덕션 모니터링 기능도 제공할 수 있는 테스트를 구축할 수 있습니다.

사용자 여정 만들기

애플리케이션에서 새로운 사용자 워크플로우 또는 주요 목표를 달성하는 기능을 개발 중인 경우, 개발자는 @elastic/synthetics 를 사용해 사용자 여정을 만들 수 있습니다. 아래 예시와 같이, 일단 설치된 init 유틸리티를 사용해 초기 프로젝트 스캐폴딩을 생성할 수 있습니다. 이 유틸리티를 사용하기 전에 Node.js를 설치해야 한다는 점에 유의하세요.

npm install -g @elastic/synthetics
npx @elastic/synthetics init synthetics-replicator-tests

마법사를 시작하기 전에, 클러스터에 Elastic 클러스터 정보와 Elastic Synthetics 통합이 설정되어 있는지 확인합니다. 다음이 필요합니다. 

  1. 시작 설명서 의 필수 구성 요소에 따라 Elastic Synthetics 앱 내에서 모니터 관리를 사용하도록 설정해야 합니다.
  2. Elastic Cloud 클러스터 클라우드 ID(Elastic Cloud를 사용하는 경우). 또는 온프레미스 호스팅을 사용 중인 경우, Kibana 엔드포인트를 입력해야 합니다.
  3. 클러스터에서 생성된 API 키. 설명서에 나와 있는 것처럼, Project API Keys 탭 아래에 이 키를 생성하는 바로 가기가 Synthetics 애플리케이션 설정에 있습니다.

이 마법사는 아래와 비슷한 구조의 구성 및 예제 모니터 여정이 포함된 샘플 프로젝트를 안내하고 생성합니다.

가상성 복제기 테스트

웹 개발자의 경우, README와package.json 및 lock 파일과 같은 대부분의 요소는 친숙합니다. 모니터의 기본 구성은 아래와 같이 synthetics.config.ts에서 제공됩니다. 이 구성은 프로덕션 및 개발별 구성을 포함하도록 수정할 수 있습니다. 이는 힘을 합하고 e2e 테스트를 위해 동일한 모니터를 재사용하고 모든 여정에서 e2e 테스트 및 프로덕션 모니터로 사용할 수 있도록 하는 데 필수적입니다. 이 예에서는 아니지만, Elastic 인프라가 아닌 자체의 전용 Elastic 인스턴스에서 모니터링하려는 경우 개인 위치에 대한 세부 정보를 포함할 수 있습니다.

import type { SyntheticsConfig } from '@elastic/synthetics';

export default env => {
  const config: SyntheticsConfig = {
    params: {
      url: 'http://localhost:5173',
    },
    playwrightOptions: {
      ignoreHTTPSErrors: false,
    },
    /**
     * Configure global monitor settings
     */
    monitor: {
      schedule: 10,
      locations: ['united_kingdom'],
      privateLocations: [],
    },
    /**
     * Project monitors settings
     */
    project: {
      id: 'synthetics-replicator-tests',
      url: 'https://elastic-deployment:port',
      space: 'default',
    },
  };
  if (env === 'production') {
    config.params = { url: 'https://synthetics-replicator.netlify.app/' }
  }
  return config;
};

첫 번째 여정 만들기

위의 구성이 프로젝트의 모든 모니터에 적용되긴 하지만, 지정된 테스트에 대해 재정의될 수 있습니다.

import { journey, step, monitor, expect, before } from '@elastic/synthetics';

journey('Replicator Order Journey', ({ page, params }) => {
  // Only relevant for the push command to create
  // monitors in Kibana
  monitor.use({
    id: 'synthetics-replicator-monitor',
    schedule: 10,
  });

// journey steps go here

});

@elastic/synthetics 래퍼는 테스트에서 일반적인 속성을 설정하고 해체할 수 있는 사전사후 구성과 같은 많은 표준 테스트 방법을 제공하며 아울러 일반적인 어설션 도우미 방법도 지원합니다. 지원되는 예상 방법의 전체 목록이 설명서에 나와 있습니다. Playwright page 객체도 표시되어, 페이지 요소를 찾고 아래 예제에 나와 있는 클릭과 같은 사용자 이벤트를 시뮬레이션하는 등 API에서 제공되는 모든 예상 작업을 수행할 수 있습니다.

import { journey, step, monitor, expect, before } from '@elastic/synthetics';

journey('Replicator Order Journey', ({ page, params }) => {
  // monitor configuration goes here
 
  before(async ()=> {
    await page.goto(params.url);
  });

  step('assert home page loads', async () => {
    const header = await page.locator('h1');
    expect(await header.textContent()).toBe('Replicatr');
  });

  step('assert move to order page', async () => {
    const orderButton = await page.locator('data-testid=order-button');
    await orderButton.click();
    
    const url = page.url();
    expect(url).toContain('/order');

    const menuTiles = await page.locator('data-testid=menu-item-card');
    expect(await menuTiles.count()).toBeGreaterThan(2);
  });


// other steps go here


});

위의 예에서 볼 수 있듯이, journeystep 구성도 표시됩니다. 이 구성은 테스트에서 애플리케이션을 통한 사용자 여정을 보여주는 행동 중심 개발(BDD) 관행을 반영합니다.

개발자는 기능 개발의 일환으로 로컬에서 작동 중인 애플리케이션에 대한 테스트를 실행하여 사용자 워크플로우에서 성공한 단계와 실패한 단계를 확인할 수 있습니다. 다음 예제에서는 로컬 서버 시작 명령이 상단에 파란색 윤곽선으로 표시됩니다. 모니터 실행 명령은 훨씬 아래쪽에 빨간색으로 표시됩니다.

각 여정 단계 옆의 녹색 표시에서 볼 수 있듯이, 각 테스트를 성공적으로 통과합니다. 야호!

CI 파이프라인 게이트

CI 파이프라인 내에서 모니터 실행을 코드 수정 사항을 병합하고 새 버전의 모니터를 업로드하는 게이트로 사용하는 것이 중요합니다. GitHub Actions 워크플로우의 각 작업에 대해서는 이 섹션과 후속 섹션에서 논의해 보겠습니다.

테스트 작업은 아래 그림과 같이 테스트 인스턴스를 스핀업하고 사용자 여정을 실행하여 수정 사항을 검증합니다. 이 단계는 푸시할 때뿐만 아니라 개발자 수정 사항의 유효성을 확인하기 위한 풀 리퀘스트에 대해서도 실행되어야 합니다.

jobs:   
  test:
    env:
      NODE_ENV: development
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 18
      - run: npm install
      - run: npm start &
      - run: "npm install @elastic/synthetics && SYNTHETICS_JUNIT_FILE='junit-synthetics.xml' npx @elastic/synthetics . --reporter=junit"
        working-directory: ./apps/synthetics-replicator-tests/journeys
      - name: Publish Unit Test Results
        uses: EnricoMi/publish-unit-test-result-action@v2
        if: always()
        with:
          junit_files: '**/junit-*.xml'
          check_name: Elastic Synthetics Tests

로컬 컴퓨터에서 여정을 실행하는 것과 달리, npx @elastic/synthetics를 실행할 때 --reporter=junit 옵션을 사용하여 CI 작업에 대해 통과한 또는 때로는 아쉽게도 실패한 여정을 가시화합니다.

모니터 자동 업로드

Elastic Uptime에서 최신 모니터를 사용할 수 있도록 하려면, 아래 예제 작업과 같이 CI 워크플로우의 일부로 모니터를 프로그래밍 방식으로 푸시하는 것이 좋습니다. 우리의 워크플로우에서는 아래에 표시된 두 번째 작업 push가 모니터를 클러스터에 업로드하는 test 작업의 성공적인 실행에 따라 달라집니다. 이 작업은 풀 리퀘스트 내에서 발생하는 것이 아니라 수정 사항이 유효한지 확인하기 위해 푸시할 때 실행되도록 워크플로우에서 구성됩니다.

jobs:   
  test: …
  push:
    env:
      NODE_ENV: production
      SYNTHETICS_API_KEY: ${{ secrets.SYNTHETICS_API_KEY }}
    needs: test
    defaults:
      run:
        working-directory: ./apps/synthetics-replicator-tests
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 18
      - run: npm install
      - run: npm run push

@elastic/synthetics init 마법사는 프로젝트 폴더에서 트리거할 수 있는 프로젝트를 만들 때 여러분을 위한 푸시 명령을 생성합니다. 이는 stepsworking_directory 구성을 통해 아래에 나와 있습니다. push 명령을 사용하려면 Elastic 클러스터의 API 키가 필요합니다. 이 키는 신뢰할 수 있는 볼트 내에 암호로 저장되고 워크플로우 환경 변수를 통해 참조되어야 합니다. 또한 프로덕션 모니터링이 중단되지 않도록 업데이트된 모니터 구성을 Elastic Synthetics 인스턴스로 푸시하기 전에 모니터를 통과시키는 것이 중요합니다. 테스팅 환경에서 실행되는 e2e 테스트와 달리, 손상된 모니터는 SRE 활동에 영향을 미치므로 모든 수정 사항을 검증해야 합니다. 따라서 needs 옵션을 통해 테스트 단계에 종속성을 적용하는 것이 좋습니다.

Elastic Synthetics를 이용한 모니터링

모니터가 업로드되면, SRE 팀에게 사용자 워크플로우가 의도한 대로 작동하는지 여부에 대한 정기적인 체크포인트를 제공합니다. 이전에 표시한 대로 프로젝트 및 개별 테스트에 대해 구성된 정기적인 일정에 따라 실행되기 때문이기도 하지만 아울러 모든 모니터 실행 상태를 확인하고 필요에 따라 실행할 수 있기 때문이기도 합니다.

Monitor Overview 탭에서는 구성된 모든 모니터의 상태를 즉시 볼 수 있을 뿐만 아니라, 카드 줄임표 메뉴를 통해 모니터를 수동으로 실행할 수 있는 기능도 제공합니다.

Elastic Observability 모니터

또한 모니터 화면에서 장애를 조사하기 위한 개별 모니터 실행의 개요로 이동할 수도 있습니다.

테스트 실행 세부 정보

SRE의 또 다른 모니터링 기능은 SRE가 APM, 메트릭 및 로그와 같은 애플리케이션의 성능 및 가용성을 면밀히 조사하는 데 이미 사용하는 익숙한 도구와 이러한 모니터들 간에 통합하는 것입니다. SRE가 잠재적인 고장 또는 병목 현상을 조사하는 동안 적절한 이름의 조사 메뉴를 사용하여 쉽게 탐색할 수 있습니다.

또한 문제를 찾는 것과 잠재적인 문제에 대해 자동으로 알림을 받는 것 사이에 균형이 유지됩니다. 문제 알림에 대한 규칙 및 임계값 설정에 이미 익숙한 SRE는 브라우저 모니터에서도 이러한 설정이 가능하다는 것을 알면 좋아할 것입니다. 예제 규칙의 편집은 다음과 같습니다.

Elastic Observability 규칙

브라우저 모니터의 상태는 위의 상태 검사에서와 같이 개별적 또는 집합적 모니터가 여러 번 중단되었는지 여부를 고려할 뿐만 아니라 지정된 기간 내에 통과된 검사의 비율을 확인하여 전체 가용성을 측정하도록 구성할 수 있습니다. SRE는 기존의 프로덕션 관리 방식으로 문제에 대응하는 데 관심이 있을 뿐만 아니라 애플리케이션의 가용성도 개선하고 싶어 합니다.

사용자 워크플로우 기록

개발 수명 주기 전반에 걸쳐 e2e 테스트를 생성하는 것의 한계는 팀이 무언가를 놓치는 경우가 있으며 이전의 도구 세트가 개발 팀에 맞춰져 있다는 것입니다. 여러 분야의 팀을 사용하여 직관적인 제품을 설계하려는 최선의 의도에도 불구하고, 사용자는 의도하지 않은 방식으로 애플리케이션을 사용할 수도 있습니다. 또한 개발자가 작성한 모니터는 예상되는 워크플로우만 커버하고 이러한 모니터가 프로덕션에서 실패할 때 또는 모니터에 이상 탐지 기능이 적용되는 경우 다르게 동작하기 시작할 때 경보를 울립니다.

사용자 문제가 발생하면, 해당 문제를 모니터와 동일한 형식으로 재생성하는 것이 유용합니다. SRE는 개발자가 어려움을 겪을 수 있는 실패 사례를 직관적으로 고려하고 만족스러운 사례에 초점을 맞출 것이기 때문에, 사용자 여정을 만들 때 SRE의 경험을 활용하는 것도 중요합니다. 그러나 모든 SRE가 Playwright와 @elastic/synthetics를 사용하여 이러한 여정을 만들 수 있는 경험이나 자신감을 가지고 있는 것은 아닙니다.

Video thumbnail

Elastic 가상 레코더를 활용하세요! 위의 동영상에서는 사용자 여정의 단계를 기록하고 이를 모니터 프로젝트에 포함하기 위해 JavaScript 파일로 내보내는 데 사용할 수 있는 방법을 상세하게 안내해 드립니다. 이는 개발 단계로 피드백하고 문제를 해결하기 위해 개발된 수정 사항을 테스트하는 데 유용합니다. 이 접근법은 우리 모두가 힘을 합쳐 이 모니터들을 함께 사용해야만 가능합니다.

사용해 보세요!

8.8 기준으로, @elastic/synthetics 및 Elastic Synthetics 앱은 정식 버전으로 제공되며, 신뢰할 수 있는 레코더는 베타 버전입니다. 커뮤니티 토론 포럼의 Uptime category을 통해 또는 Slack을 통해 Synthetic Monitoring으로 나뉘어 있는 개발자 및 운영 부서를 연결한 경험을 공유해 주세요.

즐거운 모니터링 작업 되세요!

2023년 2월 6일 최초 게시, 2023년 5월 23일 업데이트