어떤 문제들은 그 존재를 분명히 드러낸다. 다른 사람들은 "내 컴퓨터에서는 잘 작동한다"와 "모든 사람에게 잘 작동한다" 사이의 간극에 숨어 있습니다. 이것은 바로 그 공백 속에 확고히 자리 잡고 있었다.

증상은 간단해 보였습니다. 일부 사용자가 HubSpot 기반 양식을 불러올 수 없었던 것입니다. 원인은 충분히 납득할 만했습니다. 브라우저의 개인정보 보호 설정과 추적 차단 기능이 작동하여 추적기와 유사한 모든 것을 차단하고 있었던 것입니다. 하지만 문제를 측정 하려고 시도하는 순간, 우리는 예상치 못한 난관에 부딪혔고, 그로 인해 간단해 보였던 해결책은 훨씬 더 흥미로운 문제로 바뀌었습니다.

일반적으로 이러한 오류를 잡아내기 위해 사용하는 도구인 실제 사용자 모니터링이 양식을 제대로 작동하지 못하게 하는 바로 그 보안 조치에 의해 차단되고 있었습니다. 저희 New Relic RUM은 추적기처럼 생겼는데, 왜냐하면 실제로 추적기이기 때문 입니다 . 우리는 사실상 연기가 발생하여 연기 감지기 작동을 중지시키는 장치가 설치된 방에 연기 감지기를 설치하려고 했던 것입니다.

이 글에서는 우리가 어떻게 그 역설을 해결했는지에 대해 자세히 설명합니다. 즉, 타사 추적처럼 보이지 않도록 New Relic을 자체 도메인을 통해 프록시하고, 서브도메인과 관련된 복잡한 문제를 처리하고, 원격 측정 데이터를 깨끗하게 유지하고, 마지막으로 HubSpot 장애를 안정적으로 감지하는 방법을 구축했습니다. 심지어 아무것도 로드되지 않는 조용한 장애까지도 감지합니다. 이 과정에서 CDN 및 디스패처 연결, 신속 개발 환경에서의 테스트, 클라우드 관리자를 통한 배포, 그리고 임시방편적인 해결책을 신뢰할 수 있는 지표로 전환하는 데 필요한 번인 기간에 대해 다룰 것입니다.

New Relic에서 제공한 중요한 안내 사항입니다.

프록시 방식을 사용할 때는 최종 사용자 및/또는 사이트 방문자에 대한 계약상, 규제상 또는 기타 법적 의무에 따라 프록시를 사용할 권리가 있는지 확인하는 것이 중요합니다.

뉴렐릭을 퍼스트 파티 개발로 전환

뉴렐릭을 표준 엔드포인트에서 직접 로드하는 대신, 모든 것을 자체 도메인을 통해 프록시하는 방식을 택했습니다. 이렇게 하면 요청이 타사에서 자사로 전환되어 대부분의 추적 방지 기능을 회피할 수 있습니다.

두 개의 엔드포인트가 도입되었습니다.

프록시 값 하드코딩

New Relic에서 퍼스트파티 프록싱을 구성하는 가장 간단한 방법은 프록시 경로를 NREUM.init 에 정적 문자열로 직접 설정하는 것입니다. assets New Relic 에이전트 스크립트 청크를 제공하는 URL을 가리키고, beacon 원격 측정 데이터를 수신하는 URL을 가리킵니다. 둘 다 New Relic의 CDN이 아닌 자체 도메인을 통해 라우팅됩니다.

proxy: {
  assets: 'www.arborydigital.com/nr/agent',
  beacon: 'www.arborydigital.com/nr/data'
}

이것은 쉽게 추론할 수 있습니다. 경로는 한눈에 확인할 수 있고, 런타임 로직이 필요하지 않으며, 에이전트가 초기화되기 전에 설정되므로 구성이 제때 적용되는지에 대한 시간적 문제가 없습니다. 서버에 해당 두 경로가 구성되어 있고 New Relic으로 올바르게 전달되고 있는 한 정상적으로 작동합니다. 서브도메인 트래픽 없이 단일 도메인에서만 운영되는 사이트의 경우, 이것만으로도 충분한 경우가 많습니다.

서브도메인 간 프록싱

사이트에서 blog.arborydigital.com 과 같은 서브도메인을 사용하는 경우, 하드코딩된 단일 프록시 경로는 충분하지 않습니다. 각 서브도메인은 자체 출처에서 작동하며 브라우저 보안 규칙에 따라 blog.arborydigital.com 에서 www.arborydigital.com 에 호스팅된 프록시 경로로의 요청은 기술적으로 교차 출처 요청입니다. 이 방법이 효과가 있을 수도 있지만, 이는 브라우저가 이미 신뢰하는 동일한 출처를 통해 원격 측정 데이터를 전송하는 퍼스트파티 프록싱의 핵심 목적 중 하나를 무산시킵니다.

이 문제를 해결하기 위해 프록시 구성을 런타임에 동적으로 설정할 수 있습니다. 스크립트는 고정된 도메인을 가리키는 대신 window.location.hostname 확인하여 페이지가 현재 실행 중인 출처를 확인합니다. 호스트 이름이 루트 도메인이나 하위 도메인 중 하나와 일치하는 경우 프록시 엔드포인트는 window.location.origin 사용하여 구성됩니다. 즉, blog.arborydigital.com New Relic 트래픽을 blog.arborydigital.com/nr-assets/blog.arborydigital.com/nr-beacon 통해 라우팅하고 www.arborydigital.com 자체 동등한 경로를 사용합니다.

이 접근 방식은 각 서브도메인에 대해 서버 또는 CDN 수준에서 해당 프록시 경로가 구성되어 있어야 합니다. NREUM.infobeaconerrorBeacon 필드를 포함한 New Relic 에이전트 구성도 현재 호스트 이름을 반영하도록 업데이트해야 에이전트가 데이터를 보고할 위치를 알 수 있습니다.

ajax.deny_list

New Relic 브라우저 에이전트는 New Relic 자체 서버 bam.nr-data.net 대신 모든 텔레메트리를 퍼스트파티 프록시 blog.arborydigital.com/nr/data 를 통해 라우팅하도록 구성됩니다. 이렇게 하면 알려진 NR 도메인을 표적으로 하는 차단제를 피할 수 있습니다.

이것의 부작용은 다음과 같습니다. NR 에이전트는 페이지의 모든 나가는 XHR/fetch 요청을 모니터링하여 이를 AJAX 이벤트로 캡처합니다. 여기에는 blog.arborydigital.com/nr/data 으로 가는 자체 비콘 호출도 포함됩니다. 차단 목록이 없으면 NR은 자체 원격 측정 POST를 AJAX 이벤트로 기록하고, 이는 다시 원격 측정 데이터로 전송되어 내부 NR 트래픽으로 AJAX 데이터를 오염시키게 됩니다.

