- 필수 기능
- 시작하기
- Glossary
- 표준 속성
- Guides
- Agent
- 통합
- 개방형텔레메트리
- 개발자
- API
- Datadog Mobile App
- CoScreen
- Cloudcraft
- 앱 내
- 서비스 관리
- 인프라스트럭처
- 애플리케이션 성능
- APM
- Continuous Profiler
- 스팬 시각화
- 데이터 스트림 모니터링
- 데이터 작업 모니터링
- 디지털 경험
- 소프트웨어 제공
- 보안
- AI Observability
- 로그 관리
- 관리
RUM에서 수집한 데이터 및 컨텍스트를 다양한 방법으로 수정하여 필요에 따라 지원할 수 있습니다:
RUM Browser SDK는 사용자가 새 페이지에 액세스할 때마다 또는 페이지의 URL이 변경될 때(단일 페이지 애플리케이션의 경우) 보기 이벤트를 자동으로 생성합니다. 보기 이름은 현재 페이지의 URL에서 생성되며, 가변 영숫자 ID는 자동으로 삭제됩니다. 예를 들어, /dashboard/1234
는 /dashboard/?
가 됩니다.
버전 2.17.0부터 trackViewsManually
옵션을 사용하여 보기 이벤트를 수동으로 추적함으로써 보기 이름을 추가하고 팀이 소유한 전용 서비스에 할당할 수 있습니다:
RUM Browser SDK를 초기화할 때 trackViewsManually
를 true로 설정합니다.
import { datadogRum } from '@datadog/browser-rum';
datadogRum.init({
...,
trackViewsManually: true,
...
});
window.DD_RUM.onReady(function() {
window.DD_RUM.init({
...,
trackViewsManually: true,
...
})
})
window.DD_RUM &&
window.DD_RUM.init({
...,
trackViewsManually: true,
...
});
새 페이지 또는 경로 변경(단일 페이지 애플리케이션의 경우)이 있을 때마다 보기를 시작해야 합니다. 보기가 시작될 때 RUM 데이터가 수집됩니다. 버전 4.13.0부터는 선택적으로 관련 서비스 이름과 버전을 정의할 수도 있습니다.
자세한 내용은 브라우저 모니터링 설정을 참조하세요.
checkout
page in a RUM application. Use checkout
for the view name and associate the purchase
service with version 1.2.3
.datadogRum.startView({
name: 'checkout',
service: 'purchase',
version: '1.2.3'
})
window.DD_RUM.onReady(function() {
window.DD_RUM.startView({
name: 'checkout',
service: 'purchase',
version: '1.2.3'
})
})
window.DD_RUM && window.DD_RUM.startView({
name: 'checkout',
service: 'purchase',
version: '1.2.3'
})
v4.13.0
checkout
page in a RUM application. No service or version can be specified.datadogRum.startView('checkout')
window.DD_RUM.onReady(function() {
window.DD_RUM.startView('checkout')
})
window.DD_RUM && window.DD_RUM.startView('checkout')
React, Angular, Vue 또는 다른 프론트엔드 프레임워크를 사용하는 경우 Datadog은 프레임워크 라우터 수준에서 startView
로직을 구현할 것을 권장합니다.
기본 RUM 보기 이름을 재정의하여 사용자가 React 애플리케이션에서 정의한 방법과 일치하도록 하려면 다음 단계를 수행해야 합니다.
참고: 이 지침서는 React Router v6 라이브러리에만 적용됩니다.
위의 설명대로 RUM browser SDK를 초기화할 때 trackViewsManually
를 true
로 설정합니다.
각 경로 변경에 대한 보기를 시작합니다.
import { matchRoutes, useLocation } from 'react-router-dom';
import { routes } from 'path/to/routes';
import { datadogRum } from "@datadog/browser-rum";
export default function App() {
// Track every route change with useLocation API
let location = useLocation();
useEffect(() => {
const routeMatches = matchRoutes(routes, location.pathname);
const viewName = routeMatches && computeViewName(routeMatches);
if (viewName) {
datadogRum.startView({name: viewName});
}
}, [location.pathname]);
...
}
// Compute view name out of routeMatches
function computeViewName(routeMatches) {
let viewName = "";
for (let index = 0; index < routeMatches.length; index++) {
const routeMatch = routeMatches[index];
const path = routeMatch.route.path;
// Skip pathless routes
if (!path) {
continue;
}
if (path.startsWith("/")) {
// Handle absolute child route paths
viewName = path;
} else {
// Handle route paths ending with "/"
viewName += viewName.endsWith("/") ? path : `/${path}`;
}
}
return viewName || '/';
}
import { matchRoutes, useLocation } from 'react-router-dom';
import { routes } from 'path/to/routes';
export default function App() {
// Track every route change with useLocation API
let location = useLocation();
useEffect(() => {
const routeMatches = matchRoutes(routes, location.pathname);
const viewName = routeMatches && computeViewName(routeMatches);
if (viewName) {
DD_RUM.onReady(function() {
DD_RUM.startView({name: viewName});
});
}
}, [location.pathname]);
...
}
// Compute view name out of routeMatches
function computeViewName(routeMatches) {
let viewName = "";
for (let index = 0; index < routeMatches.length; index++) {
const routeMatch = routeMatches[index];
const path = routeMatch.route.path;
// Skip pathless routes
if (!path) {
continue;
}
if (path.startsWith("/")) {
// Handle absolute child route paths
viewName = path;
} else {
// Handle route paths ending with "/"
viewName += viewName.endsWith("/") ? path : `/${path}`;
}
}
return viewName || '/';
}
import { matchRoutes, useLocation } from 'react-router-dom';
import { routes } from 'path/to/routes';
export default function App() {
// Track every route change with useLocation API
let location = useLocation();
useEffect(() => {
const routeMatches = matchRoutes(routes, location.pathname);
const viewName = routeMatches && computeViewName(routeMatches);
if (viewName) {
window.DD_RUM &&
window.DD_RUM.startView({name: viewName});
}
}, [location.pathname]);
...
}
// Compute view name out of routeMatches
function computeViewName(routeMatches) {
let viewName = "";
for (let index = 0; index < routeMatches.length; index++) {
const routeMatch = routeMatches[index];
const path = routeMatch.route.path;
// Skip pathless routes
if (!path) {
continue;
}
if (path.startsWith("/")) {
// Handle absolute child route paths
viewName = path;
} else {
// Handle route paths ending with "/"
viewName += viewName.endsWith("/") ? path : `/${path}`;
}
}
return viewName || '/';
}
RUM Browser SDK는 RUM 이벤트를 캡처하고 해당 이벤트의 주요 속성을 입력합니다. beforeSend
콜백 기능을 통해 Datadog으로 전송되기 전 RUM Browser SDK에서 수집한 모든 이벤트에 액세스할 수 있습니다.
RUM 이벤트를 가로채면 다음과 같은 작업을 수행할 수 있습니다:
버전 2.13.0부터 beforeSend
는 두가지 인수를 사용합니다: RUM Browser SDK에서 생성된 event
, 그리고 RUM 이벤트 생성을 트리거한 context
입니다.
function beforeSend(event, context)
잠재적인 context
값은 다음과 같습니다:
RUM 이벤트 유형 | 컨텍스트 |
---|---|
보기 | 위치 |
작업 | 이벤트 |
리소스 (XHR) | XMLHttpRequest 및 PerformanceResourceTiming |
리소스 (Fetch) | 요청, 응답 및 [PerformanceResourceTiming9 |
리소스 (기타) | PerformanceResourceTiming |
오류 | 오류 |
긴 작업 | PerformanceLongTaskTiming |
자세한 내용은 RUM 데이터 강화 및 제어 가이드를 참조하세요.
Global Context API 또는 기능 플래그 데이터 수집으로 추가된 속성과 함께 이벤트에 추가 컨텍스트 속성을 추가할 수 있습니다. 예를 들어, 가져오기 응답 개체에서 추출한 데이터로 RUM 리소스 이벤트에 태그를 지정할 수 있습니다:
import { datadogRum } from '@datadog/browser-rum';
datadogRum.init({
...,
beforeSend: (event, context) => {
// RUM 리소스의 응답 헤더를 수집합니다.
if (event.type === 'resource' && event.resource.type === 'fetch') {
event.context.responseHeaders = Object.fromEntries(context.response.headers)
}
return true
},
...
});
window.DD_RUM.onReady(function() {
window.DD_RUM.init({
...,
beforeSend: (event, context) => {
// collect a RUM resource's response headers
if (event.type === 'resource' && event.resource.type === 'fetch') {
event.context.responseHeaders = Object.fromEntries(context.response.headers)
}
return true
},
...
})
})
window.DD_RUM &&
window.DD_RUM.init({
...,
beforeSend: (event, context) => {
// collect a RUM resource's response headers
if (event.type === 'resource' && event.resource.type === 'fetch') {
event.context.responseHeaders = Object.fromEntries(context.response.headers)
}
return true
},
...
});
사용자가 여러 팀에 속한 경우, 호출에 포함된 키-값 쌍을 Global Context API에 추가합니다.
RUM Browser SDK는 다음을 무시합니다:
event.context
외부에서 추가된 속성기능 플래그로 RUM 이벤트 데이터를 강화하여 성능 모니터링에 대한 추가 컨텍스트와 가시성을 얻을 수 있습니다. 이를 통해 어떤 사용자에게 특정 사용자 경험이 표시되는지, 그리고 이것이 사용자의 성능에 부정적인 영향을 미치는지 확인할 수 있습니다.
예를 들어 웹 애플리케이션 URL에서 이메일 주소를 삭제할 수 있습니다:
import { datadogRum } from '@datadog/browser-rum';
datadogRum.init({
...,
beforeSend: (event) => {
// 보기 URL에서 이메일 제거
event.view.url = event.view.url.replace(/email=[^&]*/, "email=REDACTED")
},
...
});
window.DD_RUM.onReady(function() {
window.DD_RUM.init({
...,
beforeSend: (event) => {
// 보기 URL에서 이메일 제거
event.view.url = event.view.url.replace(/email=[^&]*/, "email=REDACTED")
},
...
})
})
window.DD_RUM &&
window.DD_RUM.init({
...,
beforeSend: (event) => {
// 보기 URL에서 이메일 제거
event.view.url = event.view.url.replace(/email=[^&]*/, "email=REDACTED")
},
...
});
다음 이벤트 속성을 업데이트할 수 있습니다:
속성 | 유형 | 설명 |
---|---|---|
view.url | 문자열 | 활성화된 웹 페이지의 URL. |
view.referrer | 문자열 | 현재 요청된 페이지로 연결되는 링크를 따라간 이전 웹 페이지의 URL. |
view.name | 문자열 | 현재 보기의 이름. |
action.target.name | 문자열 | 사용자가 상호 작용한 요소. 자동으로 수집된 액션에만 해당합니다. |
error.message | 문자열 | 오류를 설명하는 간결하고 사람이 읽을 수 있는 한 줄 메시지. |
error.stack | 문자열 | 스택 트레이스 또는 오류에 대한 보완 정보. |
error.resource.url | 문자열 | 오류를 트리거한 리소스 URL. |
resource.url | 문자열 | 리소스 URL. |
context | 개체 | Global Context API로 추가하거나 수동으로 이벤트를 생성할 때 추가된 속성(예: addError 및 addAction )입니다. RUM 보기 이벤트 context 는 읽기 전용입니다. |
RUM Browser SDK는 위에 나열되지 않은 이벤트 속성에 대한 수정 사항은 무시합니다. 이벤트 속성에 대한 자세한 내용은 RUM Browser SDK GitHub 리포지토리를 참조하세요.
beforeSend
API과 함께 false
를 반환하여 RUM 이벤트를 삭제합니다:
import { datadogRum } from '@datadog/browser-rum';
datadogRum.init({
...,
beforeSend: (event) => {
if (shouldDiscard(event)) {
return false
}
...
},
...
});
window.DD_RUM.onReady(function() {
window.DD_RUM.init({
...,
beforeSend: (event) => {
if (shouldDiscard(event)) {
return false
},
...
},
...
})
})
window.DD_RUM &&
window.DD_RUM.init({
...,
beforeSend: (event) => {
if (shouldDiscard(event)) {
return false
}
...
},
...
});
참고: 보기 이벤트는 삭제할 수 없습니다.
RUM 세션에 사용자 정보를 추가하면 다음과 같이 도움이 될 수 있습니다.
다음 속성은 선택 사항이지만, Datadog은 이 중 하나 이상을 제공할 것을 권장합니다:
속성 | 유형 | 설명 |
---|---|---|
usr.id | 문자열 | 고유한 사용자 식별자. |
usr.name | 문자열 | RUM UI에 기본적으로 표시되는 사용자 친화적인 이름. |
usr.email | 문자열 | 사용자 이메일. 사용자 이름이 없는 경우 RUM UI에 표시됨. Gravatars를 가져오는 데 사용되기도 함. |
권장 속성 외에 추가 속성을 추가하여 필터링 기능을 향상시킬 수 있습니다. 예를 들어 사용자 요금제 또는 해당 사용자가 속한 사용자 그룹에 대한 정보를 추가할 수 있습니다.
사용자 세션 개체를 변경할 때 변경 후 수집된 모든 RUM 이벤트에는 업데이트된 정보가 포함됩니다.
참고: 로그아웃할 때와 같이 사용자 세션 정보를 삭제하면 로그아웃 전 마지막 보기의 사용자 정보는 유지되지만 세션 데이터는 마지막 보기의 값을 사용하므로 이후 보기나 세션 수준에는 유지되지 않습니다.
datadogRum.setUser(<USER_CONFIG_OBJECT>)
datadogRum.setUser({
id: '1234',
name: 'John Doe',
email: 'john@doe.com',
plan: 'premium',
...
})
window.DD_RUM.onReady(function() {
window.DD_RUM.setUser({
id: '1234',
name: 'John Doe',
email: 'john@doe.com',
plan: 'premium',
...
})
})
window.DD_RUM && window.DD_RUM.setUser({
id: '1234',
name: 'John Doe',
email: 'john@doe.com',
plan: 'premium',
...
})
datadogRum.getUser()
datadogRum.getUser()
window.DD_RUM.onReady(function() {
window.DD_RUM.getUser()
})
window.DD_RUM && window.DD_RUM.getUser()
datadogRum.setUserProperty('<USER_KEY>', <USER_VALUE>)
datadogRum.setUserProperty('name', 'John Doe')
window.DD_RUM.onReady(function() {
window.DD_RUM.setUserProperty('name', 'John Doe')
})
window.DD_RUM && window.DD_RUM.setUserProperty('name', 'John Doe')
datadogRum.removeUserProperty('<USER_KEY>')
datadogRum.removeUserProperty('name')
window.DD_RUM.onReady(function() {
window.DD_RUM.removeUserProperty('name')
})
window.DD_RUM && window.DD_RUM.removeUserProperty('name')
datadogRum.clearUser()
datadogRum.clearUser()
window.DD_RUM.onReady(function() {
window.DD_RUM.clearUser()
})
window.DD_RUM && window.DD_RUM.clearUser()
기본적으로 수집된 세션 수에는 샘플링이 적용되지 않습니다. 수집된 세션 수에 상대적인 샘플링(%)을 적용하려면 RUM을 초기화할 때 sessionSampleRate
파라미터를 사용하세요.
다음 예제는 주어진 RUM 애플리케이션의 모든 세션 중 90%만 수집합니다.
import { datadogRum } from '@datadog/browser-rum';
datadogRum.init({
applicationId: '<DATADOG_APPLICATION_ID>',
clientToken: '<DATADOG_CLIENT_TOKEN>',
site: '<DATADOG_SITE>',
sessionSampleRate: 90,
});
window.DD_RUM.onReady(function() {
window.DD_RUM.init({
clientToken: '<CLIENT_TOKEN>',
applicationId: '<APPLICATION_ID>',
site: '<DATADOG_SITE>',
sessionSampleRate: 90,
})
})
window.DD_RUM &&
window.DD_RUM.init({
clientToken: '<CLIENT_TOKEN>',
applicationId: '<APPLICATION_ID>',
site: '<DATADOG_SITE>',
sessionSampleRate: 90,
});
샘플링된 세션의 경우 해당 세션에 대한 모든 페이지 조회수 및 관련 원격 분석이 수집되지 않습니다.
GDPR, CCPA 및 유사한 규정을 준수하기 위해 RUM Browser SDK를 사용하면 초기화 시 추적 동의 값을 제공할 수 있습니다. 동의 추적에 대한 자세한 내용은 데이터 보안을 참조하세요.
trackingConsent
초기화 파라미터는 다음 값 중 하나가 될 수 있습니다.
"granted"
: RUM Browser SDK는 데이터 수집을 시작하여 Datadog으로 보냅니다."not-granted"
: RUM Browser SDK는 데이터를 수집하지 않습니다.RUM Browser SDK가 초기화된 후 추적 동의 값을 변경하려면 setTrackingConsent()
API 호출을 사용하세요. RUM Browser SDK는 새 값에 따라 동작을 변경합니다.
"granted"
에서 "not-granted"
로 변경되면 RUM 세션이 중지되고 데이터가 더 이상 Datadog으로 전송되지 않습니다."not-granted"
에서 "granted"
로 변경하면 이전 세션이 활성화되지 않은 경우 새 RUM 세션이 생성되고 데이터 수집이 재개됩니다.이 상태는 탭 간에 동기화되지 않으며 탐색 간에 유지되지 않습니다. RUM Browser SDK 초기화 중 또는 setTrackingConsent()
를 사용하여 사용자 결정을 제공해야 합니다.
init()
전에 setTrackingConsent()
를 사용하면 제공된 값이 초기화 파라미터보다 우선합니다.
import { datadogRum } from '@datadog/browser-rum';
datadogRum.init({
...,
trackingConsent: 'not-granted'
});
acceptCookieBannerButton.addEventListener('click', function() {
datadogRum.setTrackingConsent('granted');
});
window.DD_RUM.onReady(function() {
window.DD_RUM.init({
...,
trackingConsent: 'not-granted'
});
});
acceptCookieBannerButton.addEventListener('click', () => {
window.DD_RUM.onReady(function() {
window.DD_RUM.setTrackingConsent('granted');
});
});
window.DD_RUM && window.DD_RUM.init({
...,
trackingConsent: 'not-granted'
});
acceptCookieBannerButton.addEventListener('click', () => {
window.DD_RUM && window.DD_RUM.setTrackingConsent('granted');
});
RUM이 초기화된 후 setGlobalContextProperty(key: string, value: any)
API를 사용하여 애플리케이션에서 수집된 모든 RUM 이벤트에 추가 컨텍스트를 추가합니다:
import { datadogRum } from '@datadog/browser-rum';
datadogRum.setGlobalContextProperty('<CONTEXT_KEY>', <CONTEXT_VALUE>);
// 코드 예시
datadogRum.setGlobalContextProperty('activity', {
hasPaid: true,
amount: 23.42
});
window.DD_RUM.onReady(function() {
window.DD_RUM.setGlobalContextProperty('<CONTEXT_KEY>', '<CONTEXT_VALUE>');
})
// 코드 예시
window.DD_RUM.onReady(function() {
window.DD_RUM.setGlobalContextProperty('activity', {
hasPaid: true,
amount: 23.42
});
})
window.DD_RUM && window.DD_RUM.setGlobalContextProperty('<CONTEXT_KEY>', '<CONTEXT_VALUE>');
// 코드 예시
window.DD_RUM && window.DD_RUM.setGlobalContextProperty('activity', {
hasPaid: true,
amount: 23.42
});
이전에 정의된 글로벌 컨텍스트 속성을 제거할 수 있습니다.
import { datadogRum } from '@datadog/browser-rum';
datadogRum.removeGlobalContextProperty('<CONTEXT_KEY>');
// 코드 예시
datadogRum.removeGlobalContextProperty('codeVersion');
window.DD_RUM.onReady(function() {
window.DD_RUM.removeGlobalContextProperty('<CONTEXT_KEY>');
})
// 코드 예시
window.DD_RUM.onReady(function() {
window.DD_RUM.removeGlobalContextProperty('codeVersion');
})
window.DD_RUM &&
window.DD_RUM.removeGlobalContextProperty('<CONTEXT_KEY>');
// 코드 예시
window.DD_RUM &&
window.DD_RUM.removeGlobalContextProperty('codeVersion');
모든 RUM 이벤트에 대한 기본 컨텍스트를 setGlobalContext(context: Context)
API로 교체합니다.
import { datadogRum } from '@datadog/browser-rum';
datadogRum.setGlobalContext({ '<CONTEXT_KEY>': '<CONTEXT_VALUE>' });
// 코드 예시
datadogRum.setGlobalContext({
codeVersion: 34,
});
window.DD_RUM.onReady(function() {
window.DD_RUM.setGlobalContext({ '<CONTEXT_KEY>': '<CONTEXT_VALUE>' });
})
// 코드 예시
window.DD_RUM.onReady(function() {
window.DD_RUM.setGlobalContext({
codeVersion: 34,
})
})
window.DD_RUM &&
window.DD_RUM.setGlobalContext({ '<CONTEXT_KEY>': '<CONTEXT_VALUE>' });
// 코드 예시
window.DD_RUM &&
window.DD_RUM.setGlobalContext({
codeVersion: 34,
});
clearGlobalContext
를 사용하여 글로벌 컨텍스트를 지울 수 있습니다.
import { datadogRum } from '@datadog/browser-rum';
datadogRum.clearGlobalContext();
window.DD_RUM.onReady(function() {
window.DD_RUM.clearGlobalContext();
});
window.DD_RUM && window.DD_RUM.clearGlobalContext();
RUM이 초기화되면 getGlobalContext()
API로 글로벌 컨텍스트를 읽습니다.
import { datadogRum } from '@datadog/browser-rum';
const context = datadogRum.getGlobalContext();
window.DD_RUM.onReady(function() {
const context = window.DD_RUM.getGlobalContext();
});
const context = window.DD_RUM && window.DD_RUM.getGlobalContext();
기본적으로 글로벌 컨텍스트 및 사용자 컨텍스트는 현재 페이지 메모리에 저장되는데 이는 다음을 의미합니다.
세션의 모든 이벤트에 추가하려면 모든 페이지에 첨부해야 합니다.
브라우저 SDK v4.49.0에 도입된 storeContextsAcrossPages
구성 옵션을 통해 해당 컨텍스트를 localStorage
에 저장할 수 있어 다음 동작이 가능해졌습니다.
하지만 이 기능에는 몇 가지 제한 사항이 있습니다:
localStorage
에 저장된 데이터는 사용자 세션보다 오래 지속되므로 이러한 상황에서 개인 식별 정보(PII)를 설정하는 것은 권장되지 않습니다.localStorage
데이터는 동일한 출처 (login.site.com ≠ app.site.com)에서만 공유되므로 이 기능은 trackSessionAcrossSubdomains
옵션과 호환되지 않습니다.localStorage
는 출처별로 5 MiB라는 제한이 있으므로 로컬 스토리지에 저장된 애플리케이션별 데이터, Datadog 컨텍스트 및 기타 타사 데이터는 이 한도 내에 있어야 문제를 방지할 수 있습니다.추가 유용한 문서, 링크 및 기사: