• EnglishEspañol日本語한국어Português
  • 로그인지금 시작하기

사용자의 편의를 위해 제공되는 기계 번역입니다.

영문본과 번역본이 일치하지 않는 경우 영문본이 우선합니다. 보다 자세한 내용은 이 페이지를 방문하시기 바랍니다.

문제 신고

Nerdlet에서 NerdStorage에 액세스하세요.

이 강의는 처음부터 New Relic 제작 방법을 가르치는 과정의 일부입니다. 아직 확인하지 않았다면 개요를 확인하세요.

과정의 각 단원은 마지막 단원을 바탕으로 구성되므로 이 단원을 시작하기 전에 마지막 단원인 NRQL 데이터 사용자 정의를 완료했는지 확인하세요.

이전 강의에서는 차트와 A/B 테스트를 종료하는 버튼이 포함된 사용자 환경을 특수에 생성했습니다. 또한 New Relic 데이터베이스의 실제 데이터를 쿼리하도록 차트를 구성했습니다. 그러나 두 차트에 모의 데이터를 남겼습니다.

  • 과거 테스트
  • 버전별 총 취소 건수

이 두 차트 모두 New Relic에서 얻을 수 없는 데이터를 담고 있습니다. Past tests [과거 테스트는] 과거 테스트 정보를 표시하는 반면, 버전당 총 취소 수는 시간 경과에 따라 각 버전에서 확인되는 취소 수를 표시합니다. 먼저 Past tests [과거 테스트는] 에 집중하세요.

Past tests [과거 테스트에는] 과거 테스트 정보가 표시되므로 완료 시 각 테스트에 대한 정보를 저장해야 합니다. 그리고 이 작업을 수행하는 데 필요한 모든 도구가 있습니다. 먼저 저장 작업을 트리거하는 End test [테스트 종료] 버튼이 있습니다. 둘째, NerdGraph와 NerdStorage를 사용하여 테스트 정보를 보관하는 방법을 알고 있습니다.

NerdStorage에 테스트 정보 저장

교과 과정 저장소add-nerdstorage/ab-test 디렉터리로 변경합니다.

bash
$
cd nru-programmability-course/add-nerdstorage/ab-test

이 디렉토리에는 과정의 이 시점에서 귀하의 애플리케이션이 가질 것으로 예상되는 코드가 포함되어 있습니다. 각 레슨을 시작할 때 올바른 디렉토리로 이동하면 사용자 정의 코드를 남겨두어 한 레슨에서 다음 레슨으로 잘못된 코드가 전달되는 것을 방지할 수 있습니다.

nerdlets/ab-test-nerdlet/end-test.js 에서 EndTestButton.endTest() 메서드를 만듭니다.

