";let n=document.getElementById("TableOfContents");n&&(n.innerHTML=e)}rerender(){this.renderFilterMenu(),this.renderPageContent(),this.populateRightNav(),this.runHooks("afterRerender")}renderPageContent(){let e={};Object.keys(this.ifFunctionsByRef).forEach(t=>{let s=this.ifFunctionsByRef[t],o=s.value,n=(0,h.reresolveFunctionNode)(s,{variables:this.selectedValsByTraitId});this.ifFunctionsByRef[t]=n,o!==n.value&&(e[t]=n.value)});let t=document.getElementsByClassName("cdoc__toggleable");for(let n=0;n{this.fitCustomizationMenuToScreen()})}addDropdownEventListeners(){let e=document.getElementsByClassName("cdoc-dropdown");for(let t=0;t{let t=e.target;for(;!t.classList.contains("cdoc-dropdown")&&t.parentElement;)t=t.parentElement;let n=t.classList.toggle("cdoc-dropdown__expanded");t.setAttribute("aria-expanded",n.toString())});document.addEventListener("keydown",e=>{if(e.key==="Enter"){let t=e.target;t.classList.contains("cdoc-filter__option")&&t.click()}}),document.addEventListener("click",t=>{for(let n=0;nthis.handleFilterSelectionChange(e));this.addDropdownEventListeners()}locateFilterSelectorEl(){let e=document.getElementById("cdoc-selector");return!!e&&(this.filterSelectorEl=e,!0)}applyFilterSelectionOverrides(){let s=Object.keys(this.selectedValsByTraitId),e=!1,t=this.browserStorage.getTraitVals();Object.keys(t).forEach(n=>{s.includes(n)&&this.selectedValsByTraitId[n]!==t[n]&&(this.selectedValsByTraitId[n]=t[n],e=!0)});let n=(0,j.getTraitValsFromUrl)({url:new URL(window.location.href),traitIds:s});return Object.keys(n).forEach(t=>{this.selectedValsByTraitId[t]!==n[t]&&(this.selectedValsByTraitId[t]=n[t],e=!0)}),e}updateEditButton(){let t=document.getElementsByClassName("toc-edit-btn")[0];if(!t)return;let e=t.getElementsByTagName("a")[0];e&&(e.href=e.href.replace(/\.md\/$/,".mdoc.md/"))}revealPage(){this.runHooks("beforeReveal"),this.filterSelectorEl&&(this.filterSelectorEl.style.position="sticky",this.filterSelectorEl.style.backgroundColor="white",this.filterSelectorEl.style.paddingTop="10px",this.filterSelectorEl.style.visibility="visible",this.filterSelectorEl.style.zIndex="1000");let e=document.getElementById("cdoc-content");e&&(e.style.visibility="visible"),this.runHooks("afterReveal")}renderFilterMenu(){if(!this.filterSelectorEl||!this.filtersManifest)throw new Error("Cannot render filter selector without filtersManifest and filterSelectorEl");let e=(0,l.resolveFilters)({filtersManifest:this.filtersManifest,valsByTraitId:this.selectedValsByTraitId});Object.keys(e).forEach(t=>{let n=e[t];this.selectedValsByTraitId[t]=n.currentValue});let t=(0,y.buildCustomizationMenuUi)(e);this.filterSelectorEl.innerHTML=t,this.fitCustomizationMenuToScreen(),this.addFilterSelectorEventListeners()}fitCustomizationMenuToScreen(){let e=document.getElementById(g);if(!e)return;let s=e.classList.contains(n),t=document.getElementById(v);if(!t)throw new Error("Dropdown menu not found");let o=document.getElementById(b);if(!o)throw new Error("Menu wrapper not found");let i=e.scrollWidth>o.clientWidth;!s&&i?(e.classList.add(n),t.classList.remove(n)):s&&!i&&(e.classList.remove(n),t.classList.add(n))}get cdocsState(){return{selectedValsByTraitId:this.selectedValsByTraitId,ifFunctionsByRef:this.ifFunctionsByRef,filtersManifest:this.filtersManifest,browserStorage:this.browserStorage,filterSelectorEl:this.filterSelectorEl}}};e.ClientFiltersManager=r,t=r,s={value:void 0}}),y=e(e=>{Object.defineProperty(e,"__esModule",{value:!0});var t=j();window.clientFiltersManager=t.ClientFiltersManager.instance}),y()})()에이전트 기반 통합 생성
이 페이지에서는 Technology Partners가 Datadog Agent 통합을 생성하는 방법에 대해 알아봅니다. 이 통합은 Integrations 페이지에서 기본 제공 항목으로 공개하거나 Marketplace 페이지에서 유료로 공개할 수 있습니다.
Agent 기반 통합은 Datadog Agent를 사용하여 개발자가 작성한 사용자 지정 점검을 통해 데이터를 제출합니다. 이러한 점검은 메트릭, 이벤트, 서비스 점검을 고객의 Datadog 계정으로 전송할 수 있습니다. Agent 자체도 로그를 제출할 수 있지만, 이는 점검 외부에서 구성됩니다.
Agent 기반 통합은 언제 사용하나요?
Agent 통합은 다음을 실행하는 시스템이나 애플리케이션에서 데이터를 수집하는 데 가장 적합합니다.
근거리 통신망(LAN)
가상 프라이빗 클라우드(VPC)
Agent 기반 통합은 Python wheel(.whl)로 게시하고 배포해야 합니다.
개발 프로세스
Agent 기반 통합을 만드는 프로세스는 다음과 같습니다.
Datadog Partner Network에 가입하기
Datadog Partner Network에 지원하세요. 지원이 승인되면 Datadog Technology Partner 팀 담당자와의 오리엔테이션 콜 일정이 예약됩니다.
개발 환경 설정
Datadog Partner Network 포털을 통해 Datadog 샌드박스 계정을 요청합니다.
필수 개발 도구를 설치합니다.
통합 생성
Datadog 샌드박스에서 Developer Platform > add a new listing으로 이동합니다.
에이전트 통합 개발자 도구를 사용하면 통합 타일의 에셋 및 메타데이터의 골격을 생성하여 통합을 개발할 때 스캐폴딩을 만들 수 있습니다. 도구 설치에 대한 자세한 내용은 Datadog 에이전트 통합 개발자 도구 설치하기를 참조하세요.
에이전트 통합 개발자 도구를 설치한 후에는 마켓플레이스 리포지토리에 맞게 설정합니다.
marketplace를 기본 작업 리포지토리로 설정합니다:
ddev config set repos.marketplace $HOME/dd/marketplace
ddev config set repo marketplace
marketplace 디렉토리 복제를 위해 $HOME/dd 이외의 다른 디렉토리를 사용한 경우 다음 명령을 사용하여 작업 리포지토리를 설정하세요:
ddev config set repos.marketplace <PATH/TO/MARKETPLACE>
ddev config set repo marketplace
통합 생성
Docker를 다운로드하고, 적절한 버전의 Python을 설치하고, 개발 환경을 준비하면 Agent 기반 통합을 만들 수 있습니다.
다음 지침에서는 Awesome이라는 통합 예제를 사용합니다. Awesome의 코드를 사용하거나, Awesome을 직접 작성한 코드로 바꾸고 명령 내에서 통합 이름을 입력하세요. 예를 들어 ddev create Awesome 대신 ddev create <your-integration-name>을 사용합니다.
통합을 위한 스캐폴딩 만들기
ddev create 명령은 에이전트 기반 통합에 필요한 기본 파일 및 경로 구조 (또는 “스캐폴딩”)를 만드는 대화형 도구를 실행합니다.
첫 번째 통합 디렉토리를 만들기 전에 디스크에 아무것도 쓰지 않는 -n/--dry-run 플래그를 사용하여 드라이 런을 시도해 보세요:
ddev create -n Awesome
이 명령은 파일이 작성되었을 경로와 구조를 표시합니다. 출력 첫 줄의 경로가 리포지토리 위치와 일치하는지 확인하세요.
-n 플래그 없이 명령을 실행합니다. 도구에서 이메일과 이름을 입력하면 통합을 시작하는 데 필요한 파일을 생성합니다.
Datadog 마켓플레이스용 통합을 만드는 경우, 디렉토리가 {파트너 이름}_{통합 이름}의 패턴을 따르는지 확인하세요.
ddev create Awesome
에이전트 검사 작성
모든 Agent 기반 통합의 핵심은 주기적으로 정보를 수집하고 Datadog에 전송하는 Agent Check입니다.
검사는 AgentCheck 기본 클래스에서 로직을 이어 받고, 다음과 같은 요구 사항을 갖습니다:
Datadog 에이전트 v7 이상에서 실행되는 통합은 Python 3과 호환되어야 하지만, 에이전트 v5 및 v6에서 실행되는 통합은 여전히 Python 2.7을 사용합니다.
검사는 반드시 AgentCheck에서 파생되어야 합니다.
검사는 서명 check(self, instance)이 포함된 방식을 제공해야 합니다.
검사는 datadog_checks 네임스페이스 아래의 일반 Python 패키지에 구성됩니다. 예를 들어, Awesome의 코드는 awesome/datadog_checks/awesome/ 디렉토리에 있습니다.
패키지 이름은 검사 이름과 동일해야 합니다.
해당 패키지 내의 Python 모듈 이름이나 검사를 구현하는 클래스 이름에는 제한이 없습니다.
검사 로직 구현
Awesome의 경우 Agent Check는 awesome.search라는 서비스 점검으로 구성되며, 이 점검은 웹 페이지에서 문자열을 검색합니다. 문자열이 존재하면 OK, 페이지에 접근할 수 있지만 문자열을 찾을 수 없다면 WARNING, 페이지에 접근할 수 없다면 CRITICAL을 표시합니다.
awesome/datadog_checks/awesome/check.py 안에 포함된 코드는 다음과 같습니다:
check.py
importrequestsfromdatadog_checks.baseimportAgentCheck,ConfigurationErrorclassAwesomeCheck(AgentCheck):"""AwesomeCheck derives from AgentCheck, and provides the required check method."""defcheck(self,instance):url=instance.get('url')search_string=instance.get('search_string')# It's a very good idea to do some basic sanity checking.# Try to be as specific as possible with the exceptions.ifnoturlornotsearch_string:raiseConfigurationError('Configuration error, please fix awesome.yaml')try:response=requests.get(url)response.raise_for_status()# Something went horribly wrongexceptExceptionase:# Ideally we'd use a more specific message...self.service_check('awesome.search',self.CRITICAL,message=str(e))# Page is accessibleelse:# search_string is presentifsearch_stringinresponse.text:self.service_check('awesome.search',self.OK)# search_string was not foundelse:self.service_check('awesome.search',self.WARNING)
pytest 및 hatch는 테스트를 실행하는 데 사용됩니다. 통합을 게시하려면 테스트가 필요합니다.
단위 테스트 작성
Awesome용 check 메서드의 첫 번째 부분은 구성 파일에서 두 요소를 검색하고 검증합니다. 이는 단위 테스트를 작성하기에 적합한 대상입니다.
awesome/tests/test_awesome.py에서 파일을 열고 내용을 다음으로 바꿉니다:
test_awesome.py
importpytest# Don't forget to import your integrationfromdatadog_checks.awesomeimportAwesomeCheckfromdatadog_checks.baseimportConfigurationError@pytest.mark.unitdeftest_config():instance={}c=AwesomeCheck('awesome',{},[instance])# empty instancewithpytest.raises(ConfigurationError):c.check(instance)# only the urlwithpytest.raises(ConfigurationError):c.check({'url':'http://foobar'})# only the search stringwithpytest.raises(ConfigurationError):c.check({'search_string':'foo'})# this should not failc.check({'url':'http://foobar','search_string':'foo'})
pytest에는 테스트를 카테고리로 그룹화하는 데 사용할 수 있는 마커라는 개념이 있습니다. test_config이 unit 테스트로 표시된 것을 주목하세요.
awesome/tests에 있는 모든 테스트를 실행하도록 스캐폴딩이 설정되어 있습니다. 테스트를 실행하려면 다음 명령을 실행하세요:
그런 다음 awesome/tests/conftest.py에서 파일을 열고 내용을 다음으로 바꿉니다:
conftest.py
importosimportpytestfromdatadog_checks.devimportdocker_run,get_docker_hostname,get_hereURL='http://{}:8000'.format(get_docker_hostname())SEARCH_STRING='Thank you for using nginx.'INSTANCE={'url':URL,'search_string':SEARCH_STRING}@pytest.fixture(scope='session')defdd_environment():compose_file=os.path.join(get_here(),'docker-compose.yml')# 이렇게 하면 세 가지 작업이 수행됩니다:## 1. compose 파일에 정의된 서비스를 스핀업# 2. 테스트를 실행하기 전에 URL을 사용할 수 있을 때까지 대기# 3. 테스트가 완료되면 서비스 중단withdocker_run(compose_file,endpoints=[URL]):yieldINSTANCE@pytest.fixturedefinstance():returnINSTANCE.copy()
통합 테스트 추가
통합 테스트를 위한 환경을 설정한 후 awesome/tests/test_awesome.py 파일에 통합 테스트를 추가합니다:
test_awesome.py
@pytest.mark.integration@pytest.mark.usefixtures('dd_environment')deftest_service_check(aggregator,instance):c=AwesomeCheck('awesome',{},[instance])# the check should send OKc.check(instance)aggregator.assert_service_check('awesome.search',AwesomeCheck.OK)# the check should send WARNINGinstance['search_string']='Apache'c.check(instance)aggregator.assert_service_check('awesome.search',AwesomeCheck.WARNING)
개발 속도를 높이려면 -m/--marker 옵션을 사용하여 통합 테스트만 실행하세요:
ddev test -m integration awesome
통합이 거의 완료되었습니다. 샌드박스의 Developer Platform으로 돌아가서 제출을 완료하세요.
휠 구축하기
pyproject.toml 파일은 휠을 패키징하고 구축하는 데 사용되는 메타데이터를 제공합니다. 휠에는 통합 기능에 필요한 파일이 포함되어 있으며, 여기에는 에이전트 검사, 설정 예제 파일 및 휠 빌드 중에 생성된 아티팩트가 포함됩니다.
메타데이터 파일 등 모든 추가 요소는 wheel 내에 포함되지 않으며, Datadog 플랫폼과 에코시스템의 다른 곳에서 사용됩니다.