[comment]: # translation:outdated

[comment]: # aside:5

[comment]: # ({f2a0429f-ebcec779})
# Envoyer des données au serveur ou au proxy Zabbix

[zabbix\_utils](https://github.com/zabbix/python-zabbix-utils/blob/main/README.md) vous permet d'envoyer des valeurs d'élément à un [élément trapper](/manual/config/items/itemtypes/trapper) sur le serveur ou le proxy Zabbix (de manière similaire à [Zabbix sender](/manual/concepts/sender)).

Vous pouvez envoyer une seule valeur, plusieurs valeurs, ou même cibler plusieurs clusters Zabbix.

Les données peuvent être envoyées en mode synchrone ou asynchrone :

-   En mode synchrone, votre script Python envoie des valeurs et attend une réponse avant de continuer ; cela convient aux opérations simples, séquentielles et prévisibles.
-   En mode asynchrone, le script envoie des valeurs sans attendre chaque réponse, ce qui permet à d'autres opérations de se poursuivre en parallèle ; cela est plus efficace pour les requêtes lentes ou les lots de données volumineux.

Les exemples de cette page se concentrent sur le mode synchrone, bien que le [mode asynchrone](#asynchronous-mode) suive des principes similaires.
Des exemples supplémentaires sont disponibles dans le dépôt GitHub [zabbix_utils](https://github.com/zabbix/python-zabbix-utils/tree/main/examples).

[comment]: # ({/f2a0429f-ebcec779})

[comment]: # ({33a3626c-2b58225a})
#### Importation

Pour utiliser zabbix\_utils afin d’envoyer des valeurs d’élément, importez la classe `Sender` dans votre script :

```python
from zabbix_utils import Sender
```

Pour envoyer plusieurs valeurs, vous pouvez également importer la classe `ItemValue` :

```python
from zabbix_utils import Sender, ItemValue
```

[comment]: # ({/33a3626c-2b58225a})

[comment]: # ({6215a382-248fa427})
#### Envoyer une valeur unique

Pour envoyer une valeur d’élément :

1. Créez une instance de `Sender`, en spécifiant l’adresse IP et le port de votre serveur ou proxy Zabbix.
2. Appelez la méthode `send_value()` sur l’instance `Sender` en utilisant le format suivant :

```python
sender_instance.send_value('host', 'item.key', 'value', optional_timestamp, optional_nanoseconds)
```

Par exemple, pour envoyer `1` à l’élément trapper `service.status` sur l’hôte `Linux server` :

```python
sender = Sender(server='127.0.0.1', port=10051)
response = sender.send_value('Linux server', 'service.status', 1)
```

[comment]: # ({/6215a382-248fa427})

[comment]: # ({ba5ab006-8c41d6ba})
##### Utilisation d’une IP non par défaut

Si le serveur exécutant votre script possède plusieurs adresses IP, vous pouvez spécifier un `source_ip` que le `Sender` utilisera lors de l’envoi des valeurs au serveur Zabbix ou au proxy :

```python
sender = Sender(
    server='127.0.0.1',
    port=10051,
    source_ip='10.10.7.1'
)
```

[comment]: # ({/ba5ab006-8c41d6ba})

[comment]: # ({bff53bf5-de824c12})
##### Utilisation du délai d’expiration

Vous pouvez définir un `timeout` de réponse pour le `Sender` afin de contrôler combien de temps votre script doit attendre une réponse du serveur Zabbix ou du proxy avant d’abandonner :

```python
sender = Sender(
    server='127.0.0.1',
    port=10051,
    timeout=30
)
```

[comment]: # ({/bff53bf5-de824c12})

[comment]: # ({04ae72fb-62dd1793})
##### Utilisation du fichier de configuration de l'agent

Vous pouvez laisser zabbix\_utils lire les paramètres [`Server`](/manual/appendix/config/zabbix_agentd#server) ou [`ServerActive`](/manual/appendix/config/zabbix_agentd#serveractive) à partir d’un fichier de configuration local de l’agent Zabbix ou de l’agent 2.
Dans ce cas, vous n’avez pas besoin de spécifier les paramètres de connexion lors de la création d’une instance de `Sender` :

```python
sender = Sender(
    use_config=True,
    config_path='/etc/zabbix/zabbix_agent2.conf'
)
```

::: noteimportant
Si `ServerActive` contient un ou plusieurs clusters Zabbix avec plusieurs instances de serveur, `Sender` envoie les données au premier serveur disponible dans chaque cluster.
Si `ServerActive` n’est pas défini, l’adresse de `Server` avec le port par défaut (10051) est utilisée.
:::

[comment]: # ({/04ae72fb-62dd1793})

[comment]: # ({f95d47a7-a8b30296})
##### Utilisation du chiffrement

Le `Sender` n’inclut pas de prise en charge intégrée du chiffrement, mais vous pouvez l’ajouter en créant un wrapper à l’aide de bibliothèques tierces :

```python
def psk_wrapper(sock, tls):
    # ...
    # Implémentation du wrapper TLS PSK pour le socket
    # ...

sender = Sender(
    server='127.0.0.1',
    port=10051,
    socket_wrapper=psk_wrapper
)
```

[comment]: # ({/f95d47a7-a8b30296})

[comment]: # ({e0a8b11b-b6a3d94d})
##### Réponse pour une valeur unique

La réponse renvoyée par le serveur Zabbix ou le proxy est traitée par la bibliothèque et renvoyée sous la forme d’un objet `TrapperResponse` :

```python
print(response)
# {"processed": 1, "failed": 0, "total": 1, "time": "0.000123", "chunk": 1}

print(response.processed)
# 1

print(response.failed)
# 0

print(response.total)
# 1
```

[comment]: # ({/e0a8b11b-b6a3d94d})

[comment]: # ({d5faab4e-9eeea215})
##### Mode asynchrone

Le mode asynchrone permet à votre script Python d'envoyer des valeurs sans attendre de réponse du serveur Zabbix ou du proxy.
Cela peut rendre votre script plus efficace lorsqu'il doit envoyer de nombreuses valeurs ou lorsque certaines valeurs prennent beaucoup de temps à être envoyées.

Lors de l'utilisation du mode asynchrone, il existe quelques différences importantes par rapport au mode synchrone :

-   Importez le module `asyncio` de Python (vous devez d'abord [installer](/devel/python/install) les dépendances requises).
-   Importez `AsyncSender` au lieu de `Sender`.
-   Écrivez votre code dans une fonction `async`.
-   Utilisez `await` lors de l'appel de la méthode `send_value()`.

Par exemple, pour envoyer une seule valeur en utilisant le mode asynchrone :

```python
# 1. Import asyncio for asynchronous mode, and AsyncSender from zabbix_utils:
import asyncio
from zabbix_utils import AsyncSender

# 2. Define the main async function where all data sending operations (must await) will be executed:
async def main():
    sender = AsyncSender(server='127.0.0.1', port=10051)
    response = await sender.send_value('Linux server', 'service.status', 1)

    # 3. Print the response returned by Zabbix server or proxy:
    print(response)

# 4. Run the async main() function using asyncio's event loop:
asyncio.run(main())
```

[comment]: # ({/d5faab4e-9eeea215})

[comment]: # ({b845706b-34e0ff6d})
#### Envoyer plusieurs valeurs

Pour envoyer plusieurs valeurs :

1. Préparez un tableau d’objets `ItemValue`, chacun utilisant le même format que la méthode [`send_value()`](#send-single-value).
2. Créez une instance de `Sender`, en spécifiant l’adresse IP et le port de votre serveur Zabbix ou proxy.
3. Appelez la méthode `send()` (au lieu de `send_value()`) sur l’instance `Sender`, en indiquant le tableau d’objets contenant les valeurs à envoyer.

Par exemple, pour envoyer cinq valeurs à différents hôtes :

```python
items = [
    ItemValue('server-de', 'service.status', 'up', 1770887205, 100),
    ItemValue('server-fr', 'service.status', 'up', 1770887205, 100),
    ItemValue('server-uk', 'service.status', 'up', 1770887205, 100),
    ItemValue('server-nl', 'service.status', 'up', 1770887205, 100),
    ItemValue('server-pl', 'service.status', 'up', 1770887205, 100),
]

sender = Sender(server='127.0.0.1', port=10051)
response = sender.send(items)
```

[comment]: # ({/b845706b-34e0ff6d})

[comment]: # ({c0410a6d-5848e96f})
##### Utilisation d’une taille de bloc personnalisée

Si vous devez envoyer plus de valeurs qu’un élément collecteur ne peut en accepter dans une seule requête, vous pouvez les diviser en blocs.

Par défaut, la taille du bloc est de 250 valeurs.
Vous pouvez la modifier en définissant le paramètre `chunk_size` lors de la création d’une instance de `Sender`.

Par exemple, pour envoyer cinq valeurs en trois blocs (2-2-1), définissez le paramètre `chunk_size` sur `2` :

```python
items = [
    ItemValue('server-de', 'service.status', 'up'),
    ItemValue('server-fr', 'service.status', 'up'),
    ItemValue('server-uk', 'service.status', 'up'),
    ItemValue('server-nl', 'service.status', 'up'),
    ItemValue('server-pl', 'service.status', 'up'),
]

sender = Sender(server='127.0.0.1', port=10051, chunk_size=2)
response = sender.send(items)
```

[comment]: # ({/c0410a6d-5848e96f})

[comment]: # ({b06724dd-5a0b5783})
##### Envoyer des valeurs à plusieurs clusters Zabbix

Pour envoyer des valeurs à plusieurs clusters Zabbix :

1. Préparez un tableau de clusters Zabbix. Si un cluster comporte plusieurs nœuds, la valeur sera envoyée au premier nœud **disponible** de chaque cluster.
2. Créez un `Sender` en spécifiant votre tableau de clusters Zabbix.
3. Appelez la méthode `send_value()` sur l’instance `Sender` en utilisant le même format que la méthode [`send_value()`](#send-single-value).

Par exemple, pour envoyer une valeur au premier nœud disponible de chaque cluster :

```python
zabbix_clusters = [
    ['zabbix.cluster1.node1', 'zabbix.cluster1.node2:10051'],
    ['zabbix.cluster2.node1:10051', 'zabbix.cluster2.node2', 'zabbix.cluster2.node3']
]

sender = Sender(clusters=zabbix_clusters)
response = sender.send_value('Linux server', 'service.status', 1)
```

[comment]: # ({/b06724dd-5a0b5783})

[comment]: # ({2c3cc8b2-d7964287})
##### Réponse pour plusieurs valeurs

Par défaut, `Sender` renvoie un résultat agrégé de l’envoi des valeurs sur tous les hôtes ou clusters :

```python
print(response)
# {"processed": 2, "failed": 0, "total": 2, "time": "0.000108", "chunk": 2}
```

Si vous avez besoin d’informations plus détaillées, vous pouvez examiner les résultats pour chaque cluster et chaque bloc à l’aide de l’attribut `response.details` :

```python
print(response)
# {"processed": 2, "failed": 0, "total": 2, "time": "0.000108", "chunk": 2}

if response.failed == 0:
    print(f"Valeur envoyée avec succès en {response.time}")
else:
    print(response.details)
    # {
    #     127.0.0.1:10051: [
    #         {
    #             "processed": 1,
    #             "failed": 0,
    #             "total": 1,
    #             "time": "0.000051",
    #             "chunk": 1
    #         }
    #     ],
    #     zabbix.example.local:10051: [
    #         {
    #             "processed": 1,
    #             "failed": 0,
    #             "total": 1,
    #             "time": "0.000057",
    #             "chunk": 1
    #         }
    #     ]
    # }

    for node, chunks in response.details.items():
        for resp in chunks:
            print(f"Traité {resp.processed} sur {resp.total} à {node.address}:{node.port}")
            # Traité 1 sur 1 à 127.0.0.1:10051
            # Traité 1 sur 1 à zabbix.example.local:10051
```

[comment]: # ({/2c3cc8b2-d7964287})