import React from 'react';
import {
AccountStorageMutation,
BlockText,
Button,
Grid,
GridItem,
HeadingText,
Modal,
Select,
SelectItem,
} from 'nr1';
class VersionSelector extends React.Component {
constructor(props) {
super(props);
}
render() {
return <Select onChange={this.props.selectVersion} value={this.props.selectedVersion}>
<SelectItem value={'A'}>Version A</SelectItem>
<SelectItem value={'B'}>Version B</SelectItem>
</Select>
}
}
class EndTestButton extends React.Component {
constructor() {
super(...arguments);
this.state = {
modalHidden: true,
}
this.showModal = this.showModal.bind(this);
this.closeModal = this.closeModal.bind(this);
this.endTest = this.endTest.bind(this);
}
closeModal() {
this.setState({ modalHidden: true });
}
showModal() {
this.setState({ modalHidden: false });
}
endTest() {
const today = new Date();
const dd = String(today.getDate()).padStart(2, '0');
const mm = String(today.getMonth() + 1).padStart(2, '0');
const yyyy = today.getFullYear();
const endDate = `${mm}-${dd}-${yyyy}`
AccountStorageMutation.mutate(
{
accountIds: this.props.accountIds,
actionType: AccountStorageMutation.ACTION_TYPE.WRITE_DOCUMENT,
collection: "past-tests",
documentId: endDate,
document: {
versionADescription: this.props.versionADescription,
versionBDescription: this.props.versionBDescription,
winner: this.props.selectedVersion,
}
}
)
this.closeModal();
}
render() {
return <div>
<Button type={Button.TYPE.DESTRUCTIVE} onClick={this.showModal}>End test</Button>
<Modal hidden={this.state.modalHidden} onClose={this.closeModal}>
<HeadingText>Are you sure?</HeadingText>
<BlockText>
If you end the test, all your users will receive the version you selected:
</BlockText>
<BlockText spacingType={[BlockText.SPACING_TYPE.LARGE]}>
<b>Version {this.props.selectedVersion}</b>
</BlockText>
<Button onClick={this.closeModal}>No, continue test</Button>
<Button type={Button.TYPE.DESTRUCTIVE} onClick={this.closeModal}>Yes, end test</Button>
</Modal>
</div>
}
}
export default class EndTestSection extends React.Component {
constructor() {
super(...arguments);
this.state = {
selectedVersion: 'A',
};
this.selectVersion = this.selectVersion.bind(this);
}
selectVersion(event, value) {
this.setState({ selectedVersion: value });
}
render() {
return <Grid className="endTestSection">
<GridItem columnSpan={12}>
<HeadingText className="endTestHeader">
Pick the winner of your A/B test:
</HeadingText>
</GridItem>
<GridItem columnStart={5} columnEnd={6} className="versionSelector">
<VersionSelector
selectedVersion={this.state.selectedVersion}
selectVersion={this.selectVersion}
/>
</GridItem>
<GridItem columnStart={7} columnEnd={8}>
<EndTestButton selectedVersion={this.state.selectedVersion}>End test</EndTestButton>
</GridItem>
</Grid>
}
}

이 코드를 사용하여 형식이 지정된 날짜 문자열 endDate 을 작성합니다. 그런 다음 AccountStorageMutation.mutate() 을 호출하여 계정 스토리지를 변경합니다. 계정 식별자, WRITE_DOCUMENT 작업 유형, &quot;과거 테스트&quot;를 컬렉션 이름으로, endDatedocumentId 로, 문서 데이터(버전 설명 및 승자가 포함됨)를 전달합니다.

일치하는 컬렉션과 documentId 이 이미 존재하는 경우 새 문서를 생성하거나 문서를 업데이트하기 때문에 WRITE_DOCUMENT 전달합니다. documentIdendDate 이며 하루에 하나의 레코드만 생성하는 데 유용합니다.

하루에 여러 테스트를 완료할 수 있다고 의심된다면 이 논리를 변경해야 합니다.

메서드 끝에서 this.props.closeModal() 확인하세요. 테스트를 종료하려고 할 때 표시되는 모달이 닫힙니다. 따라서 EndTestButton.render()Yes, end test [예, 테스트 종료] 버튼에 대한 onClick 콜백을 대체할 수 있습니다.