이 문제를 해결하고 데이터 전송률이 마치 아키라 게임에 나오는 것처럼 보이는 것을 방지하기 위해 내장된 와일드카드를 사용하여 이러한 비콘 호출을 차단할 수 있습니다. 이것은 결국 blog.arborydigital.com/nr/data/* 처럼 보일 것입니다. 이 기능을 구현하면 브라우저 데이터가 성공적으로 캡처되었을 때 New Relic이 ajax 항목을 생성하지 않도록 지시합니다. POST 내부의 모든 정보는 보존되며 더 이상 중복된 ajax 항목이 생성되지 않습니다.

쿼리 매개변수를 기능 플래그로 사용하기

?proxy=yes 뒤에 프록시를 게이팅하면 다른 방문자에게 영향을 주지 않고 프로덕션 환경에서 동작을 테스트할 수 있습니다. URL에 해당 매개변수가 없는 경우 차단이 완전히 우회되므로 이 경우 New Relic은 작동하지 않습니다. 매개변수가 추가된 탭을 열고 개발자 도구에서 요청이 자체 도메인을 통해 라우팅되는지 확인한 다음 모든 것이 정상인지 확인하고 스크립트에서 해당 조건을 제거합니다. 그 후 호스트 이름 확인이 진행되고 프록시가 모든 트래픽에 대해 자동으로 활성화됩니다.

New Relic Agent 구현하기

다음 경로를 통해 자바스크립트 코드 조각을 찾을 수 있습니다.

  1. New Relic One(one.newrelic.com)에 로그인하세요.
  2. 브라우저데이터 추가브라우저 모니터링으로 이동
  3. 애플리케이션(앱 ID)을 선택하거나 새 앱을 만드세요.
  4. SPA 로더를 사용할 때 복사/붙여넣기 배포 방식을 선택하세요.
  5. 생성된 <script> 스니펫 전체를 복사하세요

RUM 스크립트를 저장소에 추가할 때는 해당 스크립트가 자체 newrelic.js 파일 안에 있는지 확인해야 합니다. 그래야 나중에 해당 스크립트를 호출할 수 있습니다. head.html

이 작업이 완료되면 해당 문자열에 특정 프록시 설정을 추가해야 합니다. 생성된 코드 조각의 NREUM.init 블록에 프록시 구성을 추가합니다.

proxy: {
  assets: 'www.arborydigital.com/nr/agent',
  beacon: 'www.arborydigital.com/nr/data'
}

프록시 연결(EDS/CDN 계층)

프록시 자체는 CDN 계층에 존재합니다. 목표는 간단합니다. 수신되는 /nr/* 요청을 실제 New Relic 엔드포인트로 전달합니다.

오리진 선택기에서 /nr/agent/*/nr/data/* 제외해야 이러한 요청이 에지 전송 서비스 오리진으로 라우팅되지 않습니다 . 대신, 해당 요청은 Apache ProxyPass 규칙이 실행되는 기본 AEM 게시 원본으로 전달됩니다. cdn.yaml 내부는 다음과 같습니다.

originSelectors:
  rules:
    - name: arbory-da
      when:
        allOf:
          - reqProperty: path
            like: /*
          # ...existing exclusions...
          - reqProperty: path
            doesNotMatch: /nr/agent/*
          - reqProperty: path
            doesNotMatch: /nr/data/*
      action:
        type: selectOrigin
        originName: arbory-da

VirtualHost(.vhost) 파일도 편집해야 합니다.

# New Relic Browser Agent Proxy
SSLProxyEngine on

# Proxy New Relic agent JS chunks (lazy-loaded scripts)
<Location "/nr/agent/">
    ProxyPass "https://js-agent.newrelic.com/"
    ProxyPassReverse "https://js-agent.newrelic.com/"
    RewriteEngine Off
</Location>

# Proxy New Relic beacon/telemetry data
<Location "/nr/data/">
    ProxyPass "https://bam.nr-data.net/"
    ProxyPassReverse "https://bam.nr-data.net/"
    RewriteEngine Off
</Location>

주요 세부 정보:

HubSpot 오류 감지 (아무것도 로드되지 않는 경우에도)

New Relic 차단이 해제되면 다음 문제는 HubSpot 오류가 항상 명확한 오류를 표시하지 않는다는 것입니다. 특히 스크립트가 전혀 로드되지 않는 경우에는 더욱 그렇습니다.

이를 처리하기 위해 두 가지 감지 경로가 추가되었습니다.

1. 스크립트 로드 실패

HubSpot 스크립트가 완전히 로드되지 않는 경우를 감지합니다.

script.onerror = () => {
  reportError('HubSpot script failed to load');
};

2. 런타임 오류

스크립트 로드 후 발생하는 오류를 처리합니다.

window.addEventListener('error', (e) => {
  if (e.filename && e.filename.includes('hsforms')) {
    reportError('HubSpot runtime error');
  }
});

둘 다 동일한 보고 기능에 활용됩니다.

function reportError(errorMsg) {
  console.error(errorMsg);
  if (window.newrelic) {
    window.newrelic.noticeError(new Error(errorMsg));
  }
}

실제로 작동하는지 확인하기

모든 연결이 완료되면 검증은 매우 간단하지만 여전히 중요합니다. 테스트는 추적 방지/확장 프로그램이 엄격하게 활성화된 브라우저에 집중해야 합니다. 이러한 브라우저에서 HubSpot 양식이 로드되지 않고 콘솔에 오류가 표시되며 New Relic에도 동일한 오류가 나타나는지 확인해야 합니다. DevTools에서 에이전트가 /nr/agent/ 에서 로드되고 비콘이 /nr/data/ 로 전송되며 요청이 bam.nr-data.net 와 같은 타사 도메인으로 전송되지 않는지 확인합니다. New Relic에서 대시보드에 오류가 표시되는지, 이벤트가 트리거된 오류와 일치하는지, 세션이 기록되는지 확인하십시오. 세션이 여전히 누락된 경우 프록시 설정이 올바르지 않을 가능성이 높습니다.

신속 개발 환경(RDE)을 이용한 테스트

저희 블로그를 꾸준히 읽어주시는 분이라면 CDN 구성 변경 사항을 테스트하기 위해 신속 개발 환경(RDE)을 사용하는 방법에 대한 제 글을 기억하실지도 모르겠습니다. 이 새로운 럼주를 시음할 때 저는 바로 그 방법을 사용했습니다!

모범 사례를 따르면 개발은 브랜치에서 진행됩니다. 변경 사항이 메인이 아닌 브랜치에 적용되도록 하려면 cdn.yaml 에 추가적인 변경을 해야 합니다.

    origins:
     # ...existing code...
      - name: arbory-da
        domain: (BRANCH_NAME)--(rest of domain).aem.live
        forwardHost: false

변경 사항을 푸시할 준비가 되면 필요한 주요 명령은 두 가지입니다.

aio aem:rde:install -t env-config ./config : 이렇게 하면 /config 의 내용과 이전에 설정한 제외 사항이 푸시됩니다.

aio aem:rde:install -t dispatcher-config ./dispatcher/src : 이렇게 하면 /src의 내용, 즉 디스패처 구성 .vhost 의 변경 사항이 푸시됩니다.

RDE는 다른 환경과 다른 도메인에서 작동하므로 프록시할 새 URL을 지정해야 합니다. 그렇지 않으면 제3자 도메인으로 간주됩니다.

proxy: { 
   assets: 'your-rde-domain.aem.live/nr/agent', 
   beacon: 'your-rde-domain.aem.live/nr/data' 
}

클라우드 관리자 파이프라인 배포(개발 + 프로덕션)

이를 Adobe Cloud Manager를 통해 배포하려면 일반적인 코드 변경보다 좀 더 많은 조정 작업이 필요합니다. 프록시 동작은 여러 계층(CDN, 디스패처, 브라우저)에 따라 달라지며, 이 모든 계층이 동일한 배포 환경 내에서 일관성을 유지해야 합니다.

배포 방식은 다음과 같습니다.

파이프라인 실행은 다음과 같은 작업을 수행합니다.

이 구현에서 디스패처와 CDN 변경 사항은 긴밀하게 연관되어 있습니다. 두 요소가 모두 존재하고 일관성을 유지하지 않으면 프록시가 제대로 작동하지 않습니다.

필수 변경 사항 (함께 배포해야 함)

다음 업데이트는 동일한 파이프라인 실행에 포함되어야 합니다.

이러한 요소 중 하나라도 누락되거나 동기화되지 않으면 요청이 잘못 라우팅되거나 차단되거나 타사 엔드포인트로 대체될 수 있습니다.

번인 기간

프록시 구성 및 배포가 완료되었으므로 모든 것이 예상대로 작동하는지 확인하기 위해 일정 기간의 테스트 기간을 거쳐야 합니다. 오류는 개인 정보 설정, 확장 프로그램 및 네트워크 동작과 같은 실제 사용자 환경에 따라 달라지므로 전체적인 상황을 파악하는 데는 시간이 걸릴 것입니다.

데이터가 제대로 수집되고 있는지 확인하는 데 충분한 시간을 투자했다면, 다음 단계는 해당 데이터를 검토하는 것입니다. 예상 트래픽 대비 오류율을 검증하고, 모든 환경에서 데이터가 제대로 수집되는지 확인하고, 누락된 이벤트, 일관성이 없는 도메인 또는 예외적인 상황으로 인한 차단 요소와 같은 문제점을 해결해야 합니다. 이를 통해 시간 경과에 따른 추세를 파악하고, 단편적인 보고서가 아닌 실제 사용자 영향력을 정량화하는 데 활용할 수 있는 신뢰할 수 있는 지표로 삼을 수 있습니다.

마지막으로

"단지 모니터링 기능을 추가하면 될 것"이라는 생각으로 시작했던 일이 브라우저 개인정보 보호 모델, 퍼스트파티 프록싱, CDN 라우팅, 그리고 애초에 측정하기 어려운 것을 측정하는 미묘한 기술에 대한 탐구로 이어졌습니다.

핵심적인 통찰은 기억해 둘 가치가 있습니다. 관찰하려는 대상과 관찰 사용하는 도구 모두 브라우저에서 허용되지 않는 것으로 취급될 경우, 일반적인 도구로는 모니터링을 할 수 없습니다. 브라우저가 원격 측정 데이터를 인식하는 방식을 변경해야 합니다. 자사 도메인을 통해 New Relic을 프록싱함으로써, 제3자로부터 자사 도메인으로 요청을 전환하고 차단 요소를 우회하여 이전에는 볼 수 없었던 오류를 파악할 수 있는 진정한 창을 확보할 수 있었습니다.

하지만 대리전은 싸움의 절반에 불과했습니다. HubSpot 오류, 특히 스크립트가 로드되지 않아 발생하는 숨겨진 오류를 감지하려면 로드 오류와 런타임 오류 모두를 의도적으로 처리하고, 이 모든 오류를 단일 보고 경로로 통합해야 했습니다. 그리고 실제 사용자 환경이 가정을 증거로 대체하는 번인 기간 동안 데이터가 스스로를 입증하기 전까지는 그 어떤 것도 의미가 없습니다.

그 이점은 일화를 숫자로 바꿀 수 있다는 것입니다. "일부 사용자가 양식이 로드되지 않는다고 합니다"라는 말 대신, 이제는 실제 사용자에게 미치는 영향을 정량화할 수 있는 측정 가능하고 추세 분석 가능한 신호를 갖게 되었습니다. 때로는 가장 가치 있는 해결책은 문제를 완전히 해결하는 것이 아니라, 마침내 문제를 명확하게 수 있게 해주는 것일 수 있습니다. 그리고 거기서부터 실제로 개선을 시작할 수 있습니다.

문제 해결

문제
원인
고치다
CORS 오류가 두 배로 증가했습니다. <https://https//...>
<https://> 대리 값에 포함됨
호스트 이름만 사용하십시오. arborydigital.com/nr/agent
New Relic에 데이터가 없습니다.
스크립트가 로드되지 않거나 프록시 설정이 잘못되었습니다.
브라우저 개발자 도구의 네트워크 탭에서 NR 요청을 확인하고 프록시 역방향 규칙을 검증하십시오.
세션 리플레이가 녹화되지 않습니다
샘플링 비율은 10%입니다.
NREUM.init.session_replay 에서 sampling_rate 증가시키거나 오류를 발생시켜 테스트하여 100% 캡처를 트리거하세요.
newrelic 객체가 정의되지 않았습니다
스크립트 로드 순서가 잘못되었습니다
newrelic.js <script> 의 첫 번째 인지 확인하십시오 head.html

저자 소개

노아 매티슨

Arbory Digital의 기술 제공 관리자

노아는 노스캐롤라이나 대학교 윌밍턴 캠퍼스에서 컴퓨터 과학을 전공했으며, AEM 개발자 자격증을 두 개 보유하고 있습니다. 원래 의예과 학생이었지만 암 진단과 인공지능에 대한 열정을 갖고 있던 그는 문제 해결 능력을 바탕으로 아보리에서 일하고 있습니다. 그는 프로젝트 실행 계획을 수립하고, 팀 간 업무를 위임하며, 원활한 소통을 유지하고, 내부 운영을 지원합니다. 그는 아보리 커뮤니티와 비전을 믿으며, 직장 밖에서는 환경에 관심이 많고 캠핑, 서핑, 암벽 등반 등 야외 활동을 즐깁니다.

링크드인에서 노아에게 연락하세요

마음에 드셨나요? 나에게 맞는 것이 무엇인지 궁금한 점이 있으신가요? 언제든 편하게 연락 주세요 !

관심 있을 만한 다른 글

category
AEM Technical Help
tags
AEM
number of rows
1