Pour qu’une intégration basée sur l’Agent soit considérée comme complète, et donc prête à être incluse dans le référentiel principal et intégrée au paquet de l’Agent, un certain nombre d’exigences doivent être satisfaites :
README.md
doit être au bon format et inclure le contenu adéquat.metadata.csv
doit énumérer toutes les métriques recueillies.manifest.json
doit être complet.service_checks.json
doit également être présent.Ces exigences forment une checklist de vérification qui est passée en revue durant le processus d’examen du code. Cette documentation vous expliquera comment satisfaire ces exigences et implémenter correctement votre nouvelle intégration.
Si la création et l’activation d'environnements virtuels Python est généralement conseillé pour isoler l’environnement de développement, ce n’est toutefois pas obligatoire. Pour en savoir plus, consultez la documentation sur l’environnement Python.
Clonez le référentiel integrations-extras. Par défaut, ces outils s’attendent à ce que vous travailliez dans le répertoire $HOME/dd/
. Ce n’est toutefois pas obligatoire, et vous aurez la possibilité de modifier ce paramètre ultérieurement.
mkdir $HOME/dd && cd $HOME/dd # facultatif
git clone https://github.com/DataDog/integrations-extras.git
Le kit de développement est complet et intègre de nombreuses fonctionnalités. Pour démarrer, exécutez cette commande :
pip3 install "datadog-checks-dev[cli]"
Si vous avez choisi de cloner ce référentiel à un emplacement autre que $HOME/dd/
, vous devrez modifier le fichier de configuration :
ddev config set extras "/chemin/vers/integrations-extras"
Si vous prévoyez de travailler principalement sur integrations-extras
, définissez-le comme référentiel de travail par défaut :
ddev config set repo extras
Remarque : si vous sautez cette étape, vous devrez utiliser l’option -e
à chaque appel pour vérifier que le contexte est integrations-extras
:
ddev -e COMMANDE [OPTIONS]
L’une des fonctionnalités du kit de développement est la commande create
, qui crée la structure de fichiers et de chemins générale (c’est-à-dire l'« architecture ») nécessaire pour toute nouvelle intégration.
Pour effectuer un test d’exécution, utilisez le flag -n/--dry-run
, qui n’effectue aucune écriture sur le disque.
ddev create -n Awesome
Cette commande affiche le chemin où les fichiers auraient été écrits, ainsi que la structure. Pour le moment, contentez-vous de vérifier que le chemin dans la première ligne de la sortie correspond à l’emplacement de votre référentiel Extras.
Le mode interactif est un assistant conçu pour vous aider à créer des intégrations. Il suffit de répondre à quelques questions pour que l’architecture soit automatiquement définie et préconfigurée.
ddev create Awesome
Après avoir répondu aux questions, la sortie correspond à celle du test d’exécution ci-dessus, à la différence près que l’architecture de votre nouvelle intégration existe vraiment.
Un Check est une classe Python qui doit :
AgentCheck
check(self, instance)
Les checks se présentent sous la forme de paquets Python classiques stockés dans l’espace de nommage datadog_checks
; votre code résidera donc dans awesome/datadog_checks/awesome
. La seule exigence est que le nom du paquet soit le même que le nom du check. Aucune restriction particulière n’est appliquée quant au nom des modules Python dans ce paquet, ni quant au nom de la classe qui implémente le check.
Supposons que vous souhaitez créer un check d’Agent composé uniquement d’un check de service appelé awesome.search
qui recherche une chaîne sur une page Web. Il renverra OK
si la chaîne est présente, WARNING
si la page est accessible mais que la chaîne est absente, et CRITICAL
si la page est inaccessible. Consultez la section Envoi de métriques : check custom d’Agent pour découvrir comment envoyer des métriques à l’aide de votre check d’Agent.
Le code contenu dans awesome/datadog_checks/awesome/check.py
ressemble à ceci :
import requests
from datadog_checks.base import AgentCheck, ConfigurationError
class AwesomeCheck(AgentCheck):
"""AwesomeCheck est dérivé d'AgentCheck et fournit la méthode de check requise."""
def check(self, instance):
url = instance.get('url')
search_string = instance.get('search_string')
# Il convient de réaliser quelques contrôles d'intégrité basiques.
# Soyez aussi précis que possible avec les exceptions.
if not url or not search_string:
raise ConfigurationError('Configuration error, please fix awesome.yaml')
try:
response = requests.get(url)
response.raise_for_status()
# En cas de problème sérieux
except Exception as e:
# Un message plus spécifique serait préférable
self.service_check('awesome.search', self.CRITICAL, message=str(e))
# La page est accessible
else:
# search_string est présent
if search_string in response.text:
self.service_check('awesome.search', self.OK)
# search_string est introuvable
else:
self.service_check('awesome.search', self.WARNING)
Pour en savoir plus sur la classe Python de base, consultez la documentation sur l’API Python (en anglais).
Il existe deux types de tests de base :
check
et vérifient la bonne collecte des métriquesLes tests sont obligatoires si vous souhaitez que votre intégration soit ajoutée à integrations-extras
. Notez que pytest et tox sont utilisés pour exécuter les tests.
Pour en savoir plus, consultez la documentation sur le développement de checks Datadog.
La première partie de la méthode check
récupère et vérifie deux éléments du fichier de configuration. Un test d’unité serait donc particulièrement utile. Ouvrez le fichier awesome/tests/test_awesome.py
et remplacez son contenu pour qu’il ressemble à ceci :
import pytest
# N'oubliez pas d'importer votre intégration !
from datadog_checks.awesome import AwesomeCheck
from datadog_checks.base import ConfigurationError
@pytest.mark.unit
def test_config():
instance = {}
c = AwesomeCheck('awesome', {}, [instance])
# instance vide
with pytest.raises(ConfigurationError):
c.check(instance)
# url uniquement
with pytest.raises(ConfigurationError):
c.check({'url': 'http://foobar'})
# chaîne de recherche uniquement
with pytest.raises(ConfigurationError):
c.check({'search_string': 'foo'})
# aucune erreur ne devrait survenir
c.check({'url': 'http://foobar', 'search_string': 'foo'})
pytest
permet d’utiliser ce que l’on appelle des marqueurs, qui servent à regrouper les tests par catégorie. Notez que le marqueur unit
a été appliqué à test_config
.
L’architecture a déjà été configurée de façon à ce que tous les tests situés dans awesome/tests
soient exécutés. Pour exécuter ces tests :
ddev test awesome
Ce test d’unité ne vérifie pas la logique de collecte ; nous allons donc ajouter un test d’intégration. docker
est utilisé pour lancer un conteneur Nginx et laisser le check récupérer la page d’accueil. Créez un fichier compose awesome/tests/docker-compose.yml
avec le contenu suivant :
version: "3"
services:
nginx:
image: nginx:stable-alpine
ports:
- "8000:80"
Ouvrez ensuite le fichier awesome/tests/conftest.py
et remplacez le contenu de cette manière :
import os
import pytest
from datadog_checks.dev import docker_run, get_docker_hostname, get_here
URL = 'http://{}:8000'.format(get_docker_hostname())
SEARCH_STRING = 'Thank you for using nginx.'
INSTANCE = {'url': URL, 'search_string': SEARCH_STRING}
@pytest.fixture(scope='session')
def dd_environment():
compose_file = os.path.join(get_here(), 'docker-compose.yml')
# On accomplit ici 3 choses :
#
# 1. Lancer les services définis dans le fichier compose
# 2. Attendre que l'URL soit disponible avant de lancer les tests
# 3. Démonter les services lorsque les tests sont terminés
with docker_run(compose_file, endpoints=[URL]):
yield INSTANCE
@pytest.fixture
def instance():
return INSTANCE.copy()
Enfin, ajoutez un test d’intégration au fichier awesome/tests/test_awesome.py
:
@pytest.mark.integration
@pytest.mark.usefixtures('dd_environment')
def test_service_check(aggregator, instance):
c = AwesomeCheck('awesome', {}, [instance])
# le check doit renvoyer OK
c.check(instance)
aggregator.assert_service_check('awesome.search', AwesomeCheck.OK)
# le check doit renvoyer WARNING
instance['search_string'] = 'Apache'
c.check(instance)
aggregator.assert_service_check('awesome.search', AwesomeCheck.WARNING)
Pour un développement plus rapide, lancez les tests d’intégration uniquement avec l’option -m/--marker
:
ddev test -m integration awesome
Le check est quasiment fini. Apportons la touche finale en ajoutant les configurations d’intégration.
Pour qu’un check puisse être inclus, l’ensemble des ressources créées par l’architecture ddev doit être complet :
README.md
: ce fichier contient la documentation de votre check. Il explique sa configuration, les données qu’il recueille, etc.spec.yaml
: ce fichier permet de générer un conf.yaml.example
à l’aide de l’outil ddev
(consultez l’onglet « Modèle de configuration » ci-dessous). Pour en savoir plus, consultez la documentation sur les spécifications de configuration.conf.yaml.example
: ce fichier contient les options de configuration par défaut (ou des exemples) pour votre check d’Agent. Ne modifiez pas ce fichier manuellement ! Il est généré à partir du contenu du fichier spec.yaml
. Consultez la documentation relative aux fichiers de configuration pour mieux comprendre sa logique.manifest.json
: ce fichier contient les métadonnées de votre check d’Agent, telles que le titre, les catégories, etc. Consultez la documentation relative aux manifestes pour en savoir plus.metadata.csv
: ce fichier contient la liste de toutes les métriques recueillies par votre check d’Agent. Consultez la documentation relative aux métadonnées des métriques pour en savoir plus.service_check.json
: ce fichier contient la liste de tous les checks de service recueillis par votre check d’Agent. Consultez la documentation relative aux checks de service pour en savoir plus.Dans cet exemple, ces fichiers ressembleraient à ce qui suit :
Le fichier awesome/assets/configuration/spec.yaml
utilisé pour générer awesome/datadog_checks/awesome/data/conf.yaml.example
:
name: Awesome
files:
- name: awesome.yaml
options:
- template: init_config
options:
- template: init_config/default
- template: instances
options:
- name: url
required: true
description: The URL to check.
value:
type: string
example: http://example.org
- name: search_string
required: true
description: The string to search for.
value:
type: string
example: Example Domain
- name: flag_follow_redirects
# required: false est implicite ; mettez-le en commentaire pour voir ce qui se passe !
required: false
description: Follow 301 redirects.
value:
type: boolean
example: false
# Essayez de supprimer la mise en commentaire de ce modèle pour voir ce qui se passe !
#- template: instances/default
Générez le fichier conf.yaml.example
à l’aide de ddev
:
ddev validate config --sync awesome
Le fichier awesome/manifest.json
pour le check de service Awesome. Notez que le guid
doit être unique (et valide). N’utilisez donc pas celui de cet exemple. Cet identifiant sera de toute façon automatiquement géré :
{
"display_name": "awesome",
"maintainer": "email@example.org",
"manifest_version": "1.0.0",
"name": "awesome",
"metric_prefix": "awesome.",
"metric_to_check": "",
"creates_events": false,
"short_description": "",
"guid": "x16b8750-df1e-46c0-839a-2056461b604x",
"support": "contrib",
"supported_os": ["linux", "mac_os", "windows"],
"public_title": "Intégration Datadog/Awesome",
"categories": ["web"],
"type": "check",
"is_public": false,
"integration_id": "awesome",
"assets": {
"dashboards": {
"Awesome Overview": "assets/dashboards/overview.json",
"Awesome Investigation Dashboard": "assets/dashboards/investigation.json"
},
"monitors": {},
"service_checks": "assets/service_checks.json"
}
}
L’exemple d’intégration n’envoie aucune métrique. Le fichier awesome/metadata.csv
généré contient donc uniquement la ligne avec les noms de colonne CSV.
L’exemple d’intégration contient un check de service. Vous devez donc l’ajouter au fichier awesome/assets/service_checks.json
:
[
{
"agent_version": "6.0.0",
"integration": "awesome",
"check": "awesome.search",
"statuses": ["ok", "warning", "critical"],
"groups": [],
"name": "Recherche Awesome",
"description": "Renvoie `CRITICAL` si le check n'accède pas à la page, `WARNING` si la chaîne de recherche n'a pas été trouvée ou `OK` pour les autres cas."
}
]
setup.py
contient le script de configuration setuptools, qui facilite la compilation d’un paquet au format wheel. Pour en savoir plus sur les paquets Python, consultez la documentation Python officielle (en anglais).
Une fois votre fichier setup.py
prêt, créez un wheel :
ddev
(conseillé) : ddev release build <NOM_INTÉGRATION>
ddev
: cd <RÉPERTOIRE_INTÉGRATION> && python setup.py bdist_wheel
Le wheel contient tous les fichiers nécessaires au bon fonctionnement de l’intégration. Il s’agit notamment du check, de l’exemple de fichier de configuration et de certains artefacts générés durant la compilation du wheel. Tous les autres éléments, y compris les fichiers de métadonnées, ne sont pas supposés se trouver dans le wheel. Ces éléments sont utilisés ailleurs par l’écosystème et la plateforme Datadog.
Le wheel est installé via la commande integration
de l’Agent, disponible dans les versions 6.10.0 et ultérieures de l’Agent. En fonction de votre environnement, il est possible que vous deviez utiliser un utilisateur spécifique ou certaines autorisations précises pour exécuter cette commande :
Linux (en tant que dd-agent
) :
sudo -u dd-agent datadog-agent integration install -w /chemin/vers/wheel.whl
OSX (en tant qu’admin) :
sudo datadog-agent integration install -w /chemin/vers/wheel.whl
Windows (veillez à ce que votre session shell dispose des privilèges administrateur) :
Pour les versions <= 6.11 de l’Agent :
"C:\Program Files\Datadog\Datadog Agent\embedded\agent.exe" integration install -w /chemin/vers/wheel.whl
Pour les versions >= 6.12 de l’Agent :
"C:\Program Files\Datadog\Datadog Agent\bin\agent.exe" integration install -w /chemin/vers/wheel.whl
Sur cette page