import React from 'react';
import {
AccountStorageMutation,
BlockText,
Button,
Grid,
GridItem,
HeadingText,
Modal,
Select,
SelectItem,
} from 'nr1';
class VersionSelector extends React.Component {
constructor(props) {
super(props);
}
render() {
return <Select onChange={this.props.selectVersion} value={this.props.selectedVersion}>
<SelectItem value={'A'}>Version A</SelectItem>
<SelectItem value={'B'}>Version B</SelectItem>
</Select>
}
}
class EndTestButton extends React.Component {
constructor() {
super(...arguments);
this.state = {
modalHidden: true,
}
this.showModal = this.showModal.bind(this);
this.closeModal = this.closeModal.bind(this);
this.endTest = this.endTest.bind(this);
}
closeModal() {
this.setState({ modalHidden: true });
}
showModal() {
this.setState({ modalHidden: false });
}
endTest() {
const today = new Date();
const dd = String(today.getDate()).padStart(2, '0');
const mm = String(today.getMonth() + 1).padStart(2, '0');
const yyyy = today.getFullYear();
const endDate = `${mm}-${dd}-${yyyy}`
AccountStorageMutation.mutate(
{
accountIds: this.props.accountIds,
actionType: AccountStorageMutation.ACTION_TYPE.WRITE_DOCUMENT,
collection: "past-tests",
documentId: endDate,
document: {
versionADescription: this.props.versionADescription,
versionBDescription: this.props.versionBDescription,
winner: this.props.selectedVersion,
}
}
)
this.closeModal();
}
render() {
return <div>
<Button type={Button.TYPE.DESTRUCTIVE} onClick={this.showModal}>End test</Button>
<Modal hidden={this.state.modalHidden} onClose={this.closeModal}>
<HeadingText>Are you sure?</HeadingText>
<BlockText>
If you end the test, all your users will receive the version you selected:
</BlockText>
<BlockText spacingType={[BlockText.SPACING_TYPE.LARGE]}>
<b>Version {this.props.selectedVersion}</b>
</BlockText>
<Button onClick={this.closeModal}>No, continue test</Button>
<Button type={Button.TYPE.DESTRUCTIVE} onClick={this.endTest}>Yes, end test</Button>
</Modal>
</div>
}
}
export default class EndTestSection extends React.Component {
constructor() {
super(...arguments);
this.state = {
selectedVersion: 'A',
};
this.selectVersion = this.selectVersion.bind(this);
}
selectVersion(event, value) {
this.setState({ selectedVersion: value });
}
render() {
return <Grid className="endTestSection">
<GridItem columnSpan={12}>
<HeadingText className="endTestHeader">
Pick the winner of your A/B test:
</HeadingText>
</GridItem>
<GridItem columnStart={5} columnEnd={6} className="versionSelector">
<VersionSelector
selectedVersion={this.state.selectedVersion}
selectVersion={this.selectVersion}
/>
</GridItem>
<GridItem columnStart={7} columnEnd={8}>
<EndTestButton selectedVersion={this.state.selectedVersion}>End test</EndTestButton>
</GridItem>
</Grid>
}
}

테스트를 종료하면 endTest 는 테스트 데이터를 계정 저장소에 저장하고 모달을 닫습니다. 이는 테이블을 채우는 데 필요한 동작의 절반에 불과하며 계정 저장소에서 이 컬렉션을 쿼리해야 합니다.

Nerdlet의 index.js 파일에서 계정 ID와 버전 설명을 EndTestSection 에 전달합니다.

import React from 'react';
import { ChartGroup, Grid, GridItem } from 'nr1';
import EndTestSection from './end-test';
import NewsletterSignups from './newsletter-signups';
import PastTests from './past-tests';
import TotalCancellations from './total-cancellations';
import TotalSubscriptions from './total-subscriptions';
import VersionDescription from './description';
import VersionPageViews from './page-views';
import VersionTotals from './totals';
const ACCOUNT_ID = 123456 // <YOUR NEW RELIC ACCOUNT ID>
const VERSION_A_DESCRIPTION = 'The newsletter signup message says, "Sign up for our newsletter"'
const VERSION_B_DESCRIPTION = 'The newsletter signup message says, "Sign up for our newsletter and get a free shirt!"'
export default class AbTestNerdletNerdlet extends React.Component {
render() {
return <div>
<Grid className="wrapper">
<GridItem columnSpan={6}>
<VersionDescription
description={VERSION_A_DESCRIPTION}
version="A"
/>
</GridItem>
<GridItem columnSpan={6}>
<VersionDescription
description={VERSION_B_DESCRIPTION}
version="B"
/>
</GridItem>
<GridItem columnSpan={12}><hr /></GridItem>
<GridItem columnSpan={12}><NewsletterSignups /></GridItem>
<GridItem columnSpan={6}><TotalSubscriptions /></GridItem>
<GridItem columnSpan={6}><TotalCancellations /></GridItem>
<GridItem columnSpan={6}>
<VersionTotals version='a' accountId={ACCOUNT_ID} />
</GridItem>
<GridItem columnSpan={6}>
<VersionTotals version='b' accountId={ACCOUNT_ID} />
</GridItem>
<ChartGroup>
<GridItem columnSpan={6}>
<VersionPageViews version='a' />
</GridItem>
<GridItem columnSpan={6}>
<VersionPageViews version='b' />
</GridItem>
</ChartGroup>
<GridItem columnSpan={12}>
<EndTestSection
accountId={ACCOUNT_ID}
versionADescription={VERSION_A_DESCRIPTION}
versionBDescription={VERSION_B_DESCRIPTION}
/>
</GridItem>
<GridItem columnSpan={12}><PastTests /></GridItem>
</Grid>
</div>
}
}

중요

<YOUR NEW RELIC ACCOUNT ID> 실제 뉴렐릭 계정 ID 로 바꿔야 합니다.

이제 EndTestSection props에서 이러한 변수에 액세스할 수 있습니다.

계정 ID와 버전 설명을 EndTestSection 에서 EndTestButton 로 전달하세요.

import React from 'react';
import {
AccountStorageMutation,
BlockText,
Button,
Grid,
GridItem,
HeadingText,
Modal,
Select,
SelectItem,
} from 'nr1';
class VersionSelector extends React.Component {
constructor(props) {
super(props);
}
render() {
return <Select onChange={this.props.selectVersion} value={this.props.selectedVersion}>
<SelectItem value={'A'}>Version A</SelectItem>
<SelectItem value={'B'}>Version B</SelectItem>
</Select>
}
}
class EndTestButton extends React.Component {
constructor() {
super(...arguments);
this.state = {
modalHidden: true,
}
this.showModal = this.showModal.bind(this);
this.closeModal = this.closeModal.bind(this);
this.endTest = this.endTest.bind(this);
}
closeModal() {
this.setState({ modalHidden: true });
}
showModal() {
this.setState({ modalHidden: false });
}
endTest() {
const today = new Date();
const dd = String(today.getDate()).padStart(2, '0');
const mm = String(today.getMonth() + 1).padStart(2, '0');
const yyyy = today.getFullYear();
const endDate = `${mm}-${dd}-${yyyy}`
AccountStorageMutation.mutate(
{
accountIds: this.props.accountIds,
actionType: AccountStorageMutation.ACTION_TYPE.WRITE_DOCUMENT,
collection: "past-tests",
documentId: endDate,
document: {
versionADescription: this.props.versionADescription,
versionBDescription: this.props.versionBDescription,
winner: this.props.selectedVersion,
}
}
)
this.closeModal();
}
render() {
return <div>
<Button type={Button.TYPE.DESTRUCTIVE} onClick={this.showModal}>End test</Button>
<Modal hidden={this.state.modalHidden} onClose={this.closeModal}>
<HeadingText>Are you sure?</HeadingText>
<BlockText>
If you end the test, all your users will receive the version you selected:
</BlockText>
<BlockText spacingType={[BlockText.SPACING_TYPE.LARGE]}>
<b>Version {this.props.selectedVersion}</b>
</BlockText>
<Button onClick={this.closeModal}>No, continue test</Button>
<Button type={Button.TYPE.DESTRUCTIVE} onClick={this.endTest}>Yes, end test</Button>
</Modal>
</div>
}
}
export default class EndTestSection extends React.Component {
constructor() {
super(...arguments);
this.state = {
selectedVersion: 'A',
};
this.selectVersion = this.selectVersion.bind(this);
}
selectVersion(event, value) {
this.setState({ selectedVersion: value });
}
render() {
return <Grid className="endTestSection">
<GridItem columnSpan={12}>
<HeadingText className="endTestHeader">
Pick the winner of your A/B test:
</HeadingText>
</GridItem>
<GridItem columnStart={5} columnEnd={6} className="versionSelector">
<VersionSelector
selectedVersion={this.state.selectedVersion}
selectVersion={this.selectVersion}
/>
</GridItem>
<GridItem columnStart={7} columnEnd={8}>
<EndTestButton
accountIds={this.props.accountIds}
selectedVersion={this.state.selectedVersion}
versionADescription={this.props.versionADescription}
versionBDescription={this.props.versionBDescription}
>
End test
</EndTestButton>
</GridItem>
</Grid>
}
}

NerdStorage에서 테스트 정보 가져오기

past-tests.js 에서 PastTests 업데이트하여 계정 저장소에서 데이터를 가져와서 TableChart 에 표시합니다.

import React from 'react';
import {
AccountStorageQuery,
HeadingText,
Spinner,
TableChart,
} from 'nr1';
export default class PastTests extends React.Component {
render() {
const historicalData = {
metadata: {
id: 'past-tests',
name: 'Past tests',
columns: ['endDate', 'versionADescription', 'versionBDescription', 'winner'],
},
data: [],
}
return <div>
<HeadingText className="chartHeader">
Past tests
</HeadingText>
<AccountStorageQuery accountIds={this.props.accountIds} collection="past-tests">
{({ loading, error, data }) => {
if (loading) {
return <Spinner />;
}
if (error) {
console.debug(error);
return 'There was an error fetching your data.';
}
data.forEach(
function (currentValue, index) {
historicalData.data.push({
endDate: currentValue.id,
versionADescription: currentValue.document.versionADescription,
versionBDescription: currentValue.document.versionBDescription,
winner: currentValue.document.winner,
})
}, data
)
return <TableChart data={[historicalData]} fullWidth />
}}
</AccountStorageQuery>
</div>
}
}

먼저, historicalData 에서 모의 데이터를 제거했습니다. 그런 다음 AccountStorageQuery 사용하여 NerdStorage에서 데이터를 가져왔습니다. 계정 식별자와 문서를 저장한 컬렉션의 이름을 전달했습니다.

쿼리에는 세 가지 반환 값이 있습니다.

  • loading
  • error
  • data

쿼리가 진행 중인 경우 loadingtrue 입니다. 이 경우 테이블이 아직 준비되지 않았음을 사용자에게 알리기 위해 Spinner 사용자 인터페이스 구성요소를 표시합니다. 쿼리가 오류를 반환한 경우 error 변수에서 해당 오류에 대한 정보를 볼 수 있습니다. 디버깅 목적으로 해당 정보를 콘솔에 입력하고 오류 메시지를 반환합니다. 쿼리가 성공적으로 반환되면 data 변수의 데이터에 액세스할 수 있습니다. 데이터가 TableChart 에 필요한 형식과 일치하지 않기 때문에 데이터를 반복하여 TableChart 사양에 따라 형식을 지정합니다. 마지막으로 historicalData TableChart 에 전달합니다.

Nerdlet의 index.js 파일에서 ACCOUNT_IDPastTests 에 전달합니다.

import React from 'react';
import { ChartGroup, Grid, GridItem } from 'nr1';
import EndTestSection from './end-test';
import NewsletterSignups from './newsletter-signups';
import PastTests from './past-tests';
import TotalCancellations from './total-cancellations';
import TotalSubscriptions from './total-subscriptions';
import VersionDescription from './description';
import VersionPageViews from './page-views';
import VersionTotals from './totals';
const ACCOUNT_ID = 1234567 // <YOUR NEW RELIC ACCOUNT ID>
const VERSION_A_DESCRIPTION = 'The newsletter signup message says, "Sign up for our newsletter"'
const VERSION_B_DESCRIPTION = 'The newsletter signup message says, "Sign up for our newsletter and get a free shirt!"'
export default class AbTestNerdletNerdlet extends React.Component {
render() {
return <div>
<Grid className="wrapper">
<GridItem columnSpan={6}>
<VersionDescription
description={VERSION_A_DESCRIPTION}
version="A"
/>
</GridItem>
<GridItem columnSpan={6}>
<VersionDescription
description={VERSION_B_DESCRIPTION}
version="B"
/>
</GridItem>
<GridItem columnSpan={12}><hr /></GridItem>
<GridItem columnSpan={12}><NewsletterSignups /></GridItem>
<GridItem columnSpan={6}><TotalSubscriptions /></GridItem>
<GridItem columnSpan={6}><TotalCancellations /></GridItem>
<GridItem columnSpan={6}>
<VersionTotals version='a' accountId={ACCOUNT_ID} />
</GridItem>
<GridItem columnSpan={6}>
<VersionTotals version='b' accountId={ACCOUNT_ID} />
</GridItem>
<ChartGroup>
<GridItem columnSpan={6}>
<VersionPageViews version='a' />
</GridItem>
<GridItem columnSpan={6}>
<VersionPageViews version='b' />
</GridItem>
</ChartGroup>
<GridItem columnSpan={12}>
<EndTestSection
accountId={ACCOUNT_ID}
versionADescription={VERSION_A_DESCRIPTION}
versionBDescription={VERSION_B_DESCRIPTION}
/>
</GridItem>
<GridItem columnSpan={12}>
<PastTests accountId={ACCOUNT_ID} />
</GridItem>
</Grid>
</div>
}
}

중요

<YOUR NEW RELIC ACCOUNT ID> 실제 뉴렐릭 계정 ID 로 바꿔야 합니다.

nru-programmability-course/add-nerdstorage/ab-test 에서 Nerdpack의 루트로 이동합니다.

Nerdpack에 대한 새 UUID를 생성하십시오.

bash
$
nr1 nerdpack:uuid -gf

기존 Nerdpack이 포함된 교과 과정 저장소를 복제했으므로 고유한 식별자를 생성해야 합니다. 이 UUID는 Nerdpack을 New Relic 계정에 매핑합니다. 또한 앱이 귀하의 계정을 대신하여 Nerdgraph 요청을 할 수 있도록 허용합니다.

애플리케이션을 로컬로 제공합니다.

bash
$
nr1 nerdpack:serve

https://one.newrelic.com?nerdpacks=local 로 이동하여 Apps [앱] > Your apps [클릭하면] 아래에서 애플리케이션을 확인하세요.

처음에는 데이터가 표시되지 않습니다.

End test [테스트 종료를] 클릭하고 모달에서 작업을 승인합니다. 이제 Past tests [과거 테스트] 에서 데이터를 볼 수 있습니다.

문제가 작동하지 않으면 브라우저의 디버그 도구를 사용하여 문제를 식별해 보세요.

다음 사항을 확인하세요.

  • 강의에서 코드를 올바르게 복사했습니다.
  • 새로운 UUID를 생성했습니다.
  • 프로젝트의 <YOUR NEW RELIC ACCOUNT ID> 의 모든 vit을 실제 뉴렐릭 계정 ID로 교체했습니다.

작업이 끝나면 로컬 서버의 터미널 창에서 CTRL+C 눌러 New Relic 피규어 제공을 중지하세요.

훌륭한 일! 이제 NerdStorage 쿼리 및 변형 구성 요소를 사용해 본 경험이 있습니다. 그러나 모의 데이터가 포함된 차트가 하나 더 있습니다. Total cancellations per version [버전당 총 취소 수] 입니다.

Total cancellations per version [버전당 총 취소 수는] A/B 테스트 애플리케이션의 다른 차트와 다릅니다. New Relic은 뉴스레터 구독을 취소한 사용자 수에 대해 전혀 모르기 때문에 외부 소스에서 해당 정보를 요청해야 합니다. 이 과정의 목적을 위해 우리는 귀하의 애플리케이션에서 사용할 가짜 뉴스레터 취소 데이터를 제공하는 외부 데이터 서비스를 만들었습니다. 이 모의 서비스는 https://api.nerdsletter.net/cancellations 에 있습니다.

New Relic 기능은 React 기능입니다. 즉, React 및 Javascript 기능을 사용하여 New Relic뿐만 아니라 모든 외부 서비스에서 데이터를 수집할 수 있습니다. 이후 강의에서는 소프트웨어가 비즈니스 목표 달성에 어떻게 도움이 되는지 알려주는 데이터를 New Relic 너머로 보는 방법을 배우게 됩니다. 하지만 이를 배우기 전에 모의 데이터 서비스에 대해 알아야 합니다. 이 서비스에는 Authorization 헤더가 필요합니다!

이 학습에서는 NerdStorage를 사용하여 애플리케이션의 자체 데이터 저장소에 있는 데이터를 쿼리하고 변경하는 방법을 배웠습니다. NerdStorage는 다양한 범주의 데이터에 적합한 장소이지만 Authorization 헤더에서 외부 서비스에 전달하는 토큰과 같은 민감한 데이터에는 적합하지 않습니다. 이를 위해 NerdStorageVault를 사용합니다.

이 강의는 처음부터 New Relic 제작 방법을 가르치는 과정의 일부입니다. 다음 강의로 계속 진행하세요: Nerdlet에서 NerdStorageVault에 액세스하세요.

Copyright © 2024 New Relic Inc.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